Improve AsyncToggle behavior on failure
This commit is contained in:
parent
42a3f6c880
commit
e150856e91
|
@ -13,9 +13,9 @@ public struct AsyncToggle: View {
|
||||||
@available(iOS, obsoleted: 16.0, message: "Switch to LabeledContent")
|
@available(iOS, obsoleted: 16.0, message: "Switch to LabeledContent")
|
||||||
let labelHidden: Bool
|
let labelHidden: Bool
|
||||||
@Binding var mode: Mode
|
@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.titleKey = titleKey
|
||||||
self.labelHidden = labelHidden
|
self.labelHidden = labelHidden
|
||||||
self._mode = mode
|
self._mode = mode
|
||||||
|
@ -46,8 +46,12 @@ public struct AsyncToggle: View {
|
||||||
} set: { newValue in
|
} set: { newValue in
|
||||||
mode = .loading
|
mode = .loading
|
||||||
Task {
|
Task {
|
||||||
await onChange(newValue)
|
let operationCompleted = await onChange(newValue)
|
||||||
|
if operationCompleted {
|
||||||
mode = newValue ? .on : .off
|
mode = newValue ? .on : .off
|
||||||
|
} else {
|
||||||
|
mode = newValue ? .off : .on
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.labelsHidden()
|
.labelsHidden()
|
||||||
|
@ -70,5 +74,6 @@ public struct AsyncToggle: View {
|
||||||
@State var mode = AsyncToggle.Mode.on
|
@State var mode = AsyncToggle.Mode.on
|
||||||
return AsyncToggle("", mode: $mode) { _ in
|
return AsyncToggle("", mode: $mode) { _ in
|
||||||
try! await Task.sleep(nanoseconds: NSEC_PER_SEC)
|
try! await Task.sleep(nanoseconds: NSEC_PER_SEC)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,17 +59,11 @@ struct NotificationsPrefsView: View {
|
||||||
.appGroupedListRowBackground()
|
.appGroupedListRowBackground()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func isSetupChanged(newValue: Bool) async {
|
private func isSetupChanged(newValue: Bool) async -> Bool {
|
||||||
if newValue {
|
if newValue {
|
||||||
let success = await startRegistration()
|
return await startRegistration()
|
||||||
if !success {
|
|
||||||
isSetup = .off
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
let success = await unregister()
|
return await unregister()
|
||||||
if !success {
|
|
||||||
isSetup = .on
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,13 +45,14 @@ struct PushInstanceSettingsView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateNotificationsEnabled(enabled: Bool) async {
|
private func updateNotificationsEnabled(enabled: Bool) async -> Bool {
|
||||||
if enabled {
|
if enabled {
|
||||||
do {
|
do {
|
||||||
try await enableNotifications()
|
try await enableNotifications()
|
||||||
} catch {
|
} catch {
|
||||||
PushManager.logger.error("Error creating instance subscription: \(String(describing: error))")
|
PushManager.logger.error("Error creating instance subscription: \(String(describing: error))")
|
||||||
self.error = .enabling(error)
|
self.error = .enabling(error)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
do {
|
do {
|
||||||
|
@ -59,8 +60,10 @@ struct PushInstanceSettingsView: View {
|
||||||
} catch {
|
} catch {
|
||||||
PushManager.logger.error("Error removing instance subscription: \(String(describing: error))")
|
PushManager.logger.error("Error removing instance subscription: \(String(describing: error))")
|
||||||
self.error = .disabling(error)
|
self.error = .disabling(error)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private func enableNotifications() async throws {
|
private func enableNotifications() async throws {
|
||||||
|
@ -96,8 +99,7 @@ struct PushInstanceSettingsView: View {
|
||||||
PushManager.logger.debug("Push subscription removed on \(account.instanceURL)")
|
PushManager.logger.debug("Push subscription removed on \(account.instanceURL)")
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateSubscription(alerts: PushNotifications.PushSubscription.Alerts, policy: PushNotifications.PushSubscription.Policy) async {
|
private func updateSubscription(alerts: PushNotifications.PushSubscription.Alerts, policy: PushNotifications.PushSubscription.Policy) async -> Bool {
|
||||||
try! await Task.sleep(nanoseconds: NSEC_PER_SEC)
|
|
||||||
let req = Pachyderm.PushSubscription.update(alerts: .init(alerts), policy: .init(policy))
|
let req = Pachyderm.PushSubscription.update(alerts: .init(alerts), policy: .init(policy))
|
||||||
let mastodonController = await MastodonController.getForAccount(account)
|
let mastodonController = await MastodonController.getForAccount(account)
|
||||||
do {
|
do {
|
||||||
|
@ -105,9 +107,11 @@ struct PushInstanceSettingsView: View {
|
||||||
PushManager.logger.debug("Push subscription \(result.id) updated on \(account.instanceURL)")
|
PushManager.logger.debug("Push subscription \(result.id) updated on \(account.instanceURL)")
|
||||||
subscription?.alerts = alerts
|
subscription?.alerts = alerts
|
||||||
subscription?.policy = policy
|
subscription?.policy = policy
|
||||||
|
return true
|
||||||
} catch {
|
} catch {
|
||||||
PushManager.logger.error("Error updating subscription: \(String(describing: error))")
|
PushManager.logger.error("Error updating subscription: \(String(describing: error))")
|
||||||
self.error = .updating(error)
|
self.error = .updating(error)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import TuskerComponents
|
||||||
struct PushSubscriptionView: View {
|
struct PushSubscriptionView: View {
|
||||||
let account: UserAccountInfo
|
let account: UserAccountInfo
|
||||||
let subscription: PushSubscription?
|
let subscription: PushSubscription?
|
||||||
let updateSubscription: (PushSubscription.Alerts, PushSubscription.Policy) async -> Void
|
let updateSubscription: (PushSubscription.Alerts, PushSubscription.Policy) async -> Bool
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
if let subscription {
|
if let subscription {
|
||||||
|
@ -29,10 +29,10 @@ struct PushSubscriptionView: View {
|
||||||
private struct PushSubscriptionSettingsView: View {
|
private struct PushSubscriptionSettingsView: View {
|
||||||
let account: UserAccountInfo
|
let account: UserAccountInfo
|
||||||
let subscription: PushSubscription
|
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] = [:]
|
@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.account = account
|
||||||
self.subscription = subscription
|
self.subscription = subscription
|
||||||
self.updateSubscription = updateSubscription
|
self.updateSubscription = updateSubscription
|
||||||
|
@ -64,18 +64,18 @@ private struct PushSubscriptionSettingsView: View {
|
||||||
isLoading[alert] = newValue == .loading
|
isLoading[alert] = newValue == .loading
|
||||||
}
|
}
|
||||||
return AsyncToggle(titleKey, mode: binding) {
|
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
|
var newAlerts = subscription.alerts
|
||||||
if isOn {
|
if isOn {
|
||||||
newAlerts.insert(alert)
|
newAlerts.insert(alert)
|
||||||
} else {
|
} else {
|
||||||
newAlerts.remove(alert)
|
newAlerts.remove(alert)
|
||||||
}
|
}
|
||||||
await updateSubscription(newAlerts, subscription.policy)
|
return await updateSubscription(newAlerts, subscription.policy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue