Enable Ctrl+C/X/V speech feedback in text editors
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
// Maintainer-controlled web client version.
|
// Maintainer-controlled web client version.
|
||||||
// Format: YYYY.MM.DD Rn (example: 2026.02.20 R2)
|
// Format: YYYY.MM.DD Rn (example: 2026.02.20 R2)
|
||||||
window.CHGRID_WEB_VERSION = "2026.02.21 R91";
|
window.CHGRID_WEB_VERSION = "2026.02.21 R92";
|
||||||
// Optional display timezone for timestamps. Falls back to America/Detroit if unset/invalid.
|
// Optional display timezone for timestamps. Falls back to America/Detroit if unset/invalid.
|
||||||
window.CHGRID_TIME_ZONE = "America/Detroit";
|
window.CHGRID_TIME_ZONE = "America/Detroit";
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ let connecting = false;
|
|||||||
const messageBuffer: string[] = [];
|
const messageBuffer: string[] = [];
|
||||||
let messageCursor = -1;
|
let messageCursor = -1;
|
||||||
const radioRuntime = new RadioStationRuntime(audio);
|
const radioRuntime = new RadioStationRuntime(audio);
|
||||||
|
let internalClipboardText = '';
|
||||||
let replaceTextOnNextType = false;
|
let replaceTextOnNextType = false;
|
||||||
let pendingEscapeDisconnect = false;
|
let pendingEscapeDisconnect = false;
|
||||||
|
|
||||||
@@ -571,6 +572,10 @@ function pasteIntoActiveTextInput(raw: string): boolean {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isTextEditingMode(mode: typeof state.mode): boolean {
|
||||||
|
return mode === 'nickname' || mode === 'chat' || mode === 'itemPropertyEdit';
|
||||||
|
}
|
||||||
|
|
||||||
function mapTextInputKey(code: string, key: string): string {
|
function mapTextInputKey(code: string, key: string): string {
|
||||||
if (code === 'ArrowLeft') return 'arrowleft';
|
if (code === 'ArrowLeft') return 'arrowleft';
|
||||||
if (code === 'ArrowRight') return 'arrowright';
|
if (code === 'ArrowRight') return 'arrowright';
|
||||||
@@ -2035,12 +2040,36 @@ function setupInputHandlers(): void {
|
|||||||
|
|
||||||
if (!state.running) return;
|
if (!state.running) return;
|
||||||
if (document.activeElement !== dom.canvas) return;
|
if (document.activeElement !== dom.canvas) return;
|
||||||
if (event.ctrlKey || event.altKey) return;
|
if (event.altKey) return;
|
||||||
|
if (event.ctrlKey && !isTextEditingMode(state.mode)) return;
|
||||||
|
|
||||||
if (state.mode !== 'normal' || !code.startsWith('Arrow')) {
|
if (state.mode !== 'normal' || !code.startsWith('Arrow')) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (event.ctrlKey && isTextEditingMode(state.mode)) {
|
||||||
|
if (code === 'KeyC') {
|
||||||
|
const text = state.nicknameInput;
|
||||||
|
internalClipboardText = text;
|
||||||
|
void navigator.clipboard?.writeText(text).catch(() => undefined);
|
||||||
|
updateStatus('copied');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (code === 'KeyX') {
|
||||||
|
const text = state.nicknameInput;
|
||||||
|
internalClipboardText = text;
|
||||||
|
void navigator.clipboard?.writeText(text).catch(() => undefined);
|
||||||
|
state.nicknameInput = '';
|
||||||
|
state.cursorPos = 0;
|
||||||
|
replaceTextOnNextType = false;
|
||||||
|
updateStatus('cut');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (code === 'KeyV') {
|
||||||
|
updateStatus('pasted');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isTypingKey(code) && state.keysPressed[code]) return;
|
if (isTypingKey(code) && state.keysPressed[code]) return;
|
||||||
|
|
||||||
if (state.mode === 'nickname') {
|
if (state.mode === 'nickname') {
|
||||||
@@ -2077,9 +2106,10 @@ function setupInputHandlers(): void {
|
|||||||
document.addEventListener('paste', (event) => {
|
document.addEventListener('paste', (event) => {
|
||||||
if (document.activeElement !== dom.canvas) return;
|
if (document.activeElement !== dom.canvas) return;
|
||||||
if (!state.running) return;
|
if (!state.running) return;
|
||||||
const pasted = event.clipboardData?.getData('text') ?? '';
|
const pasted = event.clipboardData?.getData('text') ?? internalClipboardText;
|
||||||
if (!pasteIntoActiveTextInput(pasted)) return;
|
if (!pasteIntoActiveTextInput(pasted)) return;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
updateStatus('pasted');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user