// // 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 -> Bool 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 -> Bool @State private var isLoading: [PushSubscription.Alerts: Bool] = [:] init(account: UserAccountInfo, subscription: PushSubscription, updateSubscription: @escaping (PushSubscription.Alerts, PushSubscription.Policy) async -> Bool) { self.account = account self.subscription = subscription self.updateSubscription = updateSubscription } var body: some View { VStack(alignment: .prefsAvatar) { toggle("All", alert: [.mention, .favorite, .reblog, .follow, .followRequest, .poll, .update]) toggle("Mentions", alert: .mention) toggle("Favorites", alert: .favorite) toggle("Reblogs", alert: .reblog) toggle("Follows", alert: [.follow, .followRequest]) toggle("Polls", alert: .poll) toggle("Edits", alert: .update) // status notifications not supported until we can enable/disable them in the app } // 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 toggle(_ titleKey: LocalizedStringKey, alert: PushSubscription.Alerts) -> some View { let binding: Binding = Binding { isLoading[alert] == true ? .loading : subscription.alerts.contains(alert) ? .on : .off } set: { newValue in isLoading[alert] = newValue == .loading } return AsyncToggle(titleKey, mode: binding) { return await updateSubscription(alert: alert, isOn: $0) } } private func updateSubscription(alert: PushSubscription.Alerts, isOn: Bool) async -> Bool { var newAlerts = subscription.alerts if isOn { newAlerts.insert(alert) } else { newAlerts.remove(alert) } return await updateSubscription(newAlerts, subscription.policy) } } //#Preview { // PushSubscriptionView() //}