Files
multitimer/MultiTimer/AlarmWindowManager.swift
T

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)
}
}