diff --git a/static/app.js b/static/app.js index 934f093..4207579 100644 --- a/static/app.js +++ b/static/app.js @@ -205,20 +205,41 @@ function renderMain() { } const el = $("#page"); if (!S.me) { - el.innerHTML = registerPage(); + // Only redraw when the form itself changes: replacing the name field under + // a phone's keyboard closes the keyboard. + const html = registerPage(); + if (el.dataset.html !== html) { + el.innerHTML = html; + el.dataset.html = html; + $("#name").value = remember("draftName") || ""; + } return; } if (page === "chat") { seenChat = Math.max(seenChat, ...S.chat.map((m) => m.t), 0); remember("seenChat", seenChat); } + // Never redraw under a focused field (the chat box aside): on a phone that + // closes the keyboard or the open dropdown. The next render catches up. + const focused = document.activeElement; + const typing = focused && el.contains(focused) && focused.matches("input, select, textarea"); + if (page === "chat" && el.querySelector("#say")) { + // The chat box stays put (and keeps the keyboard); only the lists refresh. + const holder = document.createElement("div"); + holder.innerHTML = chatPage(); + for (const id of ["chatlog", "worldlog"]) { + const fresh = holder.querySelector("#" + id).innerHTML; + const old = el.querySelector("#" + id); + if (old.innerHTML !== fresh) old.innerHTML = fresh; + } + return; + } + if (typing) return; const html = { adventure: adventurePage, quests: questsPage, character: characterPage, group: groupPage, chat: chatPage }[page](); - // Keep a half-typed chat message across re-renders. - const typing = document.activeElement?.id === "say" ? document.activeElement.value : null; - if (typing !== null && page === "chat") return; if (el.dataset.html !== html) { el.innerHTML = html; el.dataset.html = html; + animate(); } } @@ -230,7 +251,7 @@ function registerPage() { return `
You wake in Northshire Abbey. The Defias Brotherhood stirs in Westfall.
- +