[FIX] Loading and setting fixes for i18n and RTL (#11363)
parent
96ea55e56e
commit
54c9e16ba1
@ -0,0 +1,84 @@ |
||||
/* globals isRtl */ |
||||
|
||||
import moment from 'moment'; |
||||
|
||||
const currentLanguage = new ReactiveVar(); |
||||
|
||||
Meteor.startup(() => { |
||||
TAPi18n.conf.i18n_files_route = Meteor._relativeToSiteRootUrl('/tap-i18n'); |
||||
currentLanguage.set(localStorage.getItem('userLanguage')); |
||||
|
||||
const availableLanguages = TAPi18n.getLanguages(); |
||||
|
||||
const filterLanguage = language => { |
||||
// Fix browsers having all-lowercase language settings eg. pt-br, en-us
|
||||
const regex = /([a-z]{2})-([a-z]{2})/; |
||||
const matches = regex.exec(language); |
||||
if (matches) { |
||||
return `${ matches[1] }-${ matches[2].toUpperCase() }`; |
||||
} |
||||
|
||||
return language; |
||||
}; |
||||
|
||||
const getBrowserLanguage = () => filterLanguage(window.navigator.userLanguage || window.navigator.language); |
||||
|
||||
const loadMomentLocale = language => new Promise((resolve, reject) => { |
||||
if (moment.locales().includes(language.toLowerCase())) { |
||||
resolve(language); |
||||
return; |
||||
} |
||||
|
||||
Meteor.call('loadLocale', language, (error, localeSrc) => { |
||||
if (error) { |
||||
reject(error); |
||||
return; |
||||
} |
||||
|
||||
Function(localeSrc).call({ moment }); |
||||
resolve(language); |
||||
}); |
||||
}); |
||||
|
||||
const applyLanguage = (language = 'en') => { |
||||
language = filterLanguage(language); |
||||
|
||||
if (!availableLanguages[language]) { |
||||
language = language.split('-').shift(); |
||||
} |
||||
|
||||
if (!language) { |
||||
return; |
||||
} |
||||
|
||||
document.documentElement.classList[isRtl(language) ? 'add' : 'remove']('rtl'); |
||||
TAPi18n.setLanguage(language); |
||||
loadMomentLocale(language).then(locale => moment.locale(locale), error => console.error(error)); |
||||
}; |
||||
|
||||
const setLanguage = language => { |
||||
currentLanguage.set(filterLanguage(language)); |
||||
localStorage.setItem('userLanguage', currentLanguage.get()); |
||||
}; |
||||
|
||||
window.setLanguage = setLanguage; |
||||
|
||||
window.defaultUserLanguage = () => RocketChat.settings.get('Language') || getBrowserLanguage() || 'en'; |
||||
|
||||
Tracker.autorun(() => { |
||||
const user = RocketChat.models.Users.findOne(Meteor.userId(), { fields: { username: 1 }}); |
||||
const userLanguage = user && user.language; |
||||
|
||||
const defaultLanguage = userLanguage || RocketChat.settings.get('Language') || 'en'; |
||||
|
||||
if (!currentLanguage.get()) { |
||||
setLanguage(defaultLanguage); |
||||
} |
||||
|
||||
if (userLanguage && userLanguage !== currentLanguage.get()) { |
||||
setLanguage(userLanguage); |
||||
} |
||||
|
||||
applyLanguage(currentLanguage.get()); |
||||
}); |
||||
}); |
||||
@ -1,5 +1,9 @@ |
||||
<template name='loginFooter'> |
||||
<footer> |
||||
{{#if LanguageVersion}}<div class="switch-language"><button class="switch-language">{{LanguageVersion}}</button></div>{{/if}} |
||||
{{#if languageVersion}} |
||||
<div class="switch-language"> |
||||
<button class="js-switch-language">{{languageVersion}}</button> |
||||
</div> |
||||
{{/if}} |
||||
</footer> |
||||
</template> |
||||
|
||||
@ -1,35 +1,37 @@ |
||||
/*globals defaultUserLanguage */ |
||||
Template.loginFooter.helpers({ |
||||
LanguageVersion() { |
||||
if (Template.instance().languageVersion.get()) { |
||||
return TAPi18n.__('Language_Version', { |
||||
lng: Template.instance().languageVersion.get() |
||||
}); |
||||
Template.loginFooter.onCreated(function() { |
||||
this.suggestedLanguage = new ReactiveVar(); |
||||
|
||||
this.suggestAnotherLanguageFor = language => { |
||||
const loadAndSetSuggestedLanguage = language => TAPi18n._loadLanguage(language) |
||||
.then(() => this.suggestedLanguage.set(language)); |
||||
|
||||
const serverLanguage = RocketChat.settings.get('Language'); |
||||
|
||||
if (serverLanguage !== language) { |
||||
loadAndSetSuggestedLanguage(serverLanguage || 'en'); |
||||
} else if (!/^en/.test(language)) { |
||||
loadAndSetSuggestedLanguage('en'); |
||||
} else { |
||||
this.suggestedLanguage.set(undefined); |
||||
} |
||||
} |
||||
}; |
||||
|
||||
const currentLanguage = localStorage.getItem('userLanguage'); |
||||
this.suggestAnotherLanguageFor(currentLanguage); |
||||
}); |
||||
|
||||
Template.loginFooter.events({ |
||||
'click button.switch-language'(e, t) { |
||||
const userLanguage = t.languageVersion.get(); |
||||
localStorage.setItem('userLanguage', userLanguage); |
||||
TAPi18n.setLanguage(userLanguage); |
||||
moment.locale(userLanguage); |
||||
return t.languageVersion.set(userLanguage !== defaultUserLanguage() ? defaultUserLanguage() : 'en'); |
||||
Template.loginFooter.helpers({ |
||||
languageVersion() { |
||||
const lng = Template.instance().suggestedLanguage.get(); |
||||
return lng && TAPi18n.__('Language_Version', { lng }); |
||||
} |
||||
}); |
||||
|
||||
Template.loginFooter.onCreated(function() { |
||||
const self = this; |
||||
this.languageVersion = new ReactiveVar; |
||||
const userLanguage = localStorage.getItem('userLanguage'); |
||||
if (userLanguage !== defaultUserLanguage()) { |
||||
return TAPi18n._loadLanguage(defaultUserLanguage()).done(function() { |
||||
return self.languageVersion.set(defaultUserLanguage()); |
||||
}); |
||||
} else if (userLanguage.indexOf('en') !== 0) { |
||||
return TAPi18n._loadLanguage('en').done(function() { |
||||
return self.languageVersion.set('en'); |
||||
}); |
||||
Template.loginFooter.events({ |
||||
'click button.js-switch-language'(e, t) { |
||||
const language = t.suggestedLanguage.get(); |
||||
window.setLanguage(language); |
||||
t.suggestAnotherLanguageFor(language); |
||||
return false; |
||||
} |
||||
}); |
||||
|
||||
Loading…
Reference in new issue