Skip to content

Commit

Permalink
feat(event): Event added to API for map ready (#2510)
Browse files Browse the repository at this point in the history
  • Loading branch information
DamonU2 authored Sep 26, 2024
1 parent 1debc9a commit 2a03afa
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 13 deletions.
71 changes: 70 additions & 1 deletion packages/geoview-core/src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ export class API {
// utilities object
utilities;

// Keep all callback delegates references
#onMapViewerReadyHandlers: MapViewerReadyDelegate[] = [];

// Keep all callback delegates references
#onMapAddedToDivHandlers: MapAddedToDivDelegate[] = [];

Expand All @@ -54,6 +57,32 @@ export class API {
API.#manageKeyboardFocus();
}

// TODO Add getter function and make maps property private
/**
* Sets a map viewer in maps, or removes one if the mapViewer property is null.
* @param {string} mapId - ID of the map
* @param {MapViewer | null} mapViewer - The viewer to be added or null to remove
* @param {(mapViewer: MapViewer) => void} onMapViewerInit - Function to run on map init
*/
setMapViewer(mapId: string, mapViewer: MapViewer | null, onMapViewerInit?: (mapViewer: MapViewer) => void): void {
if (mapViewer) {
if (this.maps[mapId]) logger.logError(`Cannot add map. Map with ID ${mapId} already exists`);
else {
this.maps[mapId] = mapViewer;

// Register a handler (which will only happen once) for when the map viewer will get initialized.
// At the time of writing, this happens later, asynchronously, via the components/map/map.tsx when 'MapViewer.initMap()' is called.
// That should be fixed eventually, but that refactoring is out of the scope at the time of writing. So, I'm doing like this for now.
this.maps[mapId].onMapInit((viewer) => {
// MapViewer has been created and initialized, callback about it
onMapViewerInit?.(viewer);
// Emit that viewer is ready
this.#emitMapViewerReady({ mapId });
});
}
} else delete this.maps[mapId];
}

/**
* Apply outline to elements when keyboard is use to navigate
* Code from: https://github.com/MaxMaeder/keyboardFocus.js
Expand Down Expand Up @@ -123,6 +152,33 @@ export class API {
return Promise.reject(new Error(`Div with id ${divId} does not exist`));
}

/**
* Emits a map viewer ready event to all handlers.
* @private
*/
#emitMapViewerReady(event: MapViewerReadyEvent): void {
// Emit the event for all handlers
EventHelper.emitEvent(this, this.#onMapViewerReadyHandlers, event);
}

/**
* Registers a map viewer ready event callback.
* @param {MapViewerReadyDelegate} callback - The callback to be executed whenever the event is emitted
*/
onMapViewerReady(callback: MapViewerReadyDelegate): void {
// Register the event handler
EventHelper.onEvent(this.#onMapViewerReadyHandlers, callback);
}

/**
* Unregisters a map viewer ready event callback.
* @param {MapViewerReadyDelegate} callback - The callback to stop being called whenever the event is emitted
*/
offMapViewerReady(callback: MapViewerReadyDelegate): void {
// Unregister the event handler
EventHelper.offEvent(this.#onMapViewerReadyHandlers, callback);
}

/**
* Emits an event to all handlers.
* @param {MapAddedToDivEvent} event - The event to emit
Expand Down Expand Up @@ -152,6 +208,19 @@ export class API {
}
}

/**
* Define a delegate for the event handler function signature
*/
type MapViewerReadyDelegate = EventDelegateBase<API, MapViewerReadyEvent, void>;

/**
* Define an event for the delegate
*/
export type MapViewerReadyEvent = {
// The added map
mapId: string;
};

/**
* Define a delegate for the event handler function signature
*/
Expand All @@ -161,6 +230,6 @@ type MapAddedToDivDelegate = EventDelegateBase<API, MapAddedToDivEvent, void>;
* Define an event for the delegate
*/
export type MapAddedToDivEvent = {
// The added layer
// The added map
mapId: string;
};
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
TypeViewSettings,
TypePointMarker,
} from '@config/types/map-schema-types';
import { cloneDeep } from 'lodash';
import { api } from '@/app';
import { LayerApi } from '@/geo/layer/layer';
import { MapViewer, TypeMapState, TypeMapMouseInfo } from '@/geo/map/map-viewer';
Expand Down Expand Up @@ -1050,7 +1051,9 @@ export class MapEventProcessor extends AbstractEventProcessor {
: undefined,
initialSettings,
style: legendLayerInfo!.styleConfig ? legendLayerInfo!.styleConfig : undefined,
source: (layerEntryConfig! as VectorLayerEntryConfig).source ? (layerEntryConfig! as VectorLayerEntryConfig).source : undefined,
source: (layerEntryConfig! as VectorLayerEntryConfig).source
? cloneDeep((layerEntryConfig! as VectorLayerEntryConfig).source)
: undefined,
entryType: listOfLayerEntryConfig.length ? 'group' : undefined,
listOfLayerEntryConfig: listOfLayerEntryConfig.length ? listOfLayerEntryConfig : [],
};
Expand Down
11 changes: 1 addition & 10 deletions packages/geoview-core/src/core/app-start.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ export type TypeMapContext = {
*/
interface AppStartProps {
mapFeaturesConfig: TypeMapFeaturesConfig;
// eslint-disable-next-line react/require-default-props
onMapViewerInit?: (mapViewer: MapViewer) => void;
}

Expand Down Expand Up @@ -75,17 +74,9 @@ function AppStart(props: AppStartProps): JSX.Element {
// TODO: use store, remove the use of feature by viewer class and use state to gather values
if (!(mapId in api.maps)) {
const mapViewer = new MapViewer(mapFeaturesConfig, i18nInstance);
api.maps[mapId] = mapViewer;
api.setMapViewer(mapId, mapViewer, onMapViewerInit);
}

// Register a handler (which will only happen once) for when the map viewer will get initialized.
// At the time of writing, this happens later, asynchronously, via the components/map/map.tsx when 'MapViewer.initMap()' is called.
// That should be fixed eventually, but that refactoring is out of the scope at the time of writing. So, I'm doing like this for now.
api.maps[mapId].onMapInit((mapViewer) => {
// MapViewer has been created and initialized, callback about it
onMapViewerInit?.(mapViewer);
});

return (
<I18nextProvider i18n={i18nInstance}>
<MapContext.Provider value={mapContextValue}>
Expand Down
2 changes: 1 addition & 1 deletion packages/geoview-core/src/geo/map/map-viewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1201,7 +1201,7 @@ export class MapViewer {
if (deleteContainer) mapContainer.remove();

// Delete the map instance from the maps array, will delete attached plugins
delete api.maps[this.mapId];
api.setMapViewer(this.mapId, null);

// Return the map container to be remove
return mapContainer;
Expand Down

0 comments on commit 2a03afa

Please sign in to comment.