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

This commit is contained in:
Matt Bruce 2025-09-10 13:03:33 -05:00
parent 7f6f5817e1
commit 38469f4ca8
4 changed files with 107 additions and 4 deletions

View File

@ -86,7 +86,7 @@ class ClockViewModel {
} }
} }
private func saveStyle() { func saveStyle() {
persistenceWorkItem?.cancel() persistenceWorkItem?.cancel()
let work = DispatchWorkItem { let work = DispatchWorkItem {

View File

@ -13,6 +13,7 @@ struct ClockView: View {
// MARK: - Properties // MARK: - Properties
@State private var viewModel = ClockViewModel() @State private var viewModel = ClockViewModel()
@State private var showSettings = false @State private var showSettings = false
@State private var showFullScreenHint = false
// MARK: - Body // MARK: - Body
var body: some View { var body: some View {
@ -31,6 +32,11 @@ struct ClockView: View {
// Top overlay container // Top overlay container
ClockOverlayContainer(style: viewModel.style) ClockOverlayContainer(style: viewModel.style)
// Full screen hint overlay
if showFullScreenHint {
FullScreenHintView(isDisplayMode: viewModel.isDisplayMode)
}
} }
} }
} }
@ -48,7 +54,19 @@ struct ClockView: View {
// Toolbar overlay // Toolbar overlay
ClockToolbar( ClockToolbar(
isDisplayMode: viewModel.isDisplayMode, isDisplayMode: viewModel.isDisplayMode,
onSettingsTap: { showSettings = true } onSettingsTap: { showSettings = true },
onFullScreenTap: {
if !viewModel.isDisplayMode {
viewModel.toggleDisplayMode()
// Show hint after a brief delay to allow transition
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
showFullScreenHint = true
}
} else {
viewModel.toggleDisplayMode()
}
}
) )
} }
.overlay { .overlay {

View File

@ -13,6 +13,7 @@ struct ClockToolbar: View {
// MARK: - Properties // MARK: - Properties
let isDisplayMode: Bool let isDisplayMode: Bool
let onSettingsTap: () -> Void let onSettingsTap: () -> Void
let onFullScreenTap: () -> Void
// MARK: - Body // MARK: - Body
var body: some View { var body: some View {
@ -20,7 +21,16 @@ struct ClockToolbar: View {
.navigationTitle(isDisplayMode ? "" : "Clock") .navigationTitle(isDisplayMode ? "" : "Clock")
.toolbar { .toolbar {
if !isDisplayMode { if !isDisplayMode {
ToolbarItem(placement: .navigationBarTrailing) { ToolbarItemGroup(placement: .navigationBarTrailing) {
Button {
onFullScreenTap()
} label: {
Image(systemName: "rectangle.expand.diagonal")
.font(.title2)
.transition(.opacity)
}
.accessibilityLabel("Enter Full Screen Mode")
Button { Button {
onSettingsTap() onSettingsTap()
} label: { } label: {
@ -28,6 +38,7 @@ struct ClockToolbar: View {
.font(.title2) .font(.title2)
.transition(.opacity) .transition(.opacity)
} }
.accessibilityLabel("Clock Settings")
} }
} }
} }
@ -41,7 +52,8 @@ struct ClockToolbar: View {
NavigationStack { NavigationStack {
ClockToolbar( ClockToolbar(
isDisplayMode: false, isDisplayMode: false,
onSettingsTap: {} onSettingsTap: {},
onFullScreenTap: {}
) )
} }
} }

View File

@ -0,0 +1,73 @@
//
// FullScreenHintView.swift
// TheNoiseClock
//
// Created by Matt Bruce on 9/10/25.
//
import SwiftUI
/// Component that shows a subtle hint for how to exit full-screen mode
struct FullScreenHintView: View {
// MARK: - Properties
let isDisplayMode: Bool
@State private var hintOpacity: Double = 0.0
// MARK: - Body
var body: some View {
if isDisplayMode {
VStack {
Spacer()
HStack {
Image(systemName: "hand.point.up.left")
.font(.title2)
.foregroundColor(.white.opacity(0.7))
Text("Long press to exit full screen")
.font(.headline)
.foregroundColor(.white.opacity(0.7))
Image(systemName: "hand.point.up.left")
.font(.title2)
.foregroundColor(.white.opacity(0.7))
}
.padding(.horizontal, 20)
.padding(.vertical, 12)
.background(
RoundedRectangle(cornerRadius: 20)
.fill(.black.opacity(0.6))
.blur(radius: 1)
)
.opacity(hintOpacity)
Spacer()
.frame(height: 100) // Space above tab bar area
}
.transition(.opacity.combined(with: .scale(scale: 0.9)))
.onAppear {
withAnimation(.easeInOut(duration: 0.5)) {
hintOpacity = 1.0
}
// Auto-hide after 3 seconds
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
withAnimation(.easeInOut(duration: 0.5)) {
hintOpacity = 0.0
}
}
}
}
}
}
// MARK: - Preview
#Preview {
ZStack {
Color.black.ignoresSafeArea()
FullScreenHintView(isDisplayMode: true)
}
}