feat(schedule): add loop and recycle policy options to programming blocks

This commit is contained in:
2026-03-13 01:53:02 +01:00
parent eeb4e2cb41
commit 6a4eb099cb
5 changed files with 111 additions and 22 deletions

View File

@@ -58,6 +58,8 @@ const blockSchema = z.object({
items: z.array(z.string()),
}),
]),
loop_on_finish: z.boolean().optional(),
ignore_recycle_policy: z.boolean().optional(),
});
const channelFormSchema = z.object({
@@ -211,6 +213,8 @@ function defaultBlock(startMins = 20 * 60, durationMins = 60): ProgrammingBlock
start_time: minsToTime(startMins),
duration_mins: durationMins,
content: { type: "algorithmic", filter: defaultFilter(), strategy: "random" },
loop_on_finish: true,
ignore_recycle_policy: false,
};
}
@@ -534,13 +538,47 @@ function BlockEditor({ block, index, isSelected, color, errors, onChange, onRemo
</div>
{content.type === "algorithmic" && (
<AlgorithmicFilterEditor
content={content}
pfx={pfx}
errors={errors}
setFilter={setFilter}
setStrategy={setStrategy}
/>
<>
<AlgorithmicFilterEditor
content={content}
pfx={pfx}
errors={errors}
setFilter={setFilter}
setStrategy={setStrategy}
/>
{content.strategy === "sequential" && (
<div className="space-y-2 rounded-md border border-zinc-700/50 bg-zinc-800 p-3">
<p className="text-[11px] font-medium uppercase tracking-wider text-zinc-500">
Sequential options
</p>
<label className="flex items-center gap-2 cursor-pointer">
<input
type="checkbox"
checked={block.loop_on_finish ?? true}
onChange={(e) => onChange({ ...block, loop_on_finish: e.target.checked })}
className="accent-zinc-400"
/>
<span className="text-sm text-zinc-300">Loop series</span>
<span className="text-[11px] text-zinc-600">
Restart from episode 1 after the final episode
</span>
</label>
<label className="flex items-center gap-2 cursor-pointer">
<input
type="checkbox"
checked={block.ignore_recycle_policy ?? false}
onChange={(e) => onChange({ ...block, ignore_recycle_policy: e.target.checked })}
className="accent-zinc-400"
/>
<span className="text-sm text-zinc-300">Independent scheduling</span>
<span className="text-[11px] text-zinc-600">
Play episodes in order even if they aired in another block today
</span>
</label>
</div>
)}
</>
)}
{content.type === "manual" && (