Skip to content

feat: add batch unsubscribe UI to sidebar - #5075

Open
devwez wants to merge 1 commit into
RSSNext:devfrom
devwez:feat/batch-unsubscribe-sidebar
Open

devwez wants to merge 1 commit into
RSSNext:devfrom
devwez:feat/batch-unsubscribe-sidebar

Conversation

@devwez

@devwez devwez commented Aug 26, 2026

Copy link
Copy Markdown

Summary

Adds a visible multi-select mode indicator and batch action bar to the subscription column sidebar for easy multi-feed management.

Problem

Issue #5053 requests the ability to delete multiple RSS feeds at once. The batch unsubscribe functionality already exists (Cmd/Ctrl+Click to select, then right-click > Unfollow), but it is not discoverable - users have no visual indication that multi-select is possible.

Solution

  1. Multi-select mode indicator: When feeds are selected, a checkbox icon appears in the header showing that multi-select mode is active. Clicking it exits the mode.

  2. Batch action bar: When one or more feeds are selected, a bar slides up from the bottom of the sidebar showing:

    • Selection count (e.g., "3 feeds selected")
    • Cancel button to clear selection
    • "Unfollow All Selected Feeds" button with delete icon
  3. i18n: Added translation keys for the new UI elements.

Changes

  • SubscriptionColumnHeader.tsx - Added multi-select mode indicator button
  • index.tsx - Added BatchActionBar component with selection count, cancel, and unfollow actions
  • locales/app/en.json - Added translation keys

Testing

  1. Hold Cmd/Ctrl and click multiple feeds in the sidebar
  2. Verify the batch action bar appears at the bottom
  3. Click "Unfollow All Selected Feeds" to confirm batch unsubscribe
  4. Verify the multi-select mode indicator appears in the header
  5. Click the indicator to exit multi-select mode

Adds a visible multi-select mode indicator and batch action bar to the
subscription column sidebar. When feeds are selected (via Cmd/Ctrl+Click),
a bar appears at the bottom showing the selection count with options to
cancel or unfollow all selected feeds.

This makes the existing batch unsubscribe feature discoverable without
requiring users to know about the keyboard shortcut or context menu.

Closes RSSNext#5053
@devwez

devwez commented Sep 4, 2026

Copy link
Copy Markdown
Author

Friendly bump — this is ready for review when you have a moment. Happy to address feedback!

@DIYgod

DIYgod commented Sep 15, 2026

Copy link
Copy Markdown
Member

Thanks for the contribution. I reviewed and ran the desktop renderer at d77da7e775a5a66fd770eead5fd2de72fcf6e4e1, which is still the current PR head. There are several issues to address before merging:

  1. Selecting a feed crashes the renderer. index.tsx:378 references stopPropagation without importing it. Once selection becomes non-empty, rendering BatchActionBar throws ReferenceError: stopPropagation is not defined. This was reproduced in the local UI.

  2. The new buttons use unsupported props. In index.tsx:385–400, our shared Button accepts buttonClassName, not className, and its variants are text, outline, primary, and ghost; there is no destructive variant. Both usages fail typecheck. At runtime, the Cancel class overrides the generated button classes, and the unfollow button lacks the intended destructive styling.

  3. Cancel renders as words.cancel. index.tsx:391 looks up the key in the default app namespace, but it belongs to common. Please use the correct namespace.

  4. The action bar does not fit the sidebar. The sidebar defaults to 256px and its resize range is 256–300px. The single flex row at index.tsx:380 squeezes the count and buttons together; the unfollow label wraps into several lines. I verified this after temporarily adding only the missing import from item 1. Please use a layout and label that fit the supported widths.

  5. Normal navigation is treated as multi-select mode. FeedItem already sets selectedFeedIds to [feedId] on an ordinary click. Consequently, the new length > 0 checks display the batch bar and “Exit Multi-Select Mode” during normal feed navigation. Please distinguish the intended selection mode from the active feed. Also preserve route cleanup when deleting the currently open feed: the new button always uses feedIdList, while existing route cleanup only handles variables.subscription.

  6. Selection cleanup is inconsistent across deletion paths. The confirmation hook invokes the new clear-selection callback immediately after starting mutate, so a failed request loses the selection. The existing context-menu batch action passes no callback and leaves stale selected IDs visible in the new bar after successful deletion. Please clear selection on successful deletion and cover both entry points.

  7. Pluralization and translations need updating. en.json:463–464 uses the old _plural suffix. Current i18next uses _one / _other; testing with count: 2 returns 2 feed selected. Please also add the new strings to zh-CN and ja as required by the repository guidelines.

Validation on this head found four PR-introduced TypeScript errors and four targeted ESLint errors, including the unused AnimatePresence and modal-hook imports in SubscriptionColumnHeader.tsx, import ordering, and locale-key ordering. Prettier also fails for index.tsx. The existing 109 tests passed, but the new flow has no regression coverage. Please add focused coverage for selection visibility, cancellation, successful/failed deletion, and singular/plural labels, then rerun the quality checks.

Screenshot evidence

Captured from the local desktop web renderer at the reviewed commit, with a 1280 × 720 viewport and demo content.

1. Unmodified PR: selecting a feed crashes the renderer (item 1).

Renderer crash: stopPropagation is not defined

2. Action bar after temporarily adding only the missing stopPropagation import (items 2–4). The bottom-left bar shows the untranslated words.cancel key, the crowded layout, and the unfollow label wrapping across multiple lines without the intended destructive styling. No other UI fixes were applied for this screenshot.

Action bar with untranslated Cancel and crowded buttons

3. Confirmation dialog after the same temporary import fix. Included to show the next step of the changed UI flow; the destructive confirmation was not submitted and no feeds were unfollowed during this visual check.

Batch-unfollow confirmation dialog

The temporary import was reverted after capturing screenshots; no code changes were pushed.

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.

2 participants