Detach the chat navigator from the window it maximizes

Featurekamo-internal
Ya
27 Agosti 2026, 20:05 UTC
Mwandishi
kamo
Ahadi ya
8b5ccc0

The conversation navigator was a child prop of ToolWindowShell, rendered inside the maximized window's content box. Clicking a row in it opens that conversation maximized, which demotes the window holding it — so the navigator unmounted and remounted on every use. The member navigated by destroying the thing they were navigating with: bucket, scroll position and search text all reset the instant they clicked. It is a dock-level sibling now. ToolDock mounts exactly one ChatNavigatorPanel, fixed down the left edge, and the maximized window stops short of it (`leftInset`) instead of being drawn underneath. Across a swap the panel never unmounts, so from React's point of view nothing happens to it. The bucket seed is frozen at the first toolId it ever saw, so the list does not re-filter out from under a member who just clicked a row. Motion is lead-and-trail: maximizing, the navigator springs out of the left edge and the window expands into what is left behind it 70ms later; restoring plays the reverse, window first, navigator trailing by 90ms. Neither component stores a direction — both delays derive from `maximized`, so the flag IS the direction. Shared timings live in maximizeMotion.ts because the two halves can no longer see each other's state. A row click is choreographed separately (useMaximizedSwap): the pane freezes and the two conversations cross-dissolve inside it, rather than one window flying to the dock while another flies out of it beside a navigator standing perfectly still. The demoted window keeps the pane's geometry while it fades, then gets a settle beat at its dock slot with transitions still off, so it reappears by fading instead of flying back across the viewport. Opacity and transform move from CSS to framer-motion: a CSS transition cannot express "start from 8px lower" for an already-mounted element, which is what a window fading up into the pane has to do. Geometry stays on CSS — framer would re-measure calc(100vw - Npx) every frame. prefers-reduced-motion drops all of it to an opacity swap. Collapse state lifts into useChatNavigatorCollapse: ToolDock needs the navigator's width to size the window, and a component owning its own width could not tell it. No new i18n keys. Verified: tsc clean, 144 tests pass across tools/ and conversations/, all guard scripts pass. The two load-bearing behaviours (frozen bucket seed, pane held through the dissolve) were mutation-tested. Not visually verified — this repo has no headless browser.

Mabadiliko yote

Je, unaona nini kuhusu usafiri?

Kila moja ya hizi updates ardhi katika nafasi yako ya kazi moja kwa moja. Kuanza bure na kuangalia kukua wiki baada ya wiki.

Kuwa Huru MileleMtazamo wa bei