feat(frontend): make library sidebar drilldown-aware

This commit is contained in:
2026-03-20 01:18:52 +01:00
parent 66eef2c82e
commit 33338ac100
3 changed files with 162 additions and 20 deletions

View File

@@ -86,6 +86,24 @@ struct PagedResponse<T: Serialize> {
total: u32,
}
#[derive(Debug, Serialize)]
struct ShowSummaryResponse {
series_name: String,
episode_count: u32,
season_count: u32,
#[serde(skip_serializing_if = "Option::is_none")]
thumbnail_url: Option<String>,
genres: Vec<String>,
}
#[derive(Debug, Serialize)]
struct SeasonSummaryResponse {
season_number: u32,
episode_count: u32,
#[serde(skip_serializing_if = "Option::is_none")]
thumbnail_url: Option<String>,
}
#[derive(Debug, Serialize)]
struct SyncLogResponse {
id: i64,
@@ -133,6 +151,20 @@ struct ItemsQuery {
limit: Option<u32>,
offset: Option<u32>,
provider: Option<String>,
season: Option<u32>,
}
#[derive(Debug, Default, Deserialize)]
struct ShowsQuery {
q: Option<String>,
provider: Option<String>,
#[serde(default)]
genres: Vec<String>,
}
#[derive(Debug, Deserialize)]
struct SeasonsQuery {
provider: Option<String>,
}
// ============================================================================
@@ -207,6 +239,7 @@ async fn search_items(
collection_id: params.collection,
genres: params.genres,
search_term: params.q,
season_number: params.season,
offset,
limit,
..Default::default()
@@ -306,6 +339,53 @@ async fn trigger_sync(
.into_response())
}
async fn list_shows(
State(state): State<AppState>,
CurrentUser(_user): CurrentUser,
Query(params): Query<ShowsQuery>,
) -> Result<Json<Vec<ShowSummaryResponse>>, ApiError> {
let shows = state
.library_repo
.list_shows(
params.provider.as_deref(),
params.q.as_deref(),
&params.genres,
)
.await?;
let resp = shows
.into_iter()
.map(|s| ShowSummaryResponse {
series_name: s.series_name,
episode_count: s.episode_count,
season_count: s.season_count,
thumbnail_url: s.thumbnail_url,
genres: s.genres,
})
.collect();
Ok(Json(resp))
}
async fn list_seasons(
State(state): State<AppState>,
CurrentUser(_user): CurrentUser,
Path(name): Path<String>,
Query(params): Query<SeasonsQuery>,
) -> Result<Json<Vec<SeasonSummaryResponse>>, ApiError> {
let seasons = state
.library_repo
.list_seasons(&name, params.provider.as_deref())
.await?;
let resp = seasons
.into_iter()
.map(|s| SeasonSummaryResponse {
season_number: s.season_number,
episode_count: s.episode_count,
thumbnail_url: s.thumbnail_url,
})
.collect();
Ok(Json(resp))
}
async fn get_settings(
State(state): State<AppState>,
AdminUser(_user): AdminUser,