Using atomWithHash to enable back/forward actions.

This commit is contained in:
Eric van der Vlist 2022-11-01 17:58:57 +01:00
parent e1583846ed
commit fe9cc6437d
2 changed files with 52 additions and 28 deletions

View File

@ -22,32 +22,46 @@ import '@ionic/react/css/display.css';
import './theme/variables.css'; import './theme/variables.css';
import LiveMap from './components/map/LiveMap'; import LiveMap from './components/map/LiveMap';
import { useAtom } from 'jotai';
import { atomWithHash } from 'jotai/utils';
import { MapScope } from './components/map/types';
import { debounce } from 'lodash';
setupIonicReact(); setupIonicReact();
const initialScope: MapScope = {
center: { lat: -37.8403508, lon: 77.5539501 },
zoom: 13,
tileProvider: 'osm',
};
const scopeAtom = atomWithHash('scope', initialScope);
/** /**
* *
* @returns The root app component * @returns The root app component
*/ */
const App: React.FC = () => ( const App: React.FC = () => {
<IonApp> const [scope, setScope] = useAtom(scopeAtom);
<IonReactRouter>
<IonRouterOutlet> console.log(`App, scope: ${JSON.stringify(scope)}`);
<Route exact path='/home'> return (
<LiveMap <IonApp>
scope={{ <IonReactRouter>
center: { lat: -37.8403508, lon: 77.5539501 }, <IonRouterOutlet>
zoom: 13, <Route exact path='/home'>
tileProvider: 'osm', <LiveMap
}} scope={scope}
numberOfTiledLayers={5} setScope={debounce(setScope, 1000)}
/> numberOfTiledLayers={5}
</Route> />
<Route exact path='/'> </Route>
<Redirect to='/home' /> <Route exact path='/'>
</Route> <Redirect to='/home' />
</IonRouterOutlet> </Route>
</IonReactRouter> </IonRouterOutlet>
</IonApp> </IonReactRouter>
); </IonApp>
);
};
export default App; export default App;

View File

@ -1,4 +1,4 @@
import react, { useState } from 'react'; import react, { useEffect, useState } from 'react';
import { MapScope, Point } from './types'; import { MapScope, Point } from './types';
import Map from './Map'; import Map from './Map';
import Handlers from './Handlers'; import Handlers from './Handlers';
@ -31,8 +31,12 @@ export interface Transformation {
} }
export interface LiveMapProperties { export interface LiveMapProperties {
/** The initial map's scope */
scope: MapScope; scope: MapScope;
/** The number of tiled layers (default to 1) */
numberOfTiledLayers?: number; numberOfTiledLayers?: number;
/** If provided, a function to call when the scope is updated. */
setScope?: (scope: MapScope) => void;
} }
/** /**
@ -50,7 +54,10 @@ export const LiveMap: react.FC<LiveMapProperties> = (
props: LiveMapProperties props: LiveMapProperties
) => { ) => {
const [scope, setScope] = useState(props.scope); const [scope, setScope] = useState(props.scope);
// console.log(`LiveMap rendering: ${JSON.stringify(scope)}`); useEffect(() => {
setScope(props.scope);
}, [props.scope]);
console.log(`LiveMap rendering: ${JSON.stringify(scope)}`);
const transform = (t: Transformation) => { const transform = (t: Transformation) => {
const deltaZoom = t.deltaZoom === null ? 1 : t.deltaZoom; const deltaZoom = t.deltaZoom === null ? 1 : t.deltaZoom;
const deltaZoomLevel = Math.log2(deltaZoom); const deltaZoomLevel = Math.log2(deltaZoom);
@ -114,6 +121,9 @@ export const LiveMap: react.FC<LiveMapProperties> = (
// }, delta lon: ${newScope.center.lon - scope.center.lon}` // }, delta lon: ${newScope.center.lon - scope.center.lon}`
// ); // );
setScope(newScope); setScope(newScope);
if (props.setScope !== undefined) {
props.setScope(newScope);
}
}; };
return ( return (