feat(desktop): add user-defined channel sections to sidebar#789
Open
wpfleger96 wants to merge 6 commits into
Open
feat(desktop): add user-defined channel sections to sidebar#789wpfleger96 wants to merge 6 commits into
wpfleger96 wants to merge 6 commits into
Conversation
c99021f to
bfbdbad
Compare
Collaborator
|
@wpfleger96 will this work across devices as well? Like will the mobile app have access to these same groups to display? |
Collaborator
Author
|
@wesbillman no, as-is the PR will save channel sections to I'm gonna add Nostr event syncing so that sections will be shared between devices in a stacked PR so this one doesn't get too chonky |
Collaborator
Author
Collaborator
Author
All stream channels appear in a single flat list which becomes hard to navigate as channel count grows. Channel sections let users create custom named groups (e.g., "Starred", "Work") to organize channels in the sidebar, similar to Slack's sidebar sections. Sections are purely cosmetic and client-side -- stored in localStorage keyed by pubkey, with no backend changes. Users manage sections via right-click context menus: create, rename, delete, reorder (move up/down), and assign/unassign channels. Each section is independently collapsible. Channels not assigned to a section remain in the default "Channels" group.
Export storageKey from channelSectionsStorage to eliminate duplicate key definitions that could diverge during refactors. Fix createSection to return null on write failure instead of a phantom section, preventing stale channel assignments. Clean up collapsedSections state when a section is deleted. Freeze DEFAULT_STORE to guard against accidental mutation.
Extract shared parseChannelSectionPayload validator and stripOrphanedAssignments helper to channelSectionsStorage.ts. Deduplicate Create/Rename dialogs into shared SectionNameDialog base. Add per-section mark-all-read button to CustomChannelSection.
markChannelRead bailed when lastMessageAt was null because it lacked the latestByChannelRef fallback that markChannelUnread already had. This made the per-section "mark all as read" button and the individual channel "mark as read" context menu action silently do nothing. Also clear forcedContexts immediately in markContextRead so the forced-unread flag from "mark unread" is removed when the user re-opens the channel.
…ssignment Channels can be dragged between sections or back to the ungrouped list, and sections can be dragged to reorder. Uses @dnd-kit pointer events (no conflict with existing file drop prevention). DnD primitives extracted to SidebarDnd.tsx; existing context-menu and move up/down keyboard alternatives remain as accessibility fallbacks.
closestCenter collision detection required dragging to the vertical midpoint of a tall channel list before the drop target activated. Switch to pointerWithin so the drop fires as soon as the pointer enters the droppable rect, and move the droppable wrappers up to cover the entire section (header + content) instead of just the channel list.
881b951 to
f081fbf
Compare
Collaborator
Author
Collaborator
Author
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.







I added Slack-style sidebar sections to let users organize stream channels into custom named groups — the flat channel list gets unwieldy as the channel count grows.
Users create sections via right-click on any stream channel ("Move to section → New section…") and manage them via right-click on the section header (rename, move up/down, delete). Each section collapses independently. Channels not assigned to a section remain in the default "Channels" group below all custom sections.
channelSectionsStorage.ts— pure localStorage read/write keyed bysprout-channel-sections.v1:{pubkey}with type-guard validation and a safe default; sections and channel assignments stored separately for O(1) lookupsuseChannelSections.ts— hook owning all CRUD mutations (create, rename, delete, reorder, assign/unassign), with cross-tab sync viaStorageEventChannelSectionDialogs.tsx—CreateSectionDialog,RenameSectionDialog,DeleteSectionAlertDialogusing existingDialog/AlertDialog/InputprimitivesCustomChannelSection.tsx— extractedChannelGroupSection,SectionHeaderActions,CustomChannelSection, and supporting submenu components;AppSidebar.tsxupdated to drive section state and render custom sections above the default groupStacked: cross-device sync added in #792