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>
This commit is contained in:
Trey t
2026-03-07 11:36:24 -06:00
parent 28339544e5
commit 73dd440d7b
9 changed files with 247 additions and 48 deletions
+22 -3
View File
@@ -88,7 +88,12 @@ class ThemeManager {
return .bright
}
var honeycombEnabled: Bool {
sharedDefaults.bool(forKey: honeycombKey)
}
private let themeKey = "selectedTheme"
private let honeycombKey = "honeycombEnabled"
private init() {}
}
@@ -104,7 +109,14 @@ class ThemeManager: ObservableObject {
}
}
@Published var honeycombEnabled: Bool {
didSet {
sharedDefaults.set(honeycombEnabled, forKey: honeycombKey)
}
}
private let themeKey = "selectedTheme"
private let honeycombKey = "honeycombEnabled"
private init() {
// Load saved theme from shared App Group defaults
@@ -114,17 +126,24 @@ class ThemeManager: ObservableObject {
} else {
self.currentTheme = .bright
}
self.honeycombEnabled = sharedDefaults.bool(forKey: honeycombKey)
}
private func saveTheme() {
// Save to shared App Group defaults so widgets can access it
sharedDefaults.set(currentTheme.rawValue, forKey: themeKey)
// Update reactive source so all views using Color.appPrimary etc. re-render
AppThemeSource.shared.themeName = currentTheme.rawValue
}
func setTheme(_ theme: ThemeID) {
withAnimation(.easeInOut(duration: 0.3)) {
currentTheme = theme
}
currentTheme = theme
}
func setHoneycomb(_ enabled: Bool) {
honeycombEnabled = enabled
// Update reactive source so honeycomb overlays re-render
AppThemeSource.shared.honeycombEnabled = enabled
}
}
#endif