Skip to content

Commit

Permalink
refactor(store): Refactor north arrow to use the store and remove api…
Browse files Browse the repository at this point in the history
… from footer element

Closes #1329
  • Loading branch information
Johann Levesque authored and Johann Levesque committed Oct 4, 2023
1 parent da0b3f6 commit eaa360e
Show file tree
Hide file tree
Showing 21 changed files with 408 additions and 384 deletions.
4 changes: 2 additions & 2 deletions packages/geoview-core/public/templates/default-config.html
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ <h4 id="HLCONF4">4. Load layers with bad config values</h4>
}
]
},
'components': ['overview-map', 'nav-bar'],
'components': ['overview-map'],
'corePackages': [],
'theme': 'dark',
'suportedLanguages': ['en']
Expand Down Expand Up @@ -268,7 +268,7 @@ <h4 id="HLCONF7">7. Load config from function call</h4>
]
}]
},
'components': ['app-bar', 'overview-map', 'nav-bar'],
'components': ['overview-map', 'nav-bar'],
'corePackages': [],
'theme': 'dark',
'suportedLanguages': ['en']
Expand Down
4 changes: 2 additions & 2 deletions packages/geoview-core/public/templates/projections.html
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ <h4 id="HPRJ1">1. Web Mercator Projection</h4>
'labeled': true
}
},
'components': ['overview-map'],
'components': ['overview-map', 'north-arrow'],
'corePackages': [],
'theme': 'dark',
'suportedLanguages': ['en']
Expand Down Expand Up @@ -103,7 +103,7 @@ <h4 id="HPRJ2">2. LCC Projection</h4>
'labeled': true
}
},
'components': ['overview-map'],
'components': ['overview-map', 'north-arrow'],
'corePackages': [],
'theme': 'dark',
'suportedLanguages': ['en']
Expand Down
47 changes: 45 additions & 2 deletions packages/geoview-core/src/api/eventProcessors/map-event-process.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import { GeoViewStoreType } from '@/core/stores/geoview-store';
import { AbstractEventProcessor } from './abstract-event-processor';
import { api } from '@/app';
import { mapPayload, lngLatPayload, mapMouseEventPayload, numberPayload } from '@/api/events/payloads';
import {
mapPayload,
lngLatPayload,
mapMouseEventPayload,
numberPayload,
payloadIsAMapViewProjection,
PayloadBaseClass,
mapViewProjectionPayload,
} from '@/api/events/payloads';
import { EVENT_NAMES } from '@/api/events/event-types';

export class MapEventProcessor extends AbstractEventProcessor {
Expand Down Expand Up @@ -35,6 +43,18 @@ export class MapEventProcessor extends AbstractEventProcessor {
}
);

const unsubMapProjection = store.subscribe(
(state) => state.mapState.currentProjection,
(cur, prev) => {
// because emit and on from api events can be trigger in loop, compare also the api value
if (cur !== prev && api.maps[mapId].currentProjection !== cur!) {
console.log(`proj emit ${mapId}`);

Check warning on line 51 in packages/geoview-core/src/api/eventProcessors/map-event-process.ts

View workflow job for this annotation

GitHub Actions / Build demo files / build-geoview

Unexpected console statement
api.maps[mapId].currentProjection = cur!;
api.event.emit(mapViewProjectionPayload(EVENT_NAMES.MAP.EVENT_MAP_VIEW_PROJECTION_CHANGE, mapId, cur!));
}
}
);

const unsubMapZoom = store.subscribe(
(state) => state.mapState.zoom,
(cur, prev) => {
Expand All @@ -55,7 +75,30 @@ export class MapEventProcessor extends AbstractEventProcessor {
}
);

// TODO: add a destroy events on store/map destroy
api.event.on(
EVENT_NAMES.MAP.EVENT_MAP_VIEW_PROJECTION_CHANGE,
(payload: PayloadBaseClass) => {
// because emit and on from api events can be trigger in loop, compare also the api value
if (payloadIsAMapViewProjection(payload) && api.maps[mapId].currentProjection !== payload.projection!) {
console.log(`proj on ${mapId}`);

Check warning on line 84 in packages/geoview-core/src/api/eventProcessors/map-event-process.ts

View workflow job for this annotation

GitHub Actions / Build demo files / build-geoview

Unexpected console statement
api.maps[mapId].currentProjection = payload.projection!;
store.setState({
mapState: { ...store.getState().mapState, currentProjection: payload.projection! },
});
}
},
mapId
);

// add to arr of subscriptions so it can be destroyed later
this.subscriptionArr.push(unsubMapLoaded, unsubMapCenterCoord, unsubMapPointerPosition, unsubMapZoom, unsubMapSingleClick);
this.subscriptionArr.push(
unsubMapLoaded,
unsubMapCenterCoord,
unsubMapPointerPosition,
unsubMapProjection,
unsubMapZoom,
unsubMapSingleClick
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
diff a/packages/geoview-core/src/api/eventProcessors/map-event-process.ts b/packages/geoview-core/src/api/eventProcessors/map-event-process.ts (rejected hunks)
@@ -35,12 +35,12 @@
}
);

