Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>

This commit is contained in:
Matt Bruce 2026-02-09 14:13:22 -06:00
parent 950af793c0
commit bda088c9f3
3 changed files with 70 additions and 29 deletions

View File

@ -1682,7 +1682,6 @@
}
},
"Branding Preview" : {
"extractionState" : "stale",
"localizations" : {
"en" : {
"stringUnit" : {
@ -2101,7 +2100,6 @@
}
},
"Clear All Completions" : {
"extractionState" : "stale",
"localizations" : {
"es-MX" : {
"stringUnit" : {
@ -2352,7 +2350,6 @@
}
},
"Complete First Active Arc (Test Renewal)" : {
"extractionState" : "stale",
"localizations" : {
"es-MX" : {
"stringUnit" : {
@ -2949,7 +2946,6 @@
}
},
"Debug" : {
"extractionState" : "stale",
"localizations" : {
"en" : {
"stringUnit" : {
@ -3957,7 +3953,6 @@
}
},
"Generate the app icon" : {
"extractionState" : "stale",
"localizations" : {
"en" : {
"stringUnit" : {
@ -4471,7 +4466,6 @@
}
},
"Icon Generator" : {
"extractionState" : "stale",
"localizations" : {
"en" : {
"stringUnit" : {
@ -6094,7 +6088,6 @@
}
},
"Preload 6 Months Demo Data" : {
"extractionState" : "stale",
"localizations" : {
"es-MX" : {
"stringUnit" : {
@ -6219,7 +6212,6 @@
}
},
"Preview launch and icon" : {
"extractionState" : "stale",
"localizations" : {
"en" : {
"stringUnit" : {
@ -6337,7 +6329,6 @@
},
"Real" : {
"comment" : "The text for the \"Real\" option in the time of day picker.",
"extractionState" : "stale",
"isCommentAutoGenerated" : true,
"localizations" : {
"es-MX" : {
@ -6356,7 +6347,6 @@
},
"Real Time (%@)" : {
"comment" : "Text displayed in the debug picker to indicate whether it is showing the real time or a simulated time.",
"extractionState" : "stale",
"isCommentAutoGenerated" : true,
"localizations" : {
"es-MX" : {
@ -6468,7 +6458,6 @@
}
},
"Reload Widget Timelines" : {
"extractionState" : "stale",
"localizations" : {
"es-MX" : {
"stringUnit" : {
@ -6558,7 +6547,6 @@
},
"Reset Setup Wizard" : {
"comment" : "Title of a navigation row in the Settings view that resets the setup wizard state.",
"extractionState" : "stale",
"localizations" : {
"en" : {
"stringUnit" : {
@ -7245,7 +7233,6 @@
},
"Simulate Foreground Refresh" : {
"comment" : "Title of a settings option that simulates a foreground refresh of the app.",
"extractionState" : "stale",
"isCommentAutoGenerated" : true,
"localizations" : {
"es-MX" : {
@ -7264,7 +7251,6 @@
},
"Simulate Time of Day" : {
"comment" : "A label for the time of day picker.",
"extractionState" : "stale",
"isCommentAutoGenerated" : true,
"localizations" : {
"es-MX" : {
@ -8513,7 +8499,6 @@
},
"Trigger Test Notification (5s)" : {
"comment" : "Title of a settings option that triggers a test local notification.",
"extractionState" : "stale",
"isCommentAutoGenerated" : true,
"localizations" : {
"es-MX" : {

View File

@ -24,6 +24,8 @@ struct SettingsView: View {
isOn: remindersBinding,
accentColor: AppAccent.primary
)
SettingsDivider(color: AppBorder.subtle)
SettingsToggle(
title: String(localized: "Haptics"),
@ -31,6 +33,8 @@ struct SettingsView: View {
isOn: $store.hapticsEnabled,
accentColor: AppAccent.primary
)
SettingsDivider(color: AppBorder.subtle)
SettingsToggle(
title: String(localized: "Sound"),
@ -53,10 +57,12 @@ struct SettingsView: View {
)
if let categoryStore {
SettingsDivider(color: AppBorder.subtle)
SettingsNavigationRow(
title: String(localized: "Categories"),
subtitle: String(localized: "Manage ritual categories"),
backgroundColor: AppSurface.primary
backgroundColor: .clear
) {
CategoryListView(store: categoryStore)
}
@ -88,7 +94,7 @@ struct SettingsView: View {
SettingsNavigationRow(
title: String(localized: "Rituals mission"),
subtitle: String(localized: "Why arcs keep habits grounded"),
backgroundColor: AppSurface.primary
backgroundColor: .clear
) {
SettingsAboutView()
}
@ -105,15 +111,17 @@ struct SettingsView: View {
SettingsNavigationRow(
title: String(localized: "Icon Generator"),
subtitle: String(localized: "Generate the app icon"),
backgroundColor: AppSurface.primary
backgroundColor: .clear
) {
IconGeneratorView(config: .rituals, appName: "Rituals")
}
SettingsDivider(color: AppBorder.subtle)
SettingsNavigationRow(
title: String(localized: "Branding Preview"),
subtitle: String(localized: "Preview launch and icon"),
backgroundColor: AppSurface.primary
backgroundColor: .clear
) {
BrandingPreviewView(
iconConfig: .rituals,
@ -121,8 +129,10 @@ struct SettingsView: View {
appName: "Rituals"
)
}
SettingsDivider(color: AppBorder.subtle)
SettingsRow(
SettingsDebugActionRow(
systemImage: "arrow.counterclockwise",
title: String(localized: "Reset Setup Wizard"),
iconColor: AppStatus.warning
@ -133,7 +143,9 @@ struct SettingsView: View {
}
if let ritualStore {
SettingsRow(
SettingsDivider(color: AppBorder.subtle)
SettingsDebugActionRow(
systemImage: "calendar.badge.plus",
title: String(localized: "Preload 6 Months Demo Data"),
iconColor: AppStatus.info
@ -142,7 +154,9 @@ struct SettingsView: View {
}
.accessibilityIdentifier("settings.debug.preloadDemoData")
SettingsRow(
SettingsDivider(color: AppBorder.subtle)
SettingsDebugActionRow(
systemImage: "checkmark.circle.badge.xmark",
title: String(localized: "Complete First Active Arc (Test Renewal)"),
iconColor: AppStatus.success
@ -150,7 +164,9 @@ struct SettingsView: View {
ritualStore.simulateArcCompletion()
}
SettingsRow(
SettingsDivider(color: AppBorder.subtle)
SettingsDebugActionRow(
systemImage: "trash",
title: String(localized: "Clear All Completions"),
iconColor: AppStatus.error
@ -158,7 +174,9 @@ struct SettingsView: View {
ritualStore.clearAllCompletions()
}
SettingsRow(
SettingsDivider(color: AppBorder.subtle)
SettingsDebugActionRow(
systemImage: "bell.badge",
title: String(localized: "Trigger Test Notification (5s)"),
iconColor: AppStatus.info
@ -167,7 +185,9 @@ struct SettingsView: View {
}
}
SettingsRow(
SettingsDivider(color: AppBorder.subtle)
SettingsDebugActionRow(
systemImage: "arrow.clockwise",
title: String(localized: "Simulate Foreground Refresh"),
iconColor: AppStatus.info
@ -175,7 +195,9 @@ struct SettingsView: View {
UserDefaults.standard.set(true, forKey: "debugForegroundRefreshNextForeground")
}
SettingsRow(
SettingsDivider(color: AppBorder.subtle)
SettingsDebugActionRow(
systemImage: "widget.small",
title: String(localized: "Reload Widget Timelines"),
iconColor: AppAccent.primary
@ -184,7 +206,11 @@ struct SettingsView: View {
}
if let ritualStore {
TimeOfDayDebugPicker(store: ritualStore)
SettingsDivider(color: AppBorder.subtle)
SettingsCardRow {
TimeOfDayDebugPicker(store: ritualStore)
}
}
}
#endif
@ -257,6 +283,37 @@ extension SettingsView {
// MARK: - Debug Time of Day Picker
#if DEBUG
private struct SettingsDebugActionRow: View {
let systemImage: String
let title: String
let iconColor: Color
let action: () -> Void
var body: some View {
SettingsCardRow {
Button(action: action) {
HStack(spacing: Design.Spacing.medium) {
SymbolIcon(systemImage, size: .inline, color: .white)
.frame(width: Design.Size.iconContainerSmall, height: Design.Size.iconContainerSmall)
.background(iconColor.opacity(Design.Opacity.heavy))
.clipShape(.rect(cornerRadius: Design.CornerRadius.xSmall))
Text(title).styled(.subheading)
Spacer()
SymbolIcon.chevron()
}
.padding(.vertical, Design.Spacing.medium)
.padding(.horizontal, Design.Spacing.medium)
.background(Color(.secondarySystemGroupedBackground))
.clipShape(.rect(cornerRadius: Design.CornerRadius.small))
}
.buttonStyle(.plain)
}
}
}
/// Debug picker for simulating different times of day
private struct TimeOfDayDebugPicker: View {
@Bindable var store: RitualStore
@ -328,7 +385,6 @@ private struct TimeOfDayDebugPicker: View {
}
}
}
.padding(.horizontal, Design.Spacing.medium)
}
}
#endif

View File

@ -158,7 +158,7 @@ Andromida/
- **Theming**: App-specific color providers + `AppSurface`, `AppAccent`, etc.
- **Branding**: AppLaunchView, AppIconConfig, LaunchScreenConfig
- **Settings UI**: SettingsToggle, SettingsSlider, SettingsSegmentedPicker, SettingsCard
- **Settings UI**: `SettingsCard` owns row insets; use `SettingsDivider` between rows, `SettingsCardRow` for custom rows, and `SettingsNavigationRow(backgroundColor: .clear)` for in-card navigation
- **Cloud Sync**: iCloud sync for settings using CloudSyncManager
- **Onboarding**: Custom `SetupWizardView` flow (Sherpa integration pending)