Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
parent
ab8ef49ddb
commit
fb9a810262
@ -12,6 +12,15 @@ import Bedrock
|
|||||||
struct SelfieCamApp: App {
|
struct SelfieCamApp: App {
|
||||||
init() {
|
init() {
|
||||||
Design.showDebugLogs = true
|
Design.showDebugLogs = true
|
||||||
|
|
||||||
|
// Register SelfieCam theme with Bedrock
|
||||||
|
Theme.register(
|
||||||
|
text: AppTextColors.self,
|
||||||
|
surface: AppSurface.self,
|
||||||
|
accent: AppAccent.self,
|
||||||
|
status: AppStatus.self
|
||||||
|
)
|
||||||
|
Theme.register(border: AppBorder.self)
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some Scene {
|
var body: some Scene {
|
||||||
|
|||||||
@ -188,16 +188,16 @@ struct ContentView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Camera Container View
|
// MARK: - Camera Container View
|
||||||
/// Wrapper view for MCamera - only recreates when sessionKey changes
|
/// Wrapper view for MCamera - only recreates when sessionKey changes
|
||||||
struct CameraContainerView: View, Equatable {
|
struct CameraContainerView: View, Equatable {
|
||||||
let settings: SettingsViewModel
|
let settings: SettingsViewModel
|
||||||
let sessionKey: UUID
|
let sessionKey: UUID
|
||||||
let cameraPosition: CameraPosition
|
let cameraPosition: CameraPosition
|
||||||
let onImageCaptured: (UIImage) -> Void
|
let onImageCaptured: (UIImage) -> Void
|
||||||
|
|
||||||
// Only compare sessionKey and cameraPosition for equality
|
// Only compare sessionKey for equality - we want to handle position changes via runtime setCameraPosition
|
||||||
static func == (lhs: CameraContainerView, rhs: CameraContainerView) -> Bool {
|
static func == (lhs: CameraContainerView, rhs: CameraContainerView) -> Bool {
|
||||||
lhs.sessionKey == rhs.sessionKey && lhs.cameraPosition == rhs.cameraPosition
|
lhs.sessionKey == rhs.sessionKey
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
|||||||
@ -320,17 +320,17 @@ struct CustomCameraScreen: MCameraScreen {
|
|||||||
// Initial haptic for countdown start
|
// Initial haptic for countdown start
|
||||||
triggerHaptic(.light)
|
triggerHaptic(.light)
|
||||||
|
|
||||||
Task { @MainActor in
|
// Use a Timer to ensure we update on the main thread every second
|
||||||
while countdownSeconds > 0 {
|
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
|
||||||
try? await Task.sleep(for: .seconds(1))
|
if self.countdownSeconds > 1 {
|
||||||
countdownSeconds -= 1
|
self.countdownSeconds -= 1
|
||||||
// Haptic tick for each countdown second
|
self.triggerHaptic(.light)
|
||||||
triggerHaptic(.light)
|
} else {
|
||||||
|
timer.invalidate()
|
||||||
|
self.countdownSeconds = 0
|
||||||
|
self.isCountdownActive = false
|
||||||
|
self.performActualCapture()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Countdown finished, perform capture
|
|
||||||
isCountdownActive = false
|
|
||||||
performActualCapture()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -542,16 +542,8 @@ struct CustomCameraScreen: MCameraScreen {
|
|||||||
let newPosition: CameraPosition = cameraPosition == .front ? .back : .front
|
let newPosition: CameraPosition = cameraPosition == .front ? .back : .front
|
||||||
Design.debugLog("Double-tap: flipping camera to \(newPosition)")
|
Design.debugLog("Double-tap: flipping camera to \(newPosition)")
|
||||||
|
|
||||||
Task {
|
// Update settings to persist the change - this will trigger the onChange in CustomCameraScreen
|
||||||
do {
|
cameraSettings.cameraPosition = newPosition
|
||||||
try await setCameraPosition(newPosition)
|
|
||||||
// Update settings to persist the change
|
|
||||||
cameraSettings.cameraPosition = newPosition
|
|
||||||
currentCameraPosition = newPosition
|
|
||||||
} catch {
|
|
||||||
Design.debugLog("Failed to flip camera: \(error)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Haptic Feedback
|
// MARK: - Haptic Feedback
|
||||||
|
|||||||
@ -22,14 +22,14 @@ extension SettingsViewModel {
|
|||||||
|
|
||||||
var cameraPosition: CameraPosition {
|
var cameraPosition: CameraPosition {
|
||||||
get {
|
get {
|
||||||
|
// Access the data through cloudSync to ensure observation is tracked
|
||||||
let raw = cloudSync.data.cameraPositionRaw
|
let raw = cloudSync.data.cameraPositionRaw
|
||||||
let position: CameraPosition = raw == "front" ? .front : .back
|
return raw == "back" ? .back : .front
|
||||||
Design.debugLog("cameraPosition getter: raw='\(raw)' -> \(position)")
|
|
||||||
return position
|
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
let rawValue = newValue == .front ? "front" : "back"
|
let rawValue = newValue == .back ? "back" : "front"
|
||||||
Design.debugLog("cameraPosition setter: \(newValue) -> raw='\(rawValue)'")
|
|
||||||
|
// Use updateSettings to ensure modificationCount is incremented and observers are notified
|
||||||
updateSettings { $0.cameraPositionRaw = rawValue }
|
updateSettings { $0.cameraPositionRaw = rawValue }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -137,6 +137,9 @@ final class SettingsViewModel: RingLightConfigurable {
|
|||||||
|
|
||||||
/// Updates settings and saves to cloud immediately
|
/// Updates settings and saves to cloud immediately
|
||||||
func updateSettings(_ transform: (inout SyncedSettings) -> Void) {
|
func updateSettings(_ transform: (inout SyncedSettings) -> Void) {
|
||||||
|
// Since we are using @Observable, we need to ensure the property access is tracked
|
||||||
|
// The cloudSync.update call modifies the data, but we need to trigger the observation
|
||||||
|
// We wrap the update in a way that SwiftUI's observation system can see the change
|
||||||
cloudSync.update { settings in
|
cloudSync.update { settings in
|
||||||
transform(&settings)
|
transform(&settings)
|
||||||
settings.modificationCount += 1
|
settings.modificationCount += 1
|
||||||
|
|||||||
@ -27,7 +27,7 @@ struct AppLicensesView: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
LicensesView(
|
LicensesView(
|
||||||
licenses: Self.licenses,
|
licenses: Self.licenses,
|
||||||
backgroundColor: AppSurface.overlay,
|
backgroundColor: AppSurface.primary,
|
||||||
cardBackgroundColor: AppSurface.card,
|
cardBackgroundColor: AppSurface.card,
|
||||||
cardBorderColor: AppBorder.subtle,
|
cardBorderColor: AppBorder.subtle,
|
||||||
accentColor: AppAccent.primary
|
accentColor: AppAccent.primary
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user