Podcast workflow: per-lane season number set on the page, only that season shown; v2.16.1
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
900a3efee3
commit
3a69e03e60
4 files changed
+71
-19
No files matched your search
@@ -14,9 +14,9 @@ const STEPS = ['readScript', 'record', 'edit', 'upload']
|
||||
async function load() {
|
||||
try {
|
||||
const data = JSON.parse(await readFile(WORKFLOW_FILE, 'utf8'))
|
||||
return { planned: Array.isArray(data.planned) ? data.planned : [], items: data.items ?? {}, laneOverrides: data.laneOverrides ?? {} }
|
||||
return { planned: Array.isArray(data.planned) ? data.planned : [], items: data.items ?? {}, laneOverrides: data.laneOverrides ?? {}, laneSeasons: data.laneSeasons ?? {} }
|
||||
} catch {
|
||||
return { planned: [], items: {}, laneOverrides: {} }
|
||||
return { planned: [], items: {}, laneOverrides: {}, laneSeasons: {} }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,11 +29,19 @@ function emptyState() {
|
||||
}
|
||||
}
|
||||
|
||||
function laneFor(season) {
|
||||
// A lane's season comes from the workflow page's own setting, falling back to Current Series.
|
||||
function laneSeasonOf(lane, wf) {
|
||||
const saved = wf.laneSeasons?.[lane]
|
||||
if (/^\d+$/.test(String(saved ?? ''))) return String(saved)
|
||||
const content = state.cachedSiteContent ?? {}
|
||||
const fallback = lane === 'A' ? content.seriesSeason : content.secondSeries?.season
|
||||
return fallback ? String(fallback) : ''
|
||||
}
|
||||
|
||||
function laneFor(season, wf) {
|
||||
const s = String(season ?? '')
|
||||
if (s && s === String(content.seriesSeason ?? '')) return 'A'
|
||||
if (s && s === String(content.secondSeries?.season ?? '')) return 'B'
|
||||
if (s && s === laneSeasonOf('A', wf)) return 'A'
|
||||
if (s && s === laneSeasonOf('B', wf)) return 'B'
|
||||
return 'other'
|
||||
}
|
||||
|
||||
@@ -96,13 +104,13 @@ export function register(app) {
|
||||
|
||||
const items = [...byKey.values()].map(e => ({
|
||||
...e,
|
||||
lane: wf.laneOverrides[e.key] ?? e.plannedLane ?? laneFor(e.season),
|
||||
lane: wf.laneOverrides[e.key] ?? e.plannedLane ?? laneFor(e.season, wf),
|
||||
laneOverride: wf.laneOverrides[e.key] ?? '',
|
||||
released: Boolean(e.released),
|
||||
state: { ...emptyState(), ...(wf.items[e.key] ?? {}) },
|
||||
}))
|
||||
items.sort((a, b) => (Number(a.season) || 0) - (Number(b.season) || 0) || (Number(a.episodeNumber) || 0) - (Number(b.episodeNumber) || 0))
|
||||
res.json({ items, feedOk })
|
||||
res.json({ items, feedOk, laneSeasons: { A: laneSeasonOf('A', wf), B: laneSeasonOf('B', wf) } })
|
||||
})
|
||||
|
||||
app.post('/api/admin/podcast-workflow/planned', requireAdminAuth, async (req, res) => {
|
||||
@@ -133,6 +141,21 @@ export function register(app) {
|
||||
res.json({ ok: true })
|
||||
})
|
||||
|
||||
// Set the season number each lane looks for ('' goes back to the Current Series value).
|
||||
app.put('/api/admin/podcast-workflow-lane-seasons', requireAdminAuth, async (req, res) => {
|
||||
const wf = await load()
|
||||
for (const lane of ['A', 'B']) {
|
||||
const v = req.body?.[lane]
|
||||
if (v === undefined) continue
|
||||
const str = String(v).trim()
|
||||
if (str === '') delete wf.laneSeasons[lane]
|
||||
else if (/^\d+$/.test(str)) wf.laneSeasons[lane] = str
|
||||
else { res.status(400).json({ message: 'Season must be a whole number.' }); return }
|
||||
}
|
||||
await save(wf)
|
||||
res.json({ ok: true })
|
||||
})
|
||||
|
||||
// Assign an episode to a lane by hand ('auto' clears the override and goes back to season matching).
|
||||
app.put('/api/admin/podcast-workflow/:key/lane', requireAdminAuth, async (req, res) => {
|
||||
const lane = req.body?.lane
|
||||
|
||||
Reference in new issue
Block a user