Delete profile from Organizer
Swipe to delete. Address a couple things on iPad though: 1. Also check provider availability before showing view fatalError hit on iPad when navigating from a ready provider profile to a non-ready one. Similar to when navigating between different VPN protocols. 2. Suppress assertion on deleted profile Deleting current profile via swipe seems to re-render a new NavigationLink with the deleted profile, which results in loading a deleted profile and hitting the assertion. Not sure if this is a programming error or a glitch in ForEach.
This commit is contained in:
parent
18161ed1f1
commit
5d85699ce4
|
@ -78,6 +78,7 @@ extension OrganizerView {
|
|||
List {
|
||||
Section {
|
||||
ForEach(headers.sorted(), content: navigationLink(forHeader:))
|
||||
.onDelete(perform: removeProfiles)
|
||||
.onAppear(perform: selectActiveProfile)
|
||||
}
|
||||
}
|
||||
|
@ -157,6 +158,15 @@ extension OrganizerView.ProfilesList {
|
|||
}
|
||||
}
|
||||
|
||||
private func removeProfiles(_ indexSet: IndexSet) {
|
||||
let headers = profileManager.headers.sorted()
|
||||
var toDelete: [UUID] = []
|
||||
indexSet.forEach {
|
||||
toDelete.append(headers[$0].id)
|
||||
}
|
||||
profileManager.removeProfiles(withIds: toDelete)
|
||||
}
|
||||
|
||||
private func dismissSelectionIfDeleted(headers: [Profile.Header]) {
|
||||
if let selectedProfileId = selectedProfileId,
|
||||
!profileManager.isExistingProfile(withId: selectedProfileId) {
|
||||
|
|
|
@ -44,7 +44,7 @@ extension ProfileView {
|
|||
var body: some View {
|
||||
debugChanges()
|
||||
return Group {
|
||||
if !isEmpty {
|
||||
if canDisplay {
|
||||
mainView
|
||||
} else {
|
||||
EmptyView()
|
||||
|
@ -52,8 +52,14 @@ extension ProfileView {
|
|||
}
|
||||
}
|
||||
|
||||
private var isEmpty: Bool {
|
||||
currentProfile.value.isPlaceholder || !currentProfile.value.isProvider
|
||||
private var canDisplay: Bool {
|
||||
guard !currentProfile.value.isPlaceholder else {
|
||||
return false
|
||||
}
|
||||
guard let providerName = currentProfile.value.header.providerName else {
|
||||
return false
|
||||
}
|
||||
return providerManager.isAvailable(providerName, vpnProtocol: currentProfile.value.currentVPNProtocol)
|
||||
}
|
||||
|
||||
private var mainView: some View {
|
||||
|
|
|
@ -53,8 +53,6 @@ struct ProfileView: View {
|
|||
@State private var modalType: ModalType?
|
||||
|
||||
@State private var isLoaded = false
|
||||
|
||||
@State private var isAskingRemoveProfile = false
|
||||
|
||||
init(header: Profile.Header?) {
|
||||
let profileManager: ProfileManager = .shared
|
||||
|
@ -98,7 +96,6 @@ struct ProfileView: View {
|
|||
)
|
||||
ExtraSection(currentProfile: profileManager.currentProfile)
|
||||
DiagnosticsSection(currentProfile: profileManager.currentProfile)
|
||||
removeProfileSection
|
||||
UninstallVPNSection()
|
||||
}
|
||||
|
||||
|
@ -152,47 +149,6 @@ struct ProfileView: View {
|
|||
}
|
||||
}
|
||||
|
||||
private var removeProfileSection: some View {
|
||||
Section {
|
||||
Button {
|
||||
isAskingRemoveProfile = true
|
||||
} label: {
|
||||
Label(L10n.Organizer.Alerts.RemoveProfile.title, systemImage: themeDeleteImage)
|
||||
}.foregroundColor(themeErrorColor)
|
||||
.actionSheet(isPresented: $isAskingRemoveProfile) {
|
||||
ActionSheet(
|
||||
title: Text(L10n.Organizer.Alerts.RemoveProfile.message(header.name)),
|
||||
message: nil,
|
||||
buttons: [
|
||||
.destructive(Text(L10n.Organizer.Alerts.RemoveProfile.title), action: confirmRemoveProfile),
|
||||
.cancel(Text(L10n.Global.Strings.cancel))
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func confirmRemoveProfile() {
|
||||
withAnimation {
|
||||
removeProfile()
|
||||
}
|
||||
}
|
||||
|
||||
private func removeProfile() {
|
||||
guard profileManager.isExistingProfile(withId: header.id) else {
|
||||
assertionFailure("Deleting non-existent profile \(header.name)")
|
||||
return
|
||||
}
|
||||
IntentDispatcher.forgetProfile(withHeader: header)
|
||||
profileManager.removeProfiles(withIds: [header.id])
|
||||
|
||||
// XXX: iOS 14, NavigationLink removal via header removal in OrganizerView+Profiles doesn't pop
|
||||
if #available(iOS 15, *) {
|
||||
} else {
|
||||
presentationMode.wrappedValue.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
private func loadProfileIfNeeded() {
|
||||
guard !isLoaded else {
|
||||
return
|
||||
|
|
|
@ -162,7 +162,7 @@ extension ProfileManager {
|
|||
}
|
||||
|
||||
guard let profile = strategy.profile(withId: id) else {
|
||||
assertionFailure("Profile in headers yet not found in persistent store")
|
||||
// assertionFailure("Profile in headers yet not found in persistent store")
|
||||
return nil
|
||||
}
|
||||
guard availabilityFilter?(profile.header) ?? true else {
|
||||
|
|
Loading…
Reference in New Issue