From 4ecdb8fbfe75765457d1f4fb28b14cb9eae29ae0 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Sun, 4 Jan 2026 14:57:09 -0600 Subject: [PATCH] Signed-off-by: Matt Bruce --- .../Features/Settings/SettingsViewModel.swift | 81 +++++++++++++++++-- 1 file changed, 74 insertions(+), 7 deletions(-) diff --git a/SelfieCam/Features/Settings/SettingsViewModel.swift b/SelfieCam/Features/Settings/SettingsViewModel.swift index 27d3502..656e83a 100644 --- a/SelfieCam/Features/Settings/SettingsViewModel.swift +++ b/SelfieCam/Features/Settings/SettingsViewModel.swift @@ -85,12 +85,20 @@ final class SettingsViewModel: RingLightConfigurable { static let defaultRingSize: CGFloat = 40 // MARK: - Premium Manager - + /// Premium manager for checking subscription status - private let premiumManager = PremiumManager() - - /// Whether the user has premium access - var isPremiumUnlocked: Bool { premiumManager.isPremiumUnlocked } + @ObservationIgnored private let premiumManager = PremiumManager() + + /// Whether the user has premium access (stored property for proper UI updates) + private var _isPremiumUnlocked: Bool = false + + /// Whether the user has premium access (observable for UI updates) + var isPremiumUnlocked: Bool { + get { _isPremiumUnlocked } + set { + _isPremiumUnlocked = newValue + } + } // MARK: - Cloud Sync Manager @@ -340,7 +348,64 @@ final class SettingsViewModel: RingLightConfigurable { /// Debug premium toggle for testing (DEBUG builds only) var isDebugPremiumEnabled: Bool { get { premiumManager.isDebugPremiumToggleEnabled } - set { premiumManager.isDebugPremiumToggleEnabled = newValue } + set { + let wasPremium = premiumManager.isDebugPremiumToggleEnabled + premiumManager.isDebugPremiumToggleEnabled = newValue + + // Update premium status for UI refresh + isPremiumUnlocked = premiumManager.isPremiumUnlocked + + // Reset premium settings when toggling OFF + if wasPremium && !newValue { + resetPremiumSettingsToDefaults() + } + } + } + + /// Reset premium-only settings to their free defaults when debug premium is disabled + private func resetPremiumSettingsToDefaults() { + // Clear cached values that depend on premium status + _cachedRingSize = nil + _cachedLightColorId = nil + _cachedCustomColor = nil + + // Reset premium settings to defaults (bypass premium gates for direct reset) + updateSettings { settings in + if settings.lightColorId != Self.defaultFreeColorId { + settings.lightColorId = Self.defaultFreeColorId + } + + if settings.isMirrorFlipped { + settings.isMirrorFlipped = false + } + + if settings.isSkinSmoothingEnabled { + settings.isSkinSmoothingEnabled = false + } + + if settings.isFlashSyncedWithRingLight { + settings.isFlashSyncedWithRingLight = false + } + + if settings.hdrModeRaw != CameraHDRMode.off.rawValue { + settings.hdrModeRaw = CameraHDRMode.off.rawValue + } + + if settings.photoQualityRaw != PhotoQuality.medium.rawValue { + settings.photoQualityRaw = PhotoQuality.medium.rawValue + } + + if settings.selectedTimerRaw != TimerOption.three.rawValue { + settings.selectedTimerRaw = TimerOption.three.rawValue + } + + if settings.isCenterStageEnabled { + settings.isCenterStageEnabled = false + } + } + + // Force sync to ensure changes are saved + forceSync() } /// Sets the custom color and selects it (PREMIUM) @@ -371,8 +436,10 @@ final class SettingsViewModel: RingLightConfigurable { var hasCompletedInitialSync: Bool { cloudSync.hasCompletedInitialSync } // MARK: - Initialization - + init() { + // Initialize premium status + _isPremiumUnlocked = premiumManager.isPremiumUnlocked // CloudSyncManager handles syncing automatically }