mirror of
https://github.com/tiennm99/noitu.git
synced 2026-10-11 03:13:45 +00:00
fix(online): leave focus alone while a player is typing in chat
A turn arriving pulled focus into the word field even mid-sentence in the chat, dropping the rest of the message into the game. Focus is now only claimed when no other text field holds it; syllable seeding is unchanged.
This commit is contained in:
1 parent
e19b083dc0
commit
0f0cc3a357
2 files changed
+38
-1
No files matched your search
@@ -313,6 +313,24 @@ test.describe('playing a stranger', () => {
|
||||
await close();
|
||||
});
|
||||
|
||||
test('a turn arriving does not take the chat field away', async ({ browser }) => {
|
||||
const { host, guest, close } = await playingPair(browser);
|
||||
|
||||
// The guest starts typing while the host is still on turn. The word
|
||||
// field wants focus the moment a turn lands, and taking it here would
|
||||
// drop the rest of the sentence into the game.
|
||||
await chat(guest).input.click();
|
||||
await chat(guest).input.fill('đang gõ dở');
|
||||
|
||||
await playLegalMove(host, new Set(await chainWords(host)));
|
||||
await waitForMyTurn(guest);
|
||||
|
||||
await expect(chat(guest).input).toBeFocused();
|
||||
await expect(chat(guest).input).toHaveValue('đang gõ dở');
|
||||
|
||||
await close();
|
||||
});
|
||||
|
||||
test('a message is rendered as text, never as markup', async ({ browser }) => {
|
||||
const { host, guest, close } = await twoPlayers(browser);
|
||||
|
||||
|
||||
@@ -25,6 +25,23 @@
|
||||
/** @type {unknown} */
|
||||
let seededRejection = null;
|
||||
|
||||
/**
|
||||
* Whether the player is typing somewhere else — the chat, in practice,
|
||||
* which now sits beside the board rather than folded away under it.
|
||||
*
|
||||
* Taking focus off a field somebody is mid-sentence in would drop the rest
|
||||
* of that sentence into the word field, so a turn arriving is allowed to
|
||||
* ask for focus only when nothing else holds it.
|
||||
*/
|
||||
function typingElsewhere() {
|
||||
const active = document.activeElement;
|
||||
if (!active || active === field) return false;
|
||||
return (
|
||||
active instanceof HTMLElement &&
|
||||
(active.tagName === 'INPUT' || active.tagName === 'TEXTAREA' || active.isContentEditable)
|
||||
);
|
||||
}
|
||||
|
||||
// Focus when the turn arrives, so a player on a phone can type without
|
||||
// reaching for the field, and seed it with the syllable the word has to
|
||||
// start with — that part of the answer is already decided, and typing it
|
||||
@@ -37,7 +54,9 @@
|
||||
const syllable = game.state.currentSyllable;
|
||||
const rejection = game.state.rejection;
|
||||
|
||||
field?.focus();
|
||||
// The seeding below happens either way: it writes into the field
|
||||
// without disturbing wherever the player actually is.
|
||||
if (!typingElsewhere()) field?.focus();
|
||||
if (!field || (turn === seededTurn && rejection === seededRejection)) return;
|
||||
seededTurn = turn;
|
||||
seededRejection = rejection;
|
||||
|
||||
Reference in new issue
Block a user