Commit Graph

2 Commits

Author SHA1 Message Date
Jakob Wennberg 7ccaab7a08 fix(agent): contain the floating assistant panel on open and resize (#1575)
A persisted float rect saved at the viewport edge, or on a larger
monitor, passes clampFloatRect (which only keeps 48px reachable so a
live drag may deliberately hang off an edge) and renders the panel as
a 48px sliver on every open. Add containFloatRect, which snaps the
whole window inside the viewport, and an AgentSheet effect that
validates the persisted rect on sheet mount and on viewport resize
and persists the corrected position. The rect is read through a ref
so drag commits do not re-trigger containment: parking the window
half off-screen still works within a session. The live drag path and
clampFloatRect are unchanged, and containFloatRect's output is always
a fixpoint of clampFloatRect, so the render clamp stays a no-op.

Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 15:14:34 +02:00
Mattsson b4b7549004 feat(agent): resizable, undockable assistant panel (#1467)
* feat(agent): resizable, undockable assistant panel

User report: the assistant chat sheet sometimes covers the page content
the user is asking about, with no way to resize or move it.

- Docked mode is now drag-resizable from its left edge (380-800px,
  clamped so the page keeps a 480px readable column) and the page
  reflows beside it via the existing --agent-dock-w reservation.
- Expanded (focus) mode reserves page margin like the compact dock
  instead of overlaying up to 1100px of the page.
- New undock toggle turns the sheet into a floating window that can be
  dragged by its header and resized from edges/corners, clamped so the
  header always stays reachable. Desktop only; mobile keeps the
  full-screen sheet.
- Geometry (mode, dock width, float rect) persists per user in
  user_preferences.ui_state.agent_panel, server-seeded to avoid a
  first-paint jump; the ui-state API schema gains a strict agent_panel
  key with nested merge.
- Pure clamp/resize math lives in lib/agent-panel/geometry with unit
  tests; drag frames write styles imperatively and commit one
  preference update on release.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(agent): address review findings on panel drag, a11y, and persistence

CodeRabbit round 1, all six findings fixed:

- Bind drag listeners to window (plus lostpointercapture) so a failed
  pointer capture or mid-drag unmount can never leave the transition
  suppression and data-agent-resizing stuck for the session.
- Keyboard resize now steps from the visible width (expandedW in focus
  mode) instead of jumping to the persisted dock width.
- The width handle exposes window-splitter semantics: aria-valuenow,
  aria-valuemin, aria-valuemax.
- --nav-w is read reactively via a MutationObserver on #dash-shell
  instead of computed-style reads in the render body and per drag frame.
- The ui-state POST in updatePanelPrefs gets a 300ms trailing debounce
  (state stays immediate) so key auto-repeat cannot produce one
  read-merge-write per repeat; pending write flushes on unmount.
- globals.css keeps one :root token block; the agent-resizing rule moved
  below it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(agent): filter drag events by pointer id, clear fired debounce timer

CodeRabbit round 2, both findings fixed:

- Window-level drag listeners now ignore events from pointers other than
  the initiating one, so a second touch or pen cannot move the panel or
  end the first pointer's drag.
- The persist debounce timer ref is nulled when the timer fires, so the
  unmount flush only writes genuinely pending values instead of
  replaying an already-persisted (possibly stale) geometry.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 16:13:02 +02:00