Skip to content

[V1.4.1] Browser does not store UI state change #379

Description

@ahmad-ajmal

What happened:
UI layout preferences are lost whenever a page unmounts or the browser is refreshed. Two cases:

  1. Living UI chat panel: closing the chat panel (via the Hide Chat toggle) is not remembered. If I close the panel, navigate to another page (e.g. main Chat or Tasks), and come back to Living UI, the panel is open again. Same on browser refresh.
  2. Main Chat task sidebar: resizing the task sidebar (dragging the resize handle) is not remembered. Navigating away and back — or refreshing — snaps it back to the default width.

What I expected:
Layout state should survive navigation and refreshes — the panel stays closed if I closed it, and the sidebar keeps the width I dragged it to — the same way the theme preference already survives navigation.

Steps to reproduce:

Chat panel:

  1. Open the Living UI page — the chat panel is visible on the right.
  2. Click the "Hide Chat" toggle to close the panel.
  3. Navigate to another page, then back to Living UI — the panel is open again. (Refreshing gives the same result.)

Sidebar width:

  1. Open the main Chat page.
  2. Drag the resize handle to make the task sidebar noticeably wider or narrower.
  3. Navigate to another page, then back to Chat — the sidebar is back to the default width. (Refreshing gives the same result.)

Environment: Browser UI (React frontend, app/ui_layer/browser/frontend), macOS, commit 07ddba44, v0.1.0

Logs / screenshots:
No errors in console — this is a state-persistence gap, not a crash.

Notes for the fix:
Both values are plain component state with no persistence, so they reset to their defaults every time the page unmounts:

// src/pages/LivingUI/LivingUIPage.tsx:86
const [showChat, setShowChat] = useState(true)

// src/pages/Chat/ChatPage.tsx:48
const [panelWidth, setPanelWidth] = useState(DEFAULT_PANEL_WIDTH)

The frontend already persists other UI preferences to localStorage (e.g. craftbot-theme in src/contexts/ThemeContext.tsx and lastSeenMessageId in src/contexts/WebSocketContext.tsx), so the fix is to follow the same pattern: initialize each value from localStorage (falling back to the current defaults, with the width re-clamped to MIN_PANEL_WIDTH/MAX_PANEL_WIDTH on load) and write back on toggle / on mouse-up after a drag. A small shared usePersistedState hook would cover both and any future layout state.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ImprovementOptimization and improvement over existing featurepriority: low

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions