fix(plex): Restart only where an episode has a resume point; the Surprise draw is re-read, not redrawn
Show cards carry resumable (ShowState, from the same rollup) so a part-watched show whose next episode is untouched offers Play, not a Continue and a Restart that do the same thing; plexStarted is the one rule for cards and menus. The Surprise rail's key sits under the discover root: whatever refreshes the rails re-reads the draw (keep=) with its watch state now, kept past the 5-minute gc, and only the reshuffle deals. Closing the player refreshes the Discover rails. A show card's play acts on the last click only, and only where it was made.
This commit is contained in:
@@ -9,6 +9,7 @@ from sqlalchemy import and_, case, func, or_, select
|
||||
from sqlalchemy.orm import Session, aliased
|
||||
|
||||
from app.models import PlexItem, PlexState
|
||||
from app.plex.cards import ShowState
|
||||
|
||||
# Sort sentinel for a rail row whose timestamp is missing, so `key=lambda r: r[0] or NO_TS` reads the
|
||||
# same at every rail that merges two type-homogeneous lists in Python.
|
||||
@@ -32,6 +33,11 @@ def show_status(total: int, watched: int, inprog: int) -> str:
|
||||
return "new"
|
||||
|
||||
|
||||
def show_state(total: int, watched: int, inprog: int) -> ShowState:
|
||||
"""`show_status` plus whether an episode holds a resume point (the card's `ShowState`)."""
|
||||
return ShowState(show_status(total, watched, inprog), (inprog or 0) > 0)
|
||||
|
||||
|
||||
def rollup(cards: list[dict]) -> dict:
|
||||
"""From ORDERED episode cards → the aggregate watch status, the "on deck" episode to Resume (the
|
||||
last in-progress one, else the first unwatched), the first episode (for Play from the start), and
|
||||
@@ -92,11 +98,11 @@ def agg_subquery(db: Session, user_id: int, include_resumed: bool = False):
|
||||
)
|
||||
|
||||
|
||||
def state_map(db: Session, user_id: int, show_ids: list[int]) -> dict[int, str]:
|
||||
def state_map(db: Session, user_id: int, show_ids: list[int]) -> dict[int, ShowState]:
|
||||
if not show_ids:
|
||||
return {}
|
||||
rows = db.execute(agg_subquery(db, user_id).where(PlexItem.show_id.in_(show_ids))).all()
|
||||
return {r.show_id: show_status(r.total, r.watched, r.inprog) for r in rows}
|
||||
return {r.show_id: show_state(r.total, r.watched, r.inprog) for r in rows}
|
||||
|
||||
|
||||
def item_state_map(db: Session, user_id: int, item_ids: list[int]) -> dict[int, PlexState]:
|
||||
|
||||
Reference in New Issue
Block a user