Skip to content

feat(desktop): add sidebar categories and manual channel ordering - #2947

Open
NYTEMODEONLY wants to merge 4 commits into
block:mainfrom
NYTEMODEONLY:fizz/sidebar-categories-manual-order
Open

feat(desktop): add sidebar categories and manual channel ordering#2947
NYTEMODEONLY wants to merge 4 commits into
block:mainfrom
NYTEMODEONLY:fizz/sidebar-categories-manual-order

Conversation

@NYTEMODEONLY

@NYTEMODEONLY NYTEMODEONLY commented Jul 26, 2026

Copy link
Copy Markdown

Summary

  • promote existing custom channel sections into first-class sidebar categories
  • add Manual alongside A-Z and Recent for exact channel ordering
  • support pointer, touch, and keyboard movement within and across categories
  • persist exact order in a separate encrypted channel-manual-order NIP-78 document
  • preserve pending local category edits during startup/reconnect hydration
  • keep draggable sidebar rows paintable in WKWebView by avoiding content-visibility: auto on transformed sortable rows
  • hide channel drag handles at rest and reveal only the hovered, keyboard-focused, or actively dragged row, while keeping them visible on non-hover/touch devices

Why

Buzz already supported encrypted custom sections and section reordering, but category creation was buried in a channel context menu and exact channel order was not persisted. This extends the existing model rather than adding a competing category subsystem.

Behavior

  • Create categories from the Channels actions menu.
  • Rename, reorder, and safely delete categories.
  • Deleting a category returns its channels to the uncategorized Channels group.
  • Empty categories remain valid pointer and keyboard drop targets.
  • Manual ordering supports same-category and cross-category insertion.
  • Keyboard drag supports cancellation and live-region announcements.
  • Drag handles stay mounted and accessible but are visually hidden at rest.
  • Hovering anywhere on a draggable channel row reveals only that row's handle.
  • Keyboard focus and active drag keep the handle visible.
  • Non-hover/touch devices retain a persistent move affordance.
  • Existing A-Z and Recent behavior remains unchanged.

Persistence and conflict handling

  • Category membership remains in the existing encrypted channel-sections document.
  • Exact channel order uses a separate encrypted channel-manual-order document so older clients cannot erase category membership or manual order.
  • Stores are scoped by identity and normalized relay.
  • Explicit pending local category edits stay authoritative while startup/reconnect hydration is in flight. Remote timestamps are still observed, then pending local state publishes strictly newer. Idle remote updates retain the existing timestamp/event-ID conflict rules.

Canary acceptance regressions fixed

Startup sync race

Creating a category before the initial NIP-78 fetch completed could show it briefly, then silently remove it. The older fetched snapshot overwrote local state and cancelled the pending debounced publish. The second commit adds the same pending-local guard used by manual-order sync and covers idle versus pending-local remote application.

Invisible rows during drag

In the installed macOS Canary, an ungrouped draggable row could remain in the DOM and accessibility tree but stop painting while dnd-kit transformed it. The affected row combined content-visibility: auto with sortable transforms; switching sort modes or cancelling the drag forced a repaint. The third commit removes that paint-skipping utility only from draggable channel rows, while retaining it for non-draggable rows. The browser regression pins contentVisibility === visible before and after a drop and checks that every channel remains visible.

Always-visible drag handles

The drag grip previously painted on every draggable channel row, adding persistent visual noise. The follow-up keeps the control mounted and tabbable, hides it with opacity at rest, and reveals it for row hover, focus-within, focus-visible, and active drag. A hover-capability media query leaves the control visible on non-hover/touch devices. The regression covers at-rest opacity, row-to-row hover transfer, keyboard focus and pickup, cancellation, pointer reorder, persistence, and row paint visibility.

Validation

Focused upstream branch at 2097ac40f88967d2bf3ed685f5d51a54ebd1561e:

  • Desktop unit suite: 3,536 / 3,536 passed
  • TypeScript/E2E build: passed
  • category/manual-order browser flows: 5 / 5 passed after a fresh E2E build
  • changed-file Biome, px-text, pubkey-truncation, and TypeScript checks passed
  • repository-wide file-size check still reports the pre-existing desktop/src-tauri/src/managed_agents/runtime.rs limit (2,220 lines versus 2,216); this PR does not touch that file

Exact Canary integration at c4319dc4d06b6169a6f014c65f306a6c93ba2d9b:

  • Desktop unit suite: 3,525 / 3,525 passed
  • TypeScript/E2E build: passed
  • category/manual-order browser flows: 5 / 5 passed in an isolated rerun
  • changed-file Biome, px-text, pubkey-truncation, and TypeScript checks passed
  • built and installed bundle ID: xyz.block.buzz.app.dev.canary
  • built and installed executable SHA-256: 20ccbcb7836ff2eb4c81cd4b3d60cadc3e853c7b68c7cee858a0cfbf839cfcfb
  • live installed WKWebView acceptance passed: handles were absent at rest; only the hovered row revealed its handle; hover transferred cleanly between rows; keyboard pickup kept the focused handle visible and announced its position; Escape restored state; Cmd-R and a full quit/relaunch preserved all eight visible and AX-reachable Channels rows in their original order
  • no category, channel membership, or manual order was deleted, reset, or reassigned during acceptance

Co-authored-by: nytemodeonly <contact@nytemode.com>
Signed-off-by: nytemodeonly <contact@nytemode.com>
Co-authored-by: nytemodeonly <contact@nytemode.com>
Signed-off-by: nytemodeonly <contact@nytemode.com>
Co-authored-by: nytemodeonly <contact@nytemode.com>
Signed-off-by: nytemodeonly <contact@nytemode.com>
@NYTEMODEONLY
NYTEMODEONLY marked this pull request as ready for review July 26, 2026 16:24
@NYTEMODEONLY
NYTEMODEONLY requested a review from a team as a code owner July 26, 2026 16:24
Co-authored-by: nytemodeonly <contact@nytemode.com>
Signed-off-by: nytemodeonly <contact@nytemode.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