ux: keep window in edit, add escape to cancel; fix lint drift

This commit is contained in:
Peter Steinberger
2025-12-08 20:22:56 +01:00
parent cfdcabc8b4
commit ded106b9e3
3 changed files with 28 additions and 15 deletions

View File

@@ -65,6 +65,13 @@ final class VoiceWakeOverlayController: ObservableObject {
self.model.isEditing = true
}
func cancelEditingAndDismiss() {
self.autoSendTask?.cancel()
self.model.isSending = false
self.model.isEditing = false
self.dismiss(reason: .explicit)
}
func endEditing() {
self.model.isEditing = false
}
@@ -277,6 +284,9 @@ private struct VoiceWakeOverlayView: View {
onBeginEditing: {
self.controller.userBeganEditing()
},
onEscape: {
self.controller.cancelEditingAndDismiss()
},
onEndEditing: {
self.controller.endEditing()
},
@@ -348,6 +358,7 @@ private struct TranscriptTextView: NSViewRepresentable {
var isFinal: Bool
var isOverflowing: Bool
var onBeginEditing: () -> Void
var onEscape: () -> Void
var onEndEditing: () -> Void
var onSend: () -> Void
@@ -380,11 +391,12 @@ private struct TranscriptTextView: NSViewRepresentable {
.font: NSFont.systemFont(ofSize: 13, weight: .regular),
]
textView.focusRingType = .none
textView.onSend = { [weak textView] in
textView?.window?.makeFirstResponder(nil)
self.onSend()
}
textView.onBeginEditing = self.onBeginEditing
textView.onSend = { [weak textView] in
textView?.window?.makeFirstResponder(nil)
self.onSend()
}
textView.onBeginEditing = self.onBeginEditing
textView.onEscape = self.onEscape
textView.onEndEditing = self.onEndEditing
let scroll = NSScrollView()
@@ -504,6 +516,7 @@ private final class TranscriptNSTextView: NSTextView {
var onSend: (() -> Void)?
var onBeginEditing: (() -> Void)?
var onEndEditing: (() -> Void)?
var onEscape: (() -> Void)?
override func becomeFirstResponder() -> Bool {
self.onBeginEditing?()
@@ -518,6 +531,11 @@ private final class TranscriptNSTextView: NSTextView {
override func keyDown(with event: NSEvent) {
let isReturn = event.keyCode == 36
let isEscape = event.keyCode == 53
if isEscape {
self.onEscape?()
return
}
if isReturn && event.modifierFlags.contains(.command) {
self.onSend?()
return

View File

@@ -8,6 +8,10 @@ import { statusCommand } from "../commands/status.js";
import { loadConfig } from "../config/config.js";
import { danger, info, setVerbose } from "../globals.js";
import { getResolvedLoggerSettings } from "../logging.js";
import {
readLatestHeartbeat,
tailHeartbeatEvents,
} from "../process/heartbeat-events.js";
import {
loginWeb,
logoutWeb,
@@ -23,10 +27,6 @@ import {
resolveHeartbeatSeconds,
resolveReconnectPolicy,
} from "../web/reconnect.js";
import {
readLatestHeartbeat,
tailHeartbeatEvents,
} from "../process/heartbeat-events.js";
import {
ensureWebChatServerFromConfig,
startWebChatServer,

View File

@@ -6,12 +6,7 @@ import readline from "node:readline";
export type HeartbeatEvent = {
type: "heartbeat";
ts: number; // epoch ms
status:
| "sent"
| "ok-empty"
| "ok-token"
| "skipped"
| "failed";
status: "sent" | "ok-empty" | "ok-token" | "skipped" | "failed";
to?: string;
preview?: string;
durationMs?: number;