refactor(api): literal-union the closed-value string fields (R7 S3a·1)

Video.status, Playlist.kind/source (+ PlaylistDetail), DownloadJob.job_kind
were bare `string`; type them as named unions verified against the backend
(VALID_STATES={new,watched,hidden}; kind user|watch_later; source local|
youtube; job_kind download|edit). VideoStatus then propagates through the
optimistic-override map, onState, and the VideoCard/VirtualFeed/PlayerModal
props — tsc now rejects a status typo (e.g. a stale "in_progress", which is a
derived filter, never a stored status) at every call site.
This commit is contained in:
2026-07-27 22:40:11 +02:00
parent ca0312d1a1
commit 5de6be8fde
5 changed files with 28 additions and 18 deletions
+2 -2
View File
@@ -29,7 +29,7 @@ import Avatar from "./Avatar";
import AddToPlaylist from "./AddToPlaylist";
import { modalCount } from "./Modal";
import DownloadButton from "./DownloadButton";
import { api, type Video } from "../lib/api";
import { api, type Video, type VideoStatus } from "../lib/api";
import {
channelYouTubeUrl,
formatDate,
@@ -118,7 +118,7 @@ export default function PlayerModal({
queue?: Video[];
startIndex?: number;
onClose: () => void;
onState: (id: string, status: string) => void;
onState: (id: string, status: VideoStatus) => void;
// Open the active video's channel page in-app (closes the player first). The small external
// icon next to the name keeps the open-on-YouTube behaviour.
}) {