diff --git a/bigbluebutton-html5/imports/startup/client/base.jsx b/bigbluebutton-html5/imports/startup/client/base.jsx index 425f64adcd25fb502cdb292a1ad78ee35f7b429b..d825b5dc704208a5eea0c51fc5d469ee351e829d 100644 --- a/bigbluebutton-html5/imports/startup/client/base.jsx +++ b/bigbluebutton-html5/imports/startup/client/base.jsx @@ -8,8 +8,6 @@ import LoadingScreen from '/imports/ui/components/loading-screen/component'; import Settings from '/imports/ui/services/settings'; import IntlStartup from './intl'; -const BROWSER_LANGUAGE = window.navigator.userLanguage || window.navigator.language; - const propTypes = { error: PropTypes.object, errorCode: PropTypes.number, @@ -20,7 +18,7 @@ const propTypes = { const defaultProps = { error: undefined, errorCode: undefined, - locale: BROWSER_LANGUAGE, + locale: undefined, }; class Base extends Component { @@ -100,7 +98,6 @@ const BaseContainer = createContainer(({ params }) => { const credentials = Auth.credentials; const subscriptionsHandlers = SUBSCRIPTIONS_NAME.map(name => Meteor.subscribe(name, credentials)); - return { locale: Settings.application.locale, subscriptionsReady: subscriptionsHandlers.every(handler => handler.ready()), diff --git a/bigbluebutton-html5/imports/startup/client/intl.jsx b/bigbluebutton-html5/imports/startup/client/intl.jsx index 106f3c4c78d99f74d8ec673413212f8f3a4ee225..5b5c1b7e6a9821291c8ffc209902373c699b63f6 100644 --- a/bigbluebutton-html5/imports/startup/client/intl.jsx +++ b/bigbluebutton-html5/imports/startup/client/intl.jsx @@ -1,6 +1,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { IntlProvider } from 'react-intl'; +import Settings from '/imports/ui/services/settings'; const propTypes = { locale: PropTypes.string.isRequired, @@ -11,10 +12,10 @@ const propTypes = { children: PropTypes.element.isRequired, }; -const BROWSER_LANGUAGE = window.navigator.userLanguage || window.navigator.language; +const DEFAULT_LANGUAGE = Meteor.settings.public.app.defaultSettings.application.locale; const defaultProps = { - locale: BROWSER_LANGUAGE, + locale: DEFAULT_LANGUAGE, }; class IntlStartup extends Component { @@ -23,17 +24,17 @@ class IntlStartup extends Component { this.state = { messages: {}, - appLocale: this.props.locale, + locale: DEFAULT_LANGUAGE, }; this.fetchLocalizedMessages = this.fetchLocalizedMessages.bind(this); } componentWillMount() { - this.fetchLocalizedMessages(this.state.appLocale); + this.fetchLocalizedMessages(this.props.locale); } componentWillUpdate(nextProps) { - if (this.props.locale !== nextProps.locale) { + if (nextProps.locale && this.props.locale !== nextProps.locale) { this.fetchLocalizedMessages(nextProps.locale); } } @@ -42,34 +43,36 @@ class IntlStartup extends Component { const url = `/html5client/locale?locale=${locale}`; const { baseControls } = this.props; - this.setState({ appLocale: locale }); baseControls.updateLoadingState(true); fetch(url) .then((response) => { - if (response.ok) { - return response.json(); + if (!response.ok) { + return Promise.reject(); } - this.setState({ appLocale: 'en' }); + return response.json(); }) - .then((messages) => { - if (messages.statusCode === 506) { - this.setState({ appLocale: 'en' }); - } - this.setState({ messages: messages.messages }, () => { + .then(({ messages, normalizedLocale }) => { + const dasherizedLocale = normalizedLocale.replace('_', '-') + this.setState({ messages, locale: dasherizedLocale }, () => { + Settings.application.locale = dasherizedLocale; + Settings.save(); baseControls.updateLoadingState(false); }); }) - .catch((reason) => { - baseControls.updateErrorState(reason); - baseControls.updateLoadingState(false); + .catch((messages) => { + this.setState({ locale: DEFAULT_LANGUAGE }, () => { + Settings.application.locale = DEFAULT_LANGUAGE; + Settings.save(); + baseControls.updateLoadingState(false); + }); }); } render() { return ( - <IntlProvider locale={this.state.appLocale} messages={this.state.messages}> + <IntlProvider locale={this.state.locale} messages={this.state.messages}> {this.props.children} </IntlProvider> ); diff --git a/bigbluebutton-html5/imports/startup/server/index.js b/bigbluebutton-html5/imports/startup/server/index.js index 59da0fbf3abc633ca056978c5dfbdd52932362f1..34a859972f8986ec0832ac74d3de56a875950f8b 100644 --- a/bigbluebutton-html5/imports/startup/server/index.js +++ b/bigbluebutton-html5/imports/startup/server/index.js @@ -3,11 +3,14 @@ import Logger from './logger'; import Redis from './redis'; import locales from '../../utils/locales'; +let DEFAULT_LANGUAGE = null; const availableLocales = []; Meteor.startup(() => { const APP_CONFIG = Meteor.settings.public.app; Logger.info(`SERVER STARTED. ENV=${Meteor.settings.runtime.env}`, APP_CONFIG); + + DEFAULT_LANGUAGE = Meteor.settings.public.app.defaultSettings.application.locale }); WebApp.connectHandlers.use('/check', (req, res) => { @@ -21,28 +24,29 @@ WebApp.connectHandlers.use('/check', (req, res) => { WebApp.connectHandlers.use('/locale', (req, res) => { const APP_CONFIG = Meteor.settings.public.app; const defaultLocale = APP_CONFIG.defaultSettings.application.locale; - const localeRegion = req.query.locale.split('-'); + const localeRegion = req.query.locale.split(/[-_]/g);; + const localeList = [defaultLocale, localeRegion[0]]; + + let normalizedLocale = localeRegion[0]; let messages = {}; - const completeLocale = [defaultLocale, localeRegion[0]]; - let statusCode = 200; + if (localeRegion.length > 1) { - locales.push(`${localeRegion[0]}_${localeRegion[1].toUpperCase()}`); + normalizedLocale = `${localeRegion[0]}_${localeRegion[1].toUpperCase()}`; + localeList.push(normalizedLocale); } - completeLocale.forEach((locale) => { + localeList.forEach((locale) => { try { const data = Assets.getText(`locales/${locale}.json`); messages = Object.assign(messages, JSON.parse(data)); + normalizedLocale = locale } catch (e) { - // Variant Also Negotiates Status-Code, to alert the client that we - // do not support the following lang. - // https://en.wikipedia.org/wiki/Content_negotiation - statusCode = 506; + // Getting here means the locale is not available on the files. } }); res.setHeader('Content-Type', 'application/json'); - res.end(JSON.stringify({ statusCode, messages })); + res.end(JSON.stringify({ normalizedLocale, messages })); }); WebApp.connectHandlers.use('/locales', (req, res) => { diff --git a/bigbluebutton-html5/imports/ui/services/settings/index.js b/bigbluebutton-html5/imports/ui/services/settings/index.js index 2e1303c47bb785bfbe8b4f83f33c13e69d21c9e1..020f956afe1fb9bf9a63cf90fb172a6813feafde 100644 --- a/bigbluebutton-html5/imports/ui/services/settings/index.js +++ b/bigbluebutton-html5/imports/ui/services/settings/index.js @@ -30,6 +30,12 @@ class Settings { }, }); }); + + // Sets default locale to browser locale + defaultValues.application.locale = navigator.languages[0] || + navigator.language + defaultValues.application.locale; + this.setDefault(defaultValues); }