import SwiftUI import AppKit /// The menu-bar panel: permission statuses, backend health, and a link to /// Settings. Shown when the user clicks the status-bar item. struct MenuBarView: View { @EnvironmentObject private var settings: AppSettings @EnvironmentObject private var permissions: PermissionsManager @EnvironmentObject private var health: SparkControlHealth var body: some View { NavigationStack { VStack(alignment: .leading, spacing: 12) { header Divider() permissionsSection Divider() backendSection Divider() footer } .padding(14) .frame(width: 320) } .onAppear { permissions.refresh() } .task { await refreshHealth() } } private var header: some View { VStack(alignment: .leading, spacing: 2) { Text("Ten31 Transcripts").font(.headline) Text("Phase 0 · setup & status") .font(.caption) .foregroundStyle(.secondary) } } private var permissionsSection: some View { VStack(alignment: .leading, spacing: 8) { Text("Permissions").font(.subheadline).bold() PermissionRow( title: "Microphone", state: permissions.microphone, onGrant: permissions.requestMicrophone, onOpenSettings: { permissions.openSettings(.microphone) } ) PermissionRow( title: "Screen Recording", state: permissions.screenRecording, onGrant: permissions.requestScreenRecording, onOpenSettings: { permissions.openSettings(.screenRecording) } ) PermissionRow( title: "Accessibility", state: permissions.accessibility, onGrant: permissions.requestAccessibility, onOpenSettings: { permissions.openSettings(.accessibility) } ) } } private var backendSection: some View { VStack(alignment: .leading, spacing: 8) { HStack { Text("Backend").font(.subheadline).bold() Spacer() Button("Check") { Task { await refreshHealth() } } .disabled(health.status == .checking) } Text(settings.backendBaseURL) .font(.caption) .foregroundStyle(.secondary) .lineLimit(1) .truncationMode(.middle) HStack(spacing: 8) { StatusDot(color: healthColor) Text(healthText).font(.caption) } } } private var footer: some View { HStack { NavigationLink("Settings…") { SettingsView() } Spacer() Button("Quit") { NSApplication.shared.terminate(nil) } } } private func refreshHealth() async { await health.check( baseURL: settings.backendBaseURL, skipTLS: settings.skipTLSVerification ) } private var healthColor: Color { switch health.status { case .online: return .green case .offline: return .red case .checking: return .orange case .unknown: return .gray } } private var healthText: String { switch health.status { case .unknown: return "Not checked yet" case .checking: return "Checking…" case .online(let detail): return "Online · \(detail)" case .offline(let error): return "Offline · \(error)" } } }