mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-09-30 12:39:42 +02:00
fix(mobile): retain oversized composer drafts
This commit is contained in:
@@ -654,6 +654,9 @@ const KeyboardAccessoryBar = {
|
|||||||
_composerDrafts: new Map(),
|
_composerDrafts: new Map(),
|
||||||
_composerUploads: new Map(),
|
_composerUploads: new Map(),
|
||||||
_composerOverlay: null,
|
_composerOverlay: null,
|
||||||
|
// Leave room for both six-character bracketed-paste markers under the
|
||||||
|
// WebSocket input frame's 64 KiB character limit.
|
||||||
|
_composerMaxLength: 65524,
|
||||||
|
|
||||||
/** HTML for simple mode: arrows, commands, Compose, Esc, dismiss */
|
/** HTML for simple mode: arrows, commands, Compose, Esc, dismiss */
|
||||||
_simpleButtons: `
|
_simpleButtons: `
|
||||||
@@ -1193,7 +1196,12 @@ const KeyboardAccessoryBar = {
|
|||||||
// Match xterm's prepareTextForTerminal(): CR keeps embedded newlines inside
|
// Match xterm's prepareTextForTerminal(): CR keeps embedded newlines inside
|
||||||
// the single-line input transport and is what terminal.paste() emitted.
|
// the single-line input transport and is what terminal.paste() emitted.
|
||||||
const pasteText = text.replace(/\r?\n/g, '\r');
|
const pasteText = text.replace(/\r?\n/g, '\r');
|
||||||
app._sendInputAsync(sessionId, `\x1b[200~${pasteText}\x1b[201~`);
|
const payload = `\x1b[200~${pasteText}\x1b[201~`;
|
||||||
|
if (payload.length > 65536) {
|
||||||
|
app.showToast?.(`Prompt is too long to send (maximum ${this._composerMaxLength.toLocaleString()} characters)`, 'error');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
app._sendInputAsync(sessionId, payload);
|
||||||
setTimeout(() => app._sendInputAsync(sessionId, '\r', { useMux: true }), 120);
|
setTimeout(() => app._sendInputAsync(sessionId, '\r', { useMux: true }), 120);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -269,6 +269,21 @@ describe('mobile prompt composer', () => {
|
|||||||
expect(app._echoPassthroughSessions.has('session-2')).toBe(true);
|
expect(app._echoPassthroughSessions.has('session-2')).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('keeps an oversized prompt as a draft instead of queueing a rejected frame', () => {
|
||||||
|
const { app, bar, document } = loadComposer();
|
||||||
|
bar.composePrompt();
|
||||||
|
const input = textarea(document);
|
||||||
|
input.value = 'x'.repeat(65525);
|
||||||
|
input.dispatchEvent(new document.defaultView!.Event('input', { bubbles: true }));
|
||||||
|
|
||||||
|
(document.querySelector('.paste-send') as HTMLButtonElement).click();
|
||||||
|
|
||||||
|
expect(app._sendInputAsync).not.toHaveBeenCalled();
|
||||||
|
expect(app.showToast).toHaveBeenCalledWith(expect.stringContaining('too long'), 'error');
|
||||||
|
expect(document.querySelector('.prompt-composer-overlay')).not.toBeNull();
|
||||||
|
expect(bar._composerDrafts.get('session-1')).toHaveLength(65525);
|
||||||
|
});
|
||||||
|
|
||||||
it('preserves the draft and focuses xterm when Use terminal keyboard is chosen', () => {
|
it('preserves the draft and focuses xterm when Use terminal keyboard is chosen', () => {
|
||||||
const { app, bar, document, localEcho, runTimers } = loadComposer();
|
const { app, bar, document, localEcho, runTimers } = loadComposer();
|
||||||
const composeButton = mountComposeButton(bar, document);
|
const composeButton = mountComposeButton(bar, document);
|
||||||
|
|||||||
Reference in New Issue
Block a user