/* global React */ // ──────────────────────────────────────────────────────────── // MAP — полный экран карты с фильтрами // ──────────────────────────────────────────────────────────── window.MapScreen = ({ T, dark, onBack, onOpenEvent }) => { const data = window.DATA.useDataState(); const events = data.events; const mapRef = React.useRef(null); const mapId = React.useMemo(() => "map-full-" + Math.random().toString(36).slice(2,8), []); const [minMag, setMinMag] = React.useState(4.0); const [region, setRegion] = React.useState("all"); React.useEffect(() => { if (!window.L) return; if (mapRef.current) { mapRef.current.remove(); mapRef.current = null; } const m = window.L.map(mapId, { zoomControl: false, attributionControl: false }).setView([60, 100], 2); const tileUrl = dark ? "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png" : "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png"; window.L.tileLayer(tileUrl, { maxZoom: 9 }).addTo(m); events.forEach(e => { if (e.mag < minMag) return; if (region === "ru" && !e.isRu) return; const color = window.magColor(e.mag, T); const r = 5 + (e.mag - 4) * 4; if (e.mag >= 5.0 && e.minutesAgo < 180) { const pulseHtml = `
`; const icon = window.L.divIcon({ html: pulseHtml, className: "eq-pulse-icon", iconSize: [40, 40], iconAnchor: [20, 20], }); window.L.marker([e.lat, e.lon], { icon }).addTo(m).on("click", () => onOpenEvent(e)); } else { window.L.circleMarker([e.lat, e.lon], { radius: r, color, fillColor: color, fillOpacity: 0.45, weight: 1.5, }).addTo(m).on("click", () => onOpenEvent(e)); } }); mapRef.current = m; return () => { if (mapRef.current) { mapRef.current.remove(); mapRef.current = null; } }; }, [dark, minMag, region, events]); const filtered = events.filter(e => e.mag >= minMag && (region === "all" || e.isRu)); return (
{[ { id: "all", label: "Все" }, { id: "ru", label: "🇷🇺 Россия / СНГ" }, ].map(r => ( setRegion(r.id)}>{r.label} ))}
{[4.0, 4.5, 5.0, 6.0].map(m => ( setMinMag(m)}>M≥{m.toFixed(1)} ))}
{/* Compact legend in the top-right (less marker density there since most events cluster around Russia/SE Asia in the lower half). One row of dots; tap to expand a labelled view. Solid background and high z-index to never get visually obscured by Leaflet markers. */}
ВИДИМЫЕ НА КАРТЕ
{filtered.slice(0, 6).map(e => (
onOpenEvent(e)} style={{ minWidth: 160, padding: 10, borderRadius: 8, border: `1px solid ${T.border}`, background: T.bg, cursor: "pointer", flexShrink: 0, }}>
{e.timeMsk} МСК
{e.place}
))}
); }; const Chip = ({ T, active, onClick, children }) => ( ); const Legend = ({ T, c, s, v }) => (
{v}
); // Compact, solid-background legend. Bottom-left of the map (less marker // density there typically — most events cluster around Russia/SE Asia which // is in the right half). Collapsed = colored dots + "M". Tap → full key. const CompactLegend = ({ T, dark }) => { const [open, setOpen] = React.useState(false); const bg = dark ? "#161A21" : "#FFFFFF"; const border = `1px solid ${T.border}`; const baseStyle = { position: "absolute", bottom: 10, left: 10, background: bg, border, borderRadius: 8, fontFamily: '"JetBrains Mono", monospace', color: T.textDim, cursor: "pointer", userSelect: "none", zIndex: 1000, // above all Leaflet panes boxShadow: dark ? "0 1px 4px rgba(0,0,0,0.4)" : "0 1px 4px rgba(0,0,0,0.1)", }; if (!open) { return (
setOpen(true)} style={{ ...baseStyle, padding: "6px 9px", display: "flex", alignItems: "center", gap: 6, fontSize: 10.5, }}> M
); } return (
setOpen(false)} style={{ ...baseStyle, padding: "10px 12px", fontSize: 10.5, }}>
МАГНИТУДА · нажмите чтобы свернуть
); };