From 7e31564c15f0ea91072a221bf54f73232f3b1e55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Sat, 15 Aug 2026 21:27:03 +0000 Subject: [PATCH] =?UTF-8?q?=3Fview=3D=20survives=20a=20page=20load=20?= =?UTF-8?q?=E2=80=94=20it=20never=20has?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Opening or refreshing a URL with `?view=` gave you a bare file browser and a URL that had quietly rewritten itself to drop the param. Reported as "has never worked", and it never had. `useFileViewerPanels` deleted EVERY ephemeral key in a mount effect, filed under "clear stale ephemeral params". So the page came up, the effect stripped `view`, and the pane never opened. It arrived incidentally in 9acef6cf (2026-02-23) with the chat-about-a-file work rather than as a decision about deep links, which is why nothing recorded the cost. Checked what actually needs clearing before removing it, rather than assuming nothing did: chatContext fills the chat box through `defaultInput` and does NOT auto-send (`autoSend` defaults false) — restoring it costs a pre-filled input and no message view a file that has since gone shows the viewer's error, which as of today says what happened and offers a download ephemeral(2) same ephemeral2Auto STARTS AUDIO PLAYING. Reloading a page should not make sound come out of the machine. This one is still cleared, and is now the only reason the effect exists. Also `replace`, so the cleanup is not a back-button step. An old-style link carrying both `?path=` and `?view=` still works: the legacy redirect rebuilds the pathname and keeps the rest of the query, so `view` rides through and is then read relative to the folder it just landed in. tsgo clean, frontend builds, 837 pass / 7 fail unchanged. Co-Authored-By: Claude Opus 5 --- .../useFileViewerPanels.tsx | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/workspaces/officerdev/src/hooks/useFileViewerPanels/useFileViewerPanels.tsx b/src/workspaces/officerdev/src/hooks/useFileViewerPanels/useFileViewerPanels.tsx index 0eddb4f0..2efab051 100644 --- a/src/workspaces/officerdev/src/hooks/useFileViewerPanels/useFileViewerPanels.tsx +++ b/src/workspaces/officerdev/src/hooks/useFileViewerPanels/useFileViewerPanels.tsx @@ -25,17 +25,35 @@ export const useFileViewerPanels = (): EphemeralPanels | null => { const [searchParams, setSearchParams] = useSearchParams(); const didClean = useRef(false); - // Clear stale ephemeral params on mount (page refresh) + /** + * On a fresh load, drop only what must not resume — which is autoplay, and nothing else. + * + * This used to delete EVERY ephemeral key on mount, under the heading "clear stale params". The effect + * of that was that `?view=` could never be linked to or survive a refresh: the page came up, the effect + * stripped the param, and you got a bare file browser with a URL that had quietly rewritten itself. + * Reported as "has never worked", and it never had — it arrived incidentally in 9acef6cf (2026-02-23) + * with the chat-about-a-file work, not as a decision about deep links. + * + * Nothing else needs clearing. `chatContext` fills the chat box via `defaultInput` and does NOT + * auto-send (`autoSend` defaults false), so restoring it costs a pre-filled input and no message. A + * `view` or `ephemeral` pointing at a file that has since gone shows the viewer's error, which now says + * what actually happened and offers a download. + * + * `ephemeral2Auto` is the exception and the reason this effect still exists: it starts audio playing. + * Reloading a page should not make sound come out of the machine. + */ useEffect(() => { if (didClean.current) return; didClean.current = true; - if (EPHEMERAL_KEYS.some((k) => searchParams.has(k))) { - setSearchParams((prev) => { + if (!searchParams.has('ephemeral2Auto')) return; + setSearchParams( + (prev) => { const next = new URLSearchParams(prev); - EPHEMERAL_KEYS.forEach((k) => next.delete(k)); + next.delete('ephemeral2Auto'); return next; - }); - } + }, + { replace: true }, + ); }, []); const viewPath = searchParams.get('view');