diff options
| author | Christian Cleberg <[email protected]> | 2026-03-24 21:48:23 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-03-24 21:48:23 -0500 |
| commit | cf587aa0573ac4f34e1effe70108a9eca82093ac (patch) | |
| tree | 833e6f4961522e35b08af01b5f012983f8e34678 /Rune/App | |
| download | rune-cf587aa0573ac4f34e1effe70108a9eca82093ac.tar.gz rune-cf587aa0573ac4f34e1effe70108a9eca82093ac.tar.bz2 rune-cf587aa0573ac4f34e1effe70108a9eca82093ac.zip | |
v1.0v1.0.0
Diffstat (limited to 'Rune/App')
| -rw-r--r-- | Rune/App/RuneApp.swift | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/Rune/App/RuneApp.swift b/Rune/App/RuneApp.swift new file mode 100644 index 0000000..8c63dd6 --- /dev/null +++ b/Rune/App/RuneApp.swift @@ -0,0 +1,76 @@ +import SwiftUI + +@main +struct RuneApp: App { + var body: some Scene { + WindowGroup { + RootView() + } + } +} + +private struct RootView: View { + @StateObject private var settingsViewModel = SettingsViewModel() + @StateObject private var domainViewModel = DomainViewModel() + @StateObject private var tokenViewModel = TokenViewModel() + @State private var selectedTab = 0 + + var body: some View { + TabView(selection: $selectedTab) { + DomainListView(viewModel: domainViewModel, client: settingsViewModel.client) + .tabItem { + Label("Domains", systemImage: "globe") + } + .tag(0) + + TokenListView(viewModel: tokenViewModel, client: settingsViewModel.client) { deletedTokenKey in + do { + let didLogout = try settingsViewModel.logoutIfCurrentTokenDeleted(deletedTokenKey) + if didLogout { + selectedTab = 0 + } + } catch { + settingsViewModel.errorMessage = error.localizedDescription + } + } + .tabItem { + Label("Tokens", systemImage: "key.horizontal") + } + .tag(1) + + SettingsView(viewModel: settingsViewModel) { + domainViewModel.reset() + tokenViewModel.reset() + selectedTab = 0 + } + .tabItem { + Label("Settings", systemImage: "gearshape") + } + .tag(2) + } + .task { + await settingsViewModel.bootstrap() + } + .task(id: settingsViewModel.isAuthenticated) { + guard let client = settingsViewModel.client else { + domainViewModel.reset() + tokenViewModel.reset() + selectedTab = 0 + return + } + + await domainViewModel.loadDomains(client: client) + await tokenViewModel.loadTokens(client: client) + } + .fullScreenCover(isPresented: onboardingBinding) { + OnboardingView(viewModel: settingsViewModel) + } + } + + private var onboardingBinding: Binding<Bool> { + Binding( + get: { settingsViewModel.requiresOnboarding }, + set: { _ in } + ) + } +} |
