Redesign Hope iOS UI, harden playback, and document project handoff

This commit is contained in:
snowspeeder committed 2026-09-09 20:23:44 -04:00
1 parent 40aaf4fea7
commit 24f95639dc
24 files changed
+1470 -594

No files matched your search

+29 -6
View File
@@ -3,19 +3,19 @@ import Combine
final class SettingsStore: ObservableObject {
@Published var serverURL: String {
didSet { UserDefaults.standard.set(serverURL, forKey: Keys.serverURL) }
didSet { AppPreferences.store.set(serverURL, forKey: Keys.serverURL) }
}
@Published var voiceID: String {
didSet { UserDefaults.standard.set(voiceID, forKey: Keys.voiceID) }
didSet { AppPreferences.store.set(voiceID, forKey: Keys.voiceID) }
}
@Published var modelID: String? {
didSet { UserDefaults.standard.set(modelID, forKey: Keys.modelID) }
didSet { AppPreferences.store.set(modelID, forKey: Keys.modelID) }
}
@Published var textMode: Bool {
didSet { UserDefaults.standard.set(textMode, forKey: Keys.textMode) }
didSet { AppPreferences.store.set(textMode, forKey: Keys.textMode) }
}
@Published var volume: Double {
didSet { UserDefaults.standard.set(volume, forKey: Keys.volume) }
didSet { AppPreferences.store.set(volume, forKey: Keys.volume) }
}
private enum Keys {
@@ -29,7 +29,7 @@ final class SettingsStore: ObservableObject {
static let defaultServerURL = "https://192.168.86.2:9178"
init() {
let d = UserDefaults.standard
let d = AppPreferences.store
// Sanitize legacy values: earlier versions wrote the field to storage on
// every keystroke, so an invalid half-typed URL could be persisted and
// shipped to the network layer. Fall back to the documented default and
@@ -54,3 +54,26 @@ final class SettingsStore: ObservableObject {
serverURL.trimmingCharacters(in: .whitespacesAndNewlines)
}
}
enum AppPreferences {
static let store: UserDefaults = {
#if DEBUG
if ProcessInfo.processInfo.arguments.contains("--ui-testing") {
let suite = "dev.shane.voice.ui-testing"
let defaults = UserDefaults(suiteName: suite)!
if ProcessInfo.processInfo.arguments.contains("--reset-ui-testing") {
defaults.removePersistentDomain(forName: suite)
// Deterministic offline errors; UI tests must not contact the NAS.
defaults.set("https://127.0.0.1:1", forKey: "serverURL")
}
if ProcessInfo.processInfo.arguments.contains("--live-testing") {
defaults.set(SettingsStore.defaultServerURL, forKey: "serverURL")
defaults.set(true, forKey: "textMode")
defaults.set("qwen2.5-vl-3b", forKey: "modelID")
}
return defaults
}
#endif
return .standard
}()
}