// 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 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) } } } .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)") } }