- Voices.swift: 13 Azure voices, default en-US-Ava - SettingsStore: persist voiceID/modelID, fallback to default voice - VoiceSession: sync set_voice/set_model on agent_ready, selectVoice/selectModel, track models + model_changed - SettingsView: voice and model picker sheets - ControlChannel: publish via publish(data:) reliable data channel instead of sendText DataStream (agent listens on legacy data_received; DataStream text was dropped)
43 lines
1.5 KiB
Swift
43 lines
1.5 KiB
Swift
import Foundation
|
|
import Combine
|
|
|
|
final class SettingsStore: ObservableObject {
|
|
@Published var serverURL: String {
|
|
didSet { UserDefaults.standard.set(serverURL, forKey: Keys.serverURL) }
|
|
}
|
|
@Published var voiceID: String {
|
|
didSet { UserDefaults.standard.set(voiceID, forKey: Keys.voiceID) }
|
|
}
|
|
@Published var modelID: String? {
|
|
didSet { UserDefaults.standard.set(modelID, forKey: Keys.modelID) }
|
|
}
|
|
@Published var textMode: Bool {
|
|
didSet { UserDefaults.standard.set(textMode, forKey: Keys.textMode) }
|
|
}
|
|
@Published var volume: Double {
|
|
didSet { UserDefaults.standard.set(volume, forKey: Keys.volume) }
|
|
}
|
|
|
|
private enum Keys {
|
|
static let serverURL = "serverURL"
|
|
static let voiceID = "voiceID"
|
|
static let modelID = "modelID"
|
|
static let textMode = "textMode"
|
|
static let volume = "volume"
|
|
}
|
|
|
|
init() {
|
|
let d = UserDefaults.standard
|
|
serverURL = d.string(forKey: Keys.serverURL) ?? "https://192.168.86.2:9178"
|
|
let storedVoice = d.string(forKey: Keys.voiceID)
|
|
voiceID = Voices.all.contains { $0.id == storedVoice } ? (storedVoice ?? "") : Voices.defaultID
|
|
modelID = d.string(forKey: Keys.modelID)
|
|
textMode = d.bool(forKey: Keys.textMode)
|
|
volume = d.object(forKey: Keys.volume) as? Double ?? 0.8
|
|
}
|
|
|
|
var trimmedServerURL: String {
|
|
serverURL.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
}
|
|
}
|