Added user lang setting
This commit is contained in:
parent
fc56bd3273
commit
97c47c5d1d
7 changed files with 90 additions and 21 deletions
|
|
@ -1,9 +1,15 @@
|
||||||
import { Meteor } from 'meteor/meteor';
|
import { Meteor } from 'meteor/meteor';
|
||||||
import { check } from 'meteor/check';
|
import { check, Match } from 'meteor/check';
|
||||||
import { Accounts } from 'meteor/accounts-base';
|
import { Accounts } from 'meteor/accounts-base';
|
||||||
import editProfile from './edit-profile';
|
import editProfile from './edit-profile';
|
||||||
import rateLimit from '../../../modules/rate-limit';
|
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({
|
Meteor.methods({
|
||||||
'users.sendVerificationEmail': function usersSendVerificationEmail() {
|
'users.sendVerificationEmail': function usersSendVerificationEmail() {
|
||||||
return Accounts.sendVerificationEmail(this.userId);
|
return Accounts.sendVerificationEmail(this.userId);
|
||||||
|
|
@ -14,9 +20,9 @@ Meteor.methods({
|
||||||
profile: {
|
profile: {
|
||||||
name: {
|
name: {
|
||||||
first: String,
|
first: String,
|
||||||
last: String,
|
last: String
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return editProfile({ userId: this.userId, profile })
|
return editProfile({ userId: this.userId, profile })
|
||||||
|
|
@ -25,13 +31,17 @@ Meteor.methods({
|
||||||
throw new Meteor.Error('500', exception);
|
throw new Meteor.Error('500', exception);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
'users.setLang': function userLang(lang) {
|
||||||
|
check(lang, validLangCode);
|
||||||
|
Meteor.users.update({ _id: this.userId }, { $set: { lang } });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
rateLimit({
|
rateLimit({
|
||||||
methods: [
|
methods: [
|
||||||
'users.sendVerificationEmail',
|
'users.sendVerificationEmail',
|
||||||
'users.editProfile',
|
'users.editProfile'
|
||||||
],
|
],
|
||||||
limit: 5,
|
limit: 5,
|
||||||
timeRange: 1000,
|
timeRange: 1000
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
/* global CookieConsent Intl */
|
/* global CookieConsent Intl */
|
||||||
import i18n from 'i18next';
|
import i18n from 'i18next';
|
||||||
import { Meteor } from 'meteor/meteor';
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
import { Tracker } from 'meteor/tracker';
|
||||||
import backend from 'i18next-xhr-backend';
|
import backend from 'i18next-xhr-backend';
|
||||||
import LngDetector from 'i18next-browser-languagedetector';
|
import LngDetector from 'i18next-browser-languagedetector';
|
||||||
import Cache from 'i18next-localstorage-cache';
|
import Cache from 'i18next-localstorage-cache';
|
||||||
|
|
@ -98,6 +99,22 @@ i18n.use(backend)
|
||||||
i18n.on('languageChanged', (lng) => {
|
i18n.on('languageChanged', (lng) => {
|
||||||
moment.locale(lng);
|
moment.locale(lng);
|
||||||
T9n.setLanguage(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;
|
export default i18n;
|
||||||
|
|
|
||||||
|
|
@ -20,14 +20,8 @@ const shouldDebug = (forceDebug && !Meteor.isProduction);
|
||||||
|
|
||||||
const i18nOpts = {
|
const i18nOpts = {
|
||||||
backend: backOpts,
|
backend: backOpts,
|
||||||
lng: 'es',
|
// lng: 'es',
|
||||||
// fallbackLng: 'es',
|
fallbackLng: ['es', 'en'],
|
||||||
fallbackLng: {
|
|
||||||
'en-US': ['en'],
|
|
||||||
'en-GB': ['en'],
|
|
||||||
'pt-BR': ['pt'],
|
|
||||||
default: ['es']
|
|
||||||
},
|
|
||||||
interpolation: {
|
interpolation: {
|
||||||
escapeValue: false, // not needed for react!!
|
escapeValue: false, // not needed for react!!
|
||||||
formatSeparator: ',',
|
formatSeparator: ',',
|
||||||
|
|
|
||||||
|
|
@ -47,13 +47,17 @@ class Login extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSubmit = () => {
|
handleSubmit = () => {
|
||||||
const { history } = this.props;
|
const { history, i18n } = this.props;
|
||||||
|
|
||||||
Meteor.loginWithPassword(this.emailAddress.value, this.password.value, (error) => {
|
Meteor.loginWithPassword(this.emailAddress.value, this.password.value, (error) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
Bert.alert(T9n.get(`error.accounts.${error.reason}`), 'danger');
|
Bert.alert(T9n.get(`error.accounts.${error.reason}`), 'danger');
|
||||||
} else {
|
} else {
|
||||||
Bert.alert(this.t('Bienvenid@ de nuevo'), 'success');
|
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 = {
|
Login.propTypes = {
|
||||||
history: PropTypes.object.isRequired,
|
history: PropTypes.object.isRequired,
|
||||||
t: PropTypes.func.isRequired,
|
t: PropTypes.func.isRequired,
|
||||||
|
i18n: PropTypes.object.isRequired,
|
||||||
location: PropTypes.object
|
location: PropTypes.object
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ class Profile extends React.Component {
|
||||||
this.renderOAuthUser = this.renderOAuthUser.bind(this);
|
this.renderOAuthUser = this.renderOAuthUser.bind(this);
|
||||||
this.renderPasswordUser = this.renderPasswordUser.bind(this);
|
this.renderPasswordUser = this.renderPasswordUser.bind(this);
|
||||||
this.renderProfileForm = this.renderProfileForm.bind(this);
|
this.renderProfileForm = this.renderProfileForm.bind(this);
|
||||||
|
this.onLangSelect = this.onLangSelect.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
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) {
|
getUserType(user) {
|
||||||
const userToCheck = user;
|
const userToCheck = user;
|
||||||
delete userToCheck.services.resume;
|
delete userToCheck.services.resume;
|
||||||
|
|
@ -137,6 +150,8 @@ class Profile extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPasswordUser(loading, user) {
|
renderPasswordUser(loading, user) {
|
||||||
|
const {t, i18n} = this.props;
|
||||||
|
const langName = { 'en': 'English', 'es': 'Español', 'gl': 'Galego', 'ast': 'Asturianu', 'ca': 'Català' };
|
||||||
return !loading ? (<div>
|
return !loading ? (<div>
|
||||||
<Row>
|
<Row>
|
||||||
<Col xs={6}>
|
<Col xs={6}>
|
||||||
|
|
@ -174,6 +189,26 @@ class Profile extends React.Component {
|
||||||
className="form-control"
|
className="form-control"
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
<FormGroup>
|
||||||
|
<ControlLabel>{this.t("Idioma")}</ControlLabel>
|
||||||
|
<div className="btn-group">
|
||||||
|
<button className="btn btn-secondary btn-sm dropdown-toggle lang-selector" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
{langName[i18n.language]}
|
||||||
|
</button>
|
||||||
|
<div className="dropdown-menu">
|
||||||
|
{i18n.languages.map(lang => (
|
||||||
|
<button
|
||||||
|
className="dropdown-item"
|
||||||
|
onClick={() => this.onLangSelect(lang)}
|
||||||
|
key={lang}
|
||||||
|
type="button">
|
||||||
|
{langName[lang]}
|
||||||
|
</button>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</FormGroup>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<ControlLabel>{this.t("Contraseña actual")}</ControlLabel>
|
<ControlLabel>{this.t("Contraseña actual")}</ControlLabel>
|
||||||
<input
|
<input
|
||||||
|
|
@ -221,7 +256,9 @@ class Profile extends React.Component {
|
||||||
|
|
||||||
Profile.propTypes = {
|
Profile.propTypes = {
|
||||||
loading: PropTypes.bool.isRequired,
|
loading: PropTypes.bool.isRequired,
|
||||||
user: PropTypes.object.isRequired
|
user: PropTypes.object.isRequired,
|
||||||
|
t: PropTypes.func.isRequired,
|
||||||
|
i18n: PropTypes.object.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default translate([], { wait: true })(createContainer(() => {
|
export default translate([], { wait: true })(createContainer(() => {
|
||||||
|
|
|
||||||
|
|
@ -44,3 +44,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lang-selector {
|
||||||
|
margin: 10px 0 0 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -183,5 +183,7 @@
|
||||||
"Política de Privacidad": "Política de Privacidad",
|
"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",
|
"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"
|
"Iniciar sesión con Telegram",
|
||||||
|
"Idioma":
|
||||||
|
"Idioma"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue