vOOice/VoiceInk/Views/Recorder/NotchRecorderView.swift
2025-09-24 11:08:33 +05:45

106 lines
3.0 KiB
Swift

import SwiftUI
struct NotchRecorderView: View {
@ObservedObject var whisperState: WhisperState
@ObservedObject var recorder: Recorder
@EnvironmentObject var windowManager: NotchWindowManager
@State private var isHovering = false
@State private var activePopover: ActivePopoverState = .none
@ObservedObject private var powerModeManager = PowerModeManager.shared
@EnvironmentObject private var enhancementService: AIEnhancementService
private var menuBarHeight: CGFloat {
if let screen = NSScreen.main {
if screen.safeAreaInsets.top > 0 {
return screen.safeAreaInsets.top
}
return NSApplication.shared.mainMenu?.menuBarHeight ?? NSStatusBar.system.thickness
}
return NSStatusBar.system.thickness
}
private var exactNotchWidth: CGFloat {
if let screen = NSScreen.main {
if screen.safeAreaInsets.left > 0 {
return screen.safeAreaInsets.left * 2
}
return 200
}
return 200
}
private var leftSection: some View {
HStack(spacing: 12) {
RecorderPromptButton(
activePopover: $activePopover,
buttonSize: 22,
padding: EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)
)
RecorderPowerModeButton(
activePopover: $activePopover,
buttonSize: 22,
padding: EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)
)
Spacer()
}
.frame(width: 84)
.padding(.leading, 16)
}
private var centerSection: some View {
Rectangle()
.fill(Color.clear)
.frame(width: exactNotchWidth)
.contentShape(Rectangle())
}
private var rightSection: some View {
HStack(spacing: 8) {
Spacer()
statusDisplay
}
.frame(width: 84)
.padding(.trailing, 16)
}
private var statusDisplay: some View {
RecorderStatusDisplay(
currentState: whisperState.recordingState,
audioMeter: recorder.audioMeter,
menuBarHeight: menuBarHeight
)
.frame(width: 70)
.padding(.trailing, 8)
}
var body: some View {
Group {
if windowManager.isVisible {
HStack(spacing: 0) {
leftSection
centerSection
rightSection
}
.frame(height: menuBarHeight)
.frame(maxWidth: windowManager.isVisible ? .infinity : 0)
.background(Color.black)
.mask {
NotchShape(cornerRadius: 10)
}
.clipped()
.onHover { hovering in
isHovering = hovering
}
.opacity(windowManager.isVisible ? 1 : 0)
}
}
}
}