feat: enhance schedule slot handling with episode details and duration calculation

This commit is contained in:
2026-03-11 22:30:05 +01:00
parent 0f1b9c11fe
commit ee64fc0b8a
3 changed files with 101 additions and 24 deletions

View File

@@ -47,13 +47,41 @@ export function toScheduleSlots(
slots: ScheduledSlotResponse[],
currentSlotId?: string,
): ScheduleSlot[] {
return slots.map((slot) => ({
id: slot.id,
title: slot.item.title,
startTime: fmtTime(slot.start_at),
endTime: fmtTime(slot.end_at),
isCurrent: slot.id === currentSlotId,
}));
return slots.map((slot) => {
const item = slot.item;
const isEpisode = item.content_type === "episode";
// Headline: series name for episodes (fall back to episode title), film title otherwise
const title = isEpisode && item.series_name ? item.series_name : item.title;
// Subtitle: episode identifier + title, or year for films
let subtitle: string | null = null;
if (isEpisode) {
const epParts: string[] = [];
if (item.season_number != null) epParts.push(`S${item.season_number}`);
if (item.episode_number != null) epParts.push(`E${item.episode_number}`);
const epLabel = epParts.join(" · ");
subtitle = item.series_name
? [epLabel, item.title].filter(Boolean).join(" · ")
: epLabel || null;
} else if (item.year) {
subtitle = String(item.year);
}
const durationMins = Math.round(
(new Date(slot.end_at).getTime() - new Date(slot.start_at).getTime()) / 60_000,
);
return {
id: slot.id,
title,
subtitle,
durationMins,
startTime: fmtTime(slot.start_at),
endTime: fmtTime(slot.end_at),
isCurrent: slot.id === currentSlotId,
};
});
}
/**