krz/rune

an ios client for njalla

clone: git clone https://gitbay.org/krz/rune.git

v1.0.0: Rune/App/RuneApp.swift · raw

 1import SwiftUI
 2
 3@main
 4struct RuneApp: App {
 5    var body: some Scene {
 6        WindowGroup {
 7            RootView()
 8        }
 9    }
10}
11
12private struct RootView: View {
13    @StateObject private var settingsViewModel = SettingsViewModel()
14    @StateObject private var domainViewModel = DomainViewModel()
15    @StateObject private var tokenViewModel = TokenViewModel()
16    @State private var selectedTab = 0
17
18    var body: some View {
19        TabView(selection: $selectedTab) {
20            DomainListView(viewModel: domainViewModel, client: settingsViewModel.client)
21                .tabItem {
22                    Label("Domains", systemImage: "globe")
23                }
24                .tag(0)
25
26            TokenListView(viewModel: tokenViewModel, client: settingsViewModel.client) { deletedTokenKey in
27                do {
28                    let didLogout = try settingsViewModel.logoutIfCurrentTokenDeleted(deletedTokenKey)
29                    if didLogout {
30                        selectedTab = 0
31                    }
32                } catch {
33                    settingsViewModel.errorMessage = error.localizedDescription
34                }
35            }
36                .tabItem {
37                    Label("Tokens", systemImage: "key.horizontal")
38                }
39                .tag(1)
40
41            SettingsView(viewModel: settingsViewModel) {
42                domainViewModel.reset()
43                tokenViewModel.reset()
44                selectedTab = 0
45            }
46            .tabItem {
47                Label("Settings", systemImage: "gearshape")
48            }
49            .tag(2)
50        }
51        .task {
52            await settingsViewModel.bootstrap()
53        }
54        .task(id: settingsViewModel.isAuthenticated) {
55            guard let client = settingsViewModel.client else {
56                domainViewModel.reset()
57                tokenViewModel.reset()
58                selectedTab = 0
59                return
60            }
61
62            await domainViewModel.loadDomains(client: client)
63            await tokenViewModel.loadTokens(client: client)
64        }
65        .fullScreenCover(isPresented: onboardingBinding) {
66            OnboardingView(viewModel: settingsViewModel)
67        }
68    }
69
70    private var onboardingBinding: Binding<Bool> {
71        Binding(
72            get: { settingsViewModel.requiresOnboarding },
73            set: { _ in }
74        )
75    }
76}