Compare commits

...

2 Commits

Author SHA1 Message Date
Michael Freno
eab8a76a55 fix: getting enforce working 2026-01-31 16:21:57 -05:00
Michael Freno
7ca7d27f84 feat:improved animation 2026-01-31 16:21:47 -05:00
4 changed files with 55 additions and 10 deletions

View File

@@ -21,12 +21,12 @@
"p": { "p": {
"a": 1, "a": 1,
"k": [ "k": [
{ "t": 0, "s": [150, 180, 0], "i": { "x": 0.3, "y": 1 }, "o": { "x": 0.7, "y": 0 } }, { "t": 0, "s": [150, 160, 0], "i": { "x": 0.3, "y": 1 }, "o": { "x": 0.7, "y": 0 } },
{ "t": 40, "s": [150, 120, 0], "i": { "x": 0.3, "y": 1 }, "o": { "x": 0.7, "y": 0 } }, { "t": 40, "s": [150, 100, 0], "i": { "x": 0.3, "y": 1 }, "o": { "x": 0.7, "y": 0 } },
{ "t": 80, "s": [150, 140, 0], "i": { "x": 0.3, "y": 1 }, "o": { "x": 0.7, "y": 0 } }, { "t": 80, "s": [150, 120, 0], "i": { "x": 0.3, "y": 1 }, "o": { "x": 0.7, "y": 0 } },
{ "t": 120, "s": [150, 120, 0], "i": { "x": 0.3, "y": 1 }, "o": { "x": 0.7, "y": 0 } }, { "t": 120, "s": [150, 100, 0], "i": { "x": 0.3, "y": 1 }, "o": { "x": 0.7, "y": 0 } },
{ "t": 160, "s": [150, 140, 0], "i": { "x": 0.3, "y": 1 }, "o": { "x": 0.7, "y": 0 } }, { "t": 160, "s": [150, 120, 0], "i": { "x": 0.3, "y": 1 }, "o": { "x": 0.7, "y": 0 } },
{ "t": 180, "s": [150, 130, 0] } { "t": 180, "s": [150, 110, 0] }
] ]
}, },
"a": { "a": 0, "k": [0, 0, 0] }, "a": { "a": 0, "k": [0, 0, 0] },

View File

@@ -75,6 +75,22 @@ class EnforceModeService: ObservableObject {
} }
} }
.store(in: &cancellables) .store(in: &cancellables)
settingsManager._settingsSubject
.receive(on: RunLoop.main)
.sink { [weak self] _ in
self?.refreshEnforceModeState()
}
.store(in: &cancellables)
}
private func refreshEnforceModeState() {
let cameraService = CameraAccessService.shared
let enabled = isEnforcementEnabled && cameraService.isCameraAuthorized
if isEnforceModeEnabled != enabled {
isEnforceModeEnabled = enabled
logDebug("🔄 Enforce mode state refreshed: \(enabled)")
}
} }
// MARK: - Enable/Disable // MARK: - Enable/Disable

View File

@@ -5,6 +5,7 @@
// Created by Mike Freno on 1/13/26. // Created by Mike Freno on 1/13/26.
// //
import AppKit
import AVFoundation import AVFoundation
import Combine import Combine
@@ -33,11 +34,20 @@ class CameraAccessService: ObservableObject {
return return
} }
let currentStatus = AVCaptureDevice.authorizationStatus(for: .video)
if currentStatus == .denied || currentStatus == .restricted {
checkCameraAuthorizationStatus()
openSystemSettings()
throw CameraAccessError.accessDenied
}
print("🎥 Calling AVCaptureDevice.requestAccess...") print("🎥 Calling AVCaptureDevice.requestAccess...")
let status = await AVCaptureDevice.requestAccess(for: .video) let status = await AVCaptureDevice.requestAccess(for: .video)
print("🎥 Permission result: \(status)") print("🎥 Permission result: \(status)")
if !status { if !status {
checkCameraAuthorizationStatus()
openSystemSettings()
throw CameraAccessError.accessDenied throw CameraAccessError.accessDenied
} }
@@ -69,6 +79,27 @@ class CameraAccessService: ObservableObject {
} }
} }
func openSystemSettings() {
let possibleUrls = [
"x-apple.systempreferences:com.apple.preference.security?Privacy_Camera",
"x-apple.systempreferences:Privacy?Camera",
"x-apple.systempreferences:com.apple.preference.security",
"x-apple.systempreferences:Privacy",
"x-apple.systempreferences:com.apple.preferences.security",
]
for urlString in possibleUrls {
if let url = URL(string: urlString),
NSWorkspace.shared.open(url)
{
print("Successfully opened: \(urlString)")
return
}
}
print("⚠️ Failed to open System Settings")
}
func checkCameraHardware() { func checkCameraHardware() {
let devices = AVCaptureDevice.DiscoverySession( let devices = AVCaptureDevice.DiscoverySession(
deviceTypes: [.builtInWideAngleCamera], deviceTypes: [.builtInWideAngleCamera],
@@ -97,7 +128,7 @@ enum CameraAccessError: Error, LocalizedError {
switch self { switch self {
case .accessDenied: case .accessDenied:
return return
"Camera access was denied. Please enable camera permissions in System Preferences." "Camera access was denied. Please enable camera permissions in System Settings."
case .unsupportedOS: case .unsupportedOS:
return "This feature requires macOS 12 or later." return "This feature requires macOS 12 or later."
case .unknown: case .unknown:

View File

@@ -339,9 +339,7 @@ struct EnforceModeSetupContent: View {
"", "",
isOn: Binding( isOn: Binding(
get: { get: {
settingsManager.isTimerEnabled(for: .lookAway) enforceModeService.isEnforceModeEnabled
|| settingsManager.isTimerEnabled(for: .blink)
|| settingsManager.isTimerEnabled(for: .posture)
}, },
set: { newValue in set: { newValue in
guard !isProcessingToggle else { return } guard !isProcessingToggle else { return }