Fix ring light color not updating when changed in settings

Issue: SwiftUI observation wasn't tracking color changes properly

Fixes:
1. Removed intermediate 'settings' computed property in ContentView
   - Was breaking SwiftUI's observation chain
   - Now access viewModel.settings directly everywhere

2. Added cached lightColorId for immediate UI response
   - Similar pattern to ringSize caching
   - Ensures SwiftUI tracks the stored property changes

This ensures the ring light color updates immediately when
selecting a different color preset or custom color in settings.
This commit is contained in:
Matt Bruce 2026-01-02 15:49:34 -06:00
parent c442acf464
commit 533e428e94
2 changed files with 16 additions and 14 deletions

View File

@ -8,15 +8,10 @@ struct ContentView: View {
@State private var showSettings = false
@State private var showShareSheet = false
// Direct reference to shared settings
private var settings: SettingsViewModel {
viewModel.settings
}
var body: some View {
GeometryReader { geometry in
let maxRingSize = calculateMaxRingSize(for: geometry)
let effectiveRingSize = min(settings.ringSize, maxRingSize)
let effectiveRingSize = min(viewModel.settings.ringSize, maxRingSize)
ZStack {
// MARK: - Ring Light Background
@ -26,7 +21,7 @@ struct ContentView: View {
cameraPreviewArea(ringSize: effectiveRingSize)
// MARK: - Grid Overlay
if settings.isGridVisible && !viewModel.isPreviewHidden {
if viewModel.settings.isGridVisible && !viewModel.isPreviewHidden {
GridOverlay(isVisible: true)
.padding(effectiveRingSize)
}
@ -47,8 +42,8 @@ struct ContentView: View {
.onChange(of: geometry.size) { _, newSize in
// Update max ring size when screen size changes
let newMax = min(newSize.width, newSize.height) / 4
if settings.ringSize > newMax {
settings.ringSize = newMax
if viewModel.settings.ringSize > newMax {
viewModel.settings.ringSize = newMax
}
}
}
@ -105,7 +100,8 @@ struct ContentView: View {
@ViewBuilder
private var ringLightBackground: some View {
let baseColor = premiumManager.isPremiumUnlocked ? settings.lightColor : Color.RingLight.pureWhite
// Access viewModel.settings directly to ensure SwiftUI observation works
let baseColor = premiumManager.isPremiumUnlocked ? viewModel.settings.lightColor : Color.RingLight.pureWhite
baseColor
.ignoresSafeArea()
@ -120,8 +116,8 @@ struct ContentView: View {
if !viewModel.isPreviewHidden {
CameraPreview(
viewModel: viewModel,
isMirrorFlipped: settings.isMirrorFlipped,
zoomFactor: settings.currentZoomFactor
isMirrorFlipped: viewModel.settings.isMirrorFlipped,
zoomFactor: viewModel.settings.currentZoomFactor
)
.clipShape(.rect(cornerRadius: Design.CornerRadius.large))
.padding(ringSize)

View File

@ -110,10 +110,16 @@ final class SettingsViewModel: RingLightConfigurable {
}
}
/// Cached light color ID for immediate UI updates
private var _cachedLightColorId: String?
/// ID of the selected light color preset
var lightColorId: String {
get { cloudSync.data.lightColorId }
set { updateSettings { $0.lightColorId = newValue } }
get { _cachedLightColorId ?? cloudSync.data.lightColorId }
set {
_cachedLightColorId = newValue
updateSettings { $0.lightColorId = newValue }
}
}
/// Cached custom color for immediate UI updates