Localization (and language chooser)...
This commit is contained in:
parent
653574025e
commit
5822198f92
|
@ -29,7 +29,7 @@ import { useDispatch, useSelector } from 'react-redux';
|
|||
import { mapActions } from '../../store/map';
|
||||
import { SettingsState } from '../../store/settings';
|
||||
|
||||
import i18n from '../../i18n/index';
|
||||
import i18n, { setI18nLanguage } from '../../i18n/index';
|
||||
|
||||
|
||||
declare global {
|
||||
|
@ -37,6 +37,13 @@ declare global {
|
|||
}
|
||||
|
||||
const GpxRecord: React.FC<{}> = () => {
|
||||
|
||||
const language = useSelector(
|
||||
(state: { settings: SettingsState }) => state.settings.language
|
||||
);
|
||||
|
||||
setI18nLanguage(language);
|
||||
|
||||
const db = useDB();
|
||||
|
||||
const [isRecording, setIsRecording] = useState(false);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { Fragment, useEffect, useRef } from 'react';
|
||||
import React, { Fragment, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { useDB } from 'react-pouchdb';
|
||||
|
||||
|
@ -13,6 +13,8 @@ import {
|
|||
IonList,
|
||||
IonListHeader,
|
||||
IonModal,
|
||||
IonSelect,
|
||||
IonSelectOption,
|
||||
IonTitle,
|
||||
IonToolbar,
|
||||
} from '@ionic/react';
|
||||
|
@ -22,7 +24,7 @@ import { useDispatch, useSelector } from 'react-redux';
|
|||
import { settingsActions, SettingsState } from '../../store/settings';
|
||||
import uri from '../../lib/ids';
|
||||
import _ from 'lodash';
|
||||
import i18n from '../../i18n/index';
|
||||
import i18n, { setI18nLanguage } from '../../i18n/index';
|
||||
|
||||
const Settings: React.FC<{}> = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
@ -66,18 +68,18 @@ const Settings: React.FC<{}> = () => {
|
|||
};
|
||||
settingsFromRedux();
|
||||
}
|
||||
setLocalLanguage(settingsState.language);
|
||||
}, [db, settingsState]);
|
||||
|
||||
const [localLanguage, setLocalLanguage] = useState(settingsState.language);
|
||||
|
||||
const languageSelect = useRef<HTMLIonSelectElement>(null);
|
||||
const pseudo = useRef<HTMLIonInputElement>(null);
|
||||
const minTimeInterval = useRef<HTMLIonInputElement>(null);
|
||||
const minDistance = useRef<HTMLIonInputElement>(null);
|
||||
|
||||
const modal = useRef<HTMLIonModalElement>(null);
|
||||
|
||||
const dismiss = () => {
|
||||
modal.current?.dismiss();
|
||||
};
|
||||
|
||||
const save = () => {
|
||||
dispatch(
|
||||
settingsActions.saveSettings({
|
||||
|
@ -88,11 +90,19 @@ const Settings: React.FC<{}> = () => {
|
|||
minTimeInterval: minTimeInterval.current?.value,
|
||||
minDistance: minDistance.current?.value,
|
||||
},
|
||||
language: languageSelect.current?.value,
|
||||
})
|
||||
);
|
||||
dismiss();
|
||||
};
|
||||
|
||||
setI18nLanguage(localLanguage);
|
||||
|
||||
const dismiss = () => {
|
||||
modal.current?.dismiss();
|
||||
setLocalLanguage(settingsState.language);
|
||||
};
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<IonButton id='open-SettingsDialog'>
|
||||
|
@ -112,6 +122,27 @@ const Settings: React.FC<{}> = () => {
|
|||
</IonButtons>
|
||||
</IonToolbar>
|
||||
<IonContent>
|
||||
<IonList lines='full' class='ion-no-margin'>
|
||||
<IonListHeader lines='full'>
|
||||
<IonLabel>{i18n.language}</IonLabel>
|
||||
</IonListHeader>
|
||||
<IonItem>
|
||||
<IonLabel>{i18n.colonize(i18n.language)} </IonLabel>
|
||||
<IonSelect
|
||||
placeholder={i18n.languageSelect.placeHolder}
|
||||
ref={languageSelect}
|
||||
value={localLanguage}
|
||||
interface='popover'
|
||||
onIonChange={(ev) => setLocalLanguage(ev.detail.value)}
|
||||
>
|
||||
{i18n.languageSelect.choices.map((choice) => (
|
||||
<IonSelectOption key={choice.value} value={choice.value}>
|
||||
{choice.label}
|
||||
</IonSelectOption>
|
||||
))}
|
||||
</IonSelect>
|
||||
</IonItem>
|
||||
</IonList>
|
||||
<IonList lines='full' class='ion-no-margin'>
|
||||
<IonListHeader lines='full'>
|
||||
<IonLabel>{i18n.user}</IonLabel>
|
||||
|
|
|
@ -16,13 +16,20 @@ import { useDispatch, useSelector } from 'react-redux';
|
|||
import { enterAnimation, leaveAnimation } from '../../lib/animation';
|
||||
import { mapActions, MapState } from '../../store/map';
|
||||
import { tileProviders } from './tile';
|
||||
import i18n from '../../i18n/index';
|
||||
import i18n, { setI18nLanguage } from '../../i18n/index';
|
||||
import { SettingsState } from '../../store/settings';
|
||||
|
||||
const TileServerChooserDialog: React.FC<{}> = () => {
|
||||
const tileProvider = useSelector(
|
||||
(state: { map: MapState }) => state.map.scope.tileProvider
|
||||
) as keyof typeof tileProviders;
|
||||
|
||||
const language = useSelector(
|
||||
(state: { settings: SettingsState }) => state.settings.language
|
||||
);
|
||||
|
||||
setI18nLanguage(language);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const modal = useRef<HTMLIonModalElement>(null);
|
||||
|
|
|
@ -21,7 +21,9 @@ import { enterAnimation, leaveAnimation } from '../../lib/animation';
|
|||
import phoneRoute from '../../theme/icons/font-gis/svg/routing/uEB08-phone-route-nons.svg';
|
||||
import GpxImport from './gpx-import';
|
||||
import GpxExport from './GpxExport';
|
||||
import i18n from '../../i18n/index';
|
||||
import i18n, { setI18nLanguage } from '../../i18n/index';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { SettingsState } from '../../store/settings';
|
||||
|
||||
const TrackBrowser: React.FC<{}> = () => {
|
||||
const gpxes = useFind({
|
||||
|
@ -38,6 +40,13 @@ const TrackBrowser: React.FC<{}> = () => {
|
|||
modal.current?.dismiss();
|
||||
};
|
||||
|
||||
const language = useSelector(
|
||||
(state: { settings: SettingsState }) => state.settings.language
|
||||
);
|
||||
|
||||
setI18nLanguage(language);
|
||||
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<IonButton id='track-browser-button'>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { Fragment } from 'react';
|
||||
import LocalizedStrings from 'react-localization';
|
||||
|
||||
const strings = new LocalizedStrings({
|
||||
|
@ -9,6 +8,7 @@ const strings = new LocalizedStrings({
|
|||
cancel: 'Cancel',
|
||||
close: 'Close',
|
||||
settings: 'Settings',
|
||||
language: 'Language',
|
||||
user: 'User',
|
||||
pseudo: 'Pseudo',
|
||||
geolocation: 'Geolocation',
|
||||
|
@ -38,6 +38,15 @@ const strings = new LocalizedStrings({
|
|||
|
||||
chooseYourMap: 'Choose your map',
|
||||
|
||||
languageSelect: {
|
||||
placeHolder: 'Select your language',
|
||||
choices: [
|
||||
{ value: 'auto', label: 'Automatic' },
|
||||
{ value: 'en', label: 'English' },
|
||||
{ value: 'fr', label: 'Français' },
|
||||
],
|
||||
},
|
||||
|
||||
tracks: 'Tracks',
|
||||
},
|
||||
fr: {
|
||||
|
@ -47,6 +56,7 @@ const strings = new LocalizedStrings({
|
|||
cancel: 'Annuler',
|
||||
close: 'Fermer',
|
||||
settings: 'Paramètres',
|
||||
language: 'Langue',
|
||||
user: 'Utilisateur',
|
||||
pseudo: 'Pseudo',
|
||||
geolocation: 'Géolocalisation',
|
||||
|
@ -86,8 +96,25 @@ const strings = new LocalizedStrings({
|
|||
|
||||
chooseYourMap: 'Choisissez votre carte',
|
||||
|
||||
languageSelect: {
|
||||
placeHolder: 'Selectionner votre langue',
|
||||
choices: [
|
||||
{ value: 'auto', label: 'Automatique' },
|
||||
{ value: 'fr', label: 'Français' },
|
||||
{ value: 'en', label: 'English' },
|
||||
],
|
||||
},
|
||||
|
||||
tracks: 'Traces',
|
||||
},
|
||||
});
|
||||
|
||||
export default strings;
|
||||
|
||||
export const setI18nLanguage = (language: string) => {
|
||||
if (language === undefined || language === 'auto') {
|
||||
strings.setLanguage(strings.getInterfaceLanguage());
|
||||
} else {
|
||||
strings.setLanguage(language);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@ export interface SettingsState {
|
|||
minTimeInterval: number;
|
||||
minDistance: number;
|
||||
};
|
||||
language: 'auto'
|
||||
}
|
||||
|
||||
export const initialSettingsState: SettingsState = {
|
||||
|
@ -20,6 +21,7 @@ export const initialSettingsState: SettingsState = {
|
|||
minTimeInterval: 15000,
|
||||
minDistance: 10,
|
||||
},
|
||||
language: 'auto',
|
||||
};
|
||||
|
||||
const settingsSlice = createSlice({
|
||||
|
|
Loading…
Reference in New Issue