diff --git a/frontend/src/components/AudioLanguageSelector.tsx b/frontend/src/components/AudioLanguageSelector.tsx new file mode 100644 index 00000000..d009f5ea --- /dev/null +++ b/frontend/src/components/AudioLanguageSelector.tsx @@ -0,0 +1,107 @@ +import { useEffect, useMemo, useState } from 'react'; + +type AudioLanguageSelectorProps = { + name: string; + value: string | null; + oldValue: string | null; + updateCallback: (name: string, value: string | boolean | number | null) => void; +}; + +const COMMON_AUDIO_LANGUAGES = [ + { code: 'en', label: 'English' }, + { code: 'es', label: 'Spanish' }, + { code: 'fr', label: 'French' }, + { code: 'de', label: 'German' }, + { code: 'it', label: 'Italian' }, + { code: 'pt', label: 'Portuguese' }, + { code: 'ja', label: 'Japanese' }, + { code: 'ko', label: 'Korean' }, + { code: 'zh', label: 'Chinese' }, + { code: 'ru', label: 'Russian' }, + { code: 'ar', label: 'Arabic' }, + { code: 'hi', label: 'Hindi' }, +]; + +const normalizeCsv = (value: string | null): string[] => { + if (!value) return []; + + return value + .split(',') + .map(item => item.trim()) + .filter(Boolean); +}; + +const AudioLanguageSelector = ({ + name, + value, + oldValue, + updateCallback, +}: AudioLanguageSelectorProps) => { + const commonCodes = useMemo(() => new Set(COMMON_AUDIO_LANGUAGES.map(item => item.code)), []); + const [selectedCommon, setSelectedCommon] = useState([]); + const [customLanguages, setCustomLanguages] = useState(''); + + useEffect(() => { + const parsed = normalizeCsv(value); + const known = parsed.filter(item => commonCodes.has(item)); + const custom = parsed.filter(item => !commonCodes.has(item)); + + setSelectedCommon(known); + setCustomLanguages(custom.join(', ')); + }, [value, commonCodes]); + + const mergedValue = useMemo(() => { + const custom = normalizeCsv(customLanguages); + const deduped = [...new Set([...selectedCommon, ...custom])]; + return deduped.length ? deduped.join(',') : null; + }, [selectedCommon, customLanguages]); + + return ( +
+

Select common languages and/or add custom tags. No selection will download all languages.

+ + + setCustomLanguages(event.target.value)} + /> + +
+ {mergedValue !== oldValue && ( + <> + + + + )} + {oldValue !== null && } +
+
+ ); +}; + +export default AudioLanguageSelector; \ No newline at end of file