feat(filters): pick one year from a decade grid, in the feed and in Plex
A shared YearPicker: the recent years as chips with their counts, and a More dialog that lays every year out by decade (sortable by count), so a ninety-year library fits on one screen. The feed's scrolling popover gives way to it; the Plex rail gets it above its range fields, a pick setting both ends. The Plex facets now count titles per year, the year filter left out.
This commit is contained in:
+14
-11
@@ -242,6 +242,7 @@ def facets(db: Session, user: User, *, scope: str, show: str, lang: str, f: Libr
|
||||
"content_ratings": [],
|
||||
"studios": [],
|
||||
"playable": [],
|
||||
"years": [],
|
||||
"year_min": None,
|
||||
"year_max": None,
|
||||
"rating_max": None,
|
||||
@@ -302,7 +303,7 @@ def facets(db: Session, user: User, *, scope: str, show: str, lang: str, f: Libr
|
||||
cr_counts: dict[str, int] = {}
|
||||
studio_counts: dict[str, int] = {}
|
||||
playable_counts: dict[str, int] = {}
|
||||
years: list[int] = []
|
||||
year_counts: dict[int, int] = {}
|
||||
ratings: list[float] = []
|
||||
durs: list[int] = []
|
||||
|
||||
@@ -383,21 +384,22 @@ def facets(db: Session, user: User, *, scope: str, show: str, lang: str, f: Libr
|
||||
)
|
||||
for cls, c in db.execute(pcq).all():
|
||||
playable_counts[cls] = playable_counts.get(cls, 0) + c
|
||||
# Year bounds — exclude the year filter.
|
||||
by = db.execute(
|
||||
# Titles per year — exclude the year filter, so a picked year never empties the list it was
|
||||
# picked from. The year bounds are read from the same counts.
|
||||
yq = (
|
||||
wsq(
|
||||
select(func.min(model.year), func.max(model.year)),
|
||||
select(model.year, func.count()),
|
||||
model,
|
||||
ids,
|
||||
{**p, "year_min": None, "year_max": None},
|
||||
kind_movie,
|
||||
True,
|
||||
)
|
||||
).one()
|
||||
if by[0] is not None:
|
||||
years.append(by[0])
|
||||
if by[1] is not None:
|
||||
years.append(by[1])
|
||||
.where(model.year.isnot(None))
|
||||
.group_by(model.year)
|
||||
)
|
||||
for y, c in db.execute(yq).all():
|
||||
year_counts[y] = year_counts.get(y, 0) + c
|
||||
# Rating max — exclude the rating filter. Coalesce(imdb, audience) to match the score the
|
||||
# rating filter and the UI badge use (IMDb preferred, audience fallback).
|
||||
br = db.scalar(
|
||||
@@ -465,8 +467,9 @@ def facets(db: Session, user: User, *, scope: str, show: str, lang: str, f: Libr
|
||||
for c in PLAYBACK_CLASSES
|
||||
if c in playable_counts
|
||||
],
|
||||
"year_min": min(years) if years else None,
|
||||
"year_max": max(years) if years else None,
|
||||
"years": [{"year": y, "count": c} for y, c in sorted(year_counts.items(), reverse=True)],
|
||||
"year_min": min(year_counts) if year_counts else None,
|
||||
"year_max": max(year_counts) if year_counts else None,
|
||||
"rating_max": max(ratings) if ratings else None,
|
||||
"duration_min": min(durs) if durs else None,
|
||||
"duration_max": max(durs) if durs else None,
|
||||
|
||||
Reference in New Issue
Block a user