FlurSchnaps-iOS/FlurSchnaps/ContentView.swift
Christoph Hagen 1c70b21e25 Sync push
2022-09-27 21:01:22 +02:00

170 lines
5.0 KiB
Swift

import SwiftUI
import SFSafeSymbols
import UniformTypeIdentifiers
struct ContentView: View {
@AppStorage("pushToken")
var pushToken: String?
var hasPushToken: Bool {
pushToken != nil
}
@State
var hasNotificationPermissions: Bool? = nil
func statusView(_ state: Bool?) -> some View {
let symbol: SFSymbol
let color: Color
if let state = state {
symbol = state ? .checkmarkCircle : .xmarkCircle
color = state ? .green : .red
} else {
symbol = .questionmarkCircle
color = .gray
}
return Image(systemSymbol: symbol)
.renderingMode(.template)
.foregroundColor(color)
}
func updateNotificationPermissionState() {
Task {
let state = await getPushPermissionState()
DispatchQueue.main.async {
hasNotificationPermissions = state
}
}
}
private func getPushPermissionState() async -> Bool? {
let settings = await UNUserNotificationCenter.current().notificationSettings()
switch settings.authorizationStatus {
case .authorized, .provisional, .ephemeral:
return true
case .denied:
return false
case .notDetermined:
return nil
@unknown default:
return nil
}
}
@State
private var didTapText = false
var tapFootnote: String {
if didTapText {
return "Copied to clipboard"
}
return "Double tap to copy token"
}
var body: some View {
NavigationView {
VStack(spacing: 8) {
HStack {
statusView(hasPushToken)
Text("remote-notifications-title")
}
HStack {
statusView(hasNotificationPermissions)
Text("notification-permissions-title")
}
Spacer()
if let token = pushToken {
Text("push-token-title")
Text(token)
.font(.body.monospaced())
.padding()
.onTapGesture(count: 2, perform: didDoubleTapToken)
Text(tapFootnote)
.font(.footnote)
} else {
Text("register-for-remote-notifications-text")
.padding()
.multilineTextAlignment(.center)
Button("register-for-remote-notifications-button", action: registerForRemoteNotifications)
.padding()
}
if hasNotificationPermissions == nil {
Button("request-notification-permission-button", action: requestNotificationPermission)
.padding()
} else if hasNotificationPermissions == false {
Text("no-notification-permissions-text")
.padding()
.multilineTextAlignment(.center)
Button("no-notification-permissions-button", action: openNotificationSettings)
.padding()
}
Spacer()
}
.navigationTitle("FlurSchnaps")
}
.onAppear {
startPeriodicUpdates()
}.onDisappear {
stopPeriodicUpdates()
}
}
private func didDoubleTapToken() {
UIPasteboard.general
.setValue(pushToken!, forPasteboardType: UTType.plainText.identifier)
didTapText = true
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(3)) {
self.didTapText = false
}
}
@State
private var timer: Timer?
private func startPeriodicUpdates() {
guard timer == nil else {
return
}
timer = Timer.scheduledTimer(withTimeInterval: 5, repeats: true) { _ in
updateState()
}
updateState()
}
private func stopPeriodicUpdates() {
timer?.invalidate()
timer = nil
}
private func updateState() {
updateNotificationPermissionState()
}
func registerForRemoteNotifications() {
UIApplication.shared.registerForRemoteNotifications()
}
func requestNotificationPermission() {
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in
updateNotificationPermissionState()
})
}
func openNotificationSettings() {
if let appSettings = URL(string: UIApplication.openSettingsURLString), UIApplication.shared.canOpenURL(appSettings) {
UIApplication.shared.open(appSettings)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.previewDevice("iPhone 8")
}
}