77 lines
2.5 KiB
Swift
77 lines
2.5 KiB
Swift
//
|
|
// 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<AsyncToggle.Mode> {
|
|
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()
|
|
//}
|