diff --git a/k-tv-backend/infra/src/jellyfin.rs b/k-tv-backend/infra/src/jellyfin.rs index e149719..07bfd6d 100644 --- a/k-tv-backend/infra/src/jellyfin.rs +++ b/k-tv-backend/infra/src/jellyfin.rs @@ -91,17 +91,19 @@ impl JellyfinMediaProvider { params.push(("MaxRunTimeTicks", (max as i64 * TICKS_PER_SEC).to_string())); } - // Treat the first collection entry as a Jellyfin ParentId (library/folder) - if let Some(parent_id) = filter.collections.first() { - params.push(("ParentId", parent_id.clone())); - } - if let Some(name) = series_name { + // Series-level targeting: skip ParentId so the show is found regardless + // of which library it lives in. SeriesName is already precise enough. params.push(("SeriesName", name.to_string())); // Return episodes in chronological order when a specific series is // requested — season first, then episode within the season. params.push(("SortBy", "ParentIndexNumber,IndexNumber".into())); params.push(("SortOrder", "Ascending".into())); + } else { + // No series filter — scope to the collection (library) if one is set. + if let Some(parent_id) = filter.collections.first() { + params.push(("ParentId", parent_id.clone())); + } } if let Some(q) = &filter.search_term { @@ -166,12 +168,27 @@ impl IMediaProvider for JellyfinMediaProvider { self.fetch_items_for_series(filter, series).await } _ => { - let mut all = Vec::new(); + // Fetch each series independently, then interleave round-robin. + // Round-robin ensures every show gets fair representation when a + // downstream limit is applied (preview, block fill) even if one + // series has far more episodes than another. + let mut per_series: Vec> = Vec::new(); for series_name in &filter.series_names { let items = self .fetch_items_for_series(filter, Some(series_name.as_str())) .await?; - all.extend(items); + if !items.is_empty() { + per_series.push(items); + } + } + let max_len = per_series.iter().map(|s| s.len()).max().unwrap_or(0); + let mut all = Vec::with_capacity(per_series.iter().map(|s| s.len()).sum()); + for i in 0..max_len { + for s in &per_series { + if let Some(item) = s.get(i) { + all.push(item.clone()); + } + } } Ok(all) }