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 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();
const initialScope: MapScope = {
center: { lat: -37.8403508, lon: 77.5539501 },
zoom: 13,
tileProvider: 'osm',
};
const scopeAtom = atomWithHash('scope', initialScope);
/**
*
* @returns The root app component
*/
const App: React.FC = () => (
<IonApp>
<IonReactRouter>
<IonRouterOutlet>
<Route exact path='/home'>
<LiveMap
scope={{
center: { lat: -37.8403508, lon: 77.5539501 },
zoom: 13,
tileProvider: 'osm',
}}
numberOfTiledLayers={5}
/>
</Route>
<Route exact path='/'>
<Redirect to='/home' />
</Route>
</IonRouterOutlet>
</IonReactRouter>
</IonApp>
);
const App: React.FC = () => {
const [scope, setScope] = useAtom(scopeAtom);
console.log(`App, scope: ${JSON.stringify(scope)}`);
return (
<IonApp>
<IonReactRouter>
<IonRouterOutlet>
<Route exact path='/home'>
<LiveMap
scope={scope}
setScope={debounce(setScope, 1000)}
numberOfTiledLayers={5}
/>
</Route>
<Route exact path='/'>
<Redirect to='/home' />
</Route>
</IonRouterOutlet>
</IonReactRouter>
</IonApp>
);
};
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 Map from './Map';
import Handlers from './Handlers';
@ -31,26 +31,33 @@ export interface Transformation {
}
export interface LiveMapProperties {
/** The initial map's scope */
scope: MapScope;
/** The number of tiled layers (default to 1) */
numberOfTiledLayers?: number;
/** If provided, a function to call when the scope is updated. */
setScope?: (scope: MapScope) => void;
}
/**
*
* @param props
*
* @param props
* @returns A `<LiveMap>` component.
*
*
* A `<LiveMap>` is a wrapper around a {@link components/map/Map!Map} component which updates the `<Map>`'s scope according to user's mouse, wheel and touch events.
*
*
* To do so, `<LiveMap>` embeds a `<Map>` component together with a {@link components/map/Handlers!Handlers} component which listens to user's event.
*
*
* The main task of `<LiveMap>` components is thus to translate {@link Transformation}s delivered by `<Handler>` in pixels into geographical coordinates.
*/
export const LiveMap: react.FC<LiveMapProperties> = (
props: LiveMapProperties
) => {
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 deltaZoom = t.deltaZoom === null ? 1 : t.deltaZoom;
const deltaZoomLevel = Math.log2(deltaZoom);
@ -114,6 +121,9 @@ export const LiveMap: react.FC<LiveMapProperties> = (
// }, delta lon: ${newScope.center.lon - scope.center.lon}`
// );
setScope(newScope);
if (props.setScope !== undefined) {
props.setScope(newScope);
}
};
return (