From 97c47c5d1dc5bba67873604b06b7225cb24a169e Mon Sep 17 00:00:00 2001 From: vjrj Date: Tue, 9 Jan 2018 12:05:36 +0100 Subject: [PATCH] Added user lang setting --- imports/api/Users/server/methods.js | 30 ++++++++++++++------- imports/startup/client/i18n.js | 17 ++++++++++++ imports/startup/common/i18n.js | 10 ++----- imports/ui/pages/Login/Login.js | 7 ++++- imports/ui/pages/Profile/Profile.js | 39 ++++++++++++++++++++++++++- imports/ui/pages/Profile/Profile.scss | 4 +++ public/locales/es/common.json | 4 ++- 7 files changed, 90 insertions(+), 21 deletions(-) diff --git a/imports/api/Users/server/methods.js b/imports/api/Users/server/methods.js index 130c6ee..0a8e1df 100644 --- a/imports/api/Users/server/methods.js +++ b/imports/api/Users/server/methods.js @@ -1,9 +1,15 @@ import { Meteor } from 'meteor/meteor'; -import { check } from 'meteor/check'; +import { check, Match } from 'meteor/check'; import { Accounts } from 'meteor/accounts-base'; import editProfile from './edit-profile'; import rateLimit from '../../../modules/rate-limit'; +const validLangCode = Match.Where((lang) => { + check(lang, String); + const regexp = /^[a-z]{2,3}(?:-[A-Z]{2,3}(?:-[a-zA-Z]{4})?)?$/; + return regexp.test(lang); +}); + Meteor.methods({ 'users.sendVerificationEmail': function usersSendVerificationEmail() { return Accounts.sendVerificationEmail(this.userId); @@ -14,24 +20,28 @@ Meteor.methods({ profile: { name: { first: String, - last: String, - }, - }, + last: String + } + } }); return editProfile({ userId: this.userId, profile }) - .then(response => response) - .catch((exception) => { - throw new Meteor.Error('500', exception); - }); + .then(response => response) + .catch((exception) => { + throw new Meteor.Error('500', exception); + }); }, + 'users.setLang': function userLang(lang) { + check(lang, validLangCode); + Meteor.users.update({ _id: this.userId }, { $set: { lang } }); + } }); rateLimit({ methods: [ 'users.sendVerificationEmail', - 'users.editProfile', + 'users.editProfile' ], limit: 5, - timeRange: 1000, + timeRange: 1000 }); diff --git a/imports/startup/client/i18n.js b/imports/startup/client/i18n.js index 8e70ffb..a56557e 100644 --- a/imports/startup/client/i18n.js +++ b/imports/startup/client/i18n.js @@ -1,6 +1,7 @@ /* global CookieConsent Intl */ import i18n from 'i18next'; import { Meteor } from 'meteor/meteor'; +import { Tracker } from 'meteor/tracker'; import backend from 'i18next-xhr-backend'; import LngDetector from 'i18next-browser-languagedetector'; import Cache from 'i18next-localstorage-cache'; @@ -98,6 +99,22 @@ i18n.use(backend) i18n.on('languageChanged', (lng) => { moment.locale(lng); T9n.setLanguage(lng); + Tracker.autorun(() => { + if (Meteor.userId()) { + // logged + if (Meteor.user() && (typeof Meteor.user().lang === 'undefined' || + Meteor.user().lang !== lng) + ) { + // Set the autodetected/changed lang + console.log(`Setting the autodetected lang ${lng}`); + Meteor.call('users.setLang', lng, (error) => { + if (error) { + console.error(error); + } + }); + } + } + }); }); export default i18n; diff --git a/imports/startup/common/i18n.js b/imports/startup/common/i18n.js index 956e3f8..8920792 100644 --- a/imports/startup/common/i18n.js +++ b/imports/startup/common/i18n.js @@ -20,14 +20,8 @@ const shouldDebug = (forceDebug && !Meteor.isProduction); const i18nOpts = { backend: backOpts, - lng: 'es', - // fallbackLng: 'es', - fallbackLng: { - 'en-US': ['en'], - 'en-GB': ['en'], - 'pt-BR': ['pt'], - default: ['es'] - }, + // lng: 'es', + fallbackLng: ['es', 'en'], interpolation: { escapeValue: false, // not needed for react!! formatSeparator: ',', diff --git a/imports/ui/pages/Login/Login.js b/imports/ui/pages/Login/Login.js index 86e428d..bdbb696 100644 --- a/imports/ui/pages/Login/Login.js +++ b/imports/ui/pages/Login/Login.js @@ -47,13 +47,17 @@ class Login extends React.Component { } handleSubmit = () => { - const { history } = this.props; + const { history, i18n } = this.props; Meteor.loginWithPassword(this.emailAddress.value, this.password.value, (error) => { if (error) { Bert.alert(T9n.get(`error.accounts.${error.reason}`), 'danger'); } else { Bert.alert(this.t('Bienvenid@ de nuevo'), 'success'); + const userLang = Meteor.user().lang + if (typeof userLang === 'string' && i18n.language !== userLang) { + i18n.changeLanguage(userLang); + } } }); } @@ -111,6 +115,7 @@ class Login extends React.Component { Login.propTypes = { history: PropTypes.object.isRequired, t: PropTypes.func.isRequired, + i18n: PropTypes.object.isRequired, location: PropTypes.object }; diff --git a/imports/ui/pages/Profile/Profile.js b/imports/ui/pages/Profile/Profile.js index 12318c8..001b952 100644 --- a/imports/ui/pages/Profile/Profile.js +++ b/imports/ui/pages/Profile/Profile.js @@ -26,6 +26,7 @@ class Profile extends React.Component { this.renderOAuthUser = this.renderOAuthUser.bind(this); this.renderPasswordUser = this.renderPasswordUser.bind(this); this.renderProfileForm = this.renderProfileForm.bind(this); + this.onLangSelect = this.onLangSelect.bind(this); } componentDidMount() { @@ -78,6 +79,18 @@ class Profile extends React.Component { }); } + onLangSelect(lang) { + // console.log(lang); + Meteor.call('users.setLang', lang, (error) => { + if (error) { + console.error(error); + } else { + this.props.i18n.changeLanguage(lang); + // Bert.alert(this.t("¡Perfíl actualizado!"), 'success'); + } + }); + } + getUserType(user) { const userToCheck = user; delete userToCheck.services.resume; @@ -137,6 +150,8 @@ class Profile extends React.Component { } renderPasswordUser(loading, user) { + const {t, i18n} = this.props; + const langName = { 'en': 'English', 'es': 'Español', 'gl': 'Galego', 'ast': 'Asturianu', 'ca': 'Català' }; return !loading ? (
@@ -174,6 +189,26 @@ class Profile extends React.Component { className="form-control" /> + + {this.t("Idioma")} +
+ +
+ {i18n.languages.map(lang => ( + + )) + } +
+
+
{this.t("Contraseña actual")} { diff --git a/imports/ui/pages/Profile/Profile.scss b/imports/ui/pages/Profile/Profile.scss index 84b579f..049e46b 100644 --- a/imports/ui/pages/Profile/Profile.scss +++ b/imports/ui/pages/Profile/Profile.scss @@ -44,3 +44,7 @@ } } } + +.lang-selector { + margin: 10px 0 0 0; +} diff --git a/public/locales/es/common.json b/public/locales/es/common.json index 4b0439e..6eb2925 100644 --- a/public/locales/es/common.json +++ b/public/locales/es/common.json @@ -183,5 +183,7 @@ "Política de Privacidad": "Política de Privacidad", "No estás suscrito a fuegos en ninguna zona": "No estás suscrito a fuegos en ninguna zona", "Iniciar sesión con Telegram": - "Iniciar sesión con Telegram" + "Iniciar sesión con Telegram", + "Idioma": + "Idioma" }