Restore active profile on top
Flashing on activation was caused by VPNManager.disable() in ProfileView+VPN, because by setting lastError to nil it would notify a change to ProfileRow (via VPNStateView) during the profile row activation animation. That caused the flicker. Instead, disable VPN first, then start the animation. Anyway, avoid clearing a nil lastError.
This commit is contained in:
parent
edc7cdf045
commit
cfc0d4f572
|
@ -220,18 +220,15 @@ struct OrganizerView: View {
|
|||
|
||||
private var sortedHeaders: [Profile.Header] {
|
||||
profileManager.headers
|
||||
.sorted()
|
||||
|
||||
// FIXME: layout, moving active profile on top breaks row animation (content flashes on Mac)
|
||||
// .sorted {
|
||||
// if profileManager.isActiveProfile($0.id) {
|
||||
// return true
|
||||
// } else if profileManager.isActiveProfile($1.id) {
|
||||
// return false
|
||||
// } else {
|
||||
// return $0 < $1
|
||||
// }
|
||||
// }
|
||||
.sorted {
|
||||
if profileManager.isActiveProfile($0.id) {
|
||||
return true
|
||||
} else if profileManager.isActiveProfile($1.id) {
|
||||
return false
|
||||
} else {
|
||||
return $0 < $1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,8 @@ struct ProfileRow: View {
|
|||
let isActive: Bool
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 5) {
|
||||
debugChanges()
|
||||
return VStack(alignment: .leading, spacing: 5) {
|
||||
nameView
|
||||
.font(.headline)
|
||||
.themeLongTextStyle()
|
||||
|
|
|
@ -113,14 +113,18 @@ extension ProfileView {
|
|||
header: headerView
|
||||
) {
|
||||
Button(L10n.Profile.Items.UseProfile.caption) {
|
||||
withAnimation {
|
||||
profileManager.activateCurrentProfile()
|
||||
|
||||
// IMPORTANT: save immediately to keep in sync with VPN status
|
||||
appManager.activeProfileId = profileManager.activeHeader?.id
|
||||
}
|
||||
Task {
|
||||
|
||||
// do this first to not override subsequent animation
|
||||
// active profile may flicker due to unnecessary VPN updates
|
||||
await vpnManager.disable()
|
||||
|
||||
withAnimation {
|
||||
profileManager.activateCurrentProfile()
|
||||
|
||||
// IMPORTANT: save immediately to keep in sync with VPN status
|
||||
appManager.activeProfileId = profileManager.activeHeader?.id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ public class VPNManager: ObservableObject {
|
|||
}
|
||||
Task {
|
||||
pp_log.info("Toggling VPN (enabled: \(currentState.isEnabled) -> \(!currentState.isEnabled))")
|
||||
currentState.lastError = nil
|
||||
clearLastError()
|
||||
if !currentState.isEnabled {
|
||||
await strategy.connect(configuration: configuration)
|
||||
} else {
|
||||
|
@ -98,25 +98,24 @@ public class VPNManager: ObservableObject {
|
|||
|
||||
func reinstate(_ configuration: VPNConfiguration) async {
|
||||
pp_log.info("Reinstating VPN")
|
||||
currentState.lastError = nil
|
||||
clearLastError()
|
||||
await strategy.reinstate(configuration: configuration)
|
||||
}
|
||||
|
||||
func reconnect(_ configuration: VPNConfiguration) async {
|
||||
pp_log.info("Reconnecting VPN")
|
||||
currentState.lastError = nil
|
||||
await strategy.connect(configuration: configuration)
|
||||
}
|
||||
|
||||
public func disable() async {
|
||||
pp_log.info("Disabling VPN")
|
||||
currentState.lastError = nil
|
||||
clearLastError()
|
||||
await strategy.disconnect()
|
||||
}
|
||||
|
||||
public func uninstall() async {
|
||||
pp_log.info("Uninstalling VPN")
|
||||
currentState.lastError = nil
|
||||
clearLastError()
|
||||
await strategy.removeConfigurations()
|
||||
}
|
||||
|
||||
|
@ -127,6 +126,13 @@ public class VPNManager: ObservableObject {
|
|||
public func debugLogURL(forProtocol vpnProtocol: VPNProtocolType) -> URL? {
|
||||
return strategy.debugLogURL(forProtocol: vpnProtocol)
|
||||
}
|
||||
|
||||
private func clearLastError() {
|
||||
guard currentState.lastError != nil else {
|
||||
return
|
||||
}
|
||||
currentState.lastError = nil
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Observation
|
||||
|
|
Loading…
Reference in New Issue