diff options
| author | Adam Soltys <[email protected]> | 2026-08-04 07:30:25 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-08-04 07:30:25 -0700 |
| commit | 0871281ff921fabf24aba94656dd3c375958a973 (patch) | |
| tree | eaf2d2d692b5d2d7ca500aa41786dc02459bf8f5 /src/features/messages.js | |
| parent | d04882474a98e3429d7d4b71a56213c6240c2816 (diff) | |
| download | coinosv3-0871281ff921fabf24aba94656dd3c375958a973.tar.gz coinosv3-0871281ff921fabf24aba94656dd3c375958a973.zip | |
The chat log follows its bottom edge through viewport resizes
The keyboard shrinks the viewport-sized chat card: the composer stayed
on screen but the log kept its old scroll offset, hiding the newest
messages. Re-stick on every viewport resize and on composer focus —
unless the reader has deliberately scrolled up, which msgStick already
remembers.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015QwAtBSpKvECqp1rHLHjJk
Diffstat (limited to 'src/features/messages.js')
| -rw-r--r-- | src/features/messages.js | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/src/features/messages.js b/src/features/messages.js index ae8cb53..6d9217d 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -1251,6 +1251,13 @@ export function messagesFeature(ctx) { }); }; + // The chat card is sized to the viewport, so the mobile keyboard shrinks it: + // the composer stays on screen, but the log keeps its old scroll offset and + // the newest messages vanish under the fold. Follow the bottom edge through + // every viewport change (keyboard, rotation, browser chrome) — unless the + // user has deliberately scrolled up, which msgStick already remembers. + const onViewportResize = () => { if (ui.chatOpen) stickToBottom(); }; + // A remote signer that a reload dropped: say so where the typing happens, // rather than letting someone write a message and only then be told. The // identity itself is still known — it's the ability to sign as it that's @@ -1282,6 +1289,9 @@ export function messagesFeature(ctx) { value: ui.msgDraft || '', maxlength: '2000', onInput: (e) => { ui.msgDraft = e.target.value; if (onType && e.target.value) onType(); }, onKeydown: (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); onSend(); } }, + // Focus summons the keyboard; some browsers resize only after its + // animation, so re-stick once now and once when it has settled. + onFocus: () => { stickToBottom(); setTimeout(stickToBottom, 350); }, }), h('button', { class: 'btn-primary btn-sm', disabled: ui.msgSending, onClick: onSend }, ui.msgSending ? h('span', { class: 'spinner sm' }) : t('msgSend')))); @@ -1782,6 +1792,12 @@ export function messagesFeature(ctx) { loadLinkInvite(urlInvite); setTimeout(() => { ui.chatOpen = true; ui.msgView = 'home'; render(); }, 0); } + window.addEventListener('resize', onViewportResize); + window.visualViewport?.addEventListener('resize', onViewportResize); + allUnsubs.push(() => { + window.removeEventListener('resize', onViewportResize); + window.visualViewport?.removeEventListener('resize', onViewportResize); + }); startDMs(); // Communities subscribe up front too, not just when chat opens — the // header's unread dot can't report a room nobody is listening to. |
