Skip to content

fix(sidebar): open the deleted channel's neighbor, not the first row - #1327

Draft
baxen wants to merge 1 commit into
mainfrom
mbot/sidebar-owner
Draft

baxen wants to merge 1 commit into
mainfrom
mbot/sidebar-owner

Conversation

@baxen

@baxen baxen commented Oct 18, 2026

Copy link
Copy Markdown
Collaborator

Goal

The sidebar jumps when you delete a channel (TODO item from baxen). If you delete or leave the channel you're viewing, the app opened the sidebar's first row, so a long sidebar scrolled to the top to show it. In a probe with 44 channels, the sidebar's scroll went 600 → 0 and the row below the deleted one moved 570px down.

Deleting a channel you are not viewing didn't jump (probed in both engines). That case already kept its scroll position.

Change

ChannelInventory's lifecycle completion now opens the row beside the removed one: the next row in the same section, else the previous one, else the old first-row fallback. That row is already in view, so the sidebar doesn't move. The neighbors are captured while the channel is still listed, because completion can arrive after the roster has already dropped it.

Focus also goes to that neighbor instead of the first row when the removed channel wasn't open. When it was open, the neighbor opens the same way it does from its own row, with its composer focused.

Archive and unarchive are unchanged.

Tests

  • ChannelInventory.test.tsx: new mounted case where the roster drops the open channel before deletion completes, then the neighbor (gamma, not alpha) opens. The existing pending-delete case now expects the neighbor too.
  • channel-lifecycle.spec.mjs delete case: expects Beta (the neighbor) to be current with its composer focused. Before, it expected Alpha (the first row). The old Alpha focus assertion only held because Alpha's page had already been visited. Opening any unvisited channel from its row focuses its composer.
  • Ran: vitest on src/features/channel-navigation, src/bundled/channels and src/app/shell (927 passed). channel-lifecycle passed 3× in chromium and webkit. channel-header-menu, navigation-scroll-intent, sidebar-section-removal and navigation-sorting passed in chromium and webkit. tsc --noEmit is clean.
  • Fail-then-pass: the probe on main opened the first row and reset the scroll to 0. With the fix, the neighbor opens and the scroll stays at 600.

No browser case was added or removed.

Deferred: native app run and human test.

🤖 Generated with Claude Code

Deleting or leaving the open channel opened the sidebar's first row, so a
long sidebar scrolled to the top to reveal it. The row beside it in the
same section now takes its place; it is already in view, so the sidebar
stays where it was. Keyboard focus also lands on that neighbor when the
removed channel was not open.

Co-authored-by: mbot <3754f8729004d95654c46dbab3129e4ab9ef05cc2534e2a3fbfc155983bd637b@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Bradley Axen <baxen@squareup.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant