diff --git a/src/utils/dialogues/loadDialogueManifest.ts b/src/utils/dialogues/loadDialogueManifest.ts index cdfe23d..2387a12 100644 --- a/src/utils/dialogues/loadDialogueManifest.ts +++ b/src/utils/dialogues/loadDialogueManifest.ts @@ -5,10 +5,18 @@ import type { } from "@/types/dialogues/dialogues"; import type { SubtitleLanguage } from "@/managers/stores/useSettingsStore"; import { parseDialogueManifest } from "@/utils/dialogues/dialogueManifestValidation"; +import { parseSrt } from "@/utils/subtitles/parseSrt"; +import type { SubtitleCue } from "@/utils/subtitles/parseSrt"; const DIALOGUE_MANIFEST_PATH = "/sounds/dialogue/dialogues.json"; const DEFAULT_SUBTITLE_LANGUAGE: SubtitleLanguage = "fr"; +export interface DialogueSubtitleCue { + voice: DialogueVoice; + cue: SubtitleCue; + subtitlePath: string; +} + export async function loadDialogueManifest(): Promise { const response = await fetch(DIALOGUE_MANIFEST_PATH); @@ -37,6 +45,65 @@ export function getDialogueVoice( return manifest.voices.find((voice) => voice.id === voiceId) ?? null; } +export async function loadDialogueSubtitleCue( + manifest: DialogueManifest, + dialogue: DialogueDefinition, + language: SubtitleLanguage, +): Promise { + 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, + ); + + if (!cue) return null; + + return { + voice, + cue, + subtitlePath: subtitles.path, + }; +} + +export async function loadVoiceSubtitleCues( + voice: DialogueVoice, + language: SubtitleLanguage, +): Promise<{ path: string; cues: SubtitleCue[] } | null> { + const paths = getVoiceSubtitlePaths(voice, language); + + for (const path of paths) { + const srtContent = await loadSrtContent(path); + if (srtContent !== null) { + return { path, cues: parseSrt(srtContent) }; + } + } + + return null; +} + +async function loadSrtContent(path: string): Promise { + const response = await fetch(path); + + if (!response.ok) { + return null; + } + + return response.text(); +} + +function getVoiceSubtitlePaths( + voice: DialogueVoice, + language: SubtitleLanguage, +): string[] { + return [voice.subtitles[language], voice.subtitles[DEFAULT_SUBTITLE_LANGUAGE]] + .filter((path): path is string => Boolean(path)) + .filter((path, index, paths) => paths.indexOf(path) === index); +} + function getVoiceSubtitlePath( voice: DialogueVoice, language: SubtitleLanguage,