Fix watched-state sync so members' Next Up and Continue Watching follow
Synced rows only ever had the Played flag set. Jellyfin computes Next Up from LastPlayedDate on the member's own row and Continue Watching from the resume position, so a member watching through the shared account got the tick on each episode but their Next Up never advanced. Members are now written the way BaseItem.MarkPlayed/MarkUnplayed write: date and position included. Rows the old version ticked without a date are repaired the next time the item syncs. PlaybackFinished was also treated as an unwatched toggle. Jellyfin raises it on every stop, not just completion (and on 10.11 PlaybackStart resets Played to false first), so a stop halfway through on the shared account cleared members' own watched state whenever Sync unwatched was on. Playback-derived reasons (PlaybackFinished, PlaybackProgress, UpdateUserData) now only ever mirror "watched"; TogglePlayed and Import remain explicit and mirror either way. PlaybackProgress is acted on so the tick lands as soon as the completion threshold is crossed, including for clients that never report a stop. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -141,9 +141,21 @@ Two consequences worth knowing:
|
||||
|
||||
### Watched-state sync
|
||||
|
||||
The plugin subscribes to `UserDataSaved` and filters tightly: only `PlaybackFinished`,
|
||||
`TogglePlayed` and `Import` are acted on, so the constant stream of progress updates during playback
|
||||
is ignored.
|
||||
The plugin subscribes to `UserDataSaved` and decides per save reason what it means:
|
||||
|
||||
- `TogglePlayed` and `Import` are explicit - someone set the flag - so whatever it says is mirrored,
|
||||
unwatched included (subject to *Sync unwatched*).
|
||||
- `PlaybackFinished`, `PlaybackProgress` and `UpdateUserData` only ever mirror *watched*. Jellyfin
|
||||
raises `PlaybackFinished` on every stop, not just on completion, so a stop halfway through leaves
|
||||
`Played` false without anyone having marked anything unwatched; propagating that would wipe what a
|
||||
member watched on their own. Acting on progress too means the tick lands the moment the completion
|
||||
threshold is crossed, and still lands for clients that never report a stop.
|
||||
- Everything else (`PlaybackStart`, `UpdateUserRating`) is ignored.
|
||||
|
||||
A member is written the way Jellyfin's own *mark played* writes - `Played`, `LastPlayedDate` and a
|
||||
cleared resume position - not just the flag. *Next Up* is computed from `LastPlayedDate` on the
|
||||
member's own row, so a bare tick would leave their Next Up stuck on the wrong episode. Members whose
|
||||
row already matches are skipped, which keeps the progress ticks after the threshold write-free.
|
||||
|
||||
No feedback loop is possible: writing to a member raises the event again with *that member's* ID,
|
||||
which is not a shared account, so the handler stops immediately.
|
||||
|
||||
Reference in New Issue
Block a user