gitbay/gitbayApp.swift

v1.6.1
gitbay-ios/gitbay/gitbayApp.swift history · blame · raw

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}