mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-28 15:44:32 +00:00
Fix: Migrations
This commit is contained in:
parent
471fb6723e
commit
be152c1531
41 changed files with 2373 additions and 1321 deletions
|
|
@ -1,12 +1,12 @@
|
|||
import Foundation
|
||||
import Cocoa
|
||||
import SwiftUI
|
||||
import IOKit.ps
|
||||
import Defaults
|
||||
import Foundation
|
||||
import IOKit.ps
|
||||
import SwiftUI
|
||||
|
||||
/// A view model that manages and monitors the battery status of the device
|
||||
class BatteryStatusViewModel: ObservableObject {
|
||||
|
||||
|
||||
private var wasCharging: Bool = false
|
||||
private var powerSourceChangedCallback: IOPowerSourceCallbackType?
|
||||
private var runLoopSource: Unmanaged<CFRunLoopSource>?
|
||||
|
|
@ -22,14 +22,14 @@ class BatteryStatusViewModel: ObservableObject {
|
|||
@Published private(set) var isInitial: Bool = false
|
||||
@Published private(set) var timeToFullCharge: Int = 0
|
||||
@Published private(set) var statusText: String = ""
|
||||
|
||||
|
||||
private let managerBattery = BatteryActivityManager.shared
|
||||
private var managerBatteryId: Int?
|
||||
|
||||
|
||||
static let shared = BatteryStatusViewModel()
|
||||
|
||||
/// Initializes the view model with a given DynamicIslandViewModel instance
|
||||
/// - Parameter vm: The DynamicIslandViewModel instance
|
||||
/// Initializes the view model with a given BoringViewModel instance
|
||||
/// - Parameter vm: The BoringViewModel instance
|
||||
private init() {
|
||||
setupPowerStatus()
|
||||
setupMonitor()
|
||||
|
|
@ -48,58 +48,61 @@ class BatteryStatusViewModel: ObservableObject {
|
|||
self.handleBatteryEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Handles battery events and updates the corresponding properties
|
||||
/// - Parameter event: The battery event to handle
|
||||
private func handleBatteryEvent(_ event: BatteryActivityManager.BatteryEvent) {
|
||||
private func handleBatteryEvent(_ event: BatteryActivityManager.BatteryEvent) {
|
||||
switch event {
|
||||
case .powerSourceChanged(let isPluggedIn):
|
||||
print("🔌 Power source: \(isPluggedIn ? "Connected" : "Disconnected")")
|
||||
withAnimation {
|
||||
self.isPluggedIn = isPluggedIn
|
||||
self.statusText = isPluggedIn ? "Plugged In" : "Unplugged"
|
||||
self.notifyImportanChangeStatus()
|
||||
}
|
||||
|
||||
case .batteryLevelChanged(let level):
|
||||
print("🔋 Battery level: \(Int(level))%")
|
||||
withAnimation {
|
||||
self.levelBattery = level
|
||||
}
|
||||
|
||||
case .lowPowerModeChanged(let isEnabled):
|
||||
print("⚡ Low power mode: \(isEnabled ? "Enabled" : "Disabled")")
|
||||
self.notifyImportanChangeStatus()
|
||||
withAnimation {
|
||||
self.isInLowPowerMode = isEnabled
|
||||
self.statusText = "Low Power: \(self.isInLowPowerMode ? "On" : "Off")"
|
||||
}
|
||||
|
||||
case .isChargingChanged(let isCharging):
|
||||
print("🔌 Charging: \(isCharging ? "Yes" : "No")")
|
||||
print("maxCapacity: \(self.maxCapacity)")
|
||||
print("levelBattery: \(self.levelBattery)")
|
||||
self.notifyImportanChangeStatus()
|
||||
withAnimation {
|
||||
self.isCharging = isCharging
|
||||
self.statusText = isCharging ? "Charging battery" : (self.levelBattery < self.maxCapacity ? "Not charging" : "Full charge")
|
||||
}
|
||||
|
||||
case .timeToFullChargeChanged(let time):
|
||||
print("🕒 Time to full charge: \(time) minutes")
|
||||
withAnimation {
|
||||
self.timeToFullCharge = time
|
||||
}
|
||||
|
||||
case .maxCapacityChanged(let capacity):
|
||||
print("🔋 Max capacity: \(capacity)")
|
||||
withAnimation {
|
||||
self.maxCapacity = capacity
|
||||
}
|
||||
|
||||
case .error(let description):
|
||||
print("⚠️ Error: \(description)")
|
||||
case .powerSourceChanged(let isPluggedIn):
|
||||
print("🔌 Power source: \(isPluggedIn ? "Connected" : "Disconnected")")
|
||||
withAnimation {
|
||||
self.isPluggedIn = isPluggedIn
|
||||
self.statusText = isPluggedIn ? "Plugged In" : "Unplugged"
|
||||
self.notifyImportanChangeStatus()
|
||||
}
|
||||
|
||||
case .batteryLevelChanged(let level):
|
||||
print("🔋 Battery level: \(Int(level))%")
|
||||
withAnimation {
|
||||
self.levelBattery = level
|
||||
}
|
||||
|
||||
case .lowPowerModeChanged(let isEnabled):
|
||||
print("⚡ Low power mode: \(isEnabled ? "Enabled" : "Disabled")")
|
||||
self.notifyImportanChangeStatus()
|
||||
withAnimation {
|
||||
self.isInLowPowerMode = isEnabled
|
||||
self.statusText = "Low Power: \(self.isInLowPowerMode ? "On" : "Off")"
|
||||
}
|
||||
|
||||
case .isChargingChanged(let isCharging):
|
||||
print("🔌 Charging: \(isCharging ? "Yes" : "No")")
|
||||
print("maxCapacity: \(self.maxCapacity)")
|
||||
print("levelBattery: \(self.levelBattery)")
|
||||
self.notifyImportanChangeStatus()
|
||||
withAnimation {
|
||||
self.isCharging = isCharging
|
||||
self.statusText =
|
||||
isCharging
|
||||
? "Charging battery"
|
||||
: (self.levelBattery < self.maxCapacity ? "Not charging" : "Full charge")
|
||||
}
|
||||
|
||||
case .timeToFullChargeChanged(let time):
|
||||
print("🕒 Time to full charge: \(time) minutes")
|
||||
withAnimation {
|
||||
self.timeToFullCharge = time
|
||||
}
|
||||
|
||||
case .maxCapacityChanged(let capacity):
|
||||
print("🔋 Max capacity: \(capacity)")
|
||||
withAnimation {
|
||||
self.maxCapacity = capacity
|
||||
}
|
||||
|
||||
case .error(let description):
|
||||
print("⚠️ Error: \(description)")
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates the battery information with the given BatteryInfo instance
|
||||
|
|
@ -114,25 +117,13 @@ class BatteryStatusViewModel: ObservableObject {
|
|||
self.maxCapacity = batteryInfo.maxCapacity
|
||||
self.statusText = batteryInfo.isPluggedIn ? "Plugged In" : "Unplugged"
|
||||
}
|
||||
notifyImportanChangeStatus(delay: coordinator.firstLaunch ? 6 : 0.0)
|
||||
withAnimation {
|
||||
if self.isCharging {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
|
||||
self.statusText = "Charging: Yes"
|
||||
}
|
||||
}
|
||||
if self.isInLowPowerMode {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
|
||||
self.statusText = "Low Power: On"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Notifies important changes in the battery status with an optional delay
|
||||
/// - Parameter delay: The delay before notifying the change, default is 0.0
|
||||
private func notifyImportanChangeStatus(delay: Double = 0.0) {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
|
||||
Task {
|
||||
try? await Task.sleep(for: .seconds(delay))
|
||||
self.coordinator.toggleExpandingView(status: true, type: .battery)
|
||||
}
|
||||
}
|
||||
|
|
@ -143,5 +134,5 @@ class BatteryStatusViewModel: ObservableObject {
|
|||
managerBattery.removeObserver(byId: managerBatteryId)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ extension Defaults.Keys {
|
|||
static let sneakPeekStyles = Key<SneakPeekStyle>("sneakPeekStyles", default: .standard)
|
||||
static let enableFullscreenMediaDetection = Key<Bool>("enableFullscreenMediaDetection", default: true)
|
||||
static let waitInterval = Key<Double>("waitInterval", default: 3)
|
||||
static let showShuffleAndRepeat = Key<Bool>("showShuffleAndRepeat", default: false)
|
||||
|
||||
// MARK: Battery
|
||||
static let showPowerStatusNotifications = Key<Bool>("showPowerStatusNotifications", default: true)
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@ class DynamicIslandViewModel: NSObject, ObservableObject {
|
|||
@Published var isHoveringCalendar: Bool = false
|
||||
@Published var isBatteryPopoverActive: Bool = false
|
||||
@Published var isClipboardPopoverActive: Bool = false
|
||||
|
||||
let webcamManager = WebcamManager.shared
|
||||
@Published var isCameraExpanded: Bool = false
|
||||
@Published var isRequestingAuthorization: Bool = false
|
||||
|
||||
@Published var screen: String?
|
||||
|
||||
|
|
@ -172,4 +176,46 @@ class DynamicIslandViewModel: NSObject, ObservableObject {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func toggleCameraPreview() {
|
||||
if isRequestingAuthorization {
|
||||
return
|
||||
}
|
||||
|
||||
switch webcamManager.authorizationStatus {
|
||||
case .authorized:
|
||||
if webcamManager.isSessionRunning {
|
||||
webcamManager.stopSession()
|
||||
isCameraExpanded = false
|
||||
} else if webcamManager.cameraAvailable {
|
||||
webcamManager.startSession()
|
||||
isCameraExpanded = true
|
||||
}
|
||||
|
||||
case .denied, .restricted:
|
||||
DispatchQueue.main.async {
|
||||
NSApp.setActivationPolicy(.regular)
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
|
||||
let alert = NSAlert()
|
||||
alert.messageText = "Camera Access Required"
|
||||
alert.informativeText = "Please allow camera access in System Settings."
|
||||
alert.addButton(withTitle: "OK")
|
||||
alert.runModal()
|
||||
|
||||
NSApp.setActivationPolicy(.accessory)
|
||||
NSApp.deactivate()
|
||||
}
|
||||
|
||||
case .notDetermined:
|
||||
isRequestingAuthorization = true
|
||||
webcamManager.checkAndRequestVideoAuthorization()
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
|
||||
self.isRequestingAuthorization = false
|
||||
}
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,12 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
enum RepeatMode: Int, Codable {
|
||||
case off = 1
|
||||
case one = 2
|
||||
case all = 3
|
||||
}
|
||||
|
||||
struct PlaybackState {
|
||||
var bundleIdentifier: String
|
||||
var isPlaying: Bool = false
|
||||
|
|
@ -16,8 +22,8 @@ struct PlaybackState {
|
|||
var currentTime: Double = 0
|
||||
var duration: Double = 0
|
||||
var playbackRate: Double = 1
|
||||
var isShuffled: Bool? = nil
|
||||
var isRepeating: Bool? = nil
|
||||
var isShuffled: Bool = false
|
||||
var repeatMode: RepeatMode = .off
|
||||
var lastUpdated: Date = Date.distantPast
|
||||
var artwork: Data?
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue