Files
openclaw/apps/macos/Sources/OpenClaw/QuickChatController+Testing.swift
Peter Steinberger 8c8ab1ea69 feat(mac): Quick Chat v2 — enable toggle, agent switching, zoom entrance, window screenshots (#109952)
* feat(mac): Quick Chat v2 — enable toggle, agent avatars and switching, zoom entrance, window screenshots

- Settings toggle (openclaw.quickChatEnabled) gating hotkey, menu item, recorder
- agent chip renders avatar image (data URIs only; remote URLs deliberately not
  fetched to avoid SSRF), emoji, or tinted monogram; native NSMenu agent picker
  routes via canonical agent:<id>:<mainKey> or global+agentId per server contract
- 'main session' capsule removed; placeholder carries the identity
- fade+zoom presentation (96% scale in, 97% out) via frame+alpha animators
- window screenshot picker: labeled overlays on renderable windows (Peekaboo
  filtering + z-order hit tests), overlays torn down pre-capture, SCK window
  capture, ChatImageProcessor JPEG, auto-send as chat.send attachment with the
  draft or a default caption; ownership-token pipeline bound to presentation
  and route; user-initiated Screen Recording alert; cancellable bounded discovery
- ⌘Return opens the accepted route's session; global-scope agent threading is a
  filed follow-up; locale artifacts refreshed for new strings

* chore(mac): regenerate i18n inventory after rebase onto main
2026-07-17 18:55:13 +01:00

65 lines
2.3 KiB
Swift

import Foundation
import OpenClawProtocol
#if DEBUG
@MainActor
extension QuickChatController {
struct TestingSnapshot: Equatable {
let isVisible: Bool
let hasGlobalMonitor: Bool
let hasLocalMonitor: Bool
let hotkeyRegistered: Bool
let isEnabled: Bool
}
static func exerciseForTesting() -> [TestingSnapshot] {
let model = QuickChatModel(
sessionKeyProvider: { "main" },
agentsProvider: {
AgentsListResult(
defaultid: "main",
mainkey: "main",
scope: AnyCodable("per-agent"),
agents: [])
},
agentIdentityProvider: { _ in .placeholder },
sendProvider: { _, _, _, _, _ in "started" },
permissionStatusProvider: { capabilities in
Dictionary(uniqueKeysWithValues: capabilities.map { ($0, true) })
},
permissionGrantProvider: { capabilities in
Dictionary(uniqueKeysWithValues: capabilities.map { ($0, true) })
},
connectionGateProvider: { .available })
let controller = QuickChatController(
enableUI: false,
model: model,
monitoringEnabled: true,
globalMonitorInstaller: { _, _ in NSObject() },
localMonitorInstaller: { _, _ in NSObject() },
monitorClearer: { $0 = nil },
hotkeyRegistrar: { _ in },
hotkeyRemover: {},
allowsHotkeyRegistrationInTests: true)
controller.start()
controller.setEnabled(true)
let started = controller.testingSnapshot
controller.present()
let presented = controller.testingSnapshot
controller.setEnabled(false)
let disabled = controller.testingSnapshot
controller.stop()
return [started, presented, disabled, controller.testingSnapshot]
}
var testingSnapshot: TestingSnapshot {
TestingSnapshot(
isVisible: self.isVisible,
hasGlobalMonitor: self.hasGlobalMonitorForTesting,
hasLocalMonitor: self.hasLocalMonitorForTesting,
hotkeyRegistered: self.hotkeyRegisteredForTesting,
isEnabled: self.isEnabled)
}
}
#endif