import { useEffect, useState } from 'react'; import { api } from '../api/client'; import { useAction } from '../lib/hooks'; import { useGateway } from '../lib/gateway'; import { useToast } from '../lib/toast'; import { Banner, Button, Card, Field, Loading, PageHead, Tag, Toggle } from '../components/ui'; export function PlaybackPage() { const { status, error, loading, reload } = useGateway(); const { wrap, show } = useToast(); const { busy, run } = useAction(); const [enabled, setEnabled] = useState(true); const [seconds, setSeconds] = useState('6.5'); const [touched, setTouched] = useState(false); useEffect(() => { if (touched || !status) return; setEnabled(status.playbackPolicy?.prerollEnabled !== false); setSeconds(String((status.playbackPolicy?.prerollDurationMs ?? 6500) / 1000)); }, [status, touched]); const save = () => run('save', async () => { const value = Number(seconds); // Checked here as well as on the server because the server clamps rather than // refusing, and a value silently corrected to 30 would look like the field not // having saved. if (!Number.isFinite(value) || value < 1 || value > 30) { show('The preroll duration must be between 1 and 30 seconds.', 'bad'); return; } await wrap( () => api.post('/admin/api/playback-policy', { prerollEnabled: enabled, prerollDurationMs: Math.round(value * 1000), }), 'Playback policy saved.', ); setTouched(false); await reload(); }); return ( <> {loading ? ( ) : ( on ยท {seconds}s : off} footer={ void save()}> Save playback policy } > { setEnabled(next); setTouched(true); }} /> { setSeconds(event.target.value); setTouched(true); }} /> )} > ); }