Repository navigation
fix(sidebar): keep the channel drag preview under the pointer - #2019
Conversation
Every Messages channel drag preview carried data-section-creation-preview, which translated it up by its own height plus 12px and right by 12px. The preview therefore floated about 40px above the pointer for the whole drag, not only near the new-section slot. Drop the attribute and its offset rule so the preview stays where the row was grabbed, like Solo and section-reorder previews. The new-section slot still hides the preview while it accepts the drop. Co-authored-by: Iggy <42e0a2efa374023f3b716c1a8ee341e1063b06afdd3840d29cdcbc145c5f822b@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Daniel Lett <lett@squareup.com>
A transient preference read failure is retried by relay recovery after 1s. If that retry wins, it removes the Retry button from the create-section dialog, sometimes while a click on it is landing. Focus was then left on nothing, which made the webkit flake check fail on sidebar-section-creation.spec.mjs. Focus the name field whenever recovery restores writability, not only after a manual retry resolves. Co-authored-by: Iggy <42e0a2efa374023f3b716c1a8ee341e1063b06afdd3840d29cdcbc145c5f822b@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Daniel Lett <lett@squareup.com>
kalvinnchau
left a comment
There was a problem hiding this comment.
🤖 Found one focus regression during preference recovery.
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord’s automated source review via Wes’s account, integrating independent Rocket (systems/lifecycle), Mantis (correctness/concurrency), and Groot (product/accessibility) lanes.
One P2 correctness finding is attached inline. No additional actionable issue found in the drag-preview positioning change. The implementation is otherwise small and reuses the existing drag and dialog owners.
Reviewed head 18e22bd85b39ad1a3b0cc79aac0d1c1f1b8faefe, base 89e2d157ed99b8797da65fca71c1785d40079b6b, merge base 6ee523c831140a5a79e2e778af54c2672bee64b7. Scope: all six changed files, supported drag/drop and preference-recovery callers, error/retry/cancel focus, and relevant design/navigation contracts. The incoming base changes concern avatar assets and do not overlap these contracts.
Public material: inspected the description, both screenshots, both commit messages, and samples every two seconds from both attached videos; no disclosure finding in those inspected surfaces. This was not an every-frame video audit.
Validation: source-only; no tests, builds, app launches or PR code execution. A single hosted-check snapshot showed CI required and the listed flake checks successful, with Windows native validation skipped. Native keyboard behavior, screen-reader use, geometry/performance and human acceptance were not exercised by this review. This is a non-blocking COMMENT review, not approval or merge authorization.
The recovery focus handoff moved focus into the name field whenever preferences recovered, even if the user had already moved to Cancel or Close. Enter then retried creation instead of cancelling. Return focus to the field only when it was lost with the removed Retry button, and keep any other focused control in the dialog. Co-authored-by: Iggy <42e0a2efa374023f3b716c1a8ee341e1063b06afdd3840d29cdcbc145c5f822b@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Daniel Lett <lett@squareup.com>
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord’s automated source review via Wes’s account, integrating independent Rocket (systems/lifecycle), Mantis (correctness/concurrency), and Groot (product/accessibility) lanes.
No actionable findings in this revision. The prior Cancel/Close focus finding is addressed: both recovery handoffs preserve focus on surviving controls inside the dialog, and the new Cancel → Enter regression checks that closing does not invoke creation. The drag-preview change retains target-time hiding and browser geometry assertions. The complete six-file patch adds two mounted component tests and no browser cases; the follow-up itself adds one of those component tests.
Reviewed head a6a0c2694517daf916f90a5787d4836faa82202f, base 89e2d157ed99b8797da65fca71c1785d40079b6b, merge base 6ee523c831140a5a79e2e778af54c2672bee64b7. Checked both dialog callers, preference recovery and dismissal owners, relevant design/navigation contracts, and the follow-up against previously reviewed 18e22bd85b39ad1a3b0cc79aac0d1c1f1b8faefe.
Public material: inspected the description, three commit messages, both screenshots and one-second samples throughout both attached videos; no disclosure finding in those inspected surfaces. This is not an every-frame video audit.
Validation: source-only; no tests, builds, app launches or PR code execution. The one-time hosted-check snapshot still had JavaScript/native/browser lanes running; Vitest flake checks passed and Windows native validation was skipped. Current-head CI completion, browser/native focus behavior, screen-reader use, visual acceptance and test-cost measurements remain unverified. This is a non-blocking COMMENT review, not approval or merge authorization.
…isibility * origin/main: (23 commits) feat(profiles): show NIP-FI verified names (BUZZ-433) (#2005) feat(identity): sign in to the organization when Buzz opens (#2086) perf(identity-names): stop rerunning name policy for live member churn (#2092) fix(sidebar): keep the channel drag preview under the pointer (#2019) fix(identity): use xyz.block.buzz.desktop federated-session keychain service (#2094) perf(relay): read each channel's remote access once per accepted batch (#2091) fix(styles): keep page status :has() on each rule's subject (#2081) fix(navigation): show a notice for invalid deep links (#2054) fix(messages): preserve held readers through equal-height resizes (#1963) perf(sidebar): subscribe to selected live and list facts (#1966) feat(desktop): align the sign-in callback page with web branding (#2038) Show linked PRs in Solo headers and move idle huddles to Chat actions (#1968) feat(messages): mark edited messages with "(edited)" (#2020) feat(desktop): bundle the buzz CLI in every package (#2027) feat(plugins): open a plugin page from buzz://plugin links (#2053) feat(plugins): managed plugin sources (#2052) test(browser): prevent sampled clock pause races (#1955) test: fix month-boundary and Sonner mount races in StatusEditor and RelayStaff tests (#2064) test: stop tests leaving temp dirs and a flake-check fixture behind (#1977) fix(messages): release Virtua's held range when scrolling stops (#2032) ... # Conflicts: # src/bundled/channels/ChannelMemberAvatars.tsx
Why
When you drag a channel in the Messages sidebar, the drag preview floats about 40px above the pointer for the whole drag. That makes it hard to tell where the row will land.
The cause is a CSS rule from #1757 (section creation by drag). Every Messages channel preview carries
data-section-creation-preview, and that attribute appliestranslate: var(--space-3) calc(-100% - var(--space-3)). This moves the preview up by its own height plus 12px, and right by 12px. The aim was to keep the preview clear of the new-section slot as it opens. But the rule applies to every channel drag, not only drags near that slot.What
data-section-creation-previewfrom the channel drag preview inChannelInventory.tsx.translaterule inChannels.module.css.CreateSidebarSection.tsx). This fixes a webkit flake insidebar-section-creation.spec.mjs.How
The preview now stays where the row was grabbed, like the Solo and section-reorder previews already do. The new-section slot still hides the preview while it accepts the drop (
body:has([data-create-section-drop][data-drop-target]) .channelDragOverlay), so the preview never covers the slot when it matters.sidebar-section-creation.spec.mjsused to assert the translate was set. It now assertstranslate: noneand that the preview's box contains the pointer's y. On the old code it fails withReceived: "12px calc(-100% - 12px)". Two assertions that only checked the removed attribute are gone.The second commit fixes a flake that CI's flake check found once this PR touched
sidebar-section-creation.spec.mjs. After a transient 502 on the preference read, relay recovery retries the read by itself after 1s. If that retry wins the race with the user's click on "Retry preferences", the button disappears and focus is left on nothing. The dialog now focuses the name field when writability comes back and focus was lost, not only after a manual retry resolves. If the user already moved to Cancel or Close, focus stays there, so Enter still cancels (review feedback).Risk
Low. The drag fix is a CSS-only visual change to the sidebar drag preview. The focus fix only runs when the create-section dialog recovers from a failed preference read. Drop targets, collision detection and saved moves are unchanged. It does reverse a deliberate choice from #1757, so the author of that PR should confirm the slot still reads well without the offset.
Testing
npx playwright test --config tests/browser/playwright.config.mjs sidebar-section-creation navigation-group-order navigation-groups solo-chats --project chromium --project webkit --no-deps: 54 passed at0bc7db587.sidebar-section-creation.spec.mjsby waiting for the automatic retry instead of clicking. Without the focus fix it fails in Chromium and WebKit with the sametoBeFocusederror as CI. With the fix it passes.sidebar-section-creation navigation-group-order navigation-groupswith--repeat-each 3in Chromium and WebKit: 102 passed at18e22bd85.Before and after
Both clips come from the browser fixture. A red dashed line marks the cursor height.
Before: the preview floats about 50px above the cursor while Beta is dragged down and up.
before.mp4
After: the preview stays under the cursor, and dropping Beta on Starred moves it there.
after2.mp4
🤖 Generated with Claude Code