@@ -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?;
|
||||
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user