other small improvements

This commit is contained in:
delli 2026-04-22 17:25:14 +02:00
commit ffd72456d9
7 changed files with 515 additions and 302 deletions

View file

@ -42,18 +42,42 @@ struct LockScreenLiveActivity: View {
private var indicatorDimension: CGFloat {
max(0, vm.effectiveClosedNotchHeight - 12)
}
private var indicatorSideHeight: CGFloat {
max(0, vm.effectiveClosedNotchHeight - (isHovering ? 0 : 12))
}
private var expandedIndicatorSideWidth: CGFloat {
max(0, vm.effectiveClosedNotchHeight - (isHovering ? 0 : 12) + gestureProgress / 2)
}
private var indicatorSideWidth: CGFloat {
isExpanded ? expandedIndicatorSideWidth : 0
}
private var indicatorVisibilityProgress: CGFloat {
guard expandedIndicatorSideWidth > 0 else { return 0 }
return min(max(indicatorSideWidth / expandedIndicatorSideWidth, 0), 1)
}
private var indicatorOpacity: Double {
let fadeThreshold: CGFloat = 0.16
guard indicatorVisibilityProgress < fadeThreshold else { return 1 }
return Double(max(0, indicatorVisibilityProgress / fadeThreshold))
}
var body: some View {
HStack(spacing: 0) {
// Left - Lock icon with subtle glow
Color.clear
.overlay(alignment: .leading) {
if isExpanded {
LockIconProgressView(progress: iconAnimator.progress, iconColor: iconColor)
.frame(width: indicatorDimension, height: indicatorDimension)
}
LockIconProgressView(progress: iconAnimator.progress, iconColor: iconColor)
.frame(width: indicatorDimension, height: indicatorDimension)
.opacity(indicatorOpacity)
.scaleEffect(0.96 + (indicatorVisibilityProgress * 0.04))
}
.frame(width: isExpanded ? max(0, vm.effectiveClosedNotchHeight - (isHovering ? 0 : 12) + gestureProgress / 2) : 0, height: vm.effectiveClosedNotchHeight - (isHovering ? 0 : 12))
.frame(width: indicatorSideWidth, height: indicatorSideHeight, alignment: .leading)
.clipped()
// Center - Black fill
Rectangle()
@ -62,7 +86,7 @@ struct LockScreenLiveActivity: View {
// Right - Empty for symmetry with animation
Color.clear
.frame(width: isExpanded ? max(0, vm.effectiveClosedNotchHeight - (isHovering ? 0 : 12) + gestureProgress / 2) : 0, height: vm.effectiveClosedNotchHeight - (isHovering ? 0 : 12))
.frame(width: indicatorSideWidth, height: indicatorSideHeight)
}
.frame(height: vm.effectiveClosedNotchHeight + (isHovering ? 8 : 0))
.onAppear {
@ -100,6 +124,5 @@ struct LockScreenLiveActivity: View {
}
}
.animation(.spring(response: 0.5, dampingFraction: 0.85), value: lockScreenManager.isLocked)
.animation(.easeOut(duration: 0.25), value: isExpanded)
}
}

View file

@ -56,6 +56,7 @@ struct LockScreenMusicPanel: View {
@Default(.lockScreenMusicLiquidGlassVariant) private var musicGlassVariant
@Default(.lockScreenShowAppIcon) var showAppIcon
@Default(.lockScreenPanelShowsBorder) var showPanelBorder
@Default(.lockScreenMusicUsesEnhancedLiquidBorder) private var useEnhancedLiquidBorder
@Default(.lockScreenPanelUsesBlur) var enableBlur
@Default(.showMediaOutputControl) private var showMediaOutputControl
@Default(.showShuffleAndRepeat) private var showShuffleAndRepeat
@ -113,6 +114,10 @@ struct LockScreenMusicPanel: View {
private var usesLiquidGlass: Bool {
usesCustomLiquidGlass || usesStandardLiquidGlass
}
private var usesEnhancedCustomLiquidBorder: Bool {
usesCustomLiquidGlass && useEnhancedLiquidBorder
}
var body: some View {
if isActive && musicManager.hasActiveSession {
@ -131,9 +136,8 @@ struct LockScreenMusicPanel: View {
.frame(width: currentSize.width, height: currentSize.height, alignment: .topLeading)
.clipShape(RoundedRectangle(cornerRadius: panelCornerRadius, style: .continuous))
.overlay {
if showPanelBorder && !usesLiquidGlass {
RoundedRectangle(cornerRadius: panelCornerRadius)
.stroke(Color.white.opacity(0.35), lineWidth: 1.4)
if showPanelBorder {
panelBorderOverlay
}
}
.shadow(color: Color.black.opacity(0.3), radius: 20, x: 0, y: 10)
@ -1077,6 +1081,53 @@ struct LockScreenMusicPanel: View {
.accessibilityHidden(true)
}
@ViewBuilder
private var panelBorderOverlay: some View {
if usesEnhancedCustomLiquidBorder {
ZStack {
RoundedRectangle(cornerRadius: panelCornerRadius, style: .continuous)
.stroke(
Color.white.opacity(0.22),
lineWidth: 1.05
)
RoundedRectangle(cornerRadius: panelCornerRadius, style: .continuous)
.inset(by: 0.85)
.stroke(
LinearGradient(
colors: [
Color.white.opacity(0.28),
Color.white.opacity(0.1),
Color.black.opacity(0.18)
],
startPoint: .topLeading,
endPoint: .bottomTrailing
),
lineWidth: 0.9
)
RoundedRectangle(cornerRadius: panelCornerRadius, style: .continuous)
.inset(by: 1.55)
.stroke(
Color.black.opacity(0.16),
lineWidth: 0.55
)
}
.allowsHitTesting(false)
} else if usesLiquidGlass {
RoundedRectangle(cornerRadius: panelCornerRadius, style: .continuous)
.stroke(
Color.white.opacity(usesCustomLiquidGlass ? 0.15 : 0.14),
lineWidth: usesCustomLiquidGlass ? 0.95 : 0.9
)
.allowsHitTesting(false)
} else {
RoundedRectangle(cornerRadius: panelCornerRadius, style: .continuous)
.stroke(Color.white.opacity(0.35), lineWidth: 1.4)
.allowsHitTesting(false)
}
}
private func albumArtImage(size: CGFloat, cornerRadius: CGFloat) -> some View {
Image(nsImage: musicManager.albumArt)
.resizable()