fix(translation) translation button visibility for users, add missing languages
This commit is contained in:
parent
69e0a37529
commit
8162ae4dbe
10
config.js
10
config.js
|
@ -375,6 +375,14 @@ var config = {
|
|||
// // Whether the feature should be enabled or not.
|
||||
// enabled: false,
|
||||
|
||||
// // Translation languages.
|
||||
// // Available languages can be found in
|
||||
// // ./src/react/features/transcribing/translation-languages.json.
|
||||
// translationLanguages: ['en', 'es', 'fr', 'ro'],
|
||||
|
||||
// // Important languages to show on the top of the language list.
|
||||
// translationLanguagesHead: ['en'],
|
||||
|
||||
// // If true transcriber will use the application language.
|
||||
// // The application language is either explicitly set by participants in their settings or automatically
|
||||
// // detected based on the environment, e.g. if the app is opened in a chrome instance which
|
||||
|
@ -1349,6 +1357,8 @@ var config = {
|
|||
*/
|
||||
mouseMoveCallbackInterval: 1000,
|
||||
|
||||
hiddenDomain: 'tdomokos.jitsi.net',
|
||||
|
||||
/**
|
||||
Use this array to configure which notifications will be shown to the user
|
||||
The items correspond to the title or description key of that notification
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
{
|
||||
"af": "Afrikaans",
|
||||
"am": "Amharic",
|
||||
"ar": "Arabic",
|
||||
"az": "Azerbaijani",
|
||||
"be": "Belarusian",
|
||||
"bg": "Bulgarian",
|
||||
"bn": "Bengali",
|
||||
"bs": "Bosnian",
|
||||
"ca": "Catalan",
|
||||
"ceb": "Cebuano",
|
||||
"co": "Corsican",
|
||||
"cs": "Czech",
|
||||
"cy": "Welsh",
|
||||
"da": "Danish",
|
||||
"de": "German",
|
||||
"el": "Greek",
|
||||
"en": "English",
|
||||
"eo": "Esperanto",
|
||||
"es": "Spanish",
|
||||
"et": "Estonian",
|
||||
"eu": "Basque",
|
||||
"fa": "Persian",
|
||||
"fi": "Finnish",
|
||||
"fr": "French",
|
||||
"fy": "Frisian",
|
||||
"ga": "Irish",
|
||||
"gd": "Scots Gaelic",
|
||||
"gl": "Galician",
|
||||
"gu": "Gujarati",
|
||||
"ha": "Hausa",
|
||||
"haw": "Hawaiian",
|
||||
"he": "Hebrew",
|
||||
"hi": "Hindi",
|
||||
"hmn": "Hmong",
|
||||
"hr": "Croatian",
|
||||
"ht": "Haitian Creole",
|
||||
"hu": "Hungarian",
|
||||
"hy": "Armenian",
|
||||
"id": "Indonesian",
|
||||
"ig": "Igbo",
|
||||
"is": "Icelandic",
|
||||
"it": "Italian",
|
||||
"ja": "Japanese",
|
||||
"jv": "Javanese",
|
||||
"ka": "Georgian",
|
||||
"kk": "Kazakh",
|
||||
"km": "Khmer",
|
||||
"kn": "Kannada",
|
||||
"ko": "Korean",
|
||||
"ku": "Kurdish",
|
||||
"ky": "Kyrgyz",
|
||||
"la": "Latin",
|
||||
"lb": "Luxembourgish",
|
||||
"lo": "Lao",
|
||||
"lt": "Lithuanian",
|
||||
"lv": "Latvian",
|
||||
"mg": "Malagasy",
|
||||
"mi": "Maori",
|
||||
"mk": "Macedonian",
|
||||
"ml": "Malayalam",
|
||||
"mn": "Mongolian",
|
||||
"mr": "Marathi",
|
||||
"ms": "Malay",
|
||||
"mt": "Maltese",
|
||||
"my": "Myanmar (Burmese)",
|
||||
"ne": "Nepali",
|
||||
"nl": "Dutch",
|
||||
"no": "Norwegian",
|
||||
"ny": "Nyanja (Chichewa)",
|
||||
"or": "Odia (Oriya)",
|
||||
"pa": "Punjabi",
|
||||
"pl": "Polish",
|
||||
"ps": "Pashto",
|
||||
"pt": "Portuguese (Portugal, Brazil)",
|
||||
"ro": "Romanian",
|
||||
"ru": "Russian",
|
||||
"rw": "Kinyarwanda",
|
||||
"sd": "Sindhi",
|
||||
"si": "Sinhala (Sinhalese)",
|
||||
"sk": "Slovak",
|
||||
"sl": "Slovenian",
|
||||
"sm": "Samoan",
|
||||
"sn": "Shona",
|
||||
"so": "Somali",
|
||||
"sq": "Albanian",
|
||||
"sr": "Serbian",
|
||||
"st": "Sesotho",
|
||||
"su": "Sundanese",
|
||||
"sv": "Swedish",
|
||||
"sw": "Swahili",
|
||||
"ta": "Tamil",
|
||||
"te": "Telugu",
|
||||
"tg": "Tajik",
|
||||
"th": "Thai",
|
||||
"tk": "Turkmen",
|
||||
"tl": "Tagalog (Filipino)",
|
||||
"tr": "Turkish",
|
||||
"tt": "Tatar",
|
||||
"ug": "Uyghur",
|
||||
"uk": "Ukrainian",
|
||||
"ur": "Urdu",
|
||||
"uz": "Uzbek",
|
||||
"vi": "Vietnamese",
|
||||
"xh": "Xhosa",
|
||||
"yi": "Yiddish",
|
||||
"yo": "Yoruba",
|
||||
"zh-CN": "Chinese (Simplified)",
|
||||
"zh-TW": "Chinese (Traditional)",
|
||||
"zu": "Zulu"
|
||||
}
|
|
@ -464,6 +464,8 @@ export interface IConfig {
|
|||
disableStartForAll?: boolean;
|
||||
enabled?: boolean;
|
||||
preferredLanguage?: string;
|
||||
translationLanguages?: Array<string>;
|
||||
translationLanguagesHead?: Array<string>;
|
||||
useAppLanguage?: boolean;
|
||||
};
|
||||
useHostPageLocalStorage?: boolean;
|
||||
|
|
|
@ -7,6 +7,7 @@ import _ from 'lodash';
|
|||
|
||||
import LANGUAGES_RESOURCES from '../../../../lang/languages.json';
|
||||
import MAIN_RESOURCES from '../../../../lang/main.json';
|
||||
import TRANSLATION_LANGUAGES_RESOURCES from '../../../../lang/translation-languages.json';
|
||||
|
||||
import { I18NEXT_INITIALIZED, LANGUAGE_CHANGED } from './actionTypes';
|
||||
// eslint-disable-next-line lines-around-comment
|
||||
|
@ -36,22 +37,21 @@ const COUNTRIES = _.merge({}, COUNTRIES_RESOURCES, COUNTRIES_RESOURCES_OVERRIDES
|
|||
export const LANGUAGES: Array<string> = Object.keys(LANGUAGES_RESOURCES);
|
||||
|
||||
/**
|
||||
* The languages for the top section of the translation language list.
|
||||
* The available/supported translation languages.
|
||||
*
|
||||
* @public
|
||||
* @type {Array<string>}
|
||||
*/
|
||||
export const TRANSLATION_LANGUAGES: Array<string> = Object.keys(TRANSLATION_LANGUAGES_RESOURCES);
|
||||
|
||||
/**
|
||||
* The available/supported translation languages head. (Languages displayed on the top ).
|
||||
*
|
||||
* @public
|
||||
* @type {Array<string>}
|
||||
*/
|
||||
export const TRANSLATION_LANGUAGES_HEAD: Array<string> = [ 'en' ];
|
||||
|
||||
/**
|
||||
* The languages to explude from the translation language list.
|
||||
*
|
||||
* @public
|
||||
* @type {Array<string>}
|
||||
*/
|
||||
export const TRANSLATION_LANGUAGES_EXCLUDE: Array<string>
|
||||
= [ 'enGB', 'esUS', 'frCA', 'hsb', 'kab', 'ptBR', 'zhCN', 'zhTW' ];
|
||||
|
||||
/**
|
||||
* The default language.
|
||||
*
|
||||
|
@ -77,7 +77,7 @@ const options = {
|
|||
escapeValue: false // not needed for react as it escapes by default
|
||||
},
|
||||
load: 'languageOnly',
|
||||
ns: [ 'main', 'languages', 'countries' ],
|
||||
ns: [ 'main', 'languages', 'countries', 'translation-languages' ],
|
||||
react: {
|
||||
// re-render when a new resource bundle is added
|
||||
bindI18nStore: 'added',
|
||||
|
@ -109,6 +109,12 @@ i18next.addResourceBundle(
|
|||
LANGUAGES_RESOURCES,
|
||||
/* deep */ true,
|
||||
/* overwrite */ true);
|
||||
i18next.addResourceBundle(
|
||||
DEFAULT_LANGUAGE,
|
||||
'translation-languages',
|
||||
TRANSLATION_LANGUAGES_RESOURCES,
|
||||
/* deep */ true,
|
||||
/* overwrite */ true);
|
||||
i18next.addResourceBundle(
|
||||
DEFAULT_LANGUAGE,
|
||||
'main',
|
||||
|
|
|
@ -4,4 +4,4 @@ export * from './functions';
|
|||
// TODO Eventually (e.g. when the non-React Web app is rewritten into React), it
|
||||
// should not be necessary to export i18next.
|
||||
export { default as i18next, DEFAULT_LANGUAGE,
|
||||
LANGUAGES, TRANSLATION_LANGUAGES_HEAD, TRANSLATION_LANGUAGES_EXCLUDE } from './i18next';
|
||||
LANGUAGES, TRANSLATION_LANGUAGES, TRANSLATION_LANGUAGES_HEAD, i18n } from './i18next';
|
||||
|
|
|
@ -11,7 +11,7 @@ export * from './actions.any';
|
|||
* type: UPDATE_TRANSLATION_LANGUAGE
|
||||
* }}
|
||||
*/
|
||||
export function toggleLangugeSelectorDialog() {
|
||||
export function toggleLanguageSelectorDialog() {
|
||||
return function(dispatch: (Object) => Object) {
|
||||
dispatch(toggleDialog(LanguageSelectorDialogWeb));
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import { translate } from '../../base/i18n';
|
||||
import { IconClosedCaption } from '../../base/icons';
|
||||
import { connect } from '../../base/redux';
|
||||
import { toggleLangugeSelectorDialog } from '../actions';
|
||||
import { toggleLanguageSelectorDialog } from '../actions';
|
||||
|
||||
import {
|
||||
AbstractClosedCaptionButton,
|
||||
|
@ -20,7 +20,9 @@ class ClosedCaptionButton
|
|||
tooltip = 'transcribing.ccButtonTooltip';
|
||||
label = 'toolbar.startSubtitles';
|
||||
labelProps = {
|
||||
language: this.props.t(this.props._language)
|
||||
language: this.props.t(this.props._language),
|
||||
languages: this.props.t(this.props.languages),
|
||||
languagesHead: this.props.t(this.props.languagesHead)
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -31,7 +33,7 @@ class ClosedCaptionButton
|
|||
_handleClickOpenLanguageSelector() {
|
||||
const { dispatch } = this.props;
|
||||
|
||||
dispatch(toggleLangugeSelectorDialog());
|
||||
dispatch(toggleLanguageSelectorDialog());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,11 @@ const useStyles = makeStyles()((theme: Theme) => {
|
|||
display: 'flex',
|
||||
color: theme.palette.text01,
|
||||
alignItems: 'center',
|
||||
fontSize: '14px'
|
||||
fontSize: '14px',
|
||||
cursor: 'pointer',
|
||||
'&:hover': {
|
||||
backgroundColor: theme.palette.ui04
|
||||
}
|
||||
},
|
||||
iconWrapper: {
|
||||
margin: '4px 10px',
|
||||
|
|
|
@ -6,15 +6,17 @@ import { IState } from '../../app/types';
|
|||
// @ts-ignore
|
||||
import { Dialog } from '../../base/dialog';
|
||||
// @ts-ignore
|
||||
import { LANGUAGES, TRANSLATION_LANGUAGES_EXCLUDE, TRANSLATION_LANGUAGES_HEAD } from '../../base/i18n';
|
||||
import { TRANSLATION_LANGUAGES, TRANSLATION_LANGUAGES_HEAD } from '../../base/i18n';
|
||||
import { connect } from '../../base/redux/functions';
|
||||
// @ts-ignore
|
||||
import { setRequestingSubtitles, toggleLangugeSelectorDialog, updateTranslationLanguage } from '../actions';
|
||||
import { setRequestingSubtitles, toggleLanguageSelectorDialog, updateTranslationLanguage } from '../actions';
|
||||
|
||||
import LanguageList from './LanguageList';
|
||||
|
||||
interface ILanguageSelectorDialogProps {
|
||||
_language: string;
|
||||
_translationLanguages: Array<string>;
|
||||
_translationLanguagesHead: Array<string>;
|
||||
t: Function;
|
||||
}
|
||||
|
||||
|
@ -23,18 +25,21 @@ interface ILanguageSelectorDialogProps {
|
|||
*
|
||||
* @returns {React$Element<any>}
|
||||
*/
|
||||
const LanguageSelectorDialog = ({ _language }: ILanguageSelectorDialogProps) => {
|
||||
const LanguageSelectorDialog = ({ _language, _translationLanguages, _translationLanguagesHead }:
|
||||
ILanguageSelectorDialogProps) => {
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const off = 'transcribing.subtitlesOff';
|
||||
const [ language, setLanguage ] = useState(off);
|
||||
|
||||
const importantLanguages = TRANSLATION_LANGUAGES_HEAD.map((lang: string) => `languages:${lang}`);
|
||||
const fixedItems = [ off, ...importantLanguages ];
|
||||
|
||||
const languages = LANGUAGES
|
||||
.filter((lang: string) => !TRANSLATION_LANGUAGES_EXCLUDE.includes(lang))
|
||||
.map((lang: string) => `languages:${lang}`)
|
||||
.filter((lang: string) => !(lang === language || importantLanguages.includes(lang)));
|
||||
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 ]
|
||||
|
@ -55,7 +60,7 @@ const LanguageSelectorDialog = ({ _language }: ILanguageSelectorDialogProps) =>
|
|||
setLanguage(e);
|
||||
dispatch(updateTranslationLanguage(e));
|
||||
dispatch(setRequestingSubtitles(e !== off));
|
||||
dispatch(toggleLangugeSelectorDialog());
|
||||
dispatch(toggleLanguageSelectorDialog());
|
||||
}, [ _language ]);
|
||||
|
||||
return (
|
||||
|
@ -81,17 +86,18 @@ const LanguageSelectorDialog = ({ _language }: ILanguageSelectorDialogProps) =>
|
|||
* @returns {Props}
|
||||
*/
|
||||
function mapStateToProps(state: IState) {
|
||||
const {
|
||||
conference
|
||||
} = state['features/base/conference'];
|
||||
const { conference } = state['features/base/conference'];
|
||||
const { _language } = state['features/subtitles'];
|
||||
const { transcription } = state['features/base/config'];
|
||||
|
||||
const {
|
||||
_language
|
||||
} = state['features/subtitles'];
|
||||
const languages = transcription?.translationLanguages ?? TRANSLATION_LANGUAGES;
|
||||
const languagesHead = transcription?.translationLanguagesHead ?? TRANSLATION_LANGUAGES_HEAD;
|
||||
|
||||
return {
|
||||
_conference: conference,
|
||||
_language
|
||||
_language,
|
||||
_translationLanguages: languages,
|
||||
_translationLanguagesHead: languagesHead
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// @flow
|
||||
import i18next from 'i18next';
|
||||
|
||||
import { MiddlewareRegistry } from '../base/redux';
|
||||
|
||||
|
@ -115,7 +116,7 @@ function _endpointMessageReceived({ dispatch, getState }, next, action) {
|
|||
newTranscriptMessage));
|
||||
|
||||
} else if (json.type === JSON_TYPE_TRANSCRIPTION_RESULT
|
||||
&& !translationLanguage) {
|
||||
&& i18next.language === translationLanguage) {
|
||||
// Displays interim and final results without any translation if
|
||||
// translations are disabled.
|
||||
|
||||
|
@ -186,7 +187,7 @@ function _requestingSubtitlesChange({ getState }) {
|
|||
if (requestingSubtitles) {
|
||||
conference.setLocalParticipantProperty(
|
||||
P_NAME_TRANSLATION_LANGUAGE,
|
||||
_language.replace('languages:', ''));
|
||||
_language.replace('translation-languages:', ''));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue