101 lines
2.6 KiB
Swift
101 lines
2.6 KiB
Swift
import AppKit
|
|
import SwiftUI
|
|
|
|
@MainActor
|
|
final class AlarmWindowManager {
|
|
static let shared = AlarmWindowManager()
|
|
|
|
private var windows: [UUID: NSWindow] = [:]
|
|
|
|
private init() {}
|
|
|
|
func showAlarm(
|
|
timerID: UUID,
|
|
timerName: String,
|
|
onRepeat: @escaping () -> Void,
|
|
onFinish: @escaping () -> Void
|
|
) {
|
|
if let existingWindow = windows[timerID] {
|
|
existingWindow.makeKeyAndOrderFront(nil)
|
|
NSApp.activate(ignoringOtherApps: true)
|
|
return
|
|
}
|
|
|
|
let view = AlarmPopupView(
|
|
timerName: timerName,
|
|
repeatAction: { [weak self] in
|
|
onRepeat()
|
|
self?.closeWindow(timerID: timerID)
|
|
},
|
|
finishAction: { [weak self] in
|
|
onFinish()
|
|
self?.closeWindow(timerID: timerID)
|
|
}
|
|
)
|
|
|
|
let hostingView = NSHostingView(rootView: view)
|
|
|
|
let window = NSWindow(
|
|
contentRect: NSRect(x: 0, y: 0, width: 360, height: 210),
|
|
styleMask: [.titled, .closable],
|
|
backing: .buffered,
|
|
defer: false
|
|
)
|
|
|
|
window.title = "Timer abgelaufen"
|
|
window.contentView = hostingView
|
|
window.isReleasedWhenClosed = false
|
|
window.level = .floating
|
|
window.center()
|
|
|
|
windows[timerID] = window
|
|
|
|
window.makeKeyAndOrderFront(nil)
|
|
NSApp.activate(ignoringOtherApps: true)
|
|
}
|
|
|
|
func closeWindow(timerID: UUID) {
|
|
windows[timerID]?.close()
|
|
windows.removeValue(forKey: timerID)
|
|
}
|
|
}
|
|
|
|
struct AlarmPopupView: View {
|
|
let timerName: String
|
|
let repeatAction: () -> Void
|
|
let finishAction: () -> Void
|
|
|
|
var body: some View {
|
|
VStack(spacing: 18) {
|
|
Image(systemName: "timer")
|
|
.font(.system(size: 42))
|
|
.foregroundStyle(.orange)
|
|
|
|
VStack(spacing: 6) {
|
|
Text("Timer abgelaufen")
|
|
.font(.title2)
|
|
.bold()
|
|
|
|
Text("„\(timerName)” ist fertig.")
|
|
.font(.body)
|
|
.multilineTextAlignment(.center)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
|
|
HStack(spacing: 12) {
|
|
Button("Beenden") {
|
|
finishAction()
|
|
}
|
|
.keyboardShortcut(.cancelAction)
|
|
|
|
Button("Wiederholen") {
|
|
repeatAction()
|
|
}
|
|
.keyboardShortcut(.defaultAction)
|
|
}
|
|
}
|
|
.padding(24)
|
|
.frame(width: 360, height: 210)
|
|
}
|
|
}
|