diff options
| author | Shadowghost <Ghost_of_Stone@web.de> | 2026-07-02 08:49:11 +0200 |
|---|---|---|
| committer | Shadowghost <Ghost_of_Stone@web.de> | 2026-07-02 08:49:11 +0200 |
| commit | 38f1d9749ee67f18264937807b2f5882e1421557 (patch) | |
| tree | 0860e37b596ad2ce8dd60e135647df3659b6c5c6 /Emby.Server.Implementations | |
| parent | 0fb042b7403ebd7578b696aba35ba0c582ccf6ba (diff) | |
Fix review comments
Diffstat (limited to 'Emby.Server.Implementations')
5 files changed, 37 insertions, 44 deletions
diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index 2bf478953e..9881565cd2 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -1272,8 +1272,9 @@ namespace Emby.Server.Implementations.Dto // Match the per-user filtering of the media sources: versions the user cannot // access are not selectable, so they must not count towards the badge either. var mediaSourceCount = user is null - ? video.MediaSourceCount - : video.GetAllVersions().Count(v => v.Id.Equals(video.Id) || v.IsVisibleStandalone(user)); + || (!video.PrimaryVersionId.HasValue && video.LinkedAlternateVersions.Length == 0 && !video.HasLocalAlternateVersions) + ? video.MediaSourceCount + : video.GetAllVersions().Count(v => v.Id.Equals(video.Id) || v.IsVisibleStandalone(user)); if (mediaSourceCount != 1) { dto.MediaSourceCount = mediaSourceCount; diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index c0e45ab6c7..c64833ddaa 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -451,26 +451,23 @@ namespace Emby.Server.Implementations.Library } } - MediaSourceInfo resumeSource = null; - UserItemData resumeData = null; foreach (var source in sources) { - if (source.Id is null - || !dataBySourceId.TryGetValue(source.Id, out var data) - || data.PlaybackPositionTicks <= 0) + if (source.Id is not null + && dataBySourceId.TryGetValue(source.Id, out var data) + && data.PlaybackPositionTicks > 0) { - continue; - } - - source.PlaybackPositionTicks = data.PlaybackPositionTicks; - - if (resumeData is null || (data.LastPlayedDate ?? DateTime.MinValue) > (resumeData.LastPlayedDate ?? DateTime.MinValue)) - { - resumeSource = source; - resumeData = data; + source.PlaybackPositionTicks = data.PlaybackPositionTicks; } } + // Reorder only for a resumable (in-progress) version; + // a completed version has no position to resume, so it must not be pulled to the front here. + var resumeSource = VersionPlaybackSelector.SelectMostRecentlyPlayed( + sources, + source => source.Id is not null ? dataBySourceId.GetValueOrDefault(source.Id) : null, + data => data.PlaybackPositionTicks > 0); + if (resumeSource is not null && !video.PrimaryVersionId.HasValue && !ReferenceEquals(sources[0], resumeSource)) { var reordered = new List<MediaSourceInfo>(sources.Count) { resumeSource }; diff --git a/Emby.Server.Implementations/Library/UserDataManager.cs b/Emby.Server.Implementations/Library/UserDataManager.cs index 61372f8b56..40cd2bb69c 100644 --- a/Emby.Server.Implementations/Library/UserDataManager.cs +++ b/Emby.Server.Implementations/Library/UserDataManager.cs @@ -329,21 +329,15 @@ namespace Emby.Server.Implementations.Library foreach (var (primaryId, versions) in versionGroups) { - UserItemData? resumeData = null; - foreach (var version in versions) - { - // Consider both in-progress and completed versions so a finished alternate still marks the primary as played. - if (userDataByVersion.TryGetValue(version.Id, out var data) - && (data.PlaybackPositionTicks > 0 || data.Played) - && (resumeData is null || (data.LastPlayedDate ?? DateTime.MinValue) > (resumeData.LastPlayedDate ?? DateTime.MinValue))) - { - resumeData = data; - } - } + // Consider both in-progress and completed versions so a finished alternate still marks the primary as played. + var resumeVersion = VersionPlaybackSelector.SelectMostRecentlyPlayed( + versions, + version => userDataByVersion.GetValueOrDefault(version.Id), + data => data.PlaybackPositionTicks > 0 || data.Played); - if (resumeData is not null) + if (resumeVersion is not null) { - result[primaryId] = new VersionResumeData(resumeData); + result[primaryId] = new VersionResumeData(resumeVersion.Id, userDataByVersion[resumeVersion.Id]); } } diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index 6017b7cbf6..f652634c69 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -980,14 +980,17 @@ namespace Emby.Server.Implementations.Session { _userDataManager.SaveUserData(user, item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None); + // A completed version marks every alternate version played and clears their resume points, so the + // whole movie leaves Continue Watching and reads as watched everywhere. (Per-version resume positions + // only persist while nothing has been completed yet.) if (data.Played == true && item is Video playedVideo) { playedVideo.PropagatePlayedState(user, true); } } - if ((!user.RememberAudioSelections && data.AudioStreamIndex.HasValue) - || (!user.RememberSubtitleSelections && data.SubtitleStreamIndex.HasValue)) + if ((!user.RememberAudioSelections && info.AudioStreamIndex.HasValue) + || (!user.RememberSubtitleSelections && info.SubtitleStreamIndex.HasValue)) { _userDataManager.ResetPlaybackStreamSelections(user, item); } @@ -1177,7 +1180,9 @@ namespace Emby.Server.Implementations.Session _userDataManager.SaveUserData(user, item, data, UserDataSaveReason.PlaybackFinished, CancellationToken.None); - // A completed version marks all of its alternate versions played; positions stay per-version. + // A completed version marks every alternate version played and clears their resume points, so the + // whole movie leaves Continue Watching and reads as watched everywhere. (Per-version resume positions + // only persist while nothing has been completed yet.) if (data.Played == true && item is Video playedVideo) { playedVideo.PropagatePlayedState(user, true); diff --git a/Emby.Server.Implementations/TV/TVSeriesManager.cs b/Emby.Server.Implementations/TV/TVSeriesManager.cs index 9a402a5738..459ad1a17e 100644 --- a/Emby.Server.Implementations/TV/TVSeriesManager.cs +++ b/Emby.Server.Implementations/TV/TVSeriesManager.cs @@ -262,19 +262,15 @@ namespace Emby.Server.Implementations.TV return (null, null); } - Video? playedVersion = null; - DateTime? lastPlayedDate = null; - foreach (var version in lastWatchedVideo.GetAllVersions()) - { - var data = _userDataManager.GetUserData(user, version); - if (data?.LastPlayedDate is { } date && (lastPlayedDate is null || date > lastPlayedDate)) - { - lastPlayedDate = date; - playedVersion = version; - } - } + var versions = lastWatchedVideo.GetAllVersions(); + var userDataByVersion = _userDataManager.GetUserDataBatch(versions, user); + + var playedVersion = VersionPlaybackSelector.SelectMostRecentlyPlayed( + versions, + version => userDataByVersion.GetValueOrDefault(version.Id), + data => data.LastPlayedDate.HasValue); - return (playedVersion, lastPlayedDate); + return (playedVersion, playedVersion is null ? null : userDataByVersion[playedVersion.Id].LastPlayedDate); } /// <summary> |
