Fix spiderfy reliability after event toggle
This commit is contained in:
@@ -107,4 +107,4 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script type="application/json" id="{{ mapDataElementId|e('html_attr') }}">{{ mapItemsJson|raw }}</script>
|
<script type="application/json" id="{{ mapDataElementId|e('html_attr') }}">{{ mapItemsJson|raw }}</script>
|
||||||
<script type="module" src="/bundles/mummertmediaeventmanager/assets/map-module.js?v=20260226d"></script>
|
<script type="module" src="/bundles/mummertmediaeventmanager/assets/map-module.js?v=20260226g"></script>
|
||||||
|
|||||||
+69
-46
@@ -532,6 +532,7 @@ const bindExternalTagFilters = (container, map, organizationMarkerManager, event
|
|||||||
const eventToggleButton = wrapper.querySelector('[data-map-event-toggle="1"]');
|
const eventToggleButton = wrapper.querySelector('[data-map-event-toggle="1"]');
|
||||||
const canFilterByTag = tagButtons.length > 0;
|
const canFilterByTag = tagButtons.length > 0;
|
||||||
const canFilterByEvents = !!eventToggleButton;
|
const canFilterByEvents = !!eventToggleButton;
|
||||||
|
const canToggleEvents = !!(eventToggleButton && eventLayerManager);
|
||||||
|
|
||||||
const setEventButtonState = (isActive) => {
|
const setEventButtonState = (isActive) => {
|
||||||
if (!eventToggleButton) {
|
if (!eventToggleButton) {
|
||||||
@@ -549,6 +550,26 @@ const bindExternalTagFilters = (container, map, organizationMarkerManager, event
|
|||||||
let activeTagId = null;
|
let activeTagId = null;
|
||||||
let eventsOnly = false;
|
let eventsOnly = false;
|
||||||
|
|
||||||
|
const updateExclusiveButtonAccessibility = () => {
|
||||||
|
tagButtons.forEach((button) => {
|
||||||
|
const isActive = button.getAttribute('aria-pressed') === 'true';
|
||||||
|
button.setAttribute('aria-disabled', isActive ? 'true' : 'false');
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!eventToggleButton) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!canToggleEvents) {
|
||||||
|
eventToggleButton.setAttribute('aria-disabled', 'true');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isEventActive = eventToggleButton.getAttribute('aria-pressed') === 'true';
|
||||||
|
eventToggleButton.setAttribute('aria-disabled', isEventActive ? 'true' : 'false');
|
||||||
|
};
|
||||||
|
|
||||||
const applyFilter = () => {
|
const applyFilter = () => {
|
||||||
if (eventsOnly) {
|
if (eventsOnly) {
|
||||||
organizationMarkerManager.setVisible(false);
|
organizationMarkerManager.setVisible(false);
|
||||||
@@ -581,14 +602,17 @@ const bindExternalTagFilters = (container, map, organizationMarkerManager, event
|
|||||||
|
|
||||||
tagButtons.forEach((button) => {
|
tagButtons.forEach((button) => {
|
||||||
button.addEventListener('click', () => {
|
button.addEventListener('click', () => {
|
||||||
|
if (button.getAttribute('aria-disabled') === 'true') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const clickedTagId = String(button.dataset.mapTagFilter || '').trim();
|
const clickedTagId = String(button.dataset.mapTagFilter || '').trim();
|
||||||
|
|
||||||
if (!/^\d+$/.test(clickedTagId)) {
|
if (!/^\d+$/.test(clickedTagId)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isActive = button.getAttribute('aria-pressed') === 'true';
|
activeTagId = clickedTagId;
|
||||||
activeTagId = isActive ? null : clickedTagId;
|
|
||||||
eventsOnly = false;
|
eventsOnly = false;
|
||||||
|
|
||||||
tagButtons.forEach((otherButton) => {
|
tagButtons.forEach((otherButton) => {
|
||||||
@@ -597,6 +621,7 @@ const bindExternalTagFilters = (container, map, organizationMarkerManager, event
|
|||||||
});
|
});
|
||||||
|
|
||||||
setEventButtonState(false);
|
setEventButtonState(false);
|
||||||
|
updateExclusiveButtonAccessibility();
|
||||||
applyFilter();
|
applyFilter();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -628,12 +653,16 @@ const bindExternalTagFilters = (container, map, organizationMarkerManager, event
|
|||||||
|
|
||||||
if (eventToggleButton && eventLayerManager) {
|
if (eventToggleButton && eventLayerManager) {
|
||||||
eventToggleButton.addEventListener('click', () => {
|
eventToggleButton.addEventListener('click', () => {
|
||||||
const isActive = eventToggleButton.getAttribute('aria-pressed') === 'true';
|
if (eventToggleButton.getAttribute('aria-disabled') === 'true') {
|
||||||
eventsOnly = !isActive;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
eventsOnly = true;
|
||||||
activeTagId = null;
|
activeTagId = null;
|
||||||
|
|
||||||
tagButtons.forEach((button) => setButtonState(button, false));
|
tagButtons.forEach((button) => setButtonState(button, false));
|
||||||
setEventButtonState(eventsOnly);
|
setEventButtonState(eventsOnly);
|
||||||
|
updateExclusiveButtonAccessibility();
|
||||||
applyFilter();
|
applyFilter();
|
||||||
});
|
});
|
||||||
} else if (eventToggleButton) {
|
} else if (eventToggleButton) {
|
||||||
@@ -711,9 +740,11 @@ const bindExternalTagFilters = (container, map, organizationMarkerManager, event
|
|||||||
setButtonState(button, null !== activeTagId && tagId === activeTagId);
|
setButtonState(button, null !== activeTagId && tagId === activeTagId);
|
||||||
});
|
});
|
||||||
setEventButtonState(eventsOnly);
|
setEventButtonState(eventsOnly);
|
||||||
|
updateExclusiveButtonAccessibility();
|
||||||
};
|
};
|
||||||
|
|
||||||
applyInitialDisplayMode();
|
applyInitialDisplayMode();
|
||||||
|
updateExclusiveButtonAccessibility();
|
||||||
applyFilter();
|
applyFilter();
|
||||||
applyMapStyleMode();
|
applyMapStyleMode();
|
||||||
};
|
};
|
||||||
@@ -748,6 +779,7 @@ const initLocationLayers = (map, locationItems, markerImageId) => {
|
|||||||
},
|
},
|
||||||
paint: {
|
paint: {
|
||||||
'icon-opacity': 1,
|
'icon-opacity': 1,
|
||||||
|
'icon-translate': [0, 4],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -831,19 +863,9 @@ const initLocationLayers = (map, locationItems, markerImageId) => {
|
|||||||
const initEventLayers = (map, eventItems, eventColor, markerImageId, clusterMarkerImageId) => {
|
const initEventLayers = (map, eventItems, eventColor, markerImageId, clusterMarkerImageId) => {
|
||||||
const sourceId = 'eventmanager-events-source';
|
const sourceId = 'eventmanager-events-source';
|
||||||
const clusterLayerId = EVENT_CLUSTER_LAYER_ID;
|
const clusterLayerId = EVENT_CLUSTER_LAYER_ID;
|
||||||
const clusterSpiderfyLayerId = EVENT_CLUSTER_SPIDERFY_LAYER_ID;
|
|
||||||
const unclusteredLayerId = EVENT_UNCLUSTERED_LAYER_ID;
|
const unclusteredLayerId = EVENT_UNCLUSTERED_LAYER_ID;
|
||||||
const spiderfyHitAreaImageId = 'eventmanager-spiderfy-hit-area';
|
|
||||||
const features = eventItems.map(toFeature);
|
const features = eventItems.map(toFeature);
|
||||||
|
|
||||||
if (!map.hasImage(spiderfyHitAreaImageId)) {
|
|
||||||
map.addImage(spiderfyHitAreaImageId, {
|
|
||||||
width: 1,
|
|
||||||
height: 1,
|
|
||||||
data: new Uint8Array([0, 0, 0, 0]),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
map.addSource(sourceId, {
|
map.addSource(sourceId, {
|
||||||
type: 'geojson',
|
type: 'geojson',
|
||||||
data: {
|
data: {
|
||||||
@@ -875,25 +897,10 @@ const initEventLayers = (map, eventItems, eventColor, markerImageId, clusterMark
|
|||||||
},
|
},
|
||||||
paint: {
|
paint: {
|
||||||
'icon-opacity': 1,
|
'icon-opacity': 1,
|
||||||
|
'icon-translate': [0, 4],
|
||||||
'text-color': '#FFFFFF',
|
'text-color': '#FFFFFF',
|
||||||
'text-opacity': 1,
|
'text-opacity': 1,
|
||||||
},
|
'text-translate': [0, 4],
|
||||||
});
|
|
||||||
|
|
||||||
map.addLayer({
|
|
||||||
id: clusterSpiderfyLayerId,
|
|
||||||
type: 'symbol',
|
|
||||||
source: sourceId,
|
|
||||||
filter: ['has', 'point_count'],
|
|
||||||
layout: {
|
|
||||||
'icon-image': spiderfyHitAreaImageId,
|
|
||||||
'icon-size': 36,
|
|
||||||
'icon-anchor': 'bottom',
|
|
||||||
'icon-offset': [0, -1.0],
|
|
||||||
'icon-allow-overlap': true,
|
|
||||||
},
|
|
||||||
paint: {
|
|
||||||
'icon-opacity': 0,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -911,6 +918,7 @@ const initEventLayers = (map, eventItems, eventColor, markerImageId, clusterMark
|
|||||||
},
|
},
|
||||||
paint: {
|
paint: {
|
||||||
'icon-opacity': 1,
|
'icon-opacity': 1,
|
||||||
|
'icon-translate': [0, 4],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1016,7 +1024,7 @@ const initEventLayers = (map, eventItems, eventColor, markerImageId, clusterMark
|
|||||||
},
|
},
|
||||||
spiderLeavesPaint: {
|
spiderLeavesPaint: {
|
||||||
'icon-opacity': 1,
|
'icon-opacity': 1,
|
||||||
'icon-translate': [0, 8],
|
'icon-translate': [0, 9],
|
||||||
},
|
},
|
||||||
onLeafClick: (feature, spiderEvent) => {
|
onLeafClick: (feature, spiderEvent) => {
|
||||||
const clickCoordinates = spiderEvent?.lngLat
|
const clickCoordinates = spiderEvent?.lngLat
|
||||||
@@ -1048,14 +1056,6 @@ const initEventLayers = (map, eventItems, eventColor, markerImageId, clusterMark
|
|||||||
map.getCanvas().style.cursor = '';
|
map.getCanvas().style.cursor = '';
|
||||||
});
|
});
|
||||||
|
|
||||||
const setLayerLayoutVisibility = (layerId, isVisible) => {
|
|
||||||
if (!map.getLayer(layerId)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
map.setLayoutProperty(layerId, 'visibility', isVisible ? 'visible' : 'none');
|
|
||||||
};
|
|
||||||
|
|
||||||
const fadeLayerOpacity = (layerId, property, value, duration = EVENT_FADE_DURATION_MS) => {
|
const fadeLayerOpacity = (layerId, property, value, duration = EVENT_FADE_DURATION_MS) => {
|
||||||
if (!map.getLayer(layerId)) {
|
if (!map.getLayer(layerId)) {
|
||||||
return;
|
return;
|
||||||
@@ -1067,14 +1067,31 @@ const initEventLayers = (map, eventItems, eventColor, markerImageId, clusterMark
|
|||||||
|
|
||||||
const eventLayerIds = [
|
const eventLayerIds = [
|
||||||
clusterLayerId,
|
clusterLayerId,
|
||||||
clusterSpiderfyLayerId,
|
|
||||||
unclusteredLayerId,
|
unclusteredLayerId,
|
||||||
];
|
];
|
||||||
|
const clusterFilter = ['has', 'point_count'];
|
||||||
|
const unclusteredFilter = ['!', ['has', 'point_count']];
|
||||||
|
const hiddenFilter = ['has', '__eventmanager_hidden__'];
|
||||||
|
let hideLayersTimeoutId = null;
|
||||||
|
|
||||||
|
const setLayerFilter = (layerId, filter) => {
|
||||||
|
if (!map.getLayer(layerId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
map.setFilter(layerId, filter);
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
setVisible: (isVisible) => {
|
setVisible: (isVisible) => {
|
||||||
if (isVisible) {
|
if (isVisible) {
|
||||||
eventLayerIds.forEach((layerId) => setLayerLayoutVisibility(layerId, true));
|
if (null !== hideLayersTimeoutId) {
|
||||||
|
window.clearTimeout(hideLayersTimeoutId);
|
||||||
|
hideLayersTimeoutId = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
setLayerFilter(clusterLayerId, clusterFilter);
|
||||||
|
setLayerFilter(unclusteredLayerId, unclusteredFilter);
|
||||||
|
|
||||||
fadeLayerOpacity(clusterLayerId, 'icon-opacity', 1);
|
fadeLayerOpacity(clusterLayerId, 'icon-opacity', 1);
|
||||||
fadeLayerOpacity(clusterLayerId, 'text-opacity', 1);
|
fadeLayerOpacity(clusterLayerId, 'text-opacity', 1);
|
||||||
@@ -1083,16 +1100,22 @@ const initEventLayers = (map, eventItems, eventColor, markerImageId, clusterMark
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spiderfyInstance && typeof spiderfyInstance.unspiderfyAll === 'function') {
|
if (spiderfyInstance) {
|
||||||
spiderfyInstance.unspiderfyAll();
|
if (typeof spiderfyInstance._clearSpiderifiedCluster === 'function') {
|
||||||
|
spiderfyInstance._clearSpiderifiedCluster();
|
||||||
|
} else if (typeof spiderfyInstance.unspiderfyAll === 'function') {
|
||||||
|
spiderfyInstance.unspiderfyAll();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fadeLayerOpacity(clusterLayerId, 'icon-opacity', 0);
|
fadeLayerOpacity(clusterLayerId, 'icon-opacity', 0);
|
||||||
fadeLayerOpacity(clusterLayerId, 'text-opacity', 0);
|
fadeLayerOpacity(clusterLayerId, 'text-opacity', 0);
|
||||||
fadeLayerOpacity(unclusteredLayerId, 'icon-opacity', 0);
|
fadeLayerOpacity(unclusteredLayerId, 'icon-opacity', 0);
|
||||||
|
|
||||||
window.setTimeout(() => {
|
hideLayersTimeoutId = window.setTimeout(() => {
|
||||||
eventLayerIds.forEach((layerId) => setLayerLayoutVisibility(layerId, false));
|
setLayerFilter(clusterLayerId, hiddenFilter);
|
||||||
|
setLayerFilter(unclusteredLayerId, hiddenFilter);
|
||||||
|
hideLayersTimeoutId = null;
|
||||||
}, EVENT_FADE_DURATION_MS + 10);
|
}, EVENT_FADE_DURATION_MS + 10);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user