diff --git a/DynamicIsland/ContentView.swift b/DynamicIsland/ContentView.swift index c0b9a6f..08a65c4 100644 --- a/DynamicIsland/ContentView.swift +++ b/DynamicIsland/ContentView.swift @@ -40,12 +40,6 @@ struct ContentView: View { // Dynamic sizing based on view type and graph count with smooth transitions var dynamicNotchSize: CGSize { var baseSize = Defaults[.enableMinimalisticUI] ? minimalisticOpenNotchSize : openNotchSize - - if Defaults[.enableMinimalisticUI] && vm.notchState == .open { - let reminderCount = reminderManager.activeWindowReminders.count - let extraHeight = ReminderLiveActivityManager.additionalHeight(forRowCount: reminderCount) - baseSize.height += extraHeight - } guard coordinator.currentView == .stats else { return baseSize diff --git a/DynamicIsland/DynamicIslandApp.swift b/DynamicIsland/DynamicIslandApp.swift index 1e08434..65aa46d 100644 --- a/DynamicIsland/DynamicIslandApp.swift +++ b/DynamicIsland/DynamicIslandApp.swift @@ -278,12 +278,6 @@ class AppDelegate: NSObject, NSApplicationDelegate { // Use minimalistic or normal size based on settings var baseSize = Defaults[.enableMinimalisticUI] ? minimalisticOpenNotchSize : openNotchSize - - if Defaults[.enableMinimalisticUI] && vm.notchState == .open { - let reminderCount = ReminderLiveActivityManager.shared.activeWindowReminders.count - let extraHeight = ReminderLiveActivityManager.additionalHeight(forRowCount: reminderCount) - baseSize.height += extraHeight - } // Only apply dynamic sizing when on stats tab and stats are enabled guard coordinator.currentView == .stats && Defaults[.enableStatsFeature] else { diff --git a/DynamicIsland/components/Notch/MinimalisticMusicPlayerView.swift b/DynamicIsland/components/Notch/MinimalisticMusicPlayerView.swift index b1dcbb0..1b13fb6 100644 --- a/DynamicIsland/components/Notch/MinimalisticMusicPlayerView.swift +++ b/DynamicIsland/components/Notch/MinimalisticMusicPlayerView.swift @@ -166,7 +166,7 @@ struct MinimalisticMusicPlayerView: View { // Add lyrics height if enabled in settings (reserve space even while loading) if enableLyrics { let lyricsTopPadding: CGFloat = 10 - let lyricsEstimatedHeight: CGFloat = 30 + let lyricsEstimatedHeight: CGFloat = 34 height += lyricsTopPadding + lyricsEstimatedHeight } diff --git a/DynamicIsland/components/Notch/NotchHomeView.swift b/DynamicIsland/components/Notch/NotchHomeView.swift index f072590..ad5859e 100644 --- a/DynamicIsland/components/Notch/NotchHomeView.swift +++ b/DynamicIsland/components/Notch/NotchHomeView.swift @@ -162,16 +162,27 @@ struct MusicControlsView: View { removal: .move(edge: .top).combined(with: .opacity) ) - Text(musicManager.currentLyrics) - .font(.headline) - .foregroundColor(.white.opacity(0.8)) - .lineLimit(2) - .multilineTextAlignment(.leading) - .frame(maxWidth: .infinity, alignment: .leading) + let line = musicManager.currentLyrics.trimmingCharacters(in: .whitespacesAndNewlines) + + if !line.isEmpty { + let lyricsBinding = Binding( + get: { musicManager.currentLyrics }, + set: { _ in } + ) + + MarqueeText( + lyricsBinding, + font: .headline, + nsFont: .headline, + textColor: .white.opacity(0.8), + minDuration: 0.35, + frameWidth: width + ) .padding(.top, 2) - .id(musicManager.currentLyrics) + .id(line) .transition(transition) - .animation(.easeInOut(duration: 0.32), value: musicManager.currentLyrics) + .animation(.easeInOut(duration: 0.32), value: line) + } } } } diff --git a/DynamicIsland/models/DynamicIslandViewModel.swift b/DynamicIsland/models/DynamicIslandViewModel.swift index 811bb7d..cbfc80c 100644 --- a/DynamicIsland/models/DynamicIslandViewModel.swift +++ b/DynamicIsland/models/DynamicIslandViewModel.swift @@ -45,7 +45,6 @@ class DynamicIslandViewModel: NSObject, ObservableObject { @Published var notchSize: CGSize = getClosedNotchSize() @Published var closedNotchSize: CGSize = getClosedNotchSize() - private var minimalisticReminderRowCount: Int = 0 deinit { destroy() @@ -77,9 +76,8 @@ class DynamicIslandViewModel: NSObject, ObservableObject { ReminderLiveActivityManager.shared.$activeWindowReminders .removeDuplicates() .receive(on: RunLoop.main) - .sink { [weak self] entries in + .sink { [weak self] _ in guard let self else { return } - self.minimalisticReminderRowCount = entries.count let updatedTarget = self.calculateDynamicNotchSize() guard self.notchState == .open else { return } guard self.notchSize != updatedTarget else { return } @@ -195,11 +193,6 @@ class DynamicIslandViewModel: NSObject, ObservableObject { // Use minimalistic size if minimalistic UI is enabled var baseSize = Defaults[.enableMinimalisticUI] ? minimalisticOpenNotchSize : openNotchSize - if Defaults[.enableMinimalisticUI] { - let extraHeight = ReminderLiveActivityManager.additionalHeight(forRowCount: minimalisticReminderRowCount) - baseSize.height += extraHeight - } - // Only apply dynamic sizing when on stats tab and stats are enabled guard DynamicIslandViewCoordinator.shared.currentView == .stats && Defaults[.enableStatsFeature] else { return baseSize diff --git a/DynamicIsland/sizing/matters.swift b/DynamicIsland/sizing/matters.swift index f48ba08..4326a60 100644 --- a/DynamicIsland/sizing/matters.swift +++ b/DynamicIsland/sizing/matters.swift @@ -16,14 +16,23 @@ let batterySneakSize: CGSize = .init(width: 160, height: 1) let openNotchSize: CGSize = .init(width: 640, height: 190) private let minimalisticBaseOpenNotchSize: CGSize = .init(width: 420, height: 180) -private let minimalisticLyricsExtraHeight: CGFloat = 30 +private let minimalisticLyricsExtraHeight: CGFloat = 40 +@MainActor var minimalisticOpenNotchSize: CGSize { var size = minimalisticBaseOpenNotchSize if Defaults[.enableLyrics] { size.height += minimalisticLyricsExtraHeight } + + let reminderCount = ReminderLiveActivityManager.shared.activeWindowReminders.count + if reminderCount > 0 { + let reminderHeight = ReminderLiveActivityManager.additionalHeight(forRowCount: reminderCount) + size.height += reminderHeight + size.height += ReminderLiveActivityManager.listTopPadding + size.height += ReminderLiveActivityManager.listBottomPadding - ReminderLiveActivityManager.baselineMinimalisticBottomPadding + } return size }