feat(desktop): reorder pinned sessions by dragging within the sidebar - #70223
Open
SHL0MS wants to merge 1 commit into
Open
feat(desktop): reorder pinned sessions by dragging within the sidebar#70223SHL0MS wants to merge 1 commit into
SHL0MS wants to merge 1 commit into
Conversation
The pinned list had a reorder affordance on a near-invisible dnd-kit grab handle (the leading status dot), but commit ac4f596 made the whole row body a pointer session-drag source (drag onto chat to link / split). The two drag systems fought on the same row and session-drag won: grabbing a pin started a link-into-chat drag, and the handle's dotted focus ring appeared but reorder never committed. Resolve it the way the session-drag engine already works — by DROP LOCATION, not by which pixel you grab. The engine is a resolver: snapshot targets at engage, hit-test the pointer, act on release. This adds sidebar reorder as one more resolved target: - reorder-zones.ts: a small registry a flat list joins while mounted (container el + live ids + onReorder). The drag snapshots registered zones at engage; resolveReorderTarget picks the insertion slot by pointer-Y (skipping the dragged row); reorderIds applies it with a no-op guard. Both are pure and unit-tested. - session-drag.ts: resolveMove checks reorder FIRST (inside the bar it wins), else falls through to the existing stack/split/link zone logic; onCommit reorders in place instead of opening a tile/link. A dedicated atom drives the insertion line so chat surfaces never re-render on reorder churn. - reorder-zone-list.tsx: registers the zone, tags rows (data-reorder-row) for the geometry snapshot, and paints the insertion line — no dnd-kit handle. The pinned section renders through it (reorderViaDrag) instead of ReorderableList. Net: drag a pin within the sidebar → reorder; drag it onto the chat → link (unchanged). Recents/Sessions rows still use session-drag as before. Fixes the reorder half of NousResearch#47728 (which was closed implemented-on-main but never actually worked once row-body drag landed). Also relax the pinned section's fixed max-h-44 (~6 rows) to max-h-[40vh] so more pins show on tall windows; still bounded so Sessions can't be buried (the NousResearch#43147 anti-overlap invariant) and GROUP_BODY still flattens it in compact mode. Tests: reorder-zones (11 pure-logic cases: slot boundaries, dragged-row skip, foreign-drop rejection, no-op identity), reorder-zone-list (zone registration lifecycle, live ids, own-drag-only insertion line), and a real-pointer-drag e2e (pinned-reorder.spec) asserting the order flips.
Collaborator
Related: #43661 also changes Desktop sidebar drag/reorder behavior, while #66051 handles persisted manual pin order. This PR resolves the row-drag conflict through drop-location routing with separate reorder zones; the overlapping but different mechanisms need maintainer consolidation. |
12 tasks
18 tasks
Contributor
|
FYI: opened #84984 (drag to reorder profile groups in the All-profiles sidebar). It also touches |
20 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Two related asks for the pinned-sessions sidebar: reorder pinned chats, and let the pinned section grow past ~6 rows.
Reorder (the substantive half)
Reordering pinned rows was effectively broken. The pinned list had a reorder affordance on a near-invisible dnd-kit grab handle (the leading status dot), but commit
ac4f596ca2made the whole row body a pointer session-drag source (drag a row onto the chat to link it as an@sessionref, or onto a zone edge to split). The two drag systems fought on the same row and session-drag won: grabbing a pin started a link-into-chat drag, and even when you found the handle its dotted focus ring appeared but the reorder never committed.Fixed by resolving the conflict the way the session-drag engine already works — by drop location, not by which pixel you grab. The engine is a resolver: it snapshots targets at drag engage, hit-tests the pointer each move, and acts on release. This adds sidebar reorder as one more resolved target:
reorder-zones.ts— a small registry a flat list joins while mounted (container element + live id getter +onReorder). The drag snapshots registered zones at engage;resolveReorderTargetpicks the insertion slot by pointer-Y (skipping the dragged row);reorderIdsapplies it with a no-op-identity guard. Both are pure functions, unit-tested.session-drag.ts—resolveMovechecks reorder first (inside the bar's bounds it wins), otherwise falls through to the existing stack/split/link zone logic unchanged;onCommitreorders in place instead of opening a tile or link. A dedicated$sidebarReorderHintatom drives the insertion line so the chat surfaces never re-render on reorder churn (they subscribe to the heavy$dropHintonly for real link/split hints).reorder-zone-list.tsx— registers the zone, tags rows (data-reorder-row) for the geometry snapshot, and paints the insertion line. No dnd-kit handle. The pinned section renders through it (reorderViaDrag) instead ofReorderableList.Net behavior: drag a pin within the sidebar → reorder; drag it onto the chat → link (unchanged). Recents/Sessions rows keep session-drag exactly as before. This is the model the reporter asked for and it matches how the engine was built to route.
Height
The pinned body was hard-capped at
max-h-44(~6 rows) then scrolled. Relaxed tomax-h-[40vh]so more pins show on a tall window. Still bounded, so the Sessions section below can never be buried — preserving the#43147anti-overlap invariant — andGROUP_BODYstill flattens the cap in compact mode.Related Issue
Fixes the reorder half of #47728 (closed
implemented-on-main, but reorder never actually worked once row-body session-drag landed — the handle was shadowed by the link drag). The height cap is the other half of the reporter's ask.Type of Change
How was this tested?
reorder-zones.test.ts, 11 cases): slot-boundary math, dragged-row skip, foreign-drop rejection (a non-pinned row over the zone is not a reorder), multi-zone hit-testing, andreorderIdsno-op identity + end-insertion.reorder-zone-list.test.tsx, 4 cases): zone register/unregister lifecycle, live-id reporting across re-render, per-row tagging, and insertion-line rendering only for a drag of the list's own row.pinned-reorder.spec.ts): creates two pinned sessions, drags the top row down within the sidebar via actualmouse.down/move/up(stepped, liketile-unread-bug.spec), asserts the pinned order flips. Ran locally against the packaged macOS app — passes (1 passed (7.7s)).npx tsc -p ./tsconfig.electron.json/tsconfig.e2e.jsonall clean; full renderer suite2050 passed; eslint clean on touched files (test-filedocumentwarnings match existing test conventions).Checklist
Code
npx vitest run --project ui) and all tests pass;pytestN/A (no Python changes)Documentation & Housekeeping
cli-config.yaml.example— N/A (no config keys)CONTRIBUTING.md/AGENTS.md— N/Amax-h-[40vh]and pointer-drag path are platform-agnostic. The e2e was exercised on macOS.