diff --git a/Passepartout.xcodeproj/project.pbxproj b/Passepartout.xcodeproj/project.pbxproj index c6a77547..5372f780 100644 --- a/Passepartout.xcodeproj/project.pbxproj +++ b/Passepartout.xcodeproj/project.pbxproj @@ -117,6 +117,7 @@ 0EF2212D27E66EB5001D0BD7 /* AddProviderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EF2212C27E66EB5001D0BD7 /* AddProviderView.swift */; }; 0EF2212F27E66F60001D0BD7 /* AddProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EF2212E27E66F60001D0BD7 /* AddProfileView.swift */; }; 0EF2213127E674BD001D0BD7 /* AddProviderViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EF2213027E674BD001D0BD7 /* AddProviderViewModel.swift */; }; + 0EF708322811CC8400A3A308 /* VPNStatusText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EF708312811CC8400A3A308 /* VPNStatusText.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -328,6 +329,7 @@ 0EF2212C27E66EB5001D0BD7 /* AddProviderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddProviderView.swift; sourceTree = ""; }; 0EF2212E27E66F60001D0BD7 /* AddProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddProfileView.swift; sourceTree = ""; }; 0EF2213027E674BD001D0BD7 /* AddProviderViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddProviderViewModel.swift; sourceTree = ""; }; + 0EF708312811CC8400A3A308 /* VPNStatusText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNStatusText.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -454,6 +456,7 @@ 0E0BD27827B2EBE500583AC5 /* ShortcutsView.swift */, 0ED89C1B27DE3ABC008B36D6 /* ShortcutsView+Add.swift */, 0E71ACFA27C12E5300F85C4B /* VersionView.swift */, + 0EF708312811CC8400A3A308 /* VPNStatusText.swift */, ); path = Views; sourceTree = ""; @@ -896,6 +899,7 @@ 0EF2213127E674BD001D0BD7 /* AddProviderViewModel.swift in Sources */, 0E90DFE627BACC1500EF5078 /* AddHostViewModel.swift in Sources */, 0E34AC8227F892C40042F2AB /* OnDemandView+SSID.swift in Sources */, + 0EF708322811CC8400A3A308 /* VPNStatusText.swift in Sources */, 0E5324A627D297BB002565C3 /* InApp.swift in Sources */, 0E3B7FCD27E47B3700C66F13 /* AddHostView.swift in Sources */, 0EF2212D27E66EB5001D0BD7 /* AddProviderView.swift in Sources */, diff --git a/Passepartout/App/Views/OrganizerView+Profiles.swift b/Passepartout/App/Views/OrganizerView+Profiles.swift index 6374196b..de7c4ec1 100644 --- a/Passepartout/App/Views/OrganizerView+Profiles.swift +++ b/Passepartout/App/Views/OrganizerView+Profiles.swift @@ -91,11 +91,10 @@ extension OrganizerView { NavigationLink(tag: header.id, selection: $selectedProfileId) { ProfileView(header: header) } label: { - if profileManager.isActiveProfile(header.id) { - ActiveProfileHeaderRow(header: header) - } else { - ProfileHeaderRow(header: header) - } + ProfileHeaderRow( + header: header, + isActive: profileManager.isActiveProfile(header.id) + ) }.onAppear { preselectIfActiveProfile(header.id) @@ -114,32 +113,6 @@ extension OrganizerView { } } -extension OrganizerView.ProfilesList { - struct ActiveProfileHeaderRow: View { - @ObservedObject private var currentVPNState: VPNManager.ObservableState - - private let header: Profile.Header - - init(header: Profile.Header) { - currentVPNState = .shared - self.header = header - } - - var body: some View { - debugChanges() - return ProfileHeaderRow(header: header) - .withTrailingText(statusDescription) - } - - private var statusDescription: String { - return currentVPNState.localizedStatusDescription( - withErrors: false, - withDataCount: false - ) - } - } -} - extension OrganizerView.ProfilesList { private var sortedHeaders: [Profile.Header] { profileManager.headers.sorted() diff --git a/Passepartout/App/Views/ProfileHeaderRow.swift b/Passepartout/App/Views/ProfileHeaderRow.swift index d8fc1999..fe0f5654 100644 --- a/Passepartout/App/Views/ProfileHeaderRow.swift +++ b/Passepartout/App/Views/ProfileHeaderRow.swift @@ -29,24 +29,35 @@ import PassepartoutCore struct ProfileHeaderRow: View { let header: Profile.Header + let isActive: Bool + var body: some View { - if let name = header.providerName { - providerView(name) - } else { - hostView - } + VStack(alignment: .leading, spacing: 5) { + Group { + if let name = header.providerName { + providerView(name) + } else { + hostView + } + }.themeLongText() + .font(.body) + + if isActive { + VPNStatusText() + .foregroundColor(themeSecondaryColor) + .font(.caption) + } + }.frame(height: 60) } private func providerView(_ name: ProviderName) -> some View { // Label(header.name, systemImage: themeProviderImage) // Label(header.name, image: themeAssetsProviderImage(name)) Text(header.name) - .themeLongText() } private var hostView: some View { // Label(header.name, systemImage: themeHostImage) Text(header.name) - .themeLongText() } } diff --git a/Passepartout/App/Views/VPNStatusText.swift b/Passepartout/App/Views/VPNStatusText.swift new file mode 100644 index 00000000..8beb67a9 --- /dev/null +++ b/Passepartout/App/Views/VPNStatusText.swift @@ -0,0 +1,47 @@ +// +// VPNStatusText.swift +// Passepartout +// +// Created by Davide De Rosa on 4/21/22. +// Copyright (c) 2022 Davide De Rosa. All rights reserved. +// +// https://github.com/passepartoutvpn +// +// This file is part of Passepartout. +// +// Passepartout is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Passepartout is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Passepartout. If not, see . +// + +import SwiftUI +import PassepartoutCore + +struct VPNStatusText: View { + @ObservedObject private var currentVPNState: VPNManager.ObservableState + + init() { + currentVPNState = .shared + } + + var body: some View { + debugChanges() + return Text(statusDescription) + } + + private var statusDescription: String { + return currentVPNState.localizedStatusDescription( + withErrors: false, + withDataCount: true + ) + } +}