mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-27 15:14:33 +00:00
Working Lock Screen HUD
This commit is contained in:
parent
44b18513f2
commit
ce8cce0252
4 changed files with 265 additions and 10 deletions
|
|
@ -0,0 +1,95 @@
|
|||
//
|
||||
// LockScreenLiveActivityOverlay.swift
|
||||
// DynamicIsland
|
||||
//
|
||||
// Mirrors the closed-notch live activity layout on the macOS lock screen.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
enum LockLiveActivityState: Equatable {
|
||||
case locked
|
||||
case unlocking
|
||||
}
|
||||
|
||||
struct LockScreenLiveActivityOverlay: View {
|
||||
let state: LockLiveActivityState
|
||||
let notchSize: CGSize
|
||||
|
||||
private var indicatorSize: CGFloat {
|
||||
max(0, notchSize.height - 12)
|
||||
}
|
||||
|
||||
private var horizontalPadding: CGFloat {
|
||||
cornerRadiusInsets.closed.bottom
|
||||
}
|
||||
|
||||
private var baseWidth: CGFloat {
|
||||
notchSize.width + (indicatorSize * 2)
|
||||
}
|
||||
|
||||
private var totalWidth: CGFloat {
|
||||
baseWidth + (horizontalPadding * 2)
|
||||
}
|
||||
|
||||
private var iconName: String {
|
||||
state == .locked ? "lock.fill" : "lock.open.fill"
|
||||
}
|
||||
|
||||
private var iconColor: Color {
|
||||
state == .locked ? .blue : .green
|
||||
}
|
||||
|
||||
private var glowColor: Color {
|
||||
state == .locked ? Color.blue.opacity(0.15) : Color.green.opacity(0.2)
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 0) {
|
||||
Color.clear
|
||||
.background {
|
||||
HStack {
|
||||
ZStack {
|
||||
RoundedRectangle(cornerRadius: 6)
|
||||
.fill(glowColor)
|
||||
|
||||
Image(systemName: iconName)
|
||||
.font(.system(size: 12, weight: .semibold))
|
||||
.foregroundColor(iconColor)
|
||||
.modifier(LockPulsingModifier(isUnlocking: state == .unlocking))
|
||||
}
|
||||
.frame(width: indicatorSize, height: indicatorSize)
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
|
||||
}
|
||||
.frame(width: indicatorSize, height: notchSize.height)
|
||||
|
||||
Color.clear
|
||||
.frame(width: notchSize.width, height: notchSize.height)
|
||||
|
||||
Color.clear
|
||||
.frame(width: indicatorSize, height: notchSize.height)
|
||||
}
|
||||
.frame(width: baseWidth, height: notchSize.height)
|
||||
.padding(.horizontal, horizontalPadding)
|
||||
.background(Color.black)
|
||||
.clipShape(
|
||||
NotchShape(
|
||||
topCornerRadius: cornerRadiusInsets.closed.top,
|
||||
bottomCornerRadius: cornerRadiusInsets.closed.bottom
|
||||
)
|
||||
)
|
||||
.frame(width: totalWidth, height: notchSize.height)
|
||||
.animation(.spring(response: 0.45, dampingFraction: 0.85), value: state)
|
||||
.drawingGroup()
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
VStack(spacing: 24) {
|
||||
LockScreenLiveActivityOverlay(state: .locked, notchSize: CGSize(width: 220, height: 32))
|
||||
LockScreenLiveActivityOverlay(state: .unlocking, notchSize: CGSize(width: 220, height: 32))
|
||||
}
|
||||
.padding()
|
||||
.background(Color.gray.opacity(0.2))
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue