feat(web): name the drop action while dragging sidebar threads - #10378
Conversation
Bugbot is paused — on-demand spend limit reachedBugbot uses usage-based billing for this team and has hit its on-demand spend limit. A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue. |
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This PR changes the existing sidebar drag path with new action badges, dynamic section spacing, altered visual stacking, and release/cancel animations. The behavior spans the production sidebar, sorting strategy, and motion lifecycle, making it broader than a small isolated UI tweak. Not approved because:
Review your spending limits in Billing settings. You can add or adjust custom eligibility rules. Learn more. |
0853f59 to
968e2b2
Compare
0186450 to
85bf36e
Compare
While dragging a thread across sections, the destination divider lit up like an insertion line, and the row only showed "→ Section". That read as "you'll land here" rather than "this becomes pinned", and the lifted row let the rows beneath it show through. The lifted row now carries a verb badge with the matching icon (Pin, Unpin, Settle, Un-settle, Wake), derived from source and destination by resolveSidebarDropVerb. Same-section reorders show no badge. The Pinned and Settled labels wear the accent for the whole drag instead of reacting to the pointer, and the Active label and placeholders stay neutral. The lifted row is opaque and positioned so its z-index applies and nothing bleeds through. A pinned thread keeps its pin marker only while it stays inside Pinned. Fable 5.1 via Claude Code. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The lifted row's solid background lost to the hover color, which stays applied while the pointer drags it, and the hover tint is translucent in dark themes. Stack the row tint and the sidebar color as background images so boundary labels beneath the card no longer show through. Fable 5.1 via Claude Code. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The Active label stayed neutral while Pinned and Settled wore the accent, which read as Active being unavailable. All boundary labels now use the accent for the whole drag. Fable 5.1 via Claude Code. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Section labels were either too faint to find or accented all at once, which read as every section being the target. They now render at a readable neutral for the whole drag, and only the section a drop would move the thread into takes the accent. Reordering within a section highlights nothing. Fable 5.1 via Claude Code. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The accent now follows the section the lifted row is over, whether or not the drop changes state, so reordering inside Pinned lights the Pinned label. The verb badge remains the only signal of a state change. Fable 5.1 via Claude Code. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Dropping the first thread into an empty pinned section put the lifted card over the Pinned label and hid it. Boundary labels now paint above the lifted row, so the label stays readable wherever the card lands. Fable 5.1 via Claude Code. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Dragging the last pinned thread into the active list hid the Active label, because both boundary markers are zero height and the labels would share a line. The first active row then sat directly under "Pinned". The sorting strategy now keeps one label of height for the pinned header while the previewed pinned section is empty, and the header reserves the same height at rest when there are no pins, so the Active label always shows during a drag. Fable 5.1 via Claude Code. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Releasing a dragged thread snapped it from under the pointer to its committed position. The list motion now takes the lifted row's visual top at release and animates that row into wherever it lands, including back to its origin on a cancelled or rejected drop. The other rows only refresh their baseline since they already sit at their previewed positions. Fable 5.1 via Claude Code. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
272ca1f to
acdce3f
Compare
|
Re the empty band above the first thread with no pins: that was a reserved label height at rest, added so the Pinned and Active labels could stack during a drag without the list shifting at pickup. It's gone as of b91fa88 ( |
The pinned header kept one label of height at rest when there were no pins, which showed as an empty band above the first thread. The gap now exists only during a drag: the sorting strategy also projects active reorders when there are no pins, so the empty pinned header keeps its label height without the list reserving anything at rest. Fable 5.1 via Claude Code. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Boundary labels were zero-height overlays, so they always sat on a row. The sorting strategy now opens one label of height below each pinned boundary for the whole drag, and the labels render inside that gap. Every drag projects through the strategy so the space exists for same-section reorders too. The markers stay zero height at rest, so nothing is reserved and pickup measurements are unchanged. On release, the list motion glides every row from its released position into its committed slot, so the gaps close with the same motion as the drop. Fable 5.1 via Claude Code. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
## What's Changed * fix(clients): show feedback results in composer banners by @juliusmarminge in pingdotgg/t3code#10398 * fix(server): stop Windows terminal polling from spiking CPU by @UtkarshUsername in pingdotgg/t3code#9476 * fix(web): onboarding installs agents without needing Node or npm by @t3dotgg in pingdotgg/t3code#10402 * fix(server): allow settling threads with unanswered async questions by @t3dotgg in pingdotgg/t3code#10400 * feat(ci): ship stable releases from the latest nightly commit by @t3dotgg in pingdotgg/t3code#10410 * feat(marketing): add a nightly channel to the download page by @t3dotgg in pingdotgg/t3code#10408 * fix(web): keep settings inputs focused during IME composition by @Lucenx9 in pingdotgg/t3code#10262 * fix(server): preserve Codex reset credits during usage updates by @yashranaway in pingdotgg/t3code#10308 * docs: link the repository security reporting policy by @yashranaway in pingdotgg/t3code#10303 * fix(web): only show auto balance errors after failed checks by @maria-rcks in pingdotgg/t3code#10407 * fix(web): improve preview recording frame delivery by @maria-rcks in pingdotgg/t3code#10403 * fix(server): preserve inline provider secrets on redacted saves by @maxwellyoung in pingdotgg/t3code#10054 * fix(web, mobile): replace Apple desktop machine labels by @extoci in pingdotgg/t3code#10396 * fix(web): hide browser when the right panel starts closing by @Neel2107 in pingdotgg/t3code#10385 * fix(web): keep settings section headings description-free by @maria-rcks in pingdotgg/t3code#10415 * fix(usage): read and redeem hub reset credits through CLIProxyAPI by @juliusmarminge in pingdotgg/t3code#10395 * fix(web): deduplicate expanded tool labels and keep errors expandable by @Yash-Singh1 in pingdotgg/t3code#10420 * fix(server): skip git status scans while the index is locked by @Gigioxx in pingdotgg/t3code#9845 * fix(mcp): allow text-only preview snapshots by @juliusmarminge in pingdotgg/t3code#10232 * fix(claude): name the expired login or usage limit instead of a generic API error by @vitalyiegorov in pingdotgg/t3code#10321 * feat(mobile): queue a message while its attachment is still uploading by @juliusmarminge in pingdotgg/t3code#10404 * feat(mobile): show when an existing thread has a message waiting in the outbox by @juliusmarminge in pingdotgg/t3code#10405 * fix(codex): accept misalignment policy errors on thread resume by @realbakari in pingdotgg/t3code#10373 * fix(server): skip disabled settlement lookups by @t3dotgg in pingdotgg/t3code#10424 * fix(server): run OpenCode CLI commands sequentially by @t3dotgg in pingdotgg/t3code#10427 * feat(web): name the drop action while dragging sidebar threads by @SunkenInTime in pingdotgg/t3code#10378 * perf(web): keep the sidebar responsive during bulk thread updates by @t3dotgg in pingdotgg/t3code#10413 * fix(web): onboarding wizard now supports light mode by @t3dotgg in pingdotgg/t3code#10432 * feat(threads): dismiss async questions without replying by @t3dotgg in pingdotgg/t3code#10431 * fix(web): stop collapsing the composer when it loses focus by @t3dotgg in pingdotgg/t3code#10437 * fix(server): keep interrupted threads resumable after restarts by @maria-rcks in pingdotgg/t3code#10421 ## New Contributors * @Neel2107 made their first contribution in pingdotgg/t3code#10385 * @realbakari made their first contribution in pingdotgg/t3code#10373 **Full Changelog**: pingdotgg/t3code@v0.0.39-nightly.20260906.1316...v0.0.39-nightly.20260907.1325 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.39-nightly.20260907.1325
Follow-up to the merged sidebar drag work, now based on main.
Problem. While dragging a thread across sections, the destination divider lit up in the accent color, which reads as an insertion line rather than a state change, and the lifted row only said "→ Section". On first use it was not clear what a drop would do. The lifted row also let the rows beneath it show through: its z-index sat on an unpositioned list item, so neighbouring rows' content painted over it.
Fix.
resolveSidebarDropVerb. Same-section reorders show no badge. The verbs match the row actions and context menu, so nothing new to learn.Tests: two cases for the verb mapping in
Sidebar.logic.test.ts. Doc paragraph indocs/user/thread-sidebar.mdupdated.Before
After
Drop motion (unpin by drop, pin by drop, then a cancelled drag)
Screen recording of the full drag flow: https://cap.so/s/b3r1wwtkwxw0x1s
Drag recording
Pin and Settle badges during a drag, verified in an isolated web client using renamed UI fixtures. The drag is cancelled at the end.
Rebased onto main. Web typecheck and all 216 focused sidebar tests pass.
Final verification
Fixed the unused export reported by CI; no behavior changed in this fix. Web typecheck, all 216 sidebar tests, scoped Knip, and targeted lint pass. React Doctor reports only the two existing sidebar complexity warnings. Manual source review found no additional blockers.
Verified unpin, pin, and cancel in isolated web clients using the same fixture, viewport, and theme. Base
9a47c7bd405; head5dc842ea269. This applies to web and desktop’s shared sidebar; mobile, contracts, and server behavior are unchanged.Before recording · After recording
All executed CI jobs pass. Macroscope approvability is neutral because its correctness review is unavailable under the workspace spending limit; Bugbot also reports a spending limit. There are no unresolved review threads.