Files
voice-cat/clients/apple/iOS/VoiceCatiOS/Views/SettingsView.swift

95 lines
4.0 KiB
Swift
Raw Normal View History

import SwiftUI
import VoiceCatCore
struct SettingsView: View {
@Environment(AppState.self) private var appState
@Bindable var session: SessionState
var body: some View {
NavigationStack {
Form {
// Voice input section
Section("Voice Input") {
Picker("Input Mode", selection: Binding(
get: { session.voiceState.inputMode },
set: { session.setInputMode($0) }
)) {
Text("Voice Activation").tag(VoiceCatInputMode.voiceActivation)
Text("Push to Talk").tag(VoiceCatInputMode.pushToTalk)
Text("Always On").tag(VoiceCatInputMode.alwaysOn)
}
.accessibilityLabel("Voice input mode")
if session.voiceState.inputMode == .voiceActivation {
VStack(alignment: .leading, spacing: 4) {
Text("VAD Threshold: \(String(format: "%.3f", session.voiceState.vadThreshold))")
.font(.caption)
Slider(
value: Binding(
get: { Double(session.voiceState.vadThreshold) },
set: { session.setVadThreshold(Float($0)) }
),
in: 0.001...0.1, step: 0.001
)
.accessibilityLabel("Voice activation threshold")
}
}
}
// Audio device section
if !session.devices.isEmpty {
Section("Input Device") {
Picker("Microphone", selection: Binding(
get: { session.voiceState.currentDeviceId ?? "" },
set: { id in
session.voiceState.currentDeviceId = id.isEmpty ? nil : id
if session.voiceState.localStreamId != 0 {
session.client.setInputDevice(
streamId: session.voiceState.localStreamId,
deviceId: id.isEmpty ? nil : id)
}
}
)) {
Text("Default").tag("")
ForEach(session.devices) { dev in
Text(dev.name).tag(dev.id)
}
}
.accessibilityLabel("Microphone selection")
}
}
// Admin section
if session.permissions.canAdminAccounts || session.permissions.isAdmin {
Section("Administration") {
NavigationLink("Manage Accounts") {
AccountsView(session: session)
}
.accessibilityLabel("Manage server accounts")
}
}
// Server info
Section("Server") {
Button(role: .destructive) {
session.stopMicStream()
appState.disconnect()
} label: {
Label("Disconnect", systemImage: "phone.down")
.foregroundStyle(.red)
}
.accessibilityLabel("Disconnect from server")
}
Section("About") {
Text(VoiceCatClient.versionString)
.font(.caption)
.foregroundStyle(.secondary)
.accessibilityLabel("Version: \(VoiceCatClient.versionString)")
}
}
.navigationTitle("Settings")
}
}
}