diff --git a/package.json b/package.json
index fd58052..c0dca8f 100644
--- a/package.json
+++ b/package.json
@@ -24,6 +24,7 @@
"ionicons": "^6.0.4",
"isomorphic-xml2js": "^0.1.3",
"jotai": "^1.10.0",
+ "jotai-location": "^0.2.0",
"lodash": "^4.17.21",
"pouchdb": "^7.3.1",
"pouchdb-browser": "^7.3.1",
diff --git a/src/App.tsx b/src/App.tsx
index a6f5749..1c14002 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -32,7 +32,7 @@ import dispatch from './workers/dispatcher-main';
import LiveMap from './components/map/LiveMap';
import { atom, useAtom } from 'jotai';
-import { atomWithHash } from 'jotai/utils';
+import { atomWithHash } from 'jotai-location';
import { MapScope } from './components/map/types';
import { debounce } from 'lodash';
import GetLocation from './components/buttons/GetLocation';
@@ -42,6 +42,7 @@ import Forward from './components/buttons/Forward';
import CurrentLocation from './components/map/CurrentLocation';
import GpxImport from './components/dialogs/GpxImport';
import Gpxes from './components/map/Gpxes';
+import MapChooser from './components/dialogs/MapChooser';
// import { initDb } from './db';
// import PouchDB from 'pouchdb';
// import PouchDBFind from 'pouchdb-find';
@@ -93,6 +94,18 @@ export const setCenterAtom = atom(null, (get, set, center: geoPoint) => {
set(scopeAtom, newScope);
});
+export const tileProviderAtom = atom(
+ (get) => get(scopeAtom).tileProvider,
+ (get, set, tileProvider: string) => {
+ const previousScope = get(scopeAtom);
+ const newScope: MapScope = {
+ ...previousScope,
+ tileProvider,
+ };
+ set(scopeAtom, newScope);
+ }
+);
+
// const db = new PouchDB('dyomedea', { auto_compaction: true, revs_limit: 10 });
// initDb(db);
@@ -129,6 +142,7 @@ const App: React.FC = () => {
+
diff --git a/src/components/dialogs/MapChooser.tsx b/src/components/dialogs/MapChooser.tsx
new file mode 100644
index 0000000..3fae7d6
--- /dev/null
+++ b/src/components/dialogs/MapChooser.tsx
@@ -0,0 +1,78 @@
+import react, { useRef } from 'react';
+
+import {
+ IonButton,
+ IonButtons,
+ IonContent,
+ IonIcon,
+ IonItem,
+ IonLabel,
+ IonList,
+ IonModal,
+ IonRadio,
+ IonRadioGroup,
+ IonTitle,
+ IonToolbar,
+} from '@ionic/react';
+import { layersOutline } from 'ionicons/icons';
+import { nonFakeTileProviders } from '../map/tile-providers';
+import { tileProviderAtom } from '../../App';
+import i18n from '../../i18n/index';
+import { useAtom } from 'jotai';
+
+import cssDialog from './dialogs.module.css';
+
+export interface MapChooserProperties {}
+
+export const MapChooser: react.FC = (
+ props: MapChooserProperties
+) => {
+ const modal = useRef(null);
+
+ const dismiss = () => {
+ modal.current?.dismiss();
+ };
+
+ const [tileProvider, setTileProvider] = useAtom(tileProviderAtom);
+
+ const changeHandler = (event: any) => {
+ setTileProvider(event.detail.value);
+ dismiss();
+ };
+
+ return (
+ <>
+
+
+
+
+
+ {i18n.mapChooser.chooseYourMap}
+
+ dismiss()}>{i18n.common.close}
+
+
+
+
+
+ {Object.keys(nonFakeTileProviders).map((provider) => {
+ return (
+
+ {nonFakeTileProviders[provider].name}
+
+
+ );
+ })}
+
+
+
+
+ >
+ );
+};
+
+export default MapChooser;
diff --git a/src/components/dialogs/dialogs.module.css b/src/components/dialogs/dialogs.module.css
new file mode 100644
index 0000000..a5d5493
--- /dev/null
+++ b/src/components/dialogs/dialogs.module.css
@@ -0,0 +1,15 @@
+.modal {
+ --height: 100%;
+ --border-radius: 16px;
+ --box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1),
+ 0 4px 6px -4px rgb(0 0 0 / 0.1);
+}
+
+.modal ion-toolbar {
+ --background: rgba(14, 116, 144, 0.7);
+ --color: white;
+}
+
+.modal ion-content {
+ background-color: rgba(255, 255, 255, 0.7);
+}
diff --git a/src/components/map/tile-providers.tsx b/src/components/map/tile-providers.tsx
index 7fc499c..8fb86de 100644
--- a/src/components/map/tile-providers.tsx
+++ b/src/components/map/tile-providers.tsx
@@ -133,6 +133,8 @@ export const tileProviders: TileProviders = {
},
};
+export const { fake, ...nonFakeTileProviders } = tileProviders;
+
const mod = (n: number, m: number) => {
const jsMod = n % m;
return jsMod >= 0 ? jsMod : jsMod + m;
diff --git a/src/i18n/index.tsx b/src/i18n/index.tsx
new file mode 100644
index 0000000..d9a1f63
--- /dev/null
+++ b/src/i18n/index.tsx
@@ -0,0 +1,36 @@
+import LocalizedStrings from 'react-localization';
+
+const strings = new LocalizedStrings({
+ en: {
+ colonize: (input: string): any => strings.formatString('{0}:', input),
+
+ common: { save: 'Save', cancel: 'Cancel', close: 'Close' },
+
+ mapChooser: {
+ chooseYourMap: 'Choose your map',
+ },
+ },
+ fr: {
+ colonize: (input: string): any => strings.formatString('{0} :', input),
+
+ common: {
+ save: 'Sauvegarder',
+ cancel: 'Annuler',
+ close: 'Fermer',
+ },
+
+ mapChooser: {
+ chooseYourMap: 'Choisissez votre carte',
+ },
+ },
+});
+
+export default strings;
+
+export const setI18nLanguage = (language: string) => {
+ if (language === undefined || language === 'auto') {
+ strings.setLanguage(strings.getInterfaceLanguage());
+ } else {
+ strings.setLanguage(language);
+ }
+};