blob: 1766c50141754a1c85ea519ccc5d86800469f1c2 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
using System;
using System.Collections.Generic;
using MediaBrowser.Controller.Entities;
namespace MediaBrowser.Controller.Library
{
/// <summary>
/// Single definition of "which alternate version was most recently played" shared by the resume tile
/// (<see cref="IUserDataManager.GetResumeUserData"/>), 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.
/// </summary>
public static class VersionPlaybackSelector
{
/// <summary>
/// Selects the entry whose user data has the greatest <see cref="UserItemData.LastPlayedDate"/>,
/// considering only entries that satisfy <paramref name="isEligible"/>. On an exact tie the first
/// encountered entry wins.
/// </summary>
/// <typeparam name="T">The candidate type (e.g. a version item or a media source).</typeparam>
/// <param name="items">The candidates to choose from.</param>
/// <param name="dataSelector">Resolves the user data for a candidate, or <c>null</c> when it has none.</param>
/// <param name="isEligible">Whether a candidate's user data makes it a valid winner.</param>
/// <returns>The most recently played eligible candidate, or <c>default</c> when none qualify.</returns>
public static T? SelectMostRecentlyPlayed<T>(
IEnumerable<T> items,
Func<T, UserItemData?> dataSelector,
Func<UserItemData, bool> 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;
}
}
}
|