mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-27 15:14:33 +00:00
WIP: Settings
This commit is contained in:
parent
105b0466a4
commit
aeed23f950
9 changed files with 749 additions and 3 deletions
|
|
@ -700,6 +700,7 @@ struct SettingsView: View {
|
|||
SettingsSearchEntry(tab: .appearance, title: "App icon", keywords: ["app icon", "custom icon"], highlightID: SettingsTab.appearance.highlightID(for: "App icon")),
|
||||
|
||||
// Lock Screen
|
||||
SettingsSearchEntry(tab: .lockScreen, title: "Preview lock screen widgets", keywords: ["preview", "lock screen", "widgets"], highlightID: SettingsTab.lockScreen.highlightID(for: "Preview lock screen widgets")),
|
||||
SettingsSearchEntry(tab: .lockScreen, title: "Enable lock screen live activity", keywords: ["lock screen", "live activity"], highlightID: SettingsTab.lockScreen.highlightID(for: "Enable lock screen live activity")),
|
||||
SettingsSearchEntry(tab: .lockScreen, title: "Play lock/unlock sounds", keywords: ["chime", "sound"], highlightID: SettingsTab.lockScreen.highlightID(for: "Play lock/unlock sounds")),
|
||||
SettingsSearchEntry(tab: .lockScreen, title: "Material", keywords: ["glass", "frosted", "liquid"], highlightID: SettingsTab.lockScreen.highlightID(for: "Material")),
|
||||
|
|
@ -2801,7 +2802,7 @@ private struct SettingsLoopingVideoIcon: NSViewRepresentable {
|
|||
private var controller: SettingsLoopingPlayerController?
|
||||
|
||||
func attach(layer: AVPlayerLayer, url: URL) {
|
||||
controller = SettingsLoopingPlayerController(url: url)
|
||||
controller = SettingsLoopingPlayerController(url: url, autoPlay: true)
|
||||
layer.player = controller?.player
|
||||
}
|
||||
}
|
||||
|
|
@ -2811,15 +2812,25 @@ private final class SettingsLoopingPlayerController {
|
|||
let player: AVQueuePlayer
|
||||
private var looper: AVPlayerLooper?
|
||||
|
||||
init(url: URL) {
|
||||
init(url: URL, autoPlay: Bool = true) {
|
||||
let item = AVPlayerItem(url: url)
|
||||
player = AVQueuePlayer()
|
||||
player.isMuted = true
|
||||
player.actionAtItemEnd = .none
|
||||
looper = AVPlayerLooper(player: player, templateItem: item)
|
||||
if autoPlay {
|
||||
player.play()
|
||||
}
|
||||
}
|
||||
|
||||
func play() {
|
||||
player.play()
|
||||
}
|
||||
|
||||
func pause() {
|
||||
player.pause()
|
||||
}
|
||||
|
||||
deinit {
|
||||
player.pause()
|
||||
looper = nil
|
||||
|
|
@ -3298,6 +3309,9 @@ struct Appearance: View {
|
|||
.foregroundStyle(.secondary)
|
||||
}
|
||||
Slider(value: appearanceMusicVariantBinding, in: liquidVariantRange, step: 1)
|
||||
|
||||
LockScreenGlassVariantPreviewCell(variant: $lockScreenMusicLiquidGlassVariant)
|
||||
.padding(.top, 6)
|
||||
}
|
||||
.settingsHighlight(id: highlightID("Music panel variant (appearance)"))
|
||||
.disabled(!enableLockScreenMediaWidget)
|
||||
|
|
@ -3810,6 +3824,7 @@ struct Appearance: View {
|
|||
|
||||
struct LockScreenSettings: View {
|
||||
@ObservedObject private var calendarManager = CalendarManager.shared
|
||||
@ObservedObject private var previewManager = LockScreenWidgetPreviewManager.shared
|
||||
@Default(.lockScreenGlassStyle) private var lockScreenGlassStyle
|
||||
@Default(.lockScreenGlassCustomizationMode) private var lockScreenGlassCustomizationMode
|
||||
@Default(.lockScreenMusicLiquidGlassVariant) private var lockScreenMusicLiquidGlassVariant
|
||||
|
|
@ -3935,6 +3950,18 @@ struct LockScreenSettings: View {
|
|||
Text("Controls whether Dynamic Island mirrors lock/unlock events with its own live activity and audible chimes.")
|
||||
}
|
||||
|
||||
Section {
|
||||
Button(previewManager.isPreviewVisible ? "Hide lock screen preview" : "Preview lock screen widgets") {
|
||||
previewManager.togglePreview()
|
||||
}
|
||||
.buttonStyle(.borderedProminent)
|
||||
.settingsHighlight(id: highlightID("Preview lock screen widgets"))
|
||||
} header: {
|
||||
Text("Preview")
|
||||
} footer: {
|
||||
Text("Opens a transparent preview window with mock data that mirrors the current lock screen widget configuration.")
|
||||
}
|
||||
|
||||
Section {
|
||||
if #available(macOS 26.0, *) {
|
||||
Picker("Material", selection: $lockScreenGlassStyle) {
|
||||
|
|
@ -4400,7 +4427,8 @@ extension LockScreenSettings {
|
|||
value: Binding<Double>,
|
||||
currentValue: Int,
|
||||
isEnabled: Bool,
|
||||
highlight: String
|
||||
highlight: String,
|
||||
preview: AnyView? = nil
|
||||
) -> some View {
|
||||
VStack(alignment: .leading, spacing: 6) {
|
||||
HStack {
|
||||
|
|
@ -4411,6 +4439,11 @@ extension LockScreenSettings {
|
|||
.foregroundStyle(.secondary)
|
||||
}
|
||||
Slider(value: value, in: liquidVariantRange, step: 1)
|
||||
|
||||
if let preview {
|
||||
preview
|
||||
.padding(.top, 6)
|
||||
}
|
||||
}
|
||||
.settingsHighlight(id: highlight)
|
||||
.disabled(!isEnabled)
|
||||
|
|
@ -4418,6 +4451,53 @@ extension LockScreenSettings {
|
|||
}
|
||||
}
|
||||
|
||||
private struct LockScreenGlassVariantPreviewCell: View {
|
||||
@Binding var variant: LiquidGlassVariant
|
||||
|
||||
private let cornerRadius: CGFloat = 16
|
||||
private let previewCornerRadius: CGFloat = 14
|
||||
private let previewSize = CGSize(width: 190, height: 96)
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
Image("glassdesktop")
|
||||
.resizable()
|
||||
.scaledToFill()
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
.clipped()
|
||||
|
||||
liquidGlassPreview
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.frame(height: 120)
|
||||
.clipShape(RoundedRectangle(cornerRadius: cornerRadius, style: .continuous))
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: cornerRadius, style: .continuous)
|
||||
.stroke(Color.white.opacity(0.12), lineWidth: 1)
|
||||
)
|
||||
.padding(.vertical, 6)
|
||||
.allowsHitTesting(false)
|
||||
}
|
||||
|
||||
private var liquidGlassPreview: some View {
|
||||
TimelineView(.periodic(from: .now, by: 1.0 / 30.0)) { context in
|
||||
let phase = context.date.timeIntervalSinceReferenceDate.truncatingRemainder(dividingBy: 1.0)
|
||||
let opacityJitter = phase < 0.5 ? 1.0 : 0.999999
|
||||
LiquidGlassBackground(
|
||||
variant: variant,
|
||||
cornerRadius: previewCornerRadius,
|
||||
trigger: context.date.timeIntervalSinceReferenceDate
|
||||
) {
|
||||
Color.white.opacity(0.04)
|
||||
}
|
||||
.frame(width: previewSize.width, height: previewSize.height)
|
||||
.opacity(opacityJitter)
|
||||
}
|
||||
.shadow(color: Color.black.opacity(0.2), radius: 10, x: 0, y: 6)
|
||||
}
|
||||
}
|
||||
|
||||
private struct LockScreenPositioningControls: View {
|
||||
@Default(.lockScreenWeatherVerticalOffset) private var weatherOffset
|
||||
@Default(.lockScreenMusicVerticalOffset) private var musicOffset
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue