Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

LanguageSelectorDialog.web.tsx 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /* eslint-disable lines-around-comment */
  2. import i18next from 'i18next';
  3. import React, { useCallback, useEffect, useState } from 'react';
  4. import { WithTranslation } from 'react-i18next';
  5. import { useDispatch } from 'react-redux';
  6. import { makeStyles } from 'tss-react/mui';
  7. import { IReduxState } from '../../app/types';
  8. // @ts-ignore
  9. import { TRANSLATION_LANGUAGES, TRANSLATION_LANGUAGES_HEAD } from '../../base/i18n';
  10. import { translate, translateToHTML } from '../../base/i18n/functions';
  11. import { connect } from '../../base/redux/functions';
  12. import Dialog from '../../base/ui/components/web/Dialog';
  13. // @ts-ignore
  14. import { openSettingsDialog } from '../../settings/actions';
  15. import { SETTINGS_TABS } from '../../settings/constants';
  16. // @ts-ignore
  17. import { setRequestingSubtitles, toggleLanguageSelectorDialog, updateTranslationLanguage } from '../actions';
  18. import LanguageList from './LanguageList.web';
  19. interface ILanguageSelectorDialogProps extends WithTranslation {
  20. _language: string;
  21. _translationLanguages: Array<string>;
  22. _translationLanguagesHead: Array<string>;
  23. }
  24. const useStyles = makeStyles()(theme => {
  25. return {
  26. paragraphWrapper: {
  27. fontSize: 14,
  28. margin: '10px 0px',
  29. color: theme.palette.text01
  30. },
  31. spanWrapper: {
  32. fontWeight: 700,
  33. cursor: 'pointer',
  34. color: theme.palette.link01,
  35. '&:hover': {
  36. backgroundColor: theme.palette.ui04,
  37. color: theme.palette.link01Hover
  38. }
  39. }
  40. };
  41. });
  42. /**
  43. * Component that renders the subtitle language selector dialog.
  44. *
  45. * @returns {React$Element<any>}
  46. */
  47. const LanguageSelectorDialog = ({
  48. t,
  49. _language,
  50. _translationLanguages,
  51. _translationLanguagesHead
  52. }: ILanguageSelectorDialogProps) => {
  53. const { classes: styles } = useStyles();
  54. const dispatch = useDispatch();
  55. const off = 'transcribing.subtitlesOff';
  56. const [ language, setLanguage ] = useState(off);
  57. const languagesHead = _translationLanguagesHead.map((lang: string) => `translation-languages:${lang}`);
  58. // The off and the head languages are always on the top of the list. But once you are selecting
  59. // a language from the translationLanguages, that language is moved under the fixedItems list,
  60. // until a new languages is selected. FixedItems keep their positions.
  61. const fixedItems = [ off, ...languagesHead ];
  62. const languages = _translationLanguages
  63. .map((lang: string) => `translation-languages:${lang}`)
  64. .filter((lang: string) => !(lang === language || languagesHead.includes(lang)));
  65. const listItems = (fixedItems.includes(language)
  66. ? [ ...fixedItems, ...languages ]
  67. : [ ...fixedItems, language, ...languages ])
  68. .map((lang, index) => {
  69. return {
  70. id: lang + index,
  71. lang,
  72. selected: lang === language
  73. };
  74. });
  75. useEffect(() => {
  76. _language ? setLanguage(_language) : setLanguage(off);
  77. }, []);
  78. const onLanguageSelected = useCallback((e: string) => {
  79. setLanguage(e);
  80. dispatch(updateTranslationLanguage(e));
  81. dispatch(setRequestingSubtitles(e !== off));
  82. dispatch(toggleLanguageSelectorDialog());
  83. }, [ _language ]);
  84. const onSourceLanguageClick = useCallback(() => {
  85. dispatch(openSettingsDialog(SETTINGS_TABS.MORE, false));
  86. }, []);
  87. return (
  88. <Dialog
  89. cancel = {{ hidden: true }}
  90. ok = {{ hidden: true }}
  91. titleKey = 'transcribing.subtitles'>
  92. <p className = { styles.paragraphWrapper } >
  93. {
  94. translateToHTML(t, 'transcribing.sourceLanguageDesc', {
  95. 'sourceLanguage': t(`languages:${i18next.language}`).toLowerCase()
  96. })
  97. }<span
  98. className = { styles.spanWrapper }
  99. onClick = { onSourceLanguageClick }>{t('transcribing.sourceLanguageHere')}.</span>
  100. </p>
  101. <LanguageList
  102. items = { listItems }
  103. onLanguageSelected = { onLanguageSelected }
  104. selectedLanguage = { language } />
  105. </Dialog>
  106. );
  107. };
  108. /**
  109. * Maps (parts of) the Redux state to the associated props for the
  110. * {@code LanguageSelectorDialog} component.
  111. *
  112. * @param {Object} state - The Redux state.
  113. * @private
  114. * @returns {Props}
  115. */
  116. function mapStateToProps(state: IReduxState) {
  117. const { conference } = state['features/base/conference'];
  118. const { _language } = state['features/subtitles'];
  119. const { transcription } = state['features/base/config'];
  120. const languages = transcription?.translationLanguages ?? TRANSLATION_LANGUAGES;
  121. const languagesHead = transcription?.translationLanguagesHead ?? TRANSLATION_LANGUAGES_HEAD;
  122. return {
  123. _conference: conference,
  124. _language,
  125. _translationLanguages: languages,
  126. _translationLanguagesHead: languagesHead
  127. };
  128. }
  129. export default translate(connect(mapStateToProps)(LanguageSelectorDialog));