Localization (and language chooser)...

This commit is contained in:
Eric van der Vlist 2022-10-08 17:33:32 +02:00
parent 653574025e
commit 5822198f92
6 changed files with 93 additions and 10 deletions

View File

@ -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);

View File

@ -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>

View File

@ -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);

View File

@ -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'>

View File

@ -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);
}
};

View File

@ -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({