|
1 | 1 | <script lang="ts"> |
2 | 2 | import { onMount, onDestroy, tick } from "svelte"; |
3 | 3 | import { allSites, selectedSiteId } from "$lib/stores/sites"; |
| 4 | + import { theme } from "$lib/stores/theme"; |
4 | 5 | import "leaflet/dist/leaflet.css"; |
5 | 6 | import type { SiteSummary } from "$lib/stores/sites"; |
6 | 7 | let container: HTMLDivElement; |
7 | 8 | let map: any = null; |
8 | 9 | let markers: Map<string, any> = new Map(); |
| 10 | + let currentTileLayer: any = null; |
| 11 | + let themeUnsub: (() => void) | null = null; |
9 | 12 |
|
10 | 13 | const c: Record<string,string> = { stable: "#34d399", watch: "#fbbf24", critical: "#f87171" }; |
11 | 14 |
|
|
45 | 48 | maxZoom: 19, |
46 | 49 | }).addTo(map); |
47 | 50 |
|
| 51 | + themeUnsub = theme.subscribe((t) => { |
| 52 | + if (!map) return; |
| 53 | + map.eachLayer((l: any) => { if (l._url) map.removeLayer(l); }); |
| 54 | + const url = t === "light" |
| 55 | + ? "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png" |
| 56 | + : "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png"; |
| 57 | + L.tileLayer(url, { |
| 58 | + attribution: '© <a href="https://carto.com/">CARTO</a> © <a href="https://openstreetmap.org">OSM</a>', |
| 59 | + subdomains: "abcd", |
| 60 | + maxZoom: 19, |
| 61 | + }).addTo(map); |
| 62 | + }); |
| 63 | +
|
48 | 64 | function renderMarkers(sites: SiteSummary[]) { |
49 | 65 | markers.forEach(m => map.removeLayer(m)); |
50 | 66 | markers.clear(); |
|
75 | 91 | sitesUnsub = allSites.subscribe(renderMarkers); |
76 | 92 |
|
77 | 93 | selectedUnsub = selectedSiteId.subscribe((id) => { |
78 | | - const m = id ? markers.get(id) : null; |
| 94 | + if (!id) { |
| 95 | + if (map) map.flyTo([20, 20], 2, { duration: 0.6 }); |
| 96 | + return; |
| 97 | + } |
| 98 | + const m = markers.get(id); |
79 | 99 | if (m && map) { |
80 | 100 | const latlng = m.getLatLng(); |
81 | 101 | map.flyTo(latlng, 8, { duration: 0.8 }); |
|
87 | 107 | onDestroy(() => { |
88 | 108 | sitesUnsub?.(); |
89 | 109 | selectedUnsub?.(); |
| 110 | + themeUnsub?.(); |
90 | 111 | map?.remove(); |
91 | 112 | }); |
92 | 113 | </script> |
93 | 114 |
|
94 | 115 | <div class="relative z-0 w-full h-full"> |
95 | 116 | <div class="absolute inset-0 overflow-hidden"><div bind:this={container} class="w-full h-full"></div></div> |
| 117 | + {#if $theme === "night-vision"} |
| 118 | + <div class="absolute inset-0 pointer-events-none z-10" style="background: rgba(80,0,0,0.25); mix-blend-mode: multiply;"></div> |
| 119 | + {/if} |
96 | 120 | </div> |
97 | 121 |
|
98 | 122 | <style> |
|
0 commit comments