feat: conversation state machine, mic meter, history, wake lock (Phase 3)
This commit is contained in:
1 parent
4986b6d7dc
commit
5483e6ed48
8 files changed
+348
-29
No files matched your search
@@ -0,0 +1,43 @@
|
||||
import Foundation
|
||||
|
||||
struct HistoryEntry: Codable, Equatable {
|
||||
let role: String
|
||||
let text: String
|
||||
let timestamp: Date
|
||||
}
|
||||
|
||||
/// Last 50 final transcript entries persisted as JSON in UserDefaults.
|
||||
@MainActor
|
||||
final class TranscriptHistory: ObservableObject {
|
||||
@Published private(set) var entries: [HistoryEntry] = []
|
||||
|
||||
private static let key = "voice_history"
|
||||
private static let maxEntries = 50
|
||||
|
||||
init() {
|
||||
if let raw = UserDefaults.standard.string(forKey: Self.key),
|
||||
let data = raw.data(using: .utf8),
|
||||
let decoded = try? JSONDecoder().decode([HistoryEntry].self, from: data) {
|
||||
entries = Array(decoded.suffix(Self.maxEntries))
|
||||
}
|
||||
}
|
||||
|
||||
func add(role: String, text: String) {
|
||||
guard !text.isEmpty else { return }
|
||||
entries.append(HistoryEntry(role: role, text: text, timestamp: Date()))
|
||||
if entries.count > Self.maxEntries {
|
||||
entries.removeFirst(entries.count - Self.maxEntries)
|
||||
}
|
||||
persist()
|
||||
}
|
||||
|
||||
func clear() {
|
||||
entries.removeAll()
|
||||
persist()
|
||||
}
|
||||
|
||||
private func persist() {
|
||||
guard let data = try? JSONEncoder().encode(entries) else { return }
|
||||
UserDefaults.standard.set(String(decoding: data, as: UTF8.self), forKey: Self.key)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user