Files
openclaw/apps/macos/Sources/Clawdbot/TalkModeController.swift

70 lines
2.0 KiB
Swift
Raw Normal View History

2025-12-29 23:21:05 +01:00
import Observation
@MainActor
@Observable
final class TalkModeController {
static let shared = TalkModeController()
2026-01-04 14:32:47 +00:00
private let logger = Logger(subsystem: "com.clawdbot", category: "talk.controller")
2025-12-29 23:21:05 +01:00
2025-12-30 11:37:52 +01:00
private(set) var phase: TalkModePhase = .idle
private(set) var isPaused: Bool = false
2025-12-29 23:21:05 +01:00
func setEnabled(_ enabled: Bool) async {
self.logger.info("talk enabled=\(enabled)")
if enabled {
TalkOverlayController.shared.present()
} else {
TalkOverlayController.shared.dismiss()
}
await TalkModeRuntime.shared.setEnabled(enabled)
}
func updatePhase(_ phase: TalkModePhase) {
2025-12-30 11:37:52 +01:00
self.phase = phase
2025-12-29 23:21:05 +01:00
TalkOverlayController.shared.updatePhase(phase)
2025-12-30 11:37:52 +01:00
let effectivePhase = self.isPaused ? "paused" : phase.rawValue
2026-01-02 00:17:49 +01:00
Task {
await GatewayConnection.shared.talkMode(
enabled: AppStateStore.shared.talkEnabled,
phase: effectivePhase)
}
2025-12-29 23:21:05 +01:00
}
func updateLevel(_ level: Double) {
TalkOverlayController.shared.updateLevel(level)
}
2025-12-30 11:37:52 +01:00
func setPaused(_ paused: Bool) {
guard self.isPaused != paused else { return }
self.logger.info("talk paused=\(paused)")
self.isPaused = paused
TalkOverlayController.shared.updatePaused(paused)
let effectivePhase = paused ? "paused" : self.phase.rawValue
2026-01-02 00:17:49 +01:00
Task {
await GatewayConnection.shared.talkMode(
enabled: AppStateStore.shared.talkEnabled,
phase: effectivePhase)
}
2025-12-30 11:37:52 +01:00
Task { await TalkModeRuntime.shared.setPaused(paused) }
}
func togglePaused() {
self.setPaused(!self.isPaused)
}
2025-12-29 23:21:05 +01:00
func stopSpeaking(reason: TalkStopReason = .userTap) {
Task { await TalkModeRuntime.shared.stopSpeaking(reason: reason) }
}
func exitTalkMode() {
Task { await AppStateStore.shared.setTalkEnabled(false) }
}
}
enum TalkStopReason {
case userTap
case speech
case manual
}