From cc681dfeab30f14d9d775b9ea0ea2b98a3ac50ef Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Mon, 2 May 2022 10:26:51 +0200 Subject: [PATCH] Refine profile icons and animate if connected Assume 3 different profile states: - Active and connected - Active - Inactive --- Passepartout/App/Constants/Theme.swift | 12 ++++++++++ Passepartout/App/Views/ProfileRow.swift | 31 +++++++++++++++++++++---- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/Passepartout/App/Constants/Theme.swift b/Passepartout/App/Constants/Theme.swift index bfe05b71..e8501c33 100644 --- a/Passepartout/App/Constants/Theme.swift +++ b/Passepartout/App/Constants/Theme.swift @@ -156,6 +156,18 @@ extension View { "plus" } + var themeProfileActiveImage: String { + "circle" + } + + var themeProfileConnectedImage: String { + "circle.fill" + } + + var themeProfileInactiveImage: String { + "circle.dotted" + } + var themeCheckmarkImage: String { "checkmark" } diff --git a/Passepartout/App/Views/ProfileRow.swift b/Passepartout/App/Views/ProfileRow.swift index a3549d34..24657c08 100644 --- a/Passepartout/App/Views/ProfileRow.swift +++ b/Passepartout/App/Views/ProfileRow.swift @@ -40,8 +40,8 @@ struct ProfileRow: View { VPNStateView(isActive: isActive) .font(.subheadline) - .themeSecondaryTextStyle() }.padding([.top, .bottom], 5) + .opacity(isActive ? 1.0 : 0.5) } private var nameView: some View { @@ -52,6 +52,8 @@ struct ProfileRow: View { @ObservedObject private var currentVPNState: VPNManager.ObservableState private let isActive: Bool + + @State private var connectedOpacity = 1.0 init(isActive: Bool) { currentVPNState = .shared @@ -60,15 +62,14 @@ struct ProfileRow: View { var body: some View { HStack { -// Image(systemName: isActive ? "dot.radiowaves.up.forward" : "circle") + profileImage if isActive { - Image(systemName: "circle.fill") Text(statusDescription) + Spacer() currentVPNState.dataCount.map { Text($0.localizedDescription) } } else { - Image(systemName: "circle") Text(L10n.Tunnelkit.Vpn.unused) } } @@ -84,5 +85,27 @@ struct ProfileRow: View { return L10n.Organizer.Sections.active } } + + @ViewBuilder + private var profileImage: some View { + if isConnected { + Image(systemName: themeProfileConnectedImage) + .opacity(connectedOpacity) + .onAppear { + connectedOpacity = 1.0 + withAnimation(.easeInOut(duration: 1.0).repeatForever(autoreverses: true)) { + connectedOpacity = 0.05 + } + } + } else if isActive { + Image(systemName: themeProfileActiveImage) + } else { + Image(systemName: themeProfileInactiveImage) + } + } + + private var isConnected: Bool { + isActive && currentVPNState.vpnStatus == .connected + } } }