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

This commit is contained in:
Matt Bruce 2026-01-04 13:53:02 -06:00
parent 0e6d7b5355
commit 0ea6993621
2 changed files with 76 additions and 3 deletions

View File

@ -31,6 +31,10 @@ struct CustomCameraScreen: MCameraScreen {
@State private var isShowingScreenFlash: Bool = false
@State private var originalBrightness: CGFloat = UIScreen.main.brightness
// Timer countdown state
@State private var countdownSeconds: Int = 0
@State private var isCountdownActive: Bool = false
// Pinch to zoom gesture state
@GestureState private var magnification: CGFloat = 1.0
@State private var lastMagnification: CGFloat = 1.0
@ -95,8 +99,21 @@ struct CustomCameraScreen: MCameraScreen {
isCenterStageActive: cameraSettings.isCenterStageEnabled
)
// Capture Button
// Capture Button with timer indicator badge
CaptureButton(action: { performCapture() })
.overlay(alignment: .bottomTrailing) {
if cameraSettings.selectedTimer.seconds > 0 {
ZStack {
Circle()
.fill(Color.black.opacity(Design.Opacity.accent))
.frame(width: 24, height: 24)
Text(cameraSettings.selectedTimer.displayName)
.font(.system(size: 10, weight: .bold))
.foregroundColor(.white)
}
.offset(x: 4, y: 4)
}
}
.padding(.bottom, Design.Spacing.large)
}
.padding(.horizontal, Design.Spacing.large)
@ -106,6 +123,26 @@ struct CustomCameraScreen: MCameraScreen {
// Countdown overlay
if isCountdownActive {
ZStack {
Color.black.opacity(0.3)
.ignoresSafeArea()
VStack {
Text("\(countdownSeconds)")
.font(.system(size: 120, weight: .bold, design: .rounded))
.foregroundColor(.white)
.shadow(radius: 10)
Text("Get ready!")
.font(.title2)
.foregroundColor(.white.opacity(0.8))
}
}
.transition(.opacity)
}
// Screen flash overlay for front camera
if isShowingScreenFlash {
screenFlashColor
@ -114,6 +151,7 @@ struct CustomCameraScreen: MCameraScreen {
}
}
.animation(.easeInOut(duration: 0.05), value: isShowingScreenFlash)
.animation(.easeInOut(duration: 0.3), value: isCountdownActive)
.onAppear {
// Set flash mode from saved settings
setFlashMode(cameraSettings.flashMode.toMijickFlashMode)
@ -162,9 +200,40 @@ struct CustomCameraScreen: MCameraScreen {
cameraPosition == .front && cameraSettings.flashMode != .off && cameraSettings.isFlashSyncedWithRingLight
}
/// Performs capture with screen flash if needed
/// Performs capture with timer countdown and screen flash if needed
private func performCapture() {
print("performCapture called - shouldUseCustomScreenFlash: \(shouldUseCustomScreenFlash)")
// Check if timer is enabled
let timerSeconds = cameraSettings.selectedTimer.seconds
if timerSeconds > 0 && !isCountdownActive {
// Start countdown
startCountdown(seconds: timerSeconds)
} else if !isCountdownActive {
// No timer or countdown already running, proceed with capture
performActualCapture()
}
}
/// Starts the countdown timer
private func startCountdown(seconds: Int) {
countdownSeconds = seconds
isCountdownActive = true
Task { @MainActor in
while countdownSeconds > 0 {
try? await Task.sleep(for: .seconds(1))
countdownSeconds -= 1
}
// Countdown finished, perform capture
isCountdownActive = false
performActualCapture()
}
}
/// Performs the actual capture with screen flash if needed
private func performActualCapture() {
print("performActualCapture called - shouldUseCustomScreenFlash: \(shouldUseCustomScreenFlash)")
if shouldUseCustomScreenFlash {
// Save original brightness and boost to max
originalBrightness = UIScreen.main.brightness

View File

@ -210,6 +210,10 @@
"comment" : "Title of a toggle in the Settings view that controls whether the front flash is enabled.",
"isCommentAutoGenerated" : true
},
"Get ready!" : {
"comment" : "A text displayed in the countdown overlay when a photo is about to be taken.",
"isCommentAutoGenerated" : true
},
"Go Pro" : {
"comment" : "The title of the \"Go Pro\" button in the Pro paywall.",
"isCommentAutoGenerated" : true