From 69793e85c5a7968e60014239aef5eecd8f14f3ea Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Sun, 1 Feb 2026 10:51:29 -0600 Subject: [PATCH] Signed-off-by: Matt Bruce --- PRD.md | 3 ++- TheNoiseClock/App/ContentView.swift | 5 +++++ .../Features/Clock/State/ClockViewModel.swift | 8 ++++++++ .../Features/Noise/Views/NoiseView.swift | 18 +++++++++++++----- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/PRD.md b/PRD.md index 4d46e04..5eb3a61 100644 --- a/PRD.md +++ b/PRD.md @@ -563,7 +563,8 @@ The following changes **automatically require** PRD updates: 4. **Auto-stop**: Automatically stops current sound when selecting new one 5. **Play/Stop Controls**: Simple button with visual feedback 6. **Continuous playback**: Sounds loop until stopped -7. **Responsive layout**: Optimized for portrait and landscape orientations +7. **Empty state guidance**: Prompt shown when no sound is selected +8. **Responsive layout**: Optimized for portrait and landscape orientations ## Technical Requirements diff --git a/TheNoiseClock/App/ContentView.swift b/TheNoiseClock/App/ContentView.swift index cfef8cd..775297e 100644 --- a/TheNoiseClock/App/ContentView.swift +++ b/TheNoiseClock/App/ContentView.swift @@ -58,6 +58,11 @@ struct ContentView: View { } .tag(Tab.settings) } + .onChange(of: selectedTab) { oldValue, newValue in + if oldValue == .clock && newValue != .clock { + clockViewModel.setDisplayMode(false) + } + } .accentColor(AppAccent.primary) .background(Color.Branding.primary.ignoresSafeArea()) } diff --git a/TheNoiseClock/Features/Clock/State/ClockViewModel.swift b/TheNoiseClock/Features/Clock/State/ClockViewModel.swift index 6afd8a8..ace4203 100644 --- a/TheNoiseClock/Features/Clock/State/ClockViewModel.swift +++ b/TheNoiseClock/Features/Clock/State/ClockViewModel.swift @@ -68,6 +68,14 @@ class ClockViewModel { // Manage wake lock based on display mode and keep awake setting updateWakeLockState() } + + func setDisplayMode(_ enabled: Bool) { + guard isDisplayMode != enabled else { return } + withAnimation(Design.Animation.spring(bounce: Design.Animation.springBounce)) { + isDisplayMode = enabled + } + updateWakeLockState() + } func updateStyle(_ newStyle: ClockStyle) { diff --git a/TheNoiseClock/Features/Noise/Views/NoiseView.swift b/TheNoiseClock/Features/Noise/Views/NoiseView.swift index f340e84..ee22fbb 100644 --- a/TheNoiseClock/Features/Noise/Views/NoiseView.swift +++ b/TheNoiseClock/Features/Noise/Views/NoiseView.swift @@ -74,15 +74,23 @@ struct NoiseView: View { VStack(spacing: 0) { // Fixed header VStack(alignment: .leading, spacing: Design.Spacing.medium) { - if !isPad { - Text("Ambient Sounds") - .sectionTitleStyle() - } - // Playback controls - always visible when sound is selected if selectedSound != nil { soundControlView .centered() + } else { + // Placeholder when no sound selected + VStack(spacing: Design.Spacing.small) { + Image(systemName: "music.note") + .font(.largeTitle) + .foregroundColor(.secondary) + + Text("Select a sound to begin") + .font(.subheadline) + .foregroundColor(.secondary) + } + .frame(maxWidth: .infinity) + .padding(.vertical, Design.Spacing.large) } } .contentPadding(horizontal: Design.Spacing.large)