feat(plex): redesign browse tiles — 2-poster montage top, readable label band
The full-bleed 4-poster collage drowned the on-tile text. Split PosterTile in two: the top half shows up to 2 montage posters, the bottom half is a solid colour-hash band that carries the label, so the text is always readable. Genre tiles drop the count (just the label now); collection tiles show the name on one truncated line plus a sub-line of item count · total runtime. A group with no art falls back to an all-colour tile. Backend: `/collections` cards gain `total_runtime_s` (a new `runtime_by_key` grouped sum) and their montage art is capped at 2. Frontend: PosterTile reworked; a `collectionMeta` helper builds the count·runtime sub-line via the existing formatRuntime. Verified live: collection and genre tiles render 2 posters over a readable colour band with the right sub-lines; colour fallback intact for art-less groups. Gate: tsc/lint/knip/prettier clean, 423 vitest; backend ruff clean, collections tests green (+ a new art/runtime assertion).
This commit is contained in:
@@ -76,6 +76,23 @@ def top_art_keys(
|
||||
return out
|
||||
|
||||
|
||||
def runtime_by_key(db, model, lib_ids: list[int], key_col, keys: list[str]) -> dict[str, int]:
|
||||
"""Total runtime (sum of duration_s, seconds) of the items under each key in `keys` (a member of the
|
||||
JSONB array `key_col`), as {key: seconds}. ONE grouped query. Used for a collection tile's runtime."""
|
||||
if not lib_ids or not keys:
|
||||
return {}
|
||||
k = func.jsonb_array_elements_text(key_col).label("k")
|
||||
exp = (
|
||||
select(func.coalesce(model.duration_s, 0).label("d"), k)
|
||||
.where(model.library_id.in_(lib_ids), func.jsonb_typeof(key_col) == "array")
|
||||
.subquery()
|
||||
)
|
||||
rows = db.execute(
|
||||
select(exp.c.k, func.sum(exp.c.d)).where(exp.c.k.in_(keys)).group_by(exp.c.k)
|
||||
).all()
|
||||
return {key: int(total or 0) for key, total in rows}
|
||||
|
||||
|
||||
def vector_col(model, lang: str):
|
||||
# RANKING vector. In HU we rank by the Hungarian vector; a row matched only via its English vector
|
||||
# (see `vector_match`) gets rank 0 and sorts last, which is the intended HU-first ordering.
|
||||
|
||||
Reference in New Issue
Block a user