From 15d45a8fd6589dd4eb0ae2103c11bc2c58b37993 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 1 Jun 2026 19:39:18 +1000 Subject: [PATCH] fix(ui): companion rail loads current space on initial page load Co-Authored-By: Claude Opus 4.8 --- public/app.js | 4 ++++ public/components/rightrail.js | 25 ++++++++++++------------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/public/app.js b/public/app.js index 0a79399..71722d1 100644 --- a/public/app.js +++ b/public/app.js @@ -35,6 +35,10 @@ async function renderView(ctx) { } else { state.view = null; } + // Notify subscribers (right rail) of the active Space. The state bus replays + // the last value on subscribe, so this covers both the initial route() call + // and every subsequent navigation with one path. + emit('space-active', state.spaceId); const main = document.getElementById('main'); const loader = VIEWS[ctx.name] || VIEWS.home; diff --git a/public/components/rightrail.js b/public/components/rightrail.js index 7126f73..e3a1ee7 100644 --- a/public/components/rightrail.js +++ b/public/components/rightrail.js @@ -3,7 +3,7 @@ import { el, mount, clear } from '../dom.js'; import { api } from '../api.js'; import { streamTurn } from '../sse.js'; import { renderMarkdown } from '../markdown.js'; -import { state } from '../state.js'; +import { state, on } from '../state.js'; const COLLAPSE_KEY = 'void_rail_collapsed'; @@ -118,17 +118,16 @@ export async function renderRightrail(root) { input.addEventListener('keydown', handler); } - // Initial render — state.spaceId may be null if route hasn't fired yet. - await initChat(state.spaceId); - - // Re-init when navigation brings a new Space into focus. - let lastSpaceId = state.spaceId; - window.addEventListener('hashchange', async () => { - // Wait a tick so app.js's renderView can update state first. - await Promise.resolve(); - if (state.spaceId !== lastSpaceId) { - lastSpaceId = state.spaceId; - await initChat(state.spaceId); - } + // Load (and re-load) the chat whenever the active Space changes. The state + // bus replays its last value on subscribe, so this fires for the initial + // route() call (covering hard loads to #/space/) as well as every later + // navigation. We only re-init when the id actually changes so navigating + // within a Space (page/ref/etc.) doesn't wipe the conversation. + let lastSpaceId; let inited = false; + on('space-active', (spaceId) => { + if (inited && spaceId === lastSpaceId) return; + inited = true; + lastSpaceId = spaceId; + initChat(spaceId); }); }