mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-28 07:34:32 +00:00
Fix: Migrations
This commit is contained in:
parent
471fb6723e
commit
be152c1531
41 changed files with 2373 additions and 1321 deletions
|
|
@ -13,6 +13,8 @@ import Defaults
|
|||
|
||||
@MainActor
|
||||
class CalendarManager: ObservableObject {
|
||||
static let shared = CalendarManager()
|
||||
|
||||
@Published var currentWeekStartDate: Date
|
||||
@Published var events: [EventModel] = []
|
||||
@Published var allCalendars: [CalendarModel] = []
|
||||
|
|
@ -20,7 +22,7 @@ class CalendarManager: ObservableObject {
|
|||
private var selectedCalendars: [CalendarModel] = []
|
||||
private let calendarService = CalendarService()
|
||||
|
||||
init() {
|
||||
private init() {
|
||||
self.currentWeekStartDate = CalendarManager.startOfDay(Date())
|
||||
}
|
||||
|
||||
|
|
@ -33,7 +35,13 @@ class CalendarManager: ObservableObject {
|
|||
|
||||
switch status {
|
||||
case .notDetermined:
|
||||
self.authorizationStatus = await calendarService.requestAccess() ? .fullAccess : .denied
|
||||
let granted = await calendarService.requestAccess()
|
||||
self.authorizationStatus = granted ? .fullAccess : .denied
|
||||
if granted {
|
||||
allCalendars = await calendarService.calendars()
|
||||
updateSelectedCalendars()
|
||||
events = await calendarService.events(from: currentWeekStartDate, to: Calendar.current.date(byAdding: .day, value: 1, to: currentWeekStartDate)!, calendars: selectedCalendars.map{$0.id})
|
||||
}
|
||||
case .restricted, .denied:
|
||||
// Handle the case where the user has denied or restricted access
|
||||
NSLog("Calendar access denied or restricted")
|
||||
|
|
@ -48,11 +56,11 @@ class CalendarManager: ObservableObject {
|
|||
print("Unknown authorization status")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func updateSelectedCalendars() {
|
||||
selectedCalendars = allCalendars.filter { getCalendarSelected($0) }
|
||||
}
|
||||
|
||||
|
||||
func getCalendarSelected(_ calendar: CalendarModel) -> Bool {
|
||||
switch Defaults[.calendarSelectionState] {
|
||||
case .all:
|
||||
|
|
@ -78,7 +86,7 @@ class CalendarManager: ObservableObject {
|
|||
} else {
|
||||
identifiers.remove(calendar.id)
|
||||
}
|
||||
|
||||
|
||||
selectionState = identifiers.isEmpty ? .all : identifiers.count == allCalendars.count ? .all : .selected(identifiers) // if empty, select all
|
||||
}
|
||||
|
||||
|
|
@ -86,11 +94,11 @@ class CalendarManager: ObservableObject {
|
|||
updateSelectedCalendars()
|
||||
events = await calendarService.events(from: currentWeekStartDate, to: Calendar.current.date(byAdding: .day, value: 1, to: currentWeekStartDate)!, calendars: selectedCalendars.map{$0.id})
|
||||
}
|
||||
|
||||
|
||||
static func startOfDay(_ date: Date) -> Date {
|
||||
return Calendar.current.startOfDay(for: date)
|
||||
}
|
||||
|
||||
|
||||
func updateCurrentDate(_ date: Date) async {
|
||||
currentWeekStartDate = Calendar.current.startOfDay(for: date)
|
||||
events = await calendarService.events(from: currentWeekStartDate, to: Calendar.current.date(byAdding: .day, value: 1, to: currentWeekStartDate)!, calendars: selectedCalendars.map{$0.id})
|
||||
|
|
|
|||
|
|
@ -19,15 +19,11 @@ class MusicManager: ObservableObject {
|
|||
static let shared = MusicManager()
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
private var controllerCancellables = Set<AnyCancellable>()
|
||||
private var debounceToggle: DispatchWorkItem?
|
||||
private var debounceIdleTask: Task<Void, Never>?
|
||||
|
||||
// Helper to check if macOS is too new for NowPlayingController
|
||||
public var isNowPlayingDeprecated: Bool {
|
||||
if #available(macOS 15.4, *) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
// Helper to check if macOS has removed support for NowPlayingController
|
||||
public private(set) var isNowPlayingDeprecated: Bool = false
|
||||
private let mediaChecker = MediaChecker()
|
||||
|
||||
// Active controller
|
||||
private var activeController: (any MediaControllerProtocol)?
|
||||
|
|
@ -48,6 +44,8 @@ class MusicManager: ObservableObject {
|
|||
@Published var elapsedTime: TimeInterval = 0
|
||||
@Published var timestampDate: Date = .init()
|
||||
@Published var playbackRate: Double = 1
|
||||
@Published var isShuffled: Bool = false
|
||||
@Published var repeatMode: RepeatMode = .off
|
||||
@ObservedObject var coordinator = DynamicIslandViewCoordinator.shared
|
||||
@Published var usingAppIconForArtwork: Bool = false
|
||||
|
||||
|
|
@ -67,13 +65,24 @@ class MusicManager: ObservableObject {
|
|||
self?.setActiveControllerBasedOnPreference()
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
// Initialize deprecation check asynchronously
|
||||
Task { @MainActor in
|
||||
do {
|
||||
self.isNowPlayingDeprecated = try await self.mediaChecker.checkDeprecationStatus()
|
||||
print("Deprecation check completed: \(self.isNowPlayingDeprecated)")
|
||||
} catch {
|
||||
print("Failed to check deprecation status: \(error). Defaulting to false.")
|
||||
self.isNowPlayingDeprecated = false
|
||||
}
|
||||
|
||||
// Initialize the active controller
|
||||
setActiveControllerBasedOnPreference()
|
||||
// Initialize the active controller after deprecation check
|
||||
self.setActiveControllerBasedOnPreference()
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
debounceToggle?.cancel()
|
||||
debounceIdleTask?.cancel()
|
||||
cancellables.removeAll()
|
||||
controllerCancellables.removeAll()
|
||||
flipWorkItem?.cancel()
|
||||
|
|
@ -98,7 +107,17 @@ class MusicManager: ObservableObject {
|
|||
// Only create NowPlayingController if not deprecated on this macOS version
|
||||
if !self.isNowPlayingDeprecated {
|
||||
ignoreLastUpdated = false
|
||||
newController = NowPlayingController()
|
||||
if let controller = NowPlayingController() {
|
||||
// Check if the controller can actually work
|
||||
if controller.isWorking {
|
||||
newController = controller
|
||||
} else {
|
||||
print("⚠️ NowPlayingController created but resources unavailable, falling back to default")
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -285,19 +304,20 @@ class MusicManager: ObservableObject {
|
|||
private func updateIdleState(state: Bool) {
|
||||
if state {
|
||||
isPlayerIdle = false
|
||||
debounceToggle?.cancel()
|
||||
debounceIdleTask?.cancel()
|
||||
} else {
|
||||
debounceToggle = DispatchWorkItem { [weak self] in
|
||||
guard let self = self else { return }
|
||||
if self.lastUpdated.timeIntervalSinceNow < -Defaults[.waitInterval] {
|
||||
withAnimation {
|
||||
self.isPlayerIdle = !self.isPlaying
|
||||
debounceIdleTask?.cancel()
|
||||
debounceIdleTask = Task { [weak self] in
|
||||
try? await Task.sleep(for: .seconds(Defaults[.waitInterval]))
|
||||
guard let self = self, !Task.isCancelled else { return }
|
||||
await MainActor.run {
|
||||
if self.lastUpdated.timeIntervalSinceNow < -Defaults[.waitInterval] {
|
||||
withAnimation {
|
||||
self.isPlayerIdle = !self.isPlaying
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DispatchQueue.main.asyncAfter(
|
||||
deadline: .now() + Defaults[.waitInterval], execute: debounceToggle!)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -338,31 +358,57 @@ class MusicManager: ObservableObject {
|
|||
|
||||
// MARK: - Public Methods for controlling playback
|
||||
func playPause() {
|
||||
activeController?.togglePlay()
|
||||
Task {
|
||||
await activeController?.togglePlay()
|
||||
}
|
||||
}
|
||||
|
||||
func play() {
|
||||
activeController?.play()
|
||||
Task {
|
||||
await activeController?.play()
|
||||
}
|
||||
}
|
||||
|
||||
func pause() {
|
||||
activeController?.pause()
|
||||
Task {
|
||||
await activeController?.pause()
|
||||
}
|
||||
}
|
||||
|
||||
func toggleShuffle() {
|
||||
Task {
|
||||
await activeController?.toggleShuffle()
|
||||
}
|
||||
}
|
||||
|
||||
func toggleRepeat() {
|
||||
Task {
|
||||
await activeController?.toggleRepeat()
|
||||
}
|
||||
}
|
||||
|
||||
func togglePlay() {
|
||||
activeController?.togglePlay()
|
||||
Task {
|
||||
await activeController?.togglePlay()
|
||||
}
|
||||
}
|
||||
|
||||
func nextTrack() {
|
||||
activeController?.nextTrack()
|
||||
Task {
|
||||
await activeController?.nextTrack()
|
||||
}
|
||||
}
|
||||
|
||||
func previousTrack() {
|
||||
activeController?.previousTrack()
|
||||
Task {
|
||||
await activeController?.previousTrack()
|
||||
}
|
||||
}
|
||||
|
||||
func seek(to position: TimeInterval) {
|
||||
activeController?.seek(to: position)
|
||||
Task {
|
||||
await activeController?.seek(to: position)
|
||||
}
|
||||
}
|
||||
|
||||
func openMusicApp() {
|
||||
|
|
@ -388,9 +434,14 @@ class MusicManager: ObservableObject {
|
|||
|
||||
func forceUpdate() {
|
||||
// Request immediate update from the active controller
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
Task { [weak self] in
|
||||
if self?.activeController?.isActive() == true {
|
||||
self?.activeController?.updatePlaybackInfo()
|
||||
if type(of: self?.activeController) == YouTubeMusicController.self,
|
||||
let youtubeController = self?.activeController as? YouTubeMusicController {
|
||||
await youtubeController.pollPlaybackState()
|
||||
} else {
|
||||
await self?.activeController?.updatePlaybackInfo()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// NotchSpaceManager.swift
|
||||
// DynamicIsland
|
||||
//
|
||||
// Created by Alexander Greco on 2024-10-27.
|
||||
// Created by Alexander on 2024-10-27.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue