From e150856e919b40d4ece37906883a4a333c798c5d Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Tue, 9 Apr 2024 11:49:03 -0400 Subject: [PATCH] Improve AsyncToggle behavior on failure --- .../Sources/TuskerComponents/AsyncToggle.swift | 13 +++++++++---- .../Notifications/NotificationsPrefsView.swift | 12 +++--------- .../Notifications/PushInstanceSettingsView.swift | 10 +++++++--- .../Notifications/PushSubscriptionView.swift | 12 ++++++------ 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/Packages/TuskerComponents/Sources/TuskerComponents/AsyncToggle.swift b/Packages/TuskerComponents/Sources/TuskerComponents/AsyncToggle.swift index fde3aaca..7f97802a 100644 --- a/Packages/TuskerComponents/Sources/TuskerComponents/AsyncToggle.swift +++ b/Packages/TuskerComponents/Sources/TuskerComponents/AsyncToggle.swift @@ -13,9 +13,9 @@ public struct AsyncToggle: View { @available(iOS, obsoleted: 16.0, message: "Switch to LabeledContent") let labelHidden: Bool @Binding var mode: Mode - let onChange: (Bool) async -> Void + let onChange: (Bool) async -> Bool - public init(_ titleKey: LocalizedStringKey, labelHidden: Bool = false, mode: Binding, onChange: @escaping (Bool) async -> Void) { + public init(_ titleKey: LocalizedStringKey, labelHidden: Bool = false, mode: Binding, onChange: @escaping (Bool) async -> Bool) { self.titleKey = titleKey self.labelHidden = labelHidden self._mode = mode @@ -46,8 +46,12 @@ public struct AsyncToggle: View { } set: { newValue in mode = .loading Task { - await onChange(newValue) - mode = newValue ? .on : .off + let operationCompleted = await onChange(newValue) + if operationCompleted { + mode = newValue ? .on : .off + } else { + mode = newValue ? .off : .on + } } }) .labelsHidden() @@ -70,5 +74,6 @@ public struct AsyncToggle: View { @State var mode = AsyncToggle.Mode.on return AsyncToggle("", mode: $mode) { _ in try! await Task.sleep(nanoseconds: NSEC_PER_SEC) + return true } } diff --git a/Tusker/Screens/Preferences/Notifications/NotificationsPrefsView.swift b/Tusker/Screens/Preferences/Notifications/NotificationsPrefsView.swift index 21d88ecd..a923f8d1 100644 --- a/Tusker/Screens/Preferences/Notifications/NotificationsPrefsView.swift +++ b/Tusker/Screens/Preferences/Notifications/NotificationsPrefsView.swift @@ -59,17 +59,11 @@ struct NotificationsPrefsView: View { .appGroupedListRowBackground() } - private func isSetupChanged(newValue: Bool) async { + private func isSetupChanged(newValue: Bool) async -> Bool { if newValue { - let success = await startRegistration() - if !success { - isSetup = .off - } + return await startRegistration() } else { - let success = await unregister() - if !success { - isSetup = .on - } + return await unregister() } } diff --git a/Tusker/Screens/Preferences/Notifications/PushInstanceSettingsView.swift b/Tusker/Screens/Preferences/Notifications/PushInstanceSettingsView.swift index cc0aa6e5..43bff3e2 100644 --- a/Tusker/Screens/Preferences/Notifications/PushInstanceSettingsView.swift +++ b/Tusker/Screens/Preferences/Notifications/PushInstanceSettingsView.swift @@ -45,13 +45,14 @@ struct PushInstanceSettingsView: View { } } - private func updateNotificationsEnabled(enabled: Bool) async { + private func updateNotificationsEnabled(enabled: Bool) async -> Bool { if enabled { do { try await enableNotifications() } catch { PushManager.logger.error("Error creating instance subscription: \(String(describing: error))") self.error = .enabling(error) + return false } } else { do { @@ -59,8 +60,10 @@ struct PushInstanceSettingsView: View { } catch { PushManager.logger.error("Error removing instance subscription: \(String(describing: error))") self.error = .disabling(error) + return false } } + return true } private func enableNotifications() async throws { @@ -96,8 +99,7 @@ struct PushInstanceSettingsView: View { PushManager.logger.debug("Push subscription removed on \(account.instanceURL)") } - private func updateSubscription(alerts: PushNotifications.PushSubscription.Alerts, policy: PushNotifications.PushSubscription.Policy) async { - try! await Task.sleep(nanoseconds: NSEC_PER_SEC) + private func updateSubscription(alerts: PushNotifications.PushSubscription.Alerts, policy: PushNotifications.PushSubscription.Policy) async -> Bool { let req = Pachyderm.PushSubscription.update(alerts: .init(alerts), policy: .init(policy)) let mastodonController = await MastodonController.getForAccount(account) do { @@ -105,9 +107,11 @@ struct PushInstanceSettingsView: View { PushManager.logger.debug("Push subscription \(result.id) updated on \(account.instanceURL)") subscription?.alerts = alerts subscription?.policy = policy + return true } catch { PushManager.logger.error("Error updating subscription: \(String(describing: error))") self.error = .updating(error) + return false } } } diff --git a/Tusker/Screens/Preferences/Notifications/PushSubscriptionView.swift b/Tusker/Screens/Preferences/Notifications/PushSubscriptionView.swift index 86b49073..dce41c53 100644 --- a/Tusker/Screens/Preferences/Notifications/PushSubscriptionView.swift +++ b/Tusker/Screens/Preferences/Notifications/PushSubscriptionView.swift @@ -14,7 +14,7 @@ import TuskerComponents struct PushSubscriptionView: View { let account: UserAccountInfo let subscription: PushSubscription? - let updateSubscription: (PushSubscription.Alerts, PushSubscription.Policy) async -> Void + let updateSubscription: (PushSubscription.Alerts, PushSubscription.Policy) async -> Bool var body: some View { if let subscription { @@ -29,10 +29,10 @@ struct PushSubscriptionView: View { private struct PushSubscriptionSettingsView: View { let account: UserAccountInfo let subscription: PushSubscription - let updateSubscription: (PushSubscription.Alerts, PushSubscription.Policy) async -> Void + let updateSubscription: (PushSubscription.Alerts, PushSubscription.Policy) async -> Bool @State private var isLoading: [PushSubscription.Alerts: Bool] = [:] - init(account: UserAccountInfo, subscription: PushSubscription, updateSubscription: @escaping (PushSubscription.Alerts, PushSubscription.Policy) async -> Void) { + init(account: UserAccountInfo, subscription: PushSubscription, updateSubscription: @escaping (PushSubscription.Alerts, PushSubscription.Policy) async -> Bool) { self.account = account self.subscription = subscription self.updateSubscription = updateSubscription @@ -64,18 +64,18 @@ private struct PushSubscriptionSettingsView: View { isLoading[alert] = newValue == .loading } return AsyncToggle(titleKey, mode: binding) { - await updateSubscription(alert: alert, isOn: $0) + return await updateSubscription(alert: alert, isOn: $0) } } - private func updateSubscription(alert: PushSubscription.Alerts, isOn: Bool) async { + private func updateSubscription(alert: PushSubscription.Alerts, isOn: Bool) async -> Bool { var newAlerts = subscription.alerts if isOn { newAlerts.insert(alert) } else { newAlerts.remove(alert) } - await updateSubscription(newAlerts, subscription.policy) + return await updateSubscription(newAlerts, subscription.policy) } }