Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
parent
7bd01554de
commit
a88a02b671
@ -14,6 +14,8 @@ struct ClockView: View {
|
|||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
@Bindable var viewModel: ClockViewModel
|
@Bindable var viewModel: ClockViewModel
|
||||||
@State private var showFullScreenHint = false
|
@State private var showFullScreenHint = false
|
||||||
|
@State private var idleTimer: Timer?
|
||||||
|
@State private var didHandleTouch = false
|
||||||
|
|
||||||
// MARK: - Body
|
// MARK: - Body
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@ -45,32 +47,66 @@ struct ClockView: View {
|
|||||||
.overlay {
|
.overlay {
|
||||||
// Toolbar overlay
|
// Toolbar overlay
|
||||||
ClockToolbar(
|
ClockToolbar(
|
||||||
isDisplayMode: viewModel.isDisplayMode,
|
isDisplayMode: viewModel.isDisplayMode
|
||||||
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 {
|
||||||
// Tab bar management overlay
|
// Tab bar management overlay
|
||||||
ClockTabBarManager(isDisplayMode: viewModel.isDisplayMode)
|
ClockTabBarManager(isDisplayMode: viewModel.isDisplayMode)
|
||||||
}
|
}
|
||||||
.overlay {
|
.simultaneousGesture(
|
||||||
// Gesture handling overlay
|
DragGesture(minimumDistance: 0)
|
||||||
ClockGestureHandler {
|
.onChanged { _ in
|
||||||
viewModel.toggleDisplayMode()
|
guard !didHandleTouch else { return }
|
||||||
|
didHandleTouch = true
|
||||||
|
handleUserInteraction()
|
||||||
|
}
|
||||||
|
.onEnded { _ in
|
||||||
|
didHandleTouch = false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.onAppear {
|
||||||
|
resetIdleTimer()
|
||||||
|
}
|
||||||
|
.onDisappear {
|
||||||
|
idleTimer?.invalidate()
|
||||||
|
idleTimer = nil
|
||||||
|
}
|
||||||
|
.onChange(of: viewModel.isDisplayMode) { _, isDisplayMode in
|
||||||
|
if isDisplayMode {
|
||||||
|
idleTimer?.invalidate()
|
||||||
|
idleTimer = nil
|
||||||
|
} else {
|
||||||
|
resetIdleTimer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Idle Timer
|
||||||
|
private func resetIdleTimer() {
|
||||||
|
idleTimer?.invalidate()
|
||||||
|
idleTimer = nil
|
||||||
|
guard !viewModel.isDisplayMode else { return }
|
||||||
|
idleTimer = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: false) { _ in
|
||||||
|
enterDisplayModeFromIdle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func enterDisplayModeFromIdle() {
|
||||||
|
guard !viewModel.isDisplayMode else { return }
|
||||||
|
viewModel.toggleDisplayMode()
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||||
|
showFullScreenHint = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func handleUserInteraction() {
|
||||||
|
if viewModel.isDisplayMode {
|
||||||
|
viewModel.toggleDisplayMode()
|
||||||
|
showFullScreenHint = false
|
||||||
|
}
|
||||||
|
resetIdleTimer()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Preview
|
// MARK: - Preview
|
||||||
|
|||||||
@ -12,26 +12,11 @@ struct ClockToolbar: View {
|
|||||||
|
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
let isDisplayMode: Bool
|
let isDisplayMode: Bool
|
||||||
let onFullScreenTap: () -> Void
|
|
||||||
|
|
||||||
// MARK: - Body
|
// MARK: - Body
|
||||||
var body: some View {
|
var body: some View {
|
||||||
EmptyView()
|
EmptyView()
|
||||||
.navigationTitle(isDisplayMode ? "" : "Clock")
|
.navigationTitle(isDisplayMode ? "" : "Clock")
|
||||||
.toolbar {
|
|
||||||
if !isDisplayMode {
|
|
||||||
ToolbarItemGroup(placement: .navigationBarTrailing) {
|
|
||||||
Button {
|
|
||||||
onFullScreenTap()
|
|
||||||
} label: {
|
|
||||||
Image(systemName: "rectangle.expand.diagonal")
|
|
||||||
.font(.title2)
|
|
||||||
.transition(.opacity)
|
|
||||||
}
|
|
||||||
.accessibilityLabel("Enter Full Screen Mode")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.navigationBarBackButtonHidden(isDisplayMode)
|
.navigationBarBackButtonHidden(isDisplayMode)
|
||||||
.toolbar(isDisplayMode ? .hidden : .automatic)
|
.toolbar(isDisplayMode ? .hidden : .automatic)
|
||||||
}
|
}
|
||||||
@ -41,8 +26,7 @@ struct ClockToolbar: View {
|
|||||||
#Preview {
|
#Preview {
|
||||||
NavigationStack {
|
NavigationStack {
|
||||||
ClockToolbar(
|
ClockToolbar(
|
||||||
isDisplayMode: false,
|
isDisplayMode: false
|
||||||
onFullScreenTap: {}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user