feat(dialogues): support multi-cue subtitles
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled

This commit is contained in:
Tom Boullay
2026-05-30 04:00:25 +02:00
parent ce5dc8ada0
commit 02c1fb33d0
8 changed files with 192 additions and 53 deletions
+34 -5
View File
@@ -3,6 +3,7 @@ import type {
DialogueManifest,
DialogueVoice,
} from "@/types/dialogues/dialogues";
import { getDialogueCueIndices } from "@/types/dialogues/dialogues";
import type { SubtitleLanguage } from "@/types/settings/settings";
import { parseDialogueManifest } from "@/utils/dialogues/dialogueManifestValidation";
import { parseSrt } from "@/utils/subtitles/parseSrt";
@@ -17,6 +18,15 @@ export interface DialogueSubtitleCue {
subtitlePath: string;
}
/**
* Multiple subtitle cues for a single dialogue
*/
export interface DialogueSubtitleCues {
voice: DialogueVoice;
cues: SubtitleCue[];
subtitlePath: string;
}
export async function loadDialogueManifest(): Promise<DialogueManifest | null> {
const response = await fetch(DIALOGUE_MANIFEST_PATH);
@@ -39,21 +49,40 @@ export async function loadDialogueSubtitleCue(
dialogue: DialogueDefinition,
language: SubtitleLanguage,
): Promise<DialogueSubtitleCue | null> {
const result = await loadDialogueSubtitleCues(manifest, dialogue, language);
const firstCue = result?.cues[0];
if (!result || !firstCue) return null;
return {
voice: result.voice,
cue: firstCue,
subtitlePath: result.subtitlePath,
};
}
export async function loadDialogueSubtitleCues(
manifest: DialogueManifest,
dialogue: DialogueDefinition,
language: SubtitleLanguage,
): Promise<DialogueSubtitleCues | null> {
const voice = getDialogueVoice(manifest, dialogue.voice);
if (!voice) return null;
const subtitles = await loadVoiceSubtitleCues(voice, language);
if (!subtitles) return null;
const cue = subtitles.cues.find(
(item) => item.index === dialogue.subtitleCueIndex,
);
const cueIndices = getDialogueCueIndices(dialogue);
if (cueIndices.length === 0) return null;
if (!cue) return null;
const cues = cueIndices
.map((index) => subtitles.cues.find((item) => item.index === index))
.filter((cue): cue is SubtitleCue => cue !== undefined);
if (cues.length === 0) return null;
return {
voice,
cue,
cues,
subtitlePath: subtitles.path,
};
}