Improve AsyncToggle behavior on failure

This commit is contained in:
Shadowfacts 2024-04-09 11:49:03 -04:00
parent 42a3f6c880
commit e150856e91
4 changed files with 25 additions and 22 deletions

View File

@ -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<Mode>, onChange: @escaping (Bool) async -> Void) {
public init(_ titleKey: LocalizedStringKey, labelHidden: Bool = false, mode: Binding<Mode>, 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
}
}

View File

@ -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()
}
}

View File

@ -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
}
}
}

View File

@ -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)
}
}