fix(jellyfin): respect played flag for watched state

close #965
This commit is contained in:
edde746
2026-05-03 03:29:39 +02:00
parent 8a7d767e54
commit 8594a7bc52
2 changed files with 23 additions and 1 deletions
+9 -1
View File
@@ -180,7 +180,7 @@ class JellyfinMappers {
clearLogoPath: _selfImagePath(id, item, 'Logo') ?? _parentLogoImage(item),
durationMs: jellyfinTicksToMs(item['RunTimeTicks']),
viewOffsetMs: jellyfinTicksToMs(_userData(item)?['PlaybackPositionTicks']),
viewCount: _userData(item)?['PlayCount'] as int?,
viewCount: _viewCount(item),
lastViewedAt: jellyfinIsoToEpochSeconds(_userData(item)?['LastPlayedDate'] as String?),
// Plex semantics: `leafCount` = total leaf items (episodes for series).
// Jellyfin's `ChildCount` is direct children (seasons for a series),
@@ -304,6 +304,14 @@ class JellyfinMappers {
return ud is Map<String, dynamic> ? ud : null;
}
static int _viewCount(Map<String, dynamic> item) {
final ud = _userData(item);
if (ud?['Played'] != true) return 0;
final playCount = ud?['PlayCount'];
if (playCount is int && playCount > 0) return playCount;
return 1;
}
static int? _viewedLeafCount(Map<String, dynamic> item) {
final ud = _userData(item);
final unplayed = ud?['UnplayedItemCount'] as int?;
+14
View File
@@ -79,6 +79,20 @@ void main() {
expect(item.serverName, 'Home');
});
test('does not treat Jellyfin PlayCount as watched when Played is false', () {
final json = {
'Id': 'started-only',
'Name': 'Started Only',
'Type': 'Movie',
'UserData': {'PlayCount': 1, 'Played': false},
};
final item = JellyfinMappers.mediaItem(json, serverId: _serverId, absolutizer: null)!;
expect(item.viewCount, 0);
expect(item.isWatched, isFalse);
});
test('episode preserves series/season hierarchy', () {
final json = {
'Id': 'ep1',