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

@@ -12,16 +12,18 @@ import { WEEKDAYS, WEEKDAY_LABELS } from "@/lib/types";
interface Props {
selectedItems: LibraryItemFull[];
selectedShows?: ShowSummary[];
}
export function ScheduleFromLibraryDialog({ selectedItems }: Props) {
export function ScheduleFromLibraryDialog({ selectedItems, selectedShows }: Props) {
const [open, setOpen] = useState(false);
const [channelId, setChannelId] = useState("");
const [selectedDays, setSelectedDays] = useState<Set<Weekday>>(new Set());
const [startTime, setStartTime] = useState("20:00");
const [durationMins, setDurationMins] = useState(() =>
selectedItems.length === 1 ? Math.ceil(selectedItems[0].duration_secs / 60) : 60
);
const [durationMins, setDurationMins] = useState(() => {
if (selectedItems.length === 1) return Math.ceil(selectedItems[0].duration_secs / 60);
return 60;
});
const [strategy, setStrategy] = useState<"sequential" | "random" | "best_fit">("sequential");
const { data: channels } = useChannels();
@@ -47,32 +49,54 @@ export function ScheduleFromLibraryDialog({ selectedItems }: Props) {
if (!selectedChannel || selectedDays.size === 0) return;
const startTimeFull = startTime.length === 5 ? `${startTime}:00` : startTime;
const newBlock: ProgrammingBlock = allSameSeries
const hasShows = selectedShows && selectedShows.length > 0;
const newBlock: ProgrammingBlock = hasShows
? {
id: globalThis.crypto.randomUUID(),
name: `${selectedItems[0].series_name ?? "Series"}${startTime}`,
name: selectedShows!.length === 1
? `${selectedShows![0].series_name}${startTime}`
: `${selectedShows!.length} shows — ${startTime}`,
start_time: startTimeFull,
duration_mins: durationMins,
content: {
type: "algorithmic",
filter: {
content_type: "episode",
series_names: [selectedItems[0].series_name!],
series_names: selectedShows!.map(s => s.series_name),
genres: [],
tags: [],
collections: [],
},
strategy,
provider_id: selectedItems[0].id.split("::")[0],
},
}
: {
id: globalThis.crypto.randomUUID(),
name: `${selectedItems.length} items — ${startTime}`,
start_time: startTimeFull,
duration_mins: durationMins,
content: { type: "manual", items: selectedItems.map(i => i.id) },
};
: allSameSeries
? {
id: globalThis.crypto.randomUUID(),
name: `${selectedItems[0].series_name ?? "Series"}${startTime}`,
start_time: startTimeFull,
duration_mins: durationMins,
content: {
type: "algorithmic",
filter: {
content_type: "episode",
series_names: [selectedItems[0].series_name!],
genres: [],
tags: [],
collections: [],
},
strategy,
provider_id: selectedItems[0].id.split("::")[0],
},
}
: {
id: globalThis.crypto.randomUUID(),
name: `${selectedItems.length} items — ${startTime}`,
start_time: startTimeFull,
duration_mins: durationMins,
content: { type: "manual", items: selectedItems.map(i => i.id) },
};
const updatedDayBlocks = { ...selectedChannel.schedule_config.day_blocks };
for (const day of selectedDays) {