feat(web): render SxxEyy chips in attention queues

This commit is contained in:
Miguel Palhas
2026-08-23 19:45:33 +01:00
parent 7f7f26dbc7
commit 1d31ea7d1b
2 changed files with 37 additions and 16 deletions
+22 -14
View File
@@ -575,6 +575,18 @@ function rowTitle(title: string, year: number | null): HTMLElement {
return wrap;
}
function seasonTag(seasonNumber: number): string {
return `S${two(seasonNumber)}`;
}
function episodeTag(seasonNumber: number, episodeNumber: number): string {
return `${seasonTag(seasonNumber)}E${two(episodeNumber)}`;
}
function two(value: number): string {
return value < 10 ? `0${value}` : String(value);
}
function libraryRow(
movie: LibraryMovie,
roots: Root[],
@@ -1922,9 +1934,10 @@ function queuesMain(board: HTMLElement, releases: ReleasesView, views: HideableV
}
/**
* One TV lane entry: the series plus chips counting the episodes or
* seasons that put it there. The API carries internal row ids, not SxxEyy
* numbers, so counts are what can be named honestly. Inert — see above.
* One TV lane entry: the series plus one chip per episode or season that put
* it there, named `SxxEyy` so the operator knows what to act on (#140).
* Inert — the release deck and overrides arrive with the series detail view
* (issues 129 and 39).
*/
function seriesAttentionRow(entry: SeriesAttention): HTMLLIElement {
const item = document.createElement("li");
@@ -1932,21 +1945,16 @@ function seriesAttentionRow(entry: SeriesAttention): HTMLLIElement {
row.className = "row";
const chips = document.createElement("span");
chips.className = "row-chips";
if (entry.episodes.length > 0) {
const n = entry.episodes.length;
for (const episode of entry.episodes) {
const tag = episodeTag(episode.season_number, episode.episode_number);
chips.append(
chip(`${n} ${n === 1 ? "episode" : "episodes"}`, (span) => {
span.setAttribute("aria-label", `${n} ${n === 1 ? "episode" : "episodes"} waiting`);
chip(tag, (span) => {
span.setAttribute("aria-label", `${tag} waiting`);
}),
);
}
if (entry.seasons.length > 0) {
const n = entry.seasons.length;
chips.append(
chip(`${n} ${n === 1 ? "season" : "seasons"}`, (span) => {
span.setAttribute("aria-label", `${n} ${n === 1 ? "season" : "seasons"} waiting`);
}),
);
for (const season of entry.seasons) {
chips.append(chip(seasonTag(season.number)));
}
row.append(rowTitle(entry.title, entry.year), chips);
item.append(row);
+15 -2
View File
@@ -11,14 +11,27 @@ export interface AttentionMovie extends LibraryMovie {
last_searched_at: string | null;
}
/** An episode that put its series here, named for SxxEyy rendering (#140). */
export interface QueuedEpisode {
id: number;
season_number: number;
episode_number: number;
}
/** A season whose failed pack put its series here. */
export interface QueuedSeason {
id: number;
number: number;
}
/** A series in a TV attention queue, with what put it there (§9.5). */
export interface SeriesAttention {
series_id: number;
tmdb_id: number;
title: string;
year: number | null;
episodes: number[];
seasons: number[];
episodes: QueuedEpisode[];
seasons: QueuedSeason[];
}
export interface AttentionQueues {