From 38f1d9749ee67f18264937807b2f5882e1421557 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Thu, 2 Jul 2026 08:49:11 +0200 Subject: Fix review comments --- .../Library/VersionPlaybackSelector.cs | 59 ++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 MediaBrowser.Controller/Library/VersionPlaybackSelector.cs (limited to 'MediaBrowser.Controller/Library/VersionPlaybackSelector.cs') diff --git a/MediaBrowser.Controller/Library/VersionPlaybackSelector.cs b/MediaBrowser.Controller/Library/VersionPlaybackSelector.cs new file mode 100644 index 0000000000..1766c50141 --- /dev/null +++ b/MediaBrowser.Controller/Library/VersionPlaybackSelector.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using MediaBrowser.Controller.Entities; + +namespace MediaBrowser.Controller.Library +{ + /// + /// Single definition of "which alternate version was most recently played" shared by the resume tile + /// (), the media-source default ordering and Next Up. + /// Each call site declares its own eligibility rule so the intentional differences (resumable-only vs. + /// resumable-or-completed) are visible in one place instead of being re-implemented divergently. + /// The SQL resume query keeps its own translation of the same rule. + /// + public static class VersionPlaybackSelector + { + /// + /// Selects the entry whose user data has the greatest , + /// considering only entries that satisfy . On an exact tie the first + /// encountered entry wins. + /// + /// The candidate type (e.g. a version item or a media source). + /// The candidates to choose from. + /// Resolves the user data for a candidate, or null when it has none. + /// Whether a candidate's user data makes it a valid winner. + /// The most recently played eligible candidate, or default when none qualify. + public static T? SelectMostRecentlyPlayed( + IEnumerable items, + Func dataSelector, + Func isEligible) + { + ArgumentNullException.ThrowIfNull(items); + ArgumentNullException.ThrowIfNull(dataSelector); + ArgumentNullException.ThrowIfNull(isEligible); + + T? winner = default; + var winnerDate = DateTime.MinValue; + var hasWinner = false; + + foreach (var item in items) + { + var data = dataSelector(item); + if (data is null || !isEligible(data)) + { + continue; + } + + var date = data.LastPlayedDate ?? DateTime.MinValue; + if (!hasWinner || date > winnerDate) + { + winner = item; + winnerDate = date; + hasWinner = true; + } + } + + return winner; + } + } +} -- cgit v1.2.3