Files
honeyDueKMP/iosApp/iosApp/MainTabView.swift
Trey t 73dd440d7b Add honeycomb pattern toggle and make theme switching reactive
Adds a toggleable honeycomb hexagonal grid overlay (matching the website pattern)
that can be enabled independently of any theme via the Appearance screen. Uses a
cached tiled UIImage approach consistent with the existing grain texture system.

Replaces the destructive refreshID-based theme switching (which destroyed all
NavigationStacks and dismissed sheets) with @Observable AppThemeSource. Color
resolution now happens through Swift's Observation framework, so all views using
Color.appPrimary etc. automatically re-render when the theme changes — no view
identity reset needed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 11:36:24 -06:00

126 lines
4.6 KiB
Swift

import SwiftUI
struct MainTabView: View {
enum Tab: Hashable {
case residences
case tasks
case contractors
case documents
}
@EnvironmentObject private var themeManager: ThemeManager
@State private var selectedTab: Tab = .residences
@State private var residencesPath = NavigationPath()
@State private var tasksPath = NavigationPath()
@State private var contractorsPath = NavigationPath()
@State private var documentsPath = NavigationPath()
@ObservedObject private var authManager = AuthenticationManager.shared
@ObservedObject private var pushManager = PushNotificationManager.shared
var refreshID: UUID
var body: some View {
TabView(selection: $selectedTab) {
NavigationStack(path: $residencesPath) {
ResidencesListView()
}
.id(refreshID)
.tabItem {
Label("Residences", image: "tab_view")
}
.tag(Tab.residences)
.accessibilityIdentifier(AccessibilityIdentifiers.Navigation.residencesTab)
NavigationStack(path: $tasksPath) {
AllTasksView()
}
.id(refreshID)
.tabItem {
Label("Tasks", systemImage: "checklist")
}
.tag(Tab.tasks)
.accessibilityIdentifier(AccessibilityIdentifiers.Navigation.tasksTab)
NavigationStack(path: $contractorsPath) {
ContractorsListView()
}
.id(refreshID)
.tabItem {
Label("Contractors", systemImage: "wrench.and.screwdriver.fill")
}
.tag(Tab.contractors)
.accessibilityIdentifier(AccessibilityIdentifiers.Navigation.contractorsTab)
NavigationStack(path: $documentsPath) {
DocumentsWarrantiesView(residenceId: nil)
}
.id(refreshID)
.tabItem {
Label("Docs", systemImage: "doc.text.fill")
}
.tag(Tab.documents)
.accessibilityIdentifier(AccessibilityIdentifiers.Navigation.documentsTab)
}
.tabViewStyle(.sidebarAdaptable)
.tint(Color.appPrimary)
.onChange(of: authManager.isAuthenticated) { _, _ in
selectedTab = .residences
}
.onChange(of: themeManager.currentTheme) { _, _ in
updateTabBarAppearance()
}
.onAppear {
updateTabBarAppearance()
// Handle pending navigation from push notification
if pushManager.pendingNavigationTaskId != nil {
selectedTab = .tasks
} else if pushManager.pendingNavigationDocumentId != nil {
selectedTab = .documents
} else if pushManager.pendingNavigationResidenceId != nil {
selectedTab = .residences
}
}
.onReceive(NotificationCenter.default.publisher(for: .navigateToTask)) { _ in
selectedTab = .tasks
}
.onReceive(NotificationCenter.default.publisher(for: .navigateToEditTask)) { _ in
selectedTab = .tasks
}
.onReceive(NotificationCenter.default.publisher(for: .navigateToResidence)) { _ in
selectedTab = .residences
}
.onReceive(NotificationCenter.default.publisher(for: .navigateToDocument)) { _ in
selectedTab = .documents
}
.onReceive(NotificationCenter.default.publisher(for: .navigateToHome)) { _ in
selectedTab = .residences
}
}
private func updateTabBarAppearance() {
let appearance = UITabBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = UIColor(Color.appBackgroundSecondary)
appearance.stackedLayoutAppearance.selected.iconColor = UIColor(Color.appPrimary)
appearance.stackedLayoutAppearance.selected.titleTextAttributes = [
.foregroundColor: UIColor(Color.appPrimary),
.font: UIFont.preferredFont(forTextStyle: .caption2)
]
appearance.stackedLayoutAppearance.normal.iconColor = UIColor(Color.appTextSecondary)
appearance.stackedLayoutAppearance.normal.titleTextAttributes = [
.foregroundColor: UIColor(Color.appTextSecondary),
.font: UIFont.preferredFont(forTextStyle: .caption2)
]
UITabBar.appearance().standardAppearance = appearance
UITabBar.appearance().scrollEdgeAppearance = appearance
}
}
#Preview {
MainTabView(refreshID: UUID())
.environmentObject(ThemeManager.shared)
}