feat: browse and save combined category feeds

This commit is contained in:
2026-10-11 23:30:11 +02:00
parent ff7590dfa7
commit b53b57ee17
4 changed files with 1143 additions and 172 deletions
+17 -4
View File
@@ -71,6 +71,7 @@ These are the default bindings. Overrides in `[keys]` replace an action's bindin
| `s` | Edit the selected channel's tags |
| `S` | Edit tags for all saved channels in the current category |
| `R` (Shift-R) | Rename the current category, including category-scoped collection views |
| `P` (Shift-P) | Save the current combined-category feed as a new category |
| `w` | Save the selected video to watch later (also works in previews) |
| `W` | Choose combined or category watch later from any video view or preview |
| `Alt-w` | Open the current category's watch later |
@@ -112,9 +113,21 @@ In terminals supporting bracketed paste, clipboard text is inserted in one opera
### Category browser (`c`)
- **Normal:** `j` / `k` or arrow keys navigate; `i` enters filter mode; Enter browses the selected category; `p` toggles its persisted pin; `R` renames it; Esc closes.
- **Insert:** type a case-insensitive substring to filter; arrow keys or Ctrl-J / Ctrl-K navigate matches; Enter browses; Esc returns to normal mode without clearing the filter.
- Reopening the browser clears its filter. No matches makes browsing, pinning, and renaming a no-op.
- **Normal:** `j` / `k` or arrow keys navigate; Space checks/unchecks a category; `i` enters filter mode; Enter browses checked categories, or the hovered category if none are checked; `p` toggles its persisted pin; `R` renames it; Esc closes.
- **Insert:** type a case-insensitive substring to filter; arrow keys or Ctrl-J / Ctrl-K navigate matches; Enter browses the chosen categories; Esc returns to normal mode without clearing the filter. Space is ordinary input here.
- Checkboxes select categories for browsing; the dimmed `p` suffix marks pins independently. Hidden checks survive filtering. Enter still browses checked categories when there are no visible matches; without checks, an empty result makes browsing a no-op. Pinning, renaming, and toggling require a visible selected row.
### Combined category feeds
Check multiple categories in `c`, then press Enter to open their combined feed. One checked category opens its ordinary view; no checks retain the usual single-category shortcut. Esc discards the selector's staged choices. Reopening `c` from a combined feed prechecks its member categories.
The combined feed uses the shared temporary tab, replacing the prior unpinned category/channel/collection view. Channels and video IDs are deduplicated, and videos use the same newest-first ordering and infinite scrolling as other feeds. Back/forward navigation restores cached rows, selection, and pagination.
Press `P` to save the viewed union of channels under a new category name. Enter commits; Esc cancels; duplicate or invalid names leave the prompt open without overwriting anything. The new flat category becomes active without automatic pinning or re-fetching matching cached pages. Its memberships are an independent copy, not links to the original categories.
Renaming a member category updates the combined view and its history. Membership changes recompute the channel union, preserving cached rows when the resolved union is unchanged; deleting a member invalidates the combined view rather than silently widening it. Explicit refresh still reloads the active view from page one.
Combined feeds are not individual categories: `S`, `R`, and `Alt-w` / `Alt-v` require a single category. Save with `P` first to use those actions. Configure multi-selection with `selector.toggle` and saving with `category.save`; name entry uses the shared `input.*` controls.
### Saved channels (`u`)
@@ -178,7 +191,7 @@ Category entries accept `@handles`, HTTPS YouTube channel URLs, or canonical `UC
Video tables color channel names **cyan** when the creator belongs to at least one category. Untagged registrations keep the default text color; selected rows retain their black-on-cyan highlight. Membership is matched by channel ID or handle, not the displayed name, and updates after saving tags or reloading config.
- **Search** and **Feed** are permanent tabs. Feed combines all `[channels]` registrations, including untagged channels, plus channels entered directly in categories, without duplicates.
- Browsing an unpinned category, channel, watch-later list, or saved-video list uses one shared temporary tab; choosing another replaces it. Pinned categories keep their own tabs, marked with a dimmed `p`.
- Browsing an unpinned category, combined-category feed, channel, watch-later list, or saved-video list uses one shared temporary tab; choosing another replaces it. Pinned categories keep their own tabs, marked with a dimmed `p`.
- Removing a channel from a category does **not** unsubscribe it from Feed. To unsubscribe, remove its `[channels]` mappings and category references, then press `r`.
- Temporary tabs do not survive restarting; saved categories and pins do. Hidden views retain loaded rows, selection, and pagination during the session.