diff --git a/plugin-designs/doxa-maps-spa/src/tabInfo.js b/plugin-designs/doxa-maps-spa/src/tabInfo.js index 54279d00e..bf504092e 100644 --- a/plugin-designs/doxa-maps-spa/src/tabInfo.js +++ b/plugin-designs/doxa-maps-spa/src/tabInfo.js @@ -96,6 +96,7 @@ export const TAB_INFO = { }, 'research-map-plus-grid': { storageKey: 'research-map-plus-grid', + trigger: 'control', pos: { top: '56px', side: '56px' }, leadKey: 'mapInfo.tab.research-map-plus-grid.lead', takeawayKey: 'mapInfo.tab.research-map-plus-grid.takeaway', diff --git a/plugin-designs/doxa-research-map/research-map.vue b/plugin-designs/doxa-research-map/research-map.vue index e593682e4..679f97278 100644 --- a/plugin-designs/doxa-research-map/research-map.vue +++ b/plugin-designs/doxa-research-map/research-map.vue @@ -177,6 +177,9 @@ import HamburgerButton from '@map/components/map-controls/HamburgerButton.vue' import GeocoderComponent from '@map/components/map-controls/GeocoderComponent.vue' import ShareButton from '@map/components/map-controls/ShareButton.vue' import MapControlButton from '@map/components/map-controls/MapControlButton.vue' +// "What can this map do?", as the top control. By path like the rest: the map-controls barrel would pull +// the whole 'mapInfo' catalogue area into this bundle. +import MapInfoButton from '@map/components/map-controls/MapInfoButton.vue' // PERF: SideMenuDrawer is unused in the current research-map template (the // ResearchMapSideMenu sibling renders the actual menu). Removed entirely from @@ -3002,6 +3005,29 @@ function applyContainerScale(width) { } } +// ★ THE ⓘ CONTROL IS COMING, SO SAY SO BEFORE THE GALLERY DRAWS ITS FLOATING ONE. The control column +// renders only at appReady, after the style AND the people-group data, and a slow phone gets there late. +// At mount this map tells the gallery's MapInfo that a control is on its way, and the MapInfo waits for +// the map rather than flashing its floating ⓘ and swapping it out. A failure (mapError) or an unmount +// withdraws the promise, so the floating ⓘ shows at once and the popup can always be opened. With no +// MapInfo (a standalone page) nothing answers and nothing changes. This is Prayer Progress's contract. +function announceInfoPending(pending) { + const el = rmRoot.value + if (!el) return + try { el.dispatchEvent(new CustomEvent('dxmaps:mapinfo-pending', { bubbles: true, composed: true, detail: { pending } })) } catch { /* no CustomEvent */ } +} +// A MapInfo that mounted after this map asked into the void; it announces itself, and we answer again. +const reannounceInfoPending = () => { if (!appReady.value && !mapError.value) announceInfoPending(true) } +watch(mapError, (e) => { if (e) announceInfoPending(false) }) +onMounted(() => { + announceInfoPending(true) + window.addEventListener('dxmaps:mapinfo-host', reannounceInfoPending) +}) +onBeforeUnmount(() => { + window.removeEventListener('dxmaps:mapinfo-host', reannounceInfoPending) + if (!appReady.value) announceInfoPending(false) +}) + onMounted(async () => { // uiStore.init() registers the page-level ResizeObserver that drives // updateBreakpoint() — without this, breakpoint stays at default 'desktop' @@ -3202,6 +3228,10 @@ onBeforeUnmount(() => { + +