diff --git a/backend/Api/MoonfinController.cs b/backend/Api/MoonfinController.cs index da69b70..96caac4 100644 --- a/backend/Api/MoonfinController.cs +++ b/backend/Api/MoonfinController.cs @@ -534,31 +534,56 @@ private static string GetTag(ItemImageInfo info) /// private List GetLibraryItems(List? libraryIds, int limit) { - var query = new InternalItemsQuery + if (libraryIds is not { Count: > 0 }) { - IncludeItemTypes = [BaseItemKind.Movie, BaseItemKind.Series], - Limit = limit, - Recursive = true - }; + // No specific libraries selected — query across all libraries + var query = new InternalItemsQuery + { + IncludeItemTypes = [BaseItemKind.Movie, BaseItemKind.Series], + Limit = limit, + Recursive = true + }; + SetRandomOrder(query); + return _libraryManager.GetItemsResult(query).Items.ToList(); + } - // Set OrderBy = Random via reflection to avoid compile-time reference to - // SortOrder which moved assemblies between Jellyfin 10.10 and 10.11 - SetRandomOrder(query); + // Query each selected library via ParentId (matches user view IDs from getUserViews). + // TopParentIds won't work here — it filters on an internal DB column + // whose values differ from the user-facing view GUIDs. + var allItems = new List(); + var seenIds = new HashSet(); + var perLibraryLimit = Math.Max(1, limit / libraryIds.Count + 1); - if (libraryIds is { Count: > 0 }) + foreach (var libId in libraryIds) { - var parsedIds = libraryIds - .Select(id => Guid.TryParse(id, out var g) ? g : Guid.Empty) - .Where(g => g != Guid.Empty) - .ToArray(); + if (!Guid.TryParse(libId, out var parentGuid)) continue; - if (parsedIds.Length > 0) + var query = new InternalItemsQuery + { + IncludeItemTypes = [BaseItemKind.Movie, BaseItemKind.Series], + ParentId = parentGuid, + Limit = perLibraryLimit, + Recursive = true + }; + SetRandomOrder(query); + + foreach (var item in _libraryManager.GetItemsResult(query).Items) { - query.TopParentIds = parsedIds; + if (seenIds.Add(item.Id)) + { + allItems.Add(item); + } } } - return _libraryManager.GetItemsResult(query).Items.ToList(); + // Shuffle merged results for fair representation across libraries + for (var i = allItems.Count - 1; i > 0; i--) + { + var j = Random.Shared.Next(i + 1); + (allItems[i], allItems[j]) = (allItems[j], allItems[i]); + } + + return allItems.Take(limit).ToList(); } ///