worldwide todo list: global map (List/Map toggle, clustered category pins, Global strip, pick on map, location_precision, tasks.geojson)
All checks were successful
Deploy production / deploy (push) Successful in 1m13s

This commit is contained in:
2026-10-26 08:38:51 +00:00
parent 21b10ea894
commit 9d79dfb43a
15 changed files with 42669 additions and 13 deletions

View File

@@ -0,0 +1,54 @@
import type * as Leaflet from 'leaflet';
import { PUBLIC_MAPTILER_API_KEY } from '$app/env/public';
// MapTiler "Dataviz" basemaps on OpenStreetMap data (the site's existing public MapTiler
// key): dark in the dark theme, light in the light one, swapped live when the theme
// toggles. Without a key (local dev) it falls back to the standard OSM tiles, darkened
// with a CSS filter in the dark theme. CARTO's raster tiles need a key since Sept 2026.
const isDark = () => document.documentElement.classList.contains('dark');
const OSM =
'&copy; <a href="https://www.openstreetmap.org/copyright" target="_blank" rel="noopener">OpenStreetMap</a> contributors';
const MAPTILER =
'&copy; <a href="https://www.maptiler.com/copyright/" target="_blank" rel="noopener">MapTiler</a>';
function source(dark: boolean): { url: string; attribution: string; filtered: boolean } {
if (PUBLIC_MAPTILER_API_KEY) {
const style = dark ? 'dataviz-dark' : 'dataviz';
return {
url: `https://api.maptiler.com/maps/${style}/256/{z}/{x}/{y}{r}.png?key=${encodeURIComponent(PUBLIC_MAPTILER_API_KEY)}`,
attribution: `${MAPTILER} ${OSM}`,
filtered: false
};
}
return {
url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
attribution: OSM,
filtered: dark
};
}
/** Adds the themed tile layer to `map`; returns a cleanup for the theme observer. */
export function addThemedTiles(L: typeof Leaflet, map: Leaflet.Map): () => void {
const first = source(isDark());
const layer = L.tileLayer(first.url, {
maxZoom: 19,
attribution: first.attribution,
className: first.filtered ? 'wt-tiles-dim' : ''
}).addTo(map);
const apply = () => {
const s = source(isDark());
layer.getContainer()?.classList.toggle('wt-tiles-dim', s.filtered);
layer.setUrl(s.url);
};
const observer = new MutationObserver(apply);
observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
return () => observer.disconnect();
}
/** Leaflet is browser-only: load it on demand (never during SSR). */
export async function loadLeaflet(): Promise<typeof Leaflet> {
const mod = await import('leaflet');
return (mod.default ?? mod) as typeof Leaflet;
}