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

View File

@ -16,6 +16,7 @@ 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';
const TileServerChooserDialog: React.FC<{}> = () => {
const tileProvider = useSelector(
@ -35,7 +36,6 @@ const TileServerChooserDialog: React.FC<{}> = () => {
dismiss();
};
return (
<IonModal
ref={modal}
@ -44,9 +44,9 @@ const TileServerChooserDialog: React.FC<{}> = () => {
leaveAnimation={leaveAnimation}
>
<IonToolbar>
<IonTitle>Choose your map</IonTitle>
<IonTitle>{i18n.chooseYourMap}</IonTitle>
<IonButtons slot='end'>
<IonButton onClick={() => dismiss()}>Close</IonButton>
<IonButton onClick={() => dismiss()}>{i18n.close}</IonButton>
</IonButtons>
</IonToolbar>
<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 GpxImport from './gpx-import';
import GpxExport from './GpxExport';
import i18n from '../../i18n/index';
const TrackBrowser: React.FC<{}> = () => {
const gpxes = useFind({
@ -50,10 +51,10 @@ const TrackBrowser: React.FC<{}> = () => {
leaveAnimation={leaveAnimation}
>
<IonToolbar>
<IonTitle>Tracks</IonTitle>
<IonTitle>{i18n.tracks}</IonTitle>
<IonButtons slot='end'>
<GpxImport />
<IonButton onClick={() => dismiss()}>Close</IonButton>
<IonButton onClick={() => dismiss()}>{i18n.close}</IonButton>
</IonButtons>
</IonToolbar>
<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;