Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
parent
7f6f5817e1
commit
38469f4ca8
@ -86,7 +86,7 @@ class ClockViewModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func saveStyle() {
|
func saveStyle() {
|
||||||
persistenceWorkItem?.cancel()
|
persistenceWorkItem?.cancel()
|
||||||
|
|
||||||
let work = DispatchWorkItem {
|
let work = DispatchWorkItem {
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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: {}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user