krz/rune
an ios client for njalla
clone: git clone https://gitbay.org/krz/rune.git
main: 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 @StateObject private var walletViewModel = WalletViewModel()
17 @State private var selectedTab = 0
18
19 var body: some View {
20 TabView(selection: $selectedTab) {
21 DomainListView(viewModel: domainViewModel, client: settingsViewModel.client)
22 .tabItem {
23 Label("Domains", systemImage: "globe")
24 }
25 .tag(0)
26
27 TokenListView(viewModel: tokenViewModel, client: settingsViewModel.client) { deletedTokenKey in
28 do {
29 let didLogout = try settingsViewModel.logoutIfCurrentTokenDeleted(deletedTokenKey)
30 if didLogout {
31 selectedTab = 0
32 }
33 } catch {
34 settingsViewModel.errorMessage = error.localizedDescription
35 }
36 }
37 .tabItem {
38 Label("Tokens", systemImage: "key.horizontal")
39 }
40 .tag(1)
41
42 SettingsView(viewModel: settingsViewModel, walletViewModel: walletViewModel) {
43 domainViewModel.reset()
44 tokenViewModel.reset()
45 walletViewModel.reset()
46 selectedTab = 0
47 }
48 .tabItem {
49 Label("Settings", systemImage: "gearshape")
50 }
51 .tag(2)
52 }
53 .task {
54 await settingsViewModel.bootstrap()
55 await syncAuthenticatedState()
56 }
57 .onChange(of: settingsViewModel.client) { _, _ in
58 Task {
59 await syncAuthenticatedState()
60 }
61 }
62 .fullScreenCover(isPresented: onboardingBinding) {
63 OnboardingView(viewModel: settingsViewModel)
64 }
65 }
66
67 private func syncAuthenticatedState() async {
68 guard let client = settingsViewModel.client else {
69 domainViewModel.reset()
70 tokenViewModel.reset()
71 walletViewModel.reset()
72 selectedTab = 0
73 return
74 }
75
76 await domainViewModel.loadDomains(client: client)
77 await tokenViewModel.loadTokens(client: client)
78 }
79
80 private var onboardingBinding: Binding<Bool> {
81 Binding(
82 get: { settingsViewModel.requiresOnboarding },
83 set: { _ in }
84 )
85 }
86}