diff --git a/src/core/jellyfin.rs b/src/core/jellyfin.rs index 09e865c..d302b4c 100644 --- a/src/core/jellyfin.rs +++ b/src/core/jellyfin.rs @@ -173,7 +173,7 @@ impl JellyfinClient { ("Recursive", recursive), ("StartIndex", &start_index.to_string()), ("Limit", &limit.to_string()), - ("Fields", "PrimaryImageAspectRatio,SortName,ProductionYear,IndexNumber,ParentIndexNumber,RunTimeTicks,Genres,Studios,Overview,SeriesName,Album,AlbumArtist,Artists,UserData"), + ("Fields", "PrimaryImageAspectRatio,SortName,ProductionYear,IndexNumber,ParentIndexNumber,RunTimeTicks,Genres,Studios,Overview,SeriesName,Album,AlbumArtist,Artists,UserData,ChildCount,RecursiveItemCount"), ("SortBy", sort_by), ("SortOrder", "Ascending"), ]); @@ -250,7 +250,7 @@ pub fn playlist_items( ("UserId", user_id), ("StartIndex", &start_index.to_string()), ("Limit", &limit.to_string()), - ("Fields", "PrimaryImageAspectRatio,SortName,ProductionYear,IndexNumber,ParentIndexNumber,RunTimeTicks,Genres,Studios,Overview,SeriesName,Album,AlbumArtist,Artists,UserData"), + ("Fields", "PrimaryImageAspectRatio,SortName,ProductionYear,IndexNumber,ParentIndexNumber,RunTimeTicks,Genres,Studios,Overview,SeriesName,Album,AlbumArtist,Artists,UserData,ChildCount,RecursiveItemCount"), ]) .send() .map_err(|e| format!("request failed: {e}"))?; @@ -383,6 +383,11 @@ pub struct JfItem { #[serde(rename = "ProductionYear")] pub production_year: Option, + #[serde(rename = "ChildCount")] + pub child_count: Option, + #[serde(rename = "RecursiveItemCount")] + pub recursive_item_count: Option, + #[serde(rename = "IndexNumber")] pub index_number: Option, #[serde(rename = "ParentIndexNumber")] diff --git a/src/main.rs b/src/main.rs index b6ee56e..54f4c72 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1186,7 +1186,7 @@ fn format_details(it: &core::jellyfin::JfItem) -> String { join_studios(&it.studios), ); - if is_in_progress(it) { + if is_in_progress_fast(it) { let pos = playback_position_ticks(it).unwrap_or(0); let pos_secs = (pos / 10_000_000) as f64; header.push_str(&format!( @@ -1217,7 +1217,7 @@ fn format_details(it: &core::jellyfin::JfItem) -> String { year_str(it.production_year), ); - if is_in_progress(it) { + if is_in_progress_fast(it) { let pos = playback_position_ticks(it).unwrap_or(0); let pos_secs = (pos / 10_000_000) as f64; header.push_str(&format!( @@ -2385,26 +2385,55 @@ fn playback_position_ticks(it: &core::jellyfin::JfItem) -> Option { } fn is_in_progress_fast(it: &core::jellyfin::JfItem) -> bool { + // Already fully played? Never in-progress. if is_played(it) { return false; } match it.item_type.as_deref() { - Some("Movie" | "Episode") => playback_position_ticks(it).is_some(), + // Movies / Episodes → resume ticks mean in-progress + Some("Movie" | "Episode") => { + playback_position_ticks(it).is_some() + } - // THIS is the season fix (jtui-style) - Some("Season") => it.user_data - .as_ref() - .and_then(|u| u.played_percentage) - .is_some_and(|p| p > 0.1 && p < 99.9), + // Seasons → jtui-style fast logic + Some("Season") => { + // 1) Prefer server percentage if present + if let Some(p) = it.user_data + .as_ref() + .and_then(|u| u.played_percentage) + { + if p > 0.1 && p < 99.9 { + return true; + } + } - // Series: you said “complete or nothing” + // 2) Fallback to count-based detection: + // 0 < UnplayedItemCount < ChildCount + let total = it.child_count + .and_then(|v| if v > 0 { Some(v as u64) } else { None }); + + let unplayed = it.user_data + .as_ref() + .and_then(|u| u.unplayed_item_count) + .and_then(|v| if v >= 0 { Some(v as u64) } else { None }); + + match (total, unplayed) { + (Some(t), Some(u)) if t > 0 && u > 0 && u < t => true, + _ => false, + } + } + + // Series → complete or nothing (as you requested) Some("Series") => false, _ => false, } } + + + fn emoji_prefix_for(_app: &App, it: &core::jellyfin::JfItem) -> &'static str { if is_music_item(it) { return ""; } @@ -2413,7 +2442,7 @@ fn emoji_prefix_for(_app: &App, it: &core::jellyfin::JfItem) -> &'static str { "" } - +/* fn is_in_progress(it: &core::jellyfin::JfItem) -> bool { if is_played(it) { return false; @@ -2435,6 +2464,7 @@ fn is_in_progress(it: &core::jellyfin::JfItem) -> bool { _ => false, } } +*/ // --- transcoding + resume URL builder (Approach B) --- fn clamp_mbps_to_bps(mbps: u32) -> u32 {