fix(plex): address code-review findings (F1-F3, F5, F9)
- F1: refresh grid after playback/collection-edit — invalidate the renamed ["plex-library"] query key in PlexPlayer + PlexCollectionEditor (was stale ["plex-browse"], a dead no-op) - F2: exclude hidden movies from facet counts/bounds — the movie facet base now always joins watch-state and mirrors unified_library's status branches, so facets match the visible grid exactly - F3: show_detail/item_detail live-Plex enrichment degrades instead of 500ing — broaden the best-effort block to except Exception - F5: don't re-run the heavy facet computation on sort-direction toggles — key the facets query only on fields plexFacets actually sends - F9: optimistic watched-toggle also updates the search Episodes section and gives toggleEpisodeWatched an optimistic path (shared optimisticStatus helper)
This commit is contained in:
parent
186fdbb0e5
commit
9f8e410033
5 changed files with 37 additions and 21 deletions
|
|
@ -798,15 +798,18 @@ def facets(
|
|||
query = query.filter(model.duration_s >= pp["duration_min"])
|
||||
if with_dur and pp.get("duration_max") is not None:
|
||||
query = query.filter(model.duration_s <= pp["duration_max"])
|
||||
if show in ("watched", "in_progress", "unwatched"):
|
||||
st = aliased(PlexState)
|
||||
query = query.outerjoin(st, and_(st.item_id == model.id, st.user_id == uid))
|
||||
if show == "watched":
|
||||
query = query.filter(st.status == "watched")
|
||||
elif show == "in_progress":
|
||||
query = query.filter(st.position_seconds > 0, or_(st.status.is_(None), st.status != "watched"))
|
||||
else:
|
||||
query = query.filter(or_(st.status.is_(None), st.status.notin_(["watched", "hidden"])))
|
||||
# Always join watch-state and mirror the grid's status branches (unified_library) exactly —
|
||||
# hidden movies never appear in the grid, so they must not inflate facet counts/bounds either.
|
||||
st = aliased(PlexState)
|
||||
query = query.outerjoin(st, and_(st.item_id == model.id, st.user_id == uid))
|
||||
if show == "watched":
|
||||
query = query.filter(st.status == "watched")
|
||||
elif show == "in_progress":
|
||||
query = query.filter(st.position_seconds > 0, or_(st.status.is_(None), st.status != "watched"))
|
||||
elif show == "unwatched":
|
||||
query = query.filter(or_(st.status.is_(None), st.status.notin_(["watched", "hidden"])))
|
||||
else:
|
||||
query = query.filter(or_(st.status.is_(None), st.status != "hidden"))
|
||||
else:
|
||||
if show in ("watched", "in_progress", "unwatched"):
|
||||
agg = _show_agg_subq(db, uid).subquery()
|
||||
|
|
@ -1389,7 +1392,9 @@ def show_detail(
|
|||
meta = plex.metadata(sh.rating_key) or {}
|
||||
rich = _rich_meta(meta)
|
||||
related = _related_show_cards(db, user.id, plex.related(sh.rating_key), exclude=sh.id)
|
||||
except (PlexError, PlexNotConfigured):
|
||||
except Exception:
|
||||
# Best-effort enrichment only — the local episode list is already assembled, so any live-Plex
|
||||
# failure (not configured, HTTP/JSON shape, _rich_meta parse error) must degrade, not 500.
|
||||
pass
|
||||
|
||||
return {
|
||||
|
|
@ -1943,8 +1948,8 @@ def item_detail(
|
|||
"text": codec not in _BITMAP_SUBS,
|
||||
}
|
||||
)
|
||||
except (PlexError, PlexNotConfigured):
|
||||
pass # metadata extras are best-effort; playback works without them
|
||||
except Exception:
|
||||
pass # metadata extras are best-effort; any live-Plex failure must degrade, not 500 — playback works without them
|
||||
|
||||
prev_id, next_id = _episode_nav(db, it)
|
||||
show = db.get(PlexShow, it.show_id) if it.kind == "episode" and it.show_id else None
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue