diff options
Diffstat (limited to 'DomainDig/RootTabView.swift')
| -rw-r--r-- | DomainDig/RootTabView.swift | 136 |
1 files changed, 93 insertions, 43 deletions
diff --git a/DomainDig/RootTabView.swift b/DomainDig/RootTabView.swift index 9823d37..db1f524 100644 --- a/DomainDig/RootTabView.swift +++ b/DomainDig/RootTabView.swift @@ -1,15 +1,36 @@ import SwiftUI -private enum RootTab: Hashable { +private enum RootTab: Hashable, CaseIterable { case dashboard case audit case history case inspect case settings + + var title: String { + switch self { + case .dashboard: return "Dashboard" + case .audit: return "Audit" + case .history: return "History" + case .inspect: return "Inspect" + case .settings: return "Settings" + } + } + + var systemImage: String { + switch self { + case .dashboard: return "square.grid.2x2" + case .audit: return "checklist" + case .history: return "clock.arrow.trianglehead.counterclockwise.rotate.90" + case .inspect: return "magnifyingglass" + case .settings: return "gearshape" + } + } } struct RootTabView: View { @Bindable var viewModel: DomainViewModel + @Environment(\.horizontalSizeClass) private var horizontalSizeClass @State private var purchaseService = PurchaseService.shared @State private var intentRouter = DomainDigIntentRouter.shared @State private var detailDomain: TrackedDomain? @@ -18,44 +39,12 @@ struct RootTabView: View { var body: some View { let _ = purchaseService.currentTier - TabView(selection: $selectedTab) { - NavigationStack { - DashboardView(viewModel: viewModel) - } - .tabItem { - Label("Dashboard", systemImage: "square.grid.2x2") - } - .tag(RootTab.dashboard) - - NavigationStack { - AuditListView(viewModel: viewModel) - } - .tabItem { - Label("Audit", systemImage: "checklist") - } - .tag(RootTab.audit) - - NavigationStack { - HistoryView(viewModel: viewModel) - } - .tabItem { - Label("History", systemImage: "clock.arrow.trianglehead.counterclockwise.rotate.90") - } - .tag(RootTab.history) - - ContentView(viewModel: viewModel) - .tabItem { - Label("Inspect", systemImage: "magnifyingglass") - } - .tag(RootTab.inspect) - - NavigationStack { - SettingsView(viewModel: viewModel) - } - .tabItem { - Label("Settings", systemImage: "gearshape") + Group { + if horizontalSizeClass == .regular { + splitLayout + } else { + tabLayout } - .tag(RootTab.settings) } .sheet(isPresented: Binding( get: { viewModel.isPaywallPresented }, @@ -79,16 +68,16 @@ struct RootTabView: View { } ) } - .onChange(of: purchaseService.currentTier) { _, newValue in - if newValue != .free, selectedTab == .inspect, viewModel.trackedDomains.isEmpty == false { - selectedTab = .dashboard - } - } .sheet(item: $detailDomain) { trackedDomain in NavigationStack { TrackedDomainDetailView(viewModel: viewModel, trackedDomain: trackedDomain) } } + .onChange(of: purchaseService.currentTier) { _, newValue in + if newValue != .free, selectedTab == .inspect, viewModel.trackedDomains.isEmpty == false { + selectedTab = .dashboard + } + } .onOpenURL { url in guard let action = DomainDigDeepLink.action(from: url) else { return } perform(action) @@ -101,6 +90,67 @@ struct RootTabView: View { } } + // MARK: Layouts + + /// Compact (iPhone, iPad slide-over): the classic tab bar. + private var tabLayout: some View { + TabView(selection: $selectedTab) { + ForEach(RootTab.allCases, id: \.self) { tab in + section(for: tab) + .tabItem { + Label(tab.title, systemImage: tab.systemImage) + } + .tag(tab) + } + } + } + + /// Regular width (iPad, large iPhone landscape): two-column split view. + private var splitLayout: some View { + NavigationSplitView { + List(RootTab.allCases, id: \.self, selection: sidebarSelection) { tab in + Label(tab.title, systemImage: tab.systemImage) + .tag(tab) + } + .navigationTitle("DomainDig") + } detail: { + section(for: selectedTab) + } + } + + private var sidebarSelection: Binding<RootTab?> { + Binding( + get: { selectedTab }, + set: { selectedTab = $0 ?? selectedTab } + ) + } + + @ViewBuilder + private func section(for tab: RootTab) -> some View { + switch tab { + case .dashboard: + NavigationStack { + DashboardView(viewModel: viewModel) + } + case .audit: + NavigationStack { + AuditListView(viewModel: viewModel) + } + case .history: + NavigationStack { + HistoryView(viewModel: viewModel) + } + case .inspect: + ContentView(viewModel: viewModel) + case .settings: + NavigationStack { + SettingsView(viewModel: viewModel) + } + } + } + + // MARK: Intent / deep-link routing + private func consume(_ action: DomainDigDeepLink.Action?) { guard let action else { return } intentRouter.pendingAction = nil |
