gitbay/gitbayApp.swift
63 lines · 2623 bytes
1import SwiftUI
2
3@main
4struct gitbayApp: App {
5
6 @UIApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate
7 @State private var session: SessionStore
8 @State private var router = PushRouter()
9 @State private var registrar: PushRegistrar
10
11 init() {
12 GitbayFonts.register()
13 // The registrar takes the session at construction, so both are
14 // built here rather than as property initialisers — one
15 // registrar for the life of the app, which the delegate and
16 // SessionStore's removal hook then both point at.
17 let session = SessionStore()
18 _session = State(wrappedValue: session)
19 _registrar = State(wrappedValue: PushRegistrar(session: session))
20 }
21
22 var body: some Scene {
23 WindowGroup {
24 ContentView()
25 .environment(session)
26 .environment(router)
27 .environment(registrar)
28 .font(.gbSans(.body))
29 .tint(.gbAccent)
30 // The screenshot checkpoint forces appearance per run;
31 // simulator clones ignore the base device's setting.
32 .preferredColorScheme(Self.forcedColorScheme)
33 .task {
34 let registrar = self.registrar
35 appDelegate.registrar = registrar
36 appDelegate.router = router
37 appDelegate.session = session
38 // Weak: the registrar holds the session, and this
39 // closure is stored on the session.
40 session.willRemoveAccount = { [weak registrar] account in
41 await registrar?.deregister(account)
42 }
43 session.didAddAccount = { [weak registrar] account in
44 await registrar?.register(account)
45 }
46 // A tap that launched the app reaches the delegate
47 // before this runs; it parked the payload.
48 appDelegate.deliverPendingNotification()
49 await registrar.registerIfAlreadyAuthorized()
50 }
51 }
52 }
53
54 /// A clone follows whatever appearance it was created with, so the
55 /// checkpoint has to name the one it wants. Neither flag means the
56 /// app follows the system, as it does for real users.
57 private static var forcedColorScheme: ColorScheme? {
58 let args = ProcessInfo.processInfo.arguments
59 if args.contains("-gb-dark") { return .dark }
60 if args.contains("-gb-light") { return .light }
61 return nil
62 }
63}