Remove #if DEBUG guards for TestFlight, polish weekly digest and insights UX

- Remove #if DEBUG from all debug settings, exporters, and IAP bypass so
  debug options are available in TestFlight builds
- Weekly digest card: replace dismiss X with collapsible chevron caret
- Weekly digest: generate on-demand when opening Insights tab if no cached
  digest exists (BGTask + notification kept as bonus path)
- Fix digest intention text color (was .secondary, now uses theme textColor)
- Add "Generate Weekly Digest" debug button in Settings
- Add generating overlay on Insights tab with pulsing sparkles icon that
  stays visible until all sections finish loading (content at 0.2 opacity)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-04-04 11:15:23 -05:00
parent ab8d8fbdc0
commit 329fb7c671
16 changed files with 232 additions and 117 deletions

View File

@@ -37,13 +37,9 @@ class IAPManager: ObservableObject {
/// Set to `true` to bypass all subscription checks and grant full access (for development only)
/// Togglable at runtime in DEBUG builds via Settings > Debug > Bypass Subscription
#if DEBUG
@Published var bypassSubscription: Bool {
didSet { UserDefaults.standard.set(bypassSubscription, forKey: "debug_bypassSubscription") }
}
#else
let bypassSubscription = false
#endif
// MARK: - Constants
@@ -140,9 +136,7 @@ class IAPManager: ObservableObject {
// MARK: - Initialization
init() {
#if DEBUG
self.bypassSubscription = UserDefaults.standard.bool(forKey: "debug_bypassSubscription")
#endif
restoreCachedSubscriptionState()
updateListenerTask = listenForTransactions()
@@ -365,7 +359,6 @@ class IAPManager: ObservableObject {
return false
}
#if DEBUG
/// Reset subscription state for UI testing. Called after group defaults are cleared
/// so that stale cached state from previous test runs is discarded.
func resetForTesting() {
@@ -382,7 +375,6 @@ class IAPManager: ObservableObject {
updateTrialState()
}
#endif
private func updateTrialState() {
let daysSinceInstall = Calendar.current.dateComponents([.day], from: firstLaunchDate, to: Date()).day ?? 0