diff --git a/DynamicIsland/Localizable.xcstrings b/DynamicIsland/Localizable.xcstrings index 2273b82..cce2b6e 100644 --- a/DynamicIsland/Localizable.xcstrings +++ b/DynamicIsland/Localizable.xcstrings @@ -19814,6 +19814,9 @@ } } } + }, + "Fullscreen artwork on right-click" : { + }, "Fully charged" : { "comment" : "Charging fallback label when already charged", @@ -22845,6 +22848,9 @@ } } } + }, + "Keep album art visible during fullscreen artwork" : { + }, "Keep terminal open until clicked outside" : { "localizations" : { @@ -34260,6 +34266,9 @@ } } } + }, + "Right-click the album art on the lock screen to set it as the wallpaper. Right-click again or click the background to restore the original wallpaper. The swap is temporary and leaves no trace in System Settings." : { + }, "Ring" : { "comment" : "The name of the timer progress style that shows a ring shape.", diff --git a/DynamicIsland/components/LockScreen/LockScreenMusicPanel.swift b/DynamicIsland/components/LockScreen/LockScreenMusicPanel.swift index 4d6fbfd..3edc5f1 100644 --- a/DynamicIsland/components/LockScreen/LockScreenMusicPanel.swift +++ b/DynamicIsland/components/LockScreen/LockScreenMusicPanel.swift @@ -68,6 +68,7 @@ struct LockScreenMusicPanel: View { @Default(.lockScreenMusicAlbumParallaxEnabled) private var lockScreenParallaxEnabled @Default(.lockScreenMusicPanelWidth) private var collapsedPanelWidth @Default(.lockScreenMusicFullscreenArtworkEnabled) private var fullscreenArtworkEnabled + @Default(.lockScreenKeepAlbumArtVisibleDuringFullscreenArtwork) private var keepAlbumArtVisibleDuringFullscreenArtwork @Default(.lockScreenMusicFullscreenVideoArtwork) private var fullscreenVideoArtwork init(animator: LockScreenPanelAnimator) { @@ -338,7 +339,7 @@ struct LockScreenMusicPanel: View { private func albumArtButton(size: CGFloat, cornerRadius: CGFloat) -> some View { ZStack(alignment: .bottomTrailing) { - if isArtworkFullscreen { + if isArtworkFullscreen && !keepAlbumArtVisibleDuringFullscreenArtwork { RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) .fill(Color.white.opacity(0.06)) .overlay( @@ -359,8 +360,11 @@ struct LockScreenMusicPanel: View { } } } - .albumArtFlip(angle: isArtworkFullscreen ? 0 : musicManager.flipAngle) - .parallax3D(enableOverride: lockScreenParallaxEnabled && !isArtworkFullscreen, suspended: isParallaxSuspended) + .albumArtFlip(angle: isArtworkFullscreen && !keepAlbumArtVisibleDuringFullscreenArtwork ? 0 : musicManager.flipAngle) + .parallax3D( + enableOverride: lockScreenParallaxEnabled && (!isArtworkFullscreen || keepAlbumArtVisibleDuringFullscreenArtwork), + suspended: isParallaxSuspended + ) .frame(width: size) .background(albumArtBackground(cornerRadius: cornerRadius)) .clipShape(RoundedRectangle(cornerRadius: musicManager.albumArt.size.width/musicManager.albumArt.size.height > 1.0 ? appIconCornerRadius/3 : appIconCornerRadius, style: .continuous)) diff --git a/DynamicIsland/components/LockScreen/LockScreenTimerWidget.swift b/DynamicIsland/components/LockScreen/LockScreenTimerWidget.swift index d3524b1..0d6ce7c 100644 --- a/DynamicIsland/components/LockScreen/LockScreenTimerWidget.swift +++ b/DynamicIsland/components/LockScreen/LockScreenTimerWidget.swift @@ -45,10 +45,6 @@ struct LockScreenTimerWidget: View { } } - private func displayFont(size: CGFloat) -> Font { - .system(size: size, weight: .semibold, design: .rounded) - } - private var hasHoursComponent: Bool { abs(timerManager.remainingTime) >= 3600 } @@ -57,12 +53,6 @@ struct LockScreenTimerWidget: View { abs(timerManager.remainingTime) >= 36_000 // 10 hours or more } - private var titleFrameWidth: CGFloat { - if hasDoubleDigitHours { return 60 } - if hasHoursComponent { return 80 } - return 110 - } - private var countdownFrameWidth: CGFloat { if hasDoubleDigitHours { return 200 } if hasHoursComponent { return 185 } @@ -74,10 +64,6 @@ struct LockScreenTimerWidget: View { return .system(size: baseSize, weight: .bold, design: .rounded) } - private var timerLabel: String { - timerManager.timerName.isEmpty ? "Timer" : timerManager.timerName - } - private var countdownText: String { timerManager.formattedRemainingTime() } @@ -260,19 +246,6 @@ struct LockScreenTimerWidget: View { .layoutPriority(2) } - private var titleSection: some View { - MarqueeText( - .constant(timerLabel), - font: displayFont(size: 15), - nsFont: .title3, - textColor: accentColor, - minDuration: 0.16, - frameWidth: titleFrameWidth - ) - .frame(maxWidth: .infinity, alignment: .center) - .layoutPriority(0) - } - private var accentRibbon: some View { Capsule() .fill(accentGradient) diff --git a/DynamicIsland/components/Settings/SettingsView.swift b/DynamicIsland/components/Settings/SettingsView.swift index b44c3d2..e3cc1ee 100644 --- a/DynamicIsland/components/Settings/SettingsView.swift +++ b/DynamicIsland/components/Settings/SettingsView.swift @@ -2450,6 +2450,7 @@ struct Media: View { @Default(.lockScreenGlassStyle) private var lockScreenGlassStyle @Default(.lockScreenGlassCustomizationMode) private var lockScreenGlassCustomizationMode @Default(.lockScreenMusicAlbumParallaxEnabled) private var lockScreenMusicAlbumParallaxEnabled + @Default(.lockScreenMusicFullscreenArtworkEnabled) private var lockScreenMusicFullscreenArtworkEnabled @Default(.showStandardMediaControls) private var showStandardMediaControls @Default(.autoHideInactiveNotchMediaPlayer) private var autoHideInactiveNotchMediaPlayer @Default(.parallaxEffectIntensity) private var parallaxEffectIntensity @@ -2696,6 +2697,22 @@ struct Media: View { .opacity(enableLockScreenMediaWidget ? 1 : 0.5) .settingsHighlight(id: highlightID("Enable media panel blur")) } + VStack(alignment: .leading, spacing: 4) { + Defaults.Toggle(key: .lockScreenMusicFullscreenArtworkEnabled) { + Text("Fullscreen artwork on right-click") + } + .disabled(!enableLockScreenMediaWidget) + .settingsHighlight(id: highlightID("Fullscreen artwork on right-click")) + Defaults.Toggle(key: .lockScreenKeepAlbumArtVisibleDuringFullscreenArtwork) { + Text("Keep album art visible during fullscreen artwork") + } + .disabled(!enableLockScreenMediaWidget || !lockScreenMusicFullscreenArtworkEnabled) + .settingsHighlight(id: highlightID("Keep album art visible during fullscreen artwork")) + Text("Right-click the album art on the lock screen to set it as the wallpaper. Right-click again or click the background to restore the original wallpaper. The swap is temporary and leaves no trace in System Settings.") + .font(.caption) + .foregroundStyle(.secondary) + .fixedSize(horizontal: false, vertical: true) + } } header: { Text("Lock Screen Integration") } footer: { @@ -4576,6 +4593,7 @@ struct LockScreenSettings: View { @Default(.lockScreenTimerGlassCustomizationMode) private var lockScreenTimerGlassCustomizationMode @Default(.lockScreenTimerWidgetUsesBlur) private var timerGlassModeIsGlass @Default(.enableLockScreenMediaWidget) private var enableLockScreenMediaWidget + @Default(.lockScreenMusicFullscreenArtworkEnabled) private var lockScreenMusicFullscreenArtworkEnabled @Default(.enableLockScreenTimerWidget) private var enableLockScreenTimerWidget @Default(.enableLockScreenWeatherWidget) private var enableLockScreenWeatherWidget @Default(.enableLockScreenFocusWidget) private var enableLockScreenFocusWidget @@ -4809,6 +4827,22 @@ struct LockScreenSettings: View { .opacity(enableLockScreenMediaWidget ? 1 : 0.5) .settingsHighlight(id: highlightID("Enable media panel blur")) } + VStack(alignment: .leading, spacing: 4) { + Defaults.Toggle(key: .lockScreenMusicFullscreenArtworkEnabled) { + Text("Fullscreen artwork on right-click") + } + .disabled(!enableLockScreenMediaWidget) + .settingsHighlight(id: highlightID("Fullscreen artwork on right-click")) + Defaults.Toggle(key: .lockScreenKeepAlbumArtVisibleDuringFullscreenArtwork) { + Text("Keep album art visible during fullscreen artwork") + } + .disabled(!enableLockScreenMediaWidget || !lockScreenMusicFullscreenArtworkEnabled) + .settingsHighlight(id: highlightID("Keep album art visible during fullscreen artwork")) + Text("Right-click the album art on the lock screen to set it as the wallpaper. Right-click again or click the background to restore the original wallpaper. The swap is temporary and leaves no trace in System Settings.") + .font(.caption) + .foregroundStyle(.secondary) + .fixedSize(horizontal: false, vertical: true) + } if !showStandardMediaControls { Text("Enable Dynamic Island media controls to manage the lock screen panel.") diff --git a/DynamicIsland/models/Constants.swift b/DynamicIsland/models/Constants.swift index fd04466..4390df2 100644 --- a/DynamicIsland/models/Constants.swift +++ b/DynamicIsland/models/Constants.swift @@ -911,6 +911,7 @@ extension Defaults.Keys { static let lockScreenPanelUsesBlur = Key("lockScreenPanelUsesBlur", default: true) static let lockScreenMusicMergedAirPlayOutput = Key("lockScreenMusicMergedAirPlayOutput", default: true) static let lockScreenMusicFullscreenArtworkEnabled = Key("lockScreenMusicFullscreenArtworkEnabled", default: true) + static let lockScreenKeepAlbumArtVisibleDuringFullscreenArtwork = Key("lockScreenKeepAlbumArtVisibleDuringFullscreenArtwork", default: false) static let lockScreenMusicFullscreenVideoArtwork = Key("lockScreenMusicFullscreenVideoArtwork", default: true) static let lockScreenTimerWidgetUsesBlur = Key("lockScreenTimerWidgetUsesBlur", default: false) static let lockScreenReminderChipStyle = Key("lockScreenReminderChipStyle", default: .eventColor)