fix(desktop): add responsive sidebar collapse#1585
Conversation
|
Solid PR overall — the stage state machine handles WIDE/COMPACT/NARROW transitions correctly, the auto-vs-manual tracking via refs is the right pattern, RAF-debounced resize is good practice, and the CSS variable refactor of Blocker — The new rule .composer-foot {
...
overflow: hidden;
}breaks the ModelMenu popup. In
With The fix is small: just drop Follow-on gap 1 — initial narrow startup isn't covered if (prev === null) {
responsiveStageRef.current = next;
return;
}First Run the normal stage logic on first mount too: if (prev === null) {
if (next === RESPONSIVE_STAGE.NARROW) {
if (!ctxCollapsedRef.current) { setCtxCollapsed(true); autoCtxCollapsedRef.current = true; }
if (!sideCollapsedRef.current) { setSideCollapsed(true); autoSideCollapsedRef.current = true; }
} else if (next === RESPONSIVE_STAGE.COMPACT) {
if (!ctxCollapsedRef.current) { setCtxCollapsed(true); autoCtxCollapsedRef.current = true; }
}
responsiveStageRef.current = next;
return;
}Follow-on gap 2 — auto-collapse pollutes localStorage
The cleanest fix is to skip the LS write when the change came from auto-collapse — gate the existing persistence effects on the auto refs: useEffect(() => {
if (autoSideCollapsedRef.current) return;
localStorage.setItem("reasonix.sideCollapsed", sideCollapsed ? "1" : "0");
}, [sideCollapsed]);(Same shape for ctx.) That way the persisted value reflects what the user explicitly chose, and the responsive layer never writes to LS. Nit (optional)
type ResponsiveStage = "wide" | "compact" | "narrow";No strong opinion — keep if you prefer the named constants. Push a fixup with the blocker fix (and ideally the two follow-on gaps) and I'll merge. |
Follow-up to #1585. The responsive sidebar logic was split across six refs (autoSideCollapsedRef / autoCtxCollapsedRef / suppressSide... / suppressCtx... / sideCollapsedRef / ctxCollapsedRef) and a 70-line useEffect that did everything inline. Each panel's "is this collapsed because the user asked, or because the layout forced it" state was encoded across two of those refs; the resize logic had to spell out all 6 stage-transition combinations by hand. Extracted the per-panel collapse into useAutoCollapse(persistKey): - collapsed: the boolean for CSS - toggle: user-driven flip; persists to localStorage - requireCollapsed: layout asks for collapsed — claims as auto if the panel wasn't already collapsed - releaseCollapsed: layout asks for expanded — restores only if WE collapsed it (manual collapses stay) The resize effect drops to one branch per stage: WIDE → release both COMPACT → require ctx (only when entering from wider — coming from narrow we preserve a user's manual ctx-open); release side NARROW → require both Also: fixed the one-line CSS indent slip on .app[data-side-collapsed]. Behavior is unchanged — same five stage-transition outcomes that #1585 hand-coded, just expressed declaratively. Co-authored-by: reasonix <reasonix@deepseek.com>
…moved, persisted usage stats, plan dispatch gate Headline themes: - Desktop: bundle the CLI-hosted React dashboard, retire Tauri+Preact duplicate (#1418) - Config: drop preset abstraction; flash/pro are direct model selections (#1657, #1630) - Stats: persist cumulative usage to session meta + auto-restore on startup (#1667, #1680, #1643, #1628) - Plans: editMode="plan" enforced at the ToolRegistry dispatch gate (#1681); step advance fix (#1629) - Context: fold once at turn start, drop pre-flight + byte-ceiling (#1642, #1646); collapsible compacted card (#1649) - Subagents: per-skill flash/pro override + Settings UI (#1632) - Desktop polish: sidebar drag-resize (#1688), responsive collapse (#1585), copy/edit overlay + msg-history nav (#1645), Esc closes modal not turn (#1685), QQ tab isolation (#1672), DiffCard for edits (#1662), theme-aware highlighting (#1655), system events toggle (#1654/#1650), macOS TCC inheritance (#1614), dashboard.enabled (#1612) - Dashboard polish: persistent session URL (#1586, #1589, #1599), theme-aware highlighting (#1664), IME confirm-enter guard (#1689), code-fence lang fix (#1677), vendor chunk split (#1587), markdown table h-scroll (#1562) - TUI: Alt+S input stash/recall; static history isolated from input rerenders (#1635); legacy mouse drop (#1637, #1648); multi-edit gated in review (#1647) - Diff: SplitDiff column border holds under CJK (#1686) - MCP: workspace roots passed to servers (#1625); codeCommand honors mcpServers (#1603) - Config plumbing: (baseUrl, apiKey) resolved as a tuple (#1658); stale model id self-heal (#1663) See CHANGELOG for the full list.
Summary
Add responsive, stage-based sidebar auto-collapse in the desktop chat UI so the center composer stays usable on narrow windows, and restore only the sidebars that were auto-collapsed when the window widens again.
Problem
When the desktop window is narrowed, the left session sidebar and right context panel can keep occupying fixed width. That leaves the middle chat column too narrow, which is especially bad for the composer footer: model selection and inline tools can overflow the input area and become clipped.
The issue lives in the desktop shell layout:
desktop/src/App.tsxownssideCollapsedandctxCollapsedstatedesktop/src/styles.cssdefines the three-column grid layout and composer footer sizingFix
desktop/src/App.tsx— Added width-stage detection forwide,compact, andnarrowlayouts.desktop/src/App.tsx— Auto-collapses the right context panel first, then the left sidebar at a lower breakpoint.desktop/src/App.tsx— Restores only sidebars that were auto-collapsed when the window becomes wide again.desktop/src/App.tsx— Keeps manual sidebar toggles independent, so a user-closed sidebar is not reopened automatically.desktop/src/styles.css— Switched the shell grid to CSS variables and added a smooth transition for sidebar width changes.desktop/src/styles.css— Added composer footer overflow guards so the bottom toolbar does not spill out in narrow layouts.Verification
npm run buildindesktop/git diff --checkgit status --short --branchafter commitClosed #855