feat(feed): Show chips in the toolbar + key+direction sort

1) Move the Show view filter (Unwatched/In progress/All/Watched/Hidden) up into the
   toolbar chip row as its own single-select group, divided from the content-type chips;
   removed the 'show' sidebar widget (sidebar now = Upload date / Language / Topic).
2) Rework ordering like the Playlists page: a sort-key dropdown (Date, Popular, Duration,
   Name, Channel subscribers, Channel priority, Surprise me) + a single asc/desc arrow
   toggle, instead of separate directional entries. 'Most viewed' is now 'Popular'.
   Backend gains the missing directions (views_asc, title_desc, subscribers_asc,
   priority_asc); the frontend maps (key, dir) -> the backend sort string, so FeedFilters
   is unchanged. Trilingual (feed.sortKey.*, feed.dirAsc/dirDesc). Feed.tsx normalized to LF.
This commit is contained in:
npeter83 2026-06-16 02:46:26 +02:00
parent a44bdf7fdc
commit 4921a95d09
7 changed files with 115 additions and 46 deletions

View file

@ -275,10 +275,13 @@ SORTS = {
"newest": Video.published_at.desc().nulls_last(),
"oldest": Video.published_at.asc().nulls_last(),
"views": Video.view_count.desc().nulls_last(),
"views_asc": Video.view_count.asc().nulls_last(),
"duration_desc": Video.duration_seconds.desc().nulls_last(),
"duration_asc": Video.duration_seconds.asc().nulls_last(),
"title": func.lower(Video.title).asc().nulls_last(),
"title_desc": func.lower(Video.title).desc().nulls_last(),
"subscribers": Channel.subscriber_count.desc().nulls_last(),
"subscribers_asc": Channel.subscriber_count.asc().nulls_last(),
# Your per-channel priority (set in the channel manager), newest first within a tier.
# coalesce keeps it null-safe in "all" scope where unsubscribed channels have no row.
"priority": func.coalesce(Subscription.priority, 0).desc(),
@ -296,9 +299,10 @@ def get_feed(
db: Session = Depends(get_db),
) -> dict:
query, _status = _filtered_query(db, user, **params)
if sort == "priority":
if sort in ("priority", "priority_asc"):
prio = func.coalesce(Subscription.priority, 0)
query = query.order_by(
func.coalesce(Subscription.priority, 0).desc(),
prio.asc() if sort == "priority_asc" else prio.desc(),
Video.published_at.desc().nulls_last(),
)
else: