Refine profile icons and animate if connected
Assume 3 different profile states: - Active and connected - Active - Inactive
This commit is contained in:
parent
576eb1512a
commit
cc681dfeab
|
@ -156,6 +156,18 @@ extension View {
|
||||||
"plus"
|
"plus"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var themeProfileActiveImage: String {
|
||||||
|
"circle"
|
||||||
|
}
|
||||||
|
|
||||||
|
var themeProfileConnectedImage: String {
|
||||||
|
"circle.fill"
|
||||||
|
}
|
||||||
|
|
||||||
|
var themeProfileInactiveImage: String {
|
||||||
|
"circle.dotted"
|
||||||
|
}
|
||||||
|
|
||||||
var themeCheckmarkImage: String {
|
var themeCheckmarkImage: String {
|
||||||
"checkmark"
|
"checkmark"
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,8 +40,8 @@ struct ProfileRow: View {
|
||||||
|
|
||||||
VPNStateView(isActive: isActive)
|
VPNStateView(isActive: isActive)
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
.themeSecondaryTextStyle()
|
|
||||||
}.padding([.top, .bottom], 5)
|
}.padding([.top, .bottom], 5)
|
||||||
|
.opacity(isActive ? 1.0 : 0.5)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var nameView: some View {
|
private var nameView: some View {
|
||||||
|
@ -53,6 +53,8 @@ struct ProfileRow: View {
|
||||||
|
|
||||||
private let isActive: Bool
|
private let isActive: Bool
|
||||||
|
|
||||||
|
@State private var connectedOpacity = 1.0
|
||||||
|
|
||||||
init(isActive: Bool) {
|
init(isActive: Bool) {
|
||||||
currentVPNState = .shared
|
currentVPNState = .shared
|
||||||
self.isActive = isActive
|
self.isActive = isActive
|
||||||
|
@ -60,15 +62,14 @@ struct ProfileRow: View {
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
HStack {
|
HStack {
|
||||||
// Image(systemName: isActive ? "dot.radiowaves.up.forward" : "circle")
|
profileImage
|
||||||
if isActive {
|
if isActive {
|
||||||
Image(systemName: "circle.fill")
|
|
||||||
Text(statusDescription)
|
Text(statusDescription)
|
||||||
|
Spacer()
|
||||||
currentVPNState.dataCount.map {
|
currentVPNState.dataCount.map {
|
||||||
Text($0.localizedDescription)
|
Text($0.localizedDescription)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Image(systemName: "circle")
|
|
||||||
Text(L10n.Tunnelkit.Vpn.unused)
|
Text(L10n.Tunnelkit.Vpn.unused)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,5 +85,27 @@ struct ProfileRow: View {
|
||||||
return L10n.Organizer.Sections.active
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue