From 45cbe43a21a9d046afebb248b4bd455bf0fd9cd0 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Fri, 28 Aug 2026 08:34:41 +0200 Subject: feat(chat): focus the composer when the Chat tab opens ChatPanel remounts on every tab switch, so a mount effect is the tab-entry hook. `focus({ preventScroll: true })` so it does not fight the panel-sizing and scroll-to-bottom effects still settling, and so a phone opens the keyboard without the view jumping. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_018gKJ85aZyvEwarXMFzFEwi --- packages/meshbay-hub/src/meshbay_hub/static/chat-app.js | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'packages/meshbay-hub/src') diff --git a/packages/meshbay-hub/src/meshbay_hub/static/chat-app.js b/packages/meshbay-hub/src/meshbay_hub/static/chat-app.js index 3d518b3..f21ec2c 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/chat-app.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/chat-app.js @@ -316,6 +316,16 @@ function ChatPanel({ transportRef, username, entries, gekRef, onRefreshIndex, return () => ro.disconnect(); }, [messages]); + // Entering the Chat tab should leave the cursor in the composer, ready to + // type — the panel mounts fresh on every tab switch, so a mount effect is + // the tab-entry hook. `preventScroll` because the layout effects above are + // still settling the panel height and a focus-driven scroll would fight + // them; on a phone this also means the keyboard opens without the view + // jumping. + useEffect(() => { + inputRef.current?.focus({ preventScroll: true }); + }, []); + // The panel was `calc(100vh - 220px)`: a guess at how much sits above it. On a // phone the group header — title, description, edit link, delete button, tabs // — is closer to 430px, so the panel ran past the fold and the composer ended -- cgit v1.2.3