mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-09-30 12:39:42 +02:00
Merge pull request #280 from Lint111/feat/mobile-tap-toggles-keyboard
This commit is contained in:
@@ -977,7 +977,7 @@ describe('Virtual Keyboard', () => {
|
||||
expect(state.sentInputs[0]).toMatch(/^\x1b\[<0;\d+;1M\x1b\[<0;\d+;1m$/);
|
||||
});
|
||||
|
||||
it('keeps the hidden keyboard input focused after an inert Claude transcript tap', async () => {
|
||||
it('toggles the keyboard shut on a second inert Claude transcript tap', async () => {
|
||||
const point = await page.evaluate(async () => {
|
||||
window.__sentInputs = [];
|
||||
app.activeSessionId = 'mobile-claude-transcript-tap-test';
|
||||
@@ -1028,8 +1028,12 @@ describe('Virtual Keyboard', () => {
|
||||
|
||||
await page.touchscreen.tap(point!.x, point!.y);
|
||||
|
||||
// The setup above leaves the terminal focused, so this tap is the SECOND
|
||||
// one on an inert row — the case that now closes the keyboard. Previously
|
||||
// it re-focused, which left the accessory bar's chevron as the only way to
|
||||
// dismiss. The prompt row is unaffected and still positions the caret.
|
||||
const activeClass = await page.evaluate(() => document.activeElement?.className);
|
||||
expect(activeClass).toContain('xterm-helper-textarea');
|
||||
expect(activeClass).not.toContain('xterm-helper-textarea');
|
||||
});
|
||||
|
||||
it('prevents Claude subagent status taps from opening the hidden keyboard input', async () => {
|
||||
|
||||
@@ -199,6 +199,43 @@ describe('terminal touch tap mouse guard', () => {
|
||||
expect(app.terminal.focus).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it('closes the keyboard on a second tap of INERT transcript content', () => {
|
||||
const { app, setActiveElement } = loadTerminalUiHarness();
|
||||
app.activeSessionId = 'sess-1';
|
||||
app.sessions = new Map([['sess-1', { mode: 'claude' }]]);
|
||||
app.terminal = createTerminalGrid(['transcript line', '', '', '', '❯ ', ''], 4);
|
||||
app._sendInputAsync = vi.fn();
|
||||
|
||||
// Keyboard DOWN: the tap opens it.
|
||||
setActiveElement(null);
|
||||
expect(app._handleMobileTerminalTap({ clientX: 9, clientY: 1 }, false)).toBe('content');
|
||||
expect(app.terminal.focus).toHaveBeenCalledOnce();
|
||||
expect(app.terminal.textarea.blur).not.toHaveBeenCalled();
|
||||
|
||||
// Keyboard UP on the same inert row: the tap closes it.
|
||||
app.terminal.focus.mockClear();
|
||||
setActiveElement(app.terminal.textarea);
|
||||
expect(app._handleMobileTerminalTap({ clientX: 9, clientY: 1 }, true)).toBe('content');
|
||||
expect(app.terminal.textarea.blur).toHaveBeenCalledOnce();
|
||||
expect(app.terminal.focus).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('keeps the prompt row focusing rather than toggling, so the caret can still be placed', () => {
|
||||
// The toggle is scoped to 'content' on purpose: a second tap on the PROMPT
|
||||
// must still position the cursor. This is the guarantee that makes the
|
||||
// change safe to make, so it is pinned separately.
|
||||
const { app, setActiveElement } = loadTerminalUiHarness();
|
||||
app.activeSessionId = 'sess-1';
|
||||
app.sessions = new Map([['sess-1', { mode: 'claude' }]]);
|
||||
app.terminal = createTerminalGrid(['transcript line', '', '', '', '❯ ask', ''], 4);
|
||||
app._sendInputAsync = vi.fn();
|
||||
|
||||
setActiveElement(app.terminal.textarea);
|
||||
expect(app._handleMobileTerminalTap({ clientX: 9, clientY: 65 }, true)).toBe('input');
|
||||
expect(app.terminal.textarea.blur).not.toHaveBeenCalled();
|
||||
expect(app.terminal.focus).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it('suppresses browser trusted compatibility mouse events during the tap window', () => {
|
||||
const { app } = loadTerminalUiHarness();
|
||||
const { element, dispatch } = createElementHarness();
|
||||
|
||||
Reference in New Issue
Block a user