static routing fixed
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
import { storedLocation } from '$lib/stores/settings';
|
||||
import { storedLocation, storedModel, storedTheme } from '$lib/stores/settings';
|
||||
|
||||
import { mapsDomainForModel } from '$lib/utils/maps-domain';
|
||||
|
||||
// Hash piping, both directions:
|
||||
// - inbound: a #zoom/lat/lng(/bearing/pitch) hash on OUR url seeds the
|
||||
@@ -10,6 +12,16 @@
|
||||
// we mirror it into our url with replaceState. hashOverride is only set
|
||||
// once on mount, so these mirror updates never reload the iframe.
|
||||
let hashOverride = $state<string | null>(null);
|
||||
let iframeEl = $state<HTMLIFrameElement | null>(null);
|
||||
let mapReady = $state(false);
|
||||
|
||||
const postToMap = (message: Record<string, unknown>) => {
|
||||
iframeEl?.contentWindow?.postMessage(message, MAPS_ORIGIN);
|
||||
};
|
||||
|
||||
// Local maps dev server (open-meteo/maps); production: https://maps.open-meteo.com
|
||||
// Run drizzli on a different port so the map keeps 5173 to itself.
|
||||
const MAPS_ORIGIN = 'http://localhost:5173';
|
||||
|
||||
const MAP_HASH_RE = /^#\d+(\.\d+)?\/-?\d+(\.\d+)?\/-?\d+(\.\d+)?/;
|
||||
|
||||
@@ -18,10 +30,24 @@
|
||||
hashOverride = MAP_HASH_RE.test(initialHash) ? initialHash : null;
|
||||
|
||||
const onMessage = (event: MessageEvent) => {
|
||||
if (event.origin !== 'https://maps.open-meteo.com') return;
|
||||
const { type, hash } = (event.data ?? {}) as { type?: string; hash?: string };
|
||||
if (type !== 'om-maps:hash' || !hash || !MAP_HASH_RE.test(hash)) return;
|
||||
history.replaceState(history.state, '', hash);
|
||||
if (event.origin !== MAPS_ORIGIN) return;
|
||||
const { type, hash, domains } = (event.data ?? {}) as {
|
||||
type?: string;
|
||||
hash?: string;
|
||||
domains?: string[];
|
||||
};
|
||||
if (type === 'om-maps:hash') {
|
||||
if (!hash || !MAP_HASH_RE.test(hash)) return;
|
||||
history.replaceState(history.state, '', hash);
|
||||
} else if (type === 'om-maps:ready' && Array.isArray(domains)) {
|
||||
// The map is loaded and advertises which domains it can render;
|
||||
// switch it to the selected model and our theme. The domain is
|
||||
// omitted for best_match and models the map does not serve,
|
||||
// keeping the map's own default. Re-fires on iframe reloads.
|
||||
mapReady = true;
|
||||
const domain = mapsDomainForModel($storedModel, new Set(domains));
|
||||
postToMap({ type: 'om-maps:set', ...(domain && { domain }), theme: $storedTheme });
|
||||
}
|
||||
};
|
||||
window.addEventListener('message', onMessage);
|
||||
return () => window.removeEventListener('message', onMessage);
|
||||
@@ -31,11 +57,19 @@
|
||||
// opens focused on the selected location (zoomed out to regional scale);
|
||||
// picking a new location while on this page recenters the map
|
||||
const iframeSrc = $derived(
|
||||
`https://maps.open-meteo.com/${
|
||||
`${MAPS_ORIGIN}/${
|
||||
hashOverride ??
|
||||
`#6/${$storedLocation.latitude.toFixed(3)}/${$storedLocation.longitude.toFixed(3)}`
|
||||
}`
|
||||
);
|
||||
|
||||
// forward theme switches live; the initial theme travels with the
|
||||
// ready response above (the map ignores no-op updates)
|
||||
$effect(() => {
|
||||
const theme = $storedTheme;
|
||||
if (!mapReady) return;
|
||||
postToMap({ type: 'om-maps:set', theme });
|
||||
});
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
@@ -51,6 +85,7 @@
|
||||
map; it only takes effect when this site itself is served with
|
||||
COOP/COEP headers (see README, Deployment) -->
|
||||
<iframe
|
||||
bind:this={iframeEl}
|
||||
src={iframeSrc}
|
||||
title="Open-Meteo Interactive Map"
|
||||
loading="lazy"
|
||||
|
||||
Reference in New Issue
Block a user