- const unsubMapZoom = store.subscribe(
- (state) => state.mapState.zoom,
+ const unsubMapProjection = store.subscribe(
+ (state) => state.mapState.currentProjection,
(cur, prev) => {
if (cur !== prev) {
- api.maps[mapId].currentZoom = cur!;
- api.event.emit(numberPayload(EVENT_NAMES.MAP.EVENT_MAP_ZOOM_END, mapId, cur!));
+ api.maps[mapId].currentProjection = cur!;
+ api.event.emit(mapViewProjectionPayload(EVENT_NAMES.MAP.EVENT_MAP_VIEW_PROJECTION_CHANGE, mapId, cur!));
}
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { useStore } from 'zustand';
import { getGeoViewStore } from '@/core/stores/stores-managers';

import { MapContext } from '@/core/app-start';
import { api } from '@/app';
import { Tooltip, Box } from '@/ui';

const useStyles = makeStyles((theme) => ({
Expand Down Expand Up @@ -150,11 +149,10 @@ export function Attribution(): JSX.Element {
const attributionTextRef = useRef<Array<string>>([]);

// get the expand or collapse from store
const mapElement = useStore(getGeoViewStore(mapId), (state) => state.mapState.mapElement);
const expanded = useStore(getGeoViewStore(mapId), (state) => state.footerBarState.expanded);

useEffect(() => {
const { map } = api.maps[mapId];

const attributionTextElement = document.getElementById(`${mapId}-attribution-text`) as HTMLElement;

const attributionControl = new CustomAttribution(
Expand All @@ -180,10 +178,10 @@ export function Attribution(): JSX.Element {
}
attributionControl.formatAttribution();

map.addControl(attributionControl);
mapElement.addControl(attributionControl);

return () => {
map.removeControl(attributionControl);
mapElement.removeControl(attributionControl);
};
}, [mapId]);

Check warning on line 186 in packages/geoview-core/src/core/components/attribution/attribution.tsx

View workflow job for this annotation

GitHub Actions / Build demo files / build-geoview

React Hook useEffect has a missing dependency: 'mapElement'. Either include it or remove the dependency array

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ export function ClickMarker(): JSX.Element {
element: document.getElementById(clickMarkerId) as HTMLElement,
stopEvent: false,
});
api.maps[mapId].map.addOverlay(clickMarkerOverlay);

// TODO: repair using the store map element
//! came from the map creation on function call
if (api.maps[mapId].map !== undefined) api.maps[mapId].map.addOverlay(clickMarkerOverlay);

// create resources to highlight features
const animationSource = new VectorSource();
Expand Down Expand Up @@ -86,7 +89,7 @@ export function ClickMarker(): JSX.Element {
api.maps[mapId].map
.getOverlayById(`${mapId}-clickmarker`)
.setPosition(fromLonLat(lnglat, `EPSG:${api.maps[mapId].currentProjection}`));
}, 0);
}, 100);
setShowMarker(true);
}

Expand Down
50 changes: 29 additions & 21 deletions packages/geoview-core/src/core/components/crosshair/crosshair.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { KeyboardPan } from 'ol/interaction';
import { useStore } from 'zustand';
import { MapContext } from '@/core/app-start';

import { api } from '@/app';
import { TypeEventHandlerFunction, api } from '@/app';
import { EVENT_NAMES } from '@/api/events/event-types';
import { CrosshairIcon } from './crosshair-icon';

Expand Down Expand Up @@ -125,31 +125,39 @@ export function Crosshair(): JSX.Element {
useEffect(() => {
const { map } = api.maps[mapId];

const mapContainer = map.getTargetElement();

const eventMapInKeyFocusListenerFunction = (payload: PayloadBaseClass) => {
if (payloadIsAInKeyfocus(payload)) {
if (interaction !== 'static') {
store.setState({ isCrosshairsActive: true });

mapContainer.addEventListener('keydown', simulateClick);
mapContainer.addEventListener('keydown', managePanDelta);
panelButtonId.current = 'detailsPanel';
// TODO: repair using the store map element
//! came fromt he map creation on function call
let eventMapInKeyFocusListenerFunction: TypeEventHandlerFunction;
if (map !== undefined) {
const mapContainer = map.getTargetElement();

eventMapInKeyFocusListenerFunction = (payload: PayloadBaseClass) => {
if (payloadIsAInKeyfocus(payload)) {
if (interaction !== 'static') {
store.setState({ isCrosshairsActive: true });

mapContainer.addEventListener('keydown', simulateClick);
mapContainer.addEventListener('keydown', managePanDelta);
panelButtonId.current = 'detailsPanel';
}
}
}
};
};

// on map keyboard focus, add crosshair
api.event.on(EVENT_NAMES.MAP.EVENT_MAP_IN_KEYFOCUS, eventMapInKeyFocusListenerFunction, mapId);
// on map keyboard focus, add crosshair
api.event.on(EVENT_NAMES.MAP.EVENT_MAP_IN_KEYFOCUS, eventMapInKeyFocusListenerFunction, mapId);

// when map blur, remove the crosshair and click event
mapContainer.addEventListener('blur', removeCrosshair);
// when map blur, remove the crosshair and click event
mapContainer.addEventListener('blur', removeCrosshair);
}

return () => {
api.event.off(EVENT_NAMES.MAP.EVENT_MAP_IN_KEYFOCUS, mapId, eventMapInKeyFocusListenerFunction);
mapContainer.removeEventListener('keydown', simulateClick);
mapContainer.removeEventListener('keydown', managePanDelta);
mapContainer.removeEventListener('keydown', removeCrosshair);
if (map !== undefined) {
api.event.off(EVENT_NAMES.MAP.EVENT_MAP_IN_KEYFOCUS, mapId, eventMapInKeyFocusListenerFunction);
const mapContainer = map.getTargetElement();
mapContainer.removeEventListener('keydown', simulateClick);
mapContainer.removeEventListener('keydown', managePanDelta);
mapContainer.removeEventListener('keydown', removeCrosshair);
}
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,7 @@ import { getGeoViewStore } from '@/core/stores/stores-managers';

import { ExpandMoreIcon, ExpandLessIcon, IconButton, Box } from '@/ui';
import { MapContext } from '@/core/app-start';

const sxClasses = {
expandbuttonContainer: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: 'primary.light',
height: '30px',
width: '30px',
marginLeft: '5px',
},
};
import { sxClassesExportButton } from './footer-bar-style';

/**
* Footerbar Expand Button component
Expand Down Expand Up @@ -79,7 +68,7 @@ export function FooterbarExpandButton(): JSX.Element {

return (
<Box>
<IconButton sx={sxClasses.expandbuttonContainer} onClick={() => (expanded ? collapseFooterbar() : expandFooterbar())}>
<IconButton sx={sxClassesExportButton.expandbuttonContainer} onClick={() => (expanded ? collapseFooterbar() : expandFooterbar())}>
{expanded ? <ExpandMoreIcon /> : <ExpandLessIcon />}
</IconButton>
</Box>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
import React, { useContext, useEffect, useState } from 'react';
import { useContext } from 'react';

import { useTranslation } from 'react-i18next';

import { useStore } from 'zustand';
import { getGeoViewStore } from '@/core/stores/stores-managers';

import { Switch } from '@/ui';

import { api } from '@/app';
import { MapContext } from '@/core/app-start';

import { PROJECTION_NAMES } from '@/geo/projection/projection';

import { EVENT_NAMES } from '@/api/events/event-types';
import { PayloadBaseClass, booleanPayload, payloadIsAMapViewProjection } from '@/api/events/payloads';

/**
* Footerbar Fix North Switch component
*
Expand All @@ -26,54 +20,34 @@ export function FooterbarFixNorthSwitch(): JSX.Element {

const { t } = useTranslation<string>();

const [mapProjection, setMapProjection] = useState(`EPSG:${api.maps[mapId].currentProjection}`);
const [switchChecked, setSwitchChecked] = useState(false);
const [isNorthEnable] = useState(api.maps[mapId].mapFeaturesConfig.components!.indexOf('north-arrow') > -1);

// get the expand or collapse from store
const expanded = useStore(getGeoViewStore(mapId), (state) => state.footerBarState.expanded);
const mapElement = useStore(getGeoViewStore(mapId), (state) => state.mapState.mapElement);
const isNorthEnable = useStore(getGeoViewStore(mapId), (state) => state.mapState.northArrow);
const isFixNorth = useStore(getGeoViewStore(mapId), (state) => state.mapState.fixNorth);
const mapProjection = `EPSG:${useStore(getGeoViewStore(mapId), (state) => state.mapState.currentProjection)}`;

/**
* Emit an event to specify the map to rotate to keep north straight
*/
const fixNorth = (event: React.ChangeEvent<HTMLInputElement>) => {
setSwitchChecked(!switchChecked);

// this event will be listen by the north-arrow.tsx component
api.event.emit(booleanPayload(EVENT_NAMES.MAP.EVENT_MAP_FIX_NORTH, mapId, event.target.checked));
getGeoViewStore(mapId).setState({
mapState: { ...getGeoViewStore(mapId).getState().mapState, fixNorth: event.target.checked },
});

// if unchecked, reset rotation
if (!event.target.checked) {
const { map } = api.maps[mapId];
map.getView().animate({
mapElement.getView().animate({
rotation: 0,
});
}
};

const eventMapViewProjectionChangeListenerFunction = (payload: PayloadBaseClass) => {
if (payloadIsAMapViewProjection(payload)) {
setMapProjection(`EPSG:${payload.projection}`);

// uncheck the control
if (switchChecked) setSwitchChecked(false);
}
};

useEffect(() => {
// listen to geoview-basemap-panel package change projection event
api.event.on(EVENT_NAMES.MAP.EVENT_MAP_VIEW_PROJECTION_CHANGE, eventMapViewProjectionChangeListenerFunction, mapId);

return () => {
api.event.off(EVENT_NAMES.MAP.EVENT_MAP_VIEW_PROJECTION_CHANGE, mapId, eventMapViewProjectionChangeListenerFunction);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return (
<div>
{expanded && mapProjection === PROJECTION_NAMES.LCC && isNorthEnable ? (
<Switch size="small" onChange={fixNorth} title={t('mapctrl.rotation.fixedNorth')!} checked={switchChecked} />
<Switch size="small" onChange={fixNorth} title={t('mapctrl.rotation.fixedNorth')!} checked={isFixNorth} />
) : null}
</div>
);
Expand Down
Loading

0 comments on commit eaa360e

Please sign in to comment.