vOOice/VoiceInk/Views/MiniWindowManager.swift

83 lines
2.2 KiB
Swift

import SwiftUI
import AppKit
class MiniWindowManager: ObservableObject {
@Published var isVisible = false
private var windowController: NSWindowController?
private var miniPanel: MiniRecorderPanel?
private let whisperState: WhisperState
private let recorder: Recorder
init(whisperState: WhisperState, recorder: Recorder) {
self.whisperState = whisperState
self.recorder = recorder
NotificationCenter.default.addObserver(
self,
selector: #selector(handleHideNotification),
name: NSNotification.Name("HideMiniRecorder"),
object: nil
)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
@objc private func handleHideNotification() {
hide()
}
func show() {
if isVisible { return }
let activeScreen = NSApp.keyWindow?.screen ?? NSScreen.main ?? NSScreen.screens[0]
initializeWindow(screen: activeScreen)
self.isVisible = true
miniPanel?.show()
}
func hide() {
guard isVisible else { return }
self.isVisible = false
self.miniPanel?.hide { [weak self] in
guard let self = self else { return }
self.deinitializeWindow()
}
}
private func initializeWindow(screen: NSScreen) {
deinitializeWindow()
let metrics = MiniRecorderPanel.calculateWindowMetrics()
let panel = MiniRecorderPanel(contentRect: metrics)
let miniRecorderView = MiniRecorderView(whisperState: whisperState, recorder: recorder)
.environmentObject(self)
let hostingController = NSHostingController(rootView: miniRecorderView)
panel.contentView = hostingController.view
self.miniPanel = panel
self.windowController = NSWindowController(window: panel)
panel.orderFrontRegardless()
}
private func deinitializeWindow() {
windowController?.close()
windowController = nil
miniPanel = nil
}
func toggle() {
if isVisible {
hide()
} else {
show()
}
}
}