147 lines
5.1 KiB
TypeScript
147 lines
5.1 KiB
TypeScript
/* eslint-disable lines-around-comment */
|
|
import { Theme } from '@mui/material';
|
|
import i18next from 'i18next';
|
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
import { WithTranslation } from 'react-i18next';
|
|
import { useDispatch } from 'react-redux';
|
|
import { makeStyles } from 'tss-react/mui';
|
|
|
|
import { IReduxState } from '../../app/types';
|
|
// @ts-ignore
|
|
import { TRANSLATION_LANGUAGES, TRANSLATION_LANGUAGES_HEAD } from '../../base/i18n';
|
|
import { translate, translateToHTML } from '../../base/i18n/functions';
|
|
import { connect } from '../../base/redux/functions';
|
|
import Dialog from '../../base/ui/components/web/Dialog';
|
|
// @ts-ignore
|
|
import { openSettingsDialog } from '../../settings/actions';
|
|
import { SETTINGS_TABS } from '../../settings/constants';
|
|
// @ts-ignore
|
|
import { setRequestingSubtitles, toggleLanguageSelectorDialog, updateTranslationLanguage } from '../actions';
|
|
|
|
import LanguageList from './LanguageList';
|
|
|
|
|
|
interface ILanguageSelectorDialogProps extends WithTranslation {
|
|
_language: string;
|
|
_translationLanguages: Array<string>;
|
|
_translationLanguagesHead: Array<string>;
|
|
}
|
|
|
|
const useStyles = makeStyles()((theme: Theme) => {
|
|
return {
|
|
paragraphWrapper: {
|
|
fontSize: 14,
|
|
margin: '10px 0px',
|
|
color: theme.palette.text01
|
|
},
|
|
spanWrapper: {
|
|
fontWeight: 700,
|
|
cursor: 'pointer',
|
|
color: theme.palette.link01,
|
|
'&:hover': {
|
|
backgroundColor: theme.palette.ui04,
|
|
color: theme.palette.link01Hover
|
|
}
|
|
}
|
|
};
|
|
});
|
|
|
|
/**
|
|
* Component that renders the subtitle language selector dialog.
|
|
*
|
|
* @returns {React$Element<any>}
|
|
*/
|
|
const LanguageSelectorDialog = ({
|
|
t,
|
|
_language,
|
|
_translationLanguages,
|
|
_translationLanguagesHead
|
|
}: ILanguageSelectorDialogProps) => {
|
|
const { classes: styles } = useStyles();
|
|
const dispatch = useDispatch();
|
|
const off = 'transcribing.subtitlesOff';
|
|
const [ language, setLanguage ] = useState(off);
|
|
|
|
const languagesHead = _translationLanguagesHead.map((lang: string) => `translation-languages:${lang}`);
|
|
// The off and the head languages are always on the top of the list. But once you are selecting
|
|
// a language from the translationLanguages, that language is moved under the fixedItems list,
|
|
// until a new languages is selected. FixedItems keep their positions.
|
|
const fixedItems = [ off, ...languagesHead ];
|
|
const languages = _translationLanguages
|
|
.map((lang: string) => `translation-languages:${lang}`)
|
|
.filter((lang: string) => !(lang === language || languagesHead.includes(lang)));
|
|
|
|
const listItems = (fixedItems.includes(language)
|
|
? [ ...fixedItems, ...languages ]
|
|
: [ ...fixedItems, language, ...languages ])
|
|
.map((lang, index) => {
|
|
return {
|
|
id: lang + index,
|
|
lang,
|
|
selected: lang === language
|
|
};
|
|
});
|
|
|
|
useEffect(() => {
|
|
_language ? setLanguage(_language) : setLanguage(off);
|
|
}, []);
|
|
|
|
const onLanguageSelected = useCallback((e: string) => {
|
|
setLanguage(e);
|
|
dispatch(updateTranslationLanguage(e));
|
|
dispatch(setRequestingSubtitles(e !== off));
|
|
dispatch(toggleLanguageSelectorDialog());
|
|
}, [ _language ]);
|
|
|
|
const onSourceLanguageClick = useCallback(() => {
|
|
dispatch(openSettingsDialog(SETTINGS_TABS.MORE, false));
|
|
}, []);
|
|
|
|
return (
|
|
<Dialog
|
|
cancel = {{ hidden: true }}
|
|
ok = {{ hidden: true }}
|
|
titleKey = 'transcribing.subtitles'>
|
|
<p className = { styles.paragraphWrapper } >
|
|
{
|
|
translateToHTML(t, 'transcribing.sourceLanguageDesc', {
|
|
'sourceLanguage': t(`languages:${i18next.language}`).toLowerCase()
|
|
})
|
|
}<span
|
|
className = { styles.spanWrapper }
|
|
onClick = { onSourceLanguageClick }>{t('transcribing.sourceLanguageHere')}.</span>
|
|
</p>
|
|
<LanguageList
|
|
items = { listItems }
|
|
onLanguageSelected = { onLanguageSelected }
|
|
selectedLanguage = { language } />
|
|
</Dialog>
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Maps (parts of) the Redux state to the associated props for the
|
|
* {@code LanguageSelectorDialog} component.
|
|
*
|
|
* @param {Object} state - The Redux state.
|
|
* @private
|
|
* @returns {Props}
|
|
*/
|
|
function mapStateToProps(state: IReduxState) {
|
|
const { conference } = state['features/base/conference'];
|
|
const { _language } = state['features/subtitles'];
|
|
const { transcription } = state['features/base/config'];
|
|
|
|
const languages = transcription?.translationLanguages ?? TRANSLATION_LANGUAGES;
|
|
const languagesHead = transcription?.translationLanguagesHead ?? TRANSLATION_LANGUAGES_HEAD;
|
|
|
|
return {
|
|
_conference: conference,
|
|
_language,
|
|
_translationLanguages: languages,
|
|
_translationLanguagesHead: languagesHead
|
|
};
|
|
}
|
|
|
|
export default translate(connect(mapStateToProps)(LanguageSelectorDialog));
|