feat(feed,channels): "No tag" filter for untagged channels (E8·S1)

Filter to channels you haven't personally tagged in the channel manager
(no user-owned ChannelTag; auto language/topic tags don't count):

- Feed: a "No tag" sentinel in the "Your tags" sidebar combobox (exclusive
  with real tag picks) + a removable "Untagged" chip; new `untagged` bool
  feed param / `notag` URL key, persisted + coerced on every filter path.
- Channel manager: a virtual "No tag" chip in the tag-chip row filters the
  table to untagged channels (client-side, shared NO_TAG_SENTINEL).

Backend `untagged` is a plain channel-level narrowing, so feed_summary keeps
it applied in the base pass — the count/facet lockstep holds with no mirror.

Note: item E (per-tag counts) and item D (Any/All toggle) were already
shipped; S1 delivers only item B.
This commit is contained in:
2026-08-25 01:44:34 +02:00
parent 5d7be687d3
commit 4ee0dab68f
22 changed files with 223 additions and 34 deletions
+3
View File
@@ -53,6 +53,8 @@ def _feed_params(
tag_mode_language: str = "or",
tag_mode_topic: str = "or",
tag_mode_other: str = "or",
# "No tag" filter: keep only channels the user has not personally tagged (no user-owned ChannelTag).
untagged: bool = False,
channel_ids: list[str] = Query(default=[]),
q: str | None = None,
min_duration: int | None = None,
@@ -74,6 +76,7 @@ def _feed_params(
"topic": tag_mode_topic,
"other": tag_mode_other,
},
"untagged": untagged,
"channel_ids": channel_ids,
"q": q,
"min_duration": min_duration,