45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
import type { ScreenMode, ScreenPlan } from '../src/types/screen.js'
|
|
import { integer, object, text } from './remote-state.js'
|
|
|
|
const modes = [
|
|
'UNSPECIFIED',
|
|
'COVER',
|
|
'INTRO',
|
|
'INTRO_DONE',
|
|
'CONCLUSION',
|
|
'CONCLUSION_DONE',
|
|
'RESULTS',
|
|
'TIMER',
|
|
'TEXT',
|
|
]
|
|
|
|
export function parsePlan(value: unknown): ScreenPlan {
|
|
const plan = value == null ? {} : object(value)
|
|
const list = plan.steps ?? []
|
|
if (!Array.isArray(list)) throw new Error('Некорректные шаги плана')
|
|
const steps = list.map((value) => {
|
|
const step = object(value)
|
|
const mode = integer(
|
|
typeof step.mode === 'string' && step.mode.startsWith('SCREEN_MODE_')
|
|
? modes.indexOf(step.mode.slice(12))
|
|
: step.mode,
|
|
1,
|
|
8,
|
|
) as ScreenMode
|
|
const content = text(step.text ?? '').trim()
|
|
const label = text(step.timerLabel ?? '').trim()
|
|
const seconds = integer(step.timerDurationSeconds ?? 0, 0, 86400)
|
|
if (mode === 8 && (!content || Buffer.byteLength(content) > 10000))
|
|
throw new Error('Текст шага должен содержать от 1 до 10000 байт')
|
|
if (mode === 7 && (!seconds || Buffer.byteLength(label) > 200))
|
|
throw new Error('Укажите таймер от 1 до 86400 секунд и подпись до 200 байт')
|
|
return {
|
|
mode,
|
|
text: content,
|
|
timerLabel: mode === 7 ? label || 'Перерыв' : label,
|
|
timerDurationSeconds: seconds,
|
|
}
|
|
})
|
|
return { steps, currentStep: integer(plan.currentStep ?? 0, 0, Math.max(0, steps.length - 1)) }
|
|
}
|