// // PushSubscriptionView.swift // Tusker // // Created by Shadowfacts on 4/7/24. // Copyright © 2024 Shadowfacts. All rights reserved. // import SwiftUI import UserAccounts import PushNotifications import TuskerComponents struct PushSubscriptionView: View { let account: UserAccountInfo let subscription: PushSubscription? let updateSubscription: (PushSubscription.Alerts, PushSubscription.Policy) async -> Void var body: some View { if let subscription { PushSubscriptionSettingsView(account: account, subscription: subscription, updateSubscription: updateSubscription) } else { Text("No notifications") .foregroundStyle(.secondary) } } } private struct PushSubscriptionSettingsView: View { let account: UserAccountInfo let subscription: PushSubscription let updateSubscription: (PushSubscription.Alerts, PushSubscription.Policy) async -> Void @State private var isLoading: [PushSubscription.Alerts: Bool] = [:] init(account: UserAccountInfo, subscription: PushSubscription, updateSubscription: @escaping (PushSubscription.Alerts, PushSubscription.Policy) async -> Void) { self.account = account self.subscription = subscription self.updateSubscription = updateSubscription } var body: some View { VStack(alignment: .prefsAvatar) { AsyncToggle("Mentions", mode: alertsBinding(for: .mention)) { await onChange(alert: .mention, value: $0) } } // this is the default value of the alignment guide, but this modifier is loading bearing .alignmentGuide(.prefsAvatar, computeValue: { dimension in dimension[.leading] }) // otherwise the flexible view makes the containing stack extend under the edge of the list row .padding(.leading, 38) } private func alertsBinding(for alert: PushSubscription.Alerts) -> Binding { return Binding { isLoading[alert] == true ? .loading : subscription.alerts.contains(alert) ? .on : .off } set: { newValue in isLoading[alert] = newValue == .loading } } private func onChange(alert: PushSubscription.Alerts, value: Bool) async { var newAlerts = subscription.alerts if value { newAlerts.insert(alert) } else { newAlerts.remove(alert) } await updateSubscription(newAlerts, subscription.policy) } } //#Preview { // PushSubscriptionView() //}