fix(feed): conjunctive facet counts when topic match mode is AND

In AND ("All") topic mode the facet endpoint still excluded the topic selections
when counting topic chips, so every topic kept its full count and none dropped
out as you narrowed — e.g. picking Comedy left Cooking visible even though no
channel has both. Count topics conjunctively in AND mode (keep the selected
topics applied) so each remaining chip reflects channels that ALSO have all
already-selected topics; non-co-occurring tags fall to zero and hide. OR mode
stays disjunctive. Verified: Comedy selected narrows topic chips 21 -> 6.
This commit is contained in:
npeter83 2026-06-15 12:20:08 +02:00
parent 6e42e010dd
commit c44721ed98

View file

@ -318,8 +318,15 @@ def get_facets(
visible = or_(ChannelTag.user_id.is_(None), ChannelTag.user_id == user.id) visible = or_(ChannelTag.user_id.is_(None), ChannelTag.user_id == user.id)
counts: dict[int, int] = {} counts: dict[int, int] = {}
for category in ("language", "topic"): for category in ("language", "topic"):
# Disjunctive (OR) facets drop the category's own selections so its chips keep
# independent counts (you can OR more of them in). Conjunctive (AND, topics only)
# keeps them applied, so each remaining chip narrows to channels that ALSO have all
# already-selected topics — and tags that can't co-occur drop to zero (hidden).
conjunctive = category == "topic" and params.get("tag_mode") == "and"
base, _status = _filtered_query( base, _status = _filtered_query(
db, user, **{**params, "exclude_tag_category": category} db,
user,
**{**params, "exclude_tag_category": None if conjunctive else category},
) )
channels = base.with_only_columns(Video.channel_id).distinct().subquery() channels = base.with_only_columns(Video.channel_id).distinct().subquery()
rows = db.execute( rows = db.execute(