Files
wristcode/watch/WristCode/WristCodeApp.swift
T

92 lines
3.6 KiB
Swift

// App entry. Notification setup and APNs registration go through the WatchKit app delegate, and
// `input` pushes get their own long look, which sets a question's options as its actions. The Snooze
// until picker opens over every screen, from a Recent row or the thread screen.
import SwiftUI
import WatchKit
@main
struct WristCodeApp: App {
@WKApplicationDelegateAdaptor(AppDelegate.self) private var delegate
@State private var model = AppModel.shared
var body: some Scene {
WindowGroup {
RootView()
.environment(model)
}
WKNotificationScene(controller: InputNotificationController.self, category: PushCategory.input.rawValue)
}
}
struct RootView: View {
@Environment(AppModel.self) private var model
var body: some View {
@Bindable var model = model
Group {
if model.mode == .unpaired {
PairView()
} else {
NavigationStack(path: $model.path) {
FeedView()
.navigationDestination(for: Route.self) { route in
// A new identity per route, so swapping one thread for another at the
// same place in the stack starts the screen's state and polling afresh.
Group {
switch route {
case let .thread(hostId, threadId):
ThreadView(hostId: hostId, threadId: threadId)
case .newThread:
NewThreadView()
case .recent:
RecentView()
case .snoozed:
SnoozedView()
case .status:
StatusView()
case let .host(id):
HostStatusView(hostId: id)
case .notifications:
NotificationsView()
case .allThreads:
HostsView()
case let .hostProjects(hostId):
ProjectsView(hostId: hostId)
case let .projectThreads(hostId, projectId):
ProjectThreadsView(hostId: hostId, projectId: projectId)
case let .search(query):
SearchView(query: query)
}
}
.id(route)
}
}
.sheet(item: $model.snoozing) { item in
NavigationStack {
SnoozePicker(item: item)
}
}
}
}
.fontDesign(.rounded)
.tint(Theme.work)
.onOpenURL { model.open(url: $0) }
}
}
final class AppDelegate: NSObject, WKApplicationDelegate {
func applicationDidFinishLaunching() {
NotificationHandler.shared.install()
Task { await AppModel.shared.enableNotifications() }
}
func didRegisterForRemoteNotifications(withDeviceToken deviceToken: Data) {
AppModel.shared.didRegister(apnsToken: deviceToken)
}
func didFailToRegisterForRemoteNotificationsWithError(_ error: any Error) {
print("APNs registration failed: \(error.localizedDescription)")
}
}