feat: wire all components into app entry with menu bar, shortcut, and windows
This commit is contained in:
parent
1c9b44ab6b
commit
602f97253c
1 changed files with 67 additions and 5 deletions
|
|
@ -2,13 +2,75 @@ import SwiftUI
|
||||||
|
|
||||||
@main
|
@main
|
||||||
struct MyVoxtralApp: App {
|
struct MyVoxtralApp: App {
|
||||||
|
@StateObject private var manager = TranscriptionManager()
|
||||||
|
@StateObject private var settings = AppSettings.shared
|
||||||
|
@State private var transcriptionPanel: TranscriptionPanel?
|
||||||
|
@State private var settingsWindow: NSWindow?
|
||||||
|
|
||||||
|
private let globalShortcut = GlobalShortcut()
|
||||||
|
|
||||||
var body: some Scene {
|
var body: some Scene {
|
||||||
MenuBarExtra("MyVoxtral", systemImage: "mic.fill") {
|
MenuBarExtra {
|
||||||
Text("MyVoxtral")
|
MenuBarView(
|
||||||
Divider()
|
manager: manager,
|
||||||
Button("Quit") {
|
onShowTranscription: { showTranscriptionWindow() },
|
||||||
NSApplication.shared.terminate(nil)
|
onShowSettings: { showSettingsWindow() }
|
||||||
|
)
|
||||||
|
.task {
|
||||||
|
if !settings.hasAPIKey {
|
||||||
|
showSettingsWindow()
|
||||||
|
}
|
||||||
|
registerShortcut()
|
||||||
|
}
|
||||||
|
.onChange(of: manager.isRecording) {
|
||||||
|
if manager.isRecording && settings.outputMode == .textBox {
|
||||||
|
showTranscriptionWindow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} label: {
|
||||||
|
Image(systemName: manager.isRecording ? "mic.fill" : "mic")
|
||||||
|
.symbolRenderingMode(.palette)
|
||||||
|
.foregroundStyle(manager.isRecording ? .red : .primary)
|
||||||
|
}
|
||||||
|
.onChange(of: settings.shortcutKeyCode) { registerShortcut() }
|
||||||
|
.onChange(of: settings.shortcutModifiers) { registerShortcut() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private func registerShortcut() {
|
||||||
|
globalShortcut.register(
|
||||||
|
keyCode: settings.shortcutKeyCode,
|
||||||
|
modifiers: settings.shortcutModifiers
|
||||||
|
)
|
||||||
|
globalShortcut.onTrigger = { [weak manager] in
|
||||||
|
Task { @MainActor in
|
||||||
|
manager?.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func showTranscriptionWindow() {
|
||||||
|
if transcriptionPanel == nil {
|
||||||
|
transcriptionPanel = TranscriptionPanel(manager: manager)
|
||||||
|
}
|
||||||
|
transcriptionPanel?.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func showSettingsWindow() {
|
||||||
|
if let settingsWindow, settingsWindow.isVisible {
|
||||||
|
settingsWindow.makeKeyAndOrderFront(nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let window = NSWindow(
|
||||||
|
contentRect: NSRect(x: 0, y: 0, width: 360, height: 340),
|
||||||
|
styleMask: [.titled, .closable],
|
||||||
|
backing: .buffered,
|
||||||
|
defer: false
|
||||||
|
)
|
||||||
|
window.title = "MyVoxtral Settings"
|
||||||
|
window.contentView = NSHostingView(rootView: SettingsView())
|
||||||
|
window.center()
|
||||||
|
window.makeKeyAndOrderFront(nil)
|
||||||
|
NSApp.activate(ignoringOtherApps: true)
|
||||||
|
self.settingsWindow = window
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue