I18n using react-localization (#8)

This commit is contained in:
Eric van der Vlist 2022-10-04 19:04:49 +02:00
parent 16e439db41
commit 2612d7a3b4
7 changed files with 114 additions and 50 deletions

View File

@ -95,5 +95,6 @@
"devDependencies": { "devDependencies": {
"@types/lodash": "^4.14.184" "@types/lodash": "^4.14.184"
}, },
"description": "An Ionic project" "description": "An Ionic project",
"postinstall": "npx patch-package"
} }

View File

@ -0,0 +1,15 @@
diff --git a/node_modules/localized-strings/lib/LocalizedStrings.js b/node_modules/localized-strings/lib/LocalizedStrings.js
index eefa6c8..e0a3cae 100644
--- a/node_modules/localized-strings/lib/LocalizedStrings.js
+++ b/node_modules/localized-strings/lib/LocalizedStrings.js
@@ -192,8 +192,8 @@ var LocalizedStrings = function () {
if (_this4._opts.logsEnabled) {
console.log("\uD83D\uDEA7 \uD83D\uDC77 key '" + key + "' not found in localizedStrings for language " + _this4._language + " \uD83D\uDEA7");
}
- } else if (typeof strings[key] !== "string") {
- // It's an object
+ } else if (typeof strings[key] !== "string" && defaultStrings[key].$$typeof === undefined) {
+ // It's an object (and it's not a React component)
_this4._fallbackValues(defaultStrings[key], strings[key]);
}
});

View File

@ -29,6 +29,9 @@ import { useDispatch, useSelector } from 'react-redux';
import { mapActions } from '../../store/map'; import { mapActions } from '../../store/map';
import { SettingsState } from '../../store/settings'; import { SettingsState } from '../../store/settings';
import i18n from '../../i18n/index';
declare global { declare global {
var $lastValidLocationTime: number; var $lastValidLocationTime: number;
} }
@ -144,9 +147,9 @@ const GpxRecord: React.FC<{}> = () => {
leaveAnimation={leaveAnimation} leaveAnimation={leaveAnimation}
> >
<IonToolbar> <IonToolbar>
<IonTitle>Track recording</IonTitle> <IonTitle>{i18n.trackRecording}</IonTitle>
<IonButtons slot='end'> <IonButtons slot='end'>
<IonButton onClick={() => dismiss()}>Close</IonButton> <IonButton onClick={() => dismiss()}>{i18n.close}</IonButton>
</IonButtons> </IonButtons>
</IonToolbar> </IonToolbar>
<IonContent> <IonContent>
@ -159,9 +162,9 @@ const GpxRecord: React.FC<{}> = () => {
> >
<IonIcon slot='start' icon={recording}></IonIcon> <IonIcon slot='start' icon={recording}></IonIcon>
{hasCurrentTrack ? ( {hasCurrentTrack ? (
<span>Resume recording</span> <span>{i18n.resumeRecording}</span>
) : ( ) : (
<span>Start recording</span> <span>{i18n.startRecording}</span>
)} )}
</IonButton> </IonButton>
)} )}
@ -172,7 +175,7 @@ const GpxRecord: React.FC<{}> = () => {
size='large' size='large'
onClick={pauseRecording} onClick={pauseRecording}
> >
<IonIcon slot='start' icon={pauseCircle}></IonIcon>Pause <IonIcon slot='start' icon={pauseCircle}></IonIcon>{i18n.pauseRecording}
</IonButton> </IonButton>
)} )}
{hasCurrentTrack && ( {hasCurrentTrack && (
@ -183,9 +186,7 @@ const GpxRecord: React.FC<{}> = () => {
size='large' size='large'
onClick={stopRecording} onClick={stopRecording}
> >
<IonIcon slot='start' icon={stop}></IonIcon>Stop recording <IonIcon slot='start' icon={stop}></IonIcon>{i18n.stopRecording}
<br />
(and save track)
</IonButton> </IonButton>
<IonButton <IonButton
expand='block' expand='block'
@ -193,10 +194,7 @@ const GpxRecord: React.FC<{}> = () => {
size='large' size='large'
onClick={deleteRecording} onClick={deleteRecording}
> >
<IonIcon slot='start' icon={closeCircle}></IonIcon>Cancel <IonIcon slot='start' icon={closeCircle}></IonIcon>{i18n.cancelRecording}
recording
<br />
(and clear track)
</IonButton> </IonButton>
</> </>
)} )}

View File

@ -16,6 +16,7 @@ import { useDispatch, useSelector } from 'react-redux';
import { enterAnimation, leaveAnimation } from '../../lib/animation'; import { enterAnimation, leaveAnimation } from '../../lib/animation';
import { mapActions, MapState } from '../../store/map'; import { mapActions, MapState } from '../../store/map';
import { tileProviders } from './tile'; import { tileProviders } from './tile';
import i18n from '../../i18n/index';
const TileServerChooserDialog: React.FC<{}> = () => { const TileServerChooserDialog: React.FC<{}> = () => {
const tileProvider = useSelector( const tileProvider = useSelector(
@ -35,7 +36,6 @@ const TileServerChooserDialog: React.FC<{}> = () => {
dismiss(); dismiss();
}; };
return ( return (
<IonModal <IonModal
ref={modal} ref={modal}
@ -44,9 +44,9 @@ const TileServerChooserDialog: React.FC<{}> = () => {
leaveAnimation={leaveAnimation} leaveAnimation={leaveAnimation}
> >
<IonToolbar> <IonToolbar>
<IonTitle>Choose your map</IonTitle> <IonTitle>{i18n.chooseYourMap}</IonTitle>
<IonButtons slot='end'> <IonButtons slot='end'>
<IonButton onClick={() => dismiss()}>Close</IonButton> <IonButton onClick={() => dismiss()}>{i18n.close}</IonButton>
</IonButtons> </IonButtons>
</IonToolbar> </IonToolbar>
<IonContent> <IonContent>

View File

@ -21,6 +21,7 @@ import { enterAnimation, leaveAnimation } from '../../lib/animation';
import phoneRoute from '../../theme/icons/font-gis/svg/routing/uEB08-phone-route-nons.svg'; import phoneRoute from '../../theme/icons/font-gis/svg/routing/uEB08-phone-route-nons.svg';
import GpxImport from './gpx-import'; import GpxImport from './gpx-import';
import GpxExport from './GpxExport'; import GpxExport from './GpxExport';
import i18n from '../../i18n/index';
const TrackBrowser: React.FC<{}> = () => { const TrackBrowser: React.FC<{}> = () => {
const gpxes = useFind({ const gpxes = useFind({
@ -50,10 +51,10 @@ const TrackBrowser: React.FC<{}> = () => {
leaveAnimation={leaveAnimation} leaveAnimation={leaveAnimation}
> >
<IonToolbar> <IonToolbar>
<IonTitle>Tracks</IonTitle> <IonTitle>{i18n.tracks}</IonTitle>
<IonButtons slot='end'> <IonButtons slot='end'>
<GpxImport /> <GpxImport />
<IonButton onClick={() => dismiss()}>Close</IonButton> <IonButton onClick={() => dismiss()}>{i18n.close}</IonButton>
</IonButtons> </IonButtons>
</IonToolbar> </IonToolbar>
<IonContent> <IonContent>

View File

@ -1,32 +0,0 @@
import LocalizedStrings from 'react-localization';
const strings = new LocalizedStrings({
en: {
colonize: (input: string): any => strings.formatString('{0}:', input),
save: 'Save',
cancel: 'Cancel',
close: 'Close',
settings: 'Settings',
user: 'User',
pseudo: 'Pseudo',
geolocation: 'Geolocation',
minTimeInt: 'Minimal time interval (ms)',
minDist:'Minimal distance (m)',
},
fr: {
colonize: (input: string): any => strings.formatString('{0} :', input),
save: 'Sauvegarder',
cancel: 'Annuler',
close: 'Fermer',
settings: 'Paramètres',
user: 'Utilisateur',
pseudo: 'Pseudo',
geolocation: 'Géolocalisation',
minTimeInt: 'Interval minimal (ms)',
minDist:'Distance minimale (m)',
},
});
export default strings;

81
src/i18n/index.tsx Normal file
View File

@ -0,0 +1,81 @@
import { Fragment } from 'react';
import LocalizedStrings from 'react-localization';
const strings = new LocalizedStrings({
en: {
colonize: (input: string): any => strings.formatString('{0}:', input),
save: 'Save',
cancel: 'Cancel',
close: 'Close',
settings: 'Settings',
user: 'User',
pseudo: 'Pseudo',
geolocation: 'Geolocation',
minTimeInt: 'Minimal time interval (ms)',
minDist: 'Minimal distance (m)',
trackRecording: 'Track recording',
resumeRecording: 'Resume recording',
startRecording: 'Start recording',
pauseRecording: 'Pause',
// stopRecording: 'stop',
// cancelRecording: 'cancel',
stopRecording: (
<Fragment key='x'>
Stop recording
<br key='x'/>
(and save track)
</Fragment>
),
cancelRecording: (
<Fragment key='x'>
Cancel recording
<br key='x'/>
(and clear track)
</Fragment>
),
chooseYourMap: 'Choose your map',
tracks: 'Tracks',
},
fr: {
colonize: (input: string): any => strings.formatString('{0} :', input),
save: 'Sauvegarder',
cancel: 'Annuler',
close: 'Fermer',
settings: 'Paramètres',
user: 'Utilisateur',
pseudo: 'Pseudo',
geolocation: 'Géolocalisation',
minTimeInt: 'Interval minimal (ms)',
minDist: 'Distance minimale (m)',
trackRecording: 'Enregistrement de trace',
resumeRecording: "Reprendre l'enregistrement",
startRecording: "Démarre l'enregistrement",
pauseRecording: 'Pause',
stopRecording: (
<Fragment key='x'>
Arrêter
<br key='x'/>
(et sauvegarder)
</Fragment>
),
cancelRecording: (
<Fragment key='x'>
Annuler
<br key='x'/>
(et effacer)
</Fragment>
),
chooseYourMap: 'Choisissez votre carte',
tracks: 'Traces',
},
});
export default strings;