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

View File

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

View File

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