feat(rover): Maidenhead grid overlay on location detail map

LocationMap hook now adds a togglable grid layer (matching the contact
map pattern) so the rover-location detail page shows the standard
Maidenhead overlay alongside the marker.
This commit is contained in:
Graham McIntire 2026-05-02 17:14:45 -05:00
parent d052dcaa91
commit 0b0718e047
No known key found for this signature in database
GPG key ID: F4ABF488E6029E59

View file

@ -1,8 +1,11 @@
import type { ViewHook } from "phoenix_live_view"
import { updateGridOverlay } from "./maidenhead_grid"
interface LocationMapHook extends ViewHook {
map: L.Map
marker: L.CircleMarker
gridLayer: L.LayerGroup
gridVisible: boolean
visibilityHandler: (() => void) | null
}
@ -48,6 +51,39 @@ export const LocationMap: Partial<LocationMapHook> = {
}).addTo(map)
this.marker.bindPopup(`${lat.toFixed(6)}, ${lon.toFixed(6)}`)
// Maidenhead grid overlay + toggle
this.gridLayer = L.layerGroup().addTo(map)
this.gridVisible = true
updateGridOverlay(map, this.gridLayer)
map.on("moveend", () => {
if (this.gridVisible) updateGridOverlay(map, this.gridLayer)
})
const GridToggle = L.Control.extend({
options: { position: "topright" as const },
onAdd: () => {
const btn = L.DomUtil.create("button", "leaflet-bar leaflet-control")
btn.innerHTML = "Grid"
btn.title = "Toggle Maidenhead grid"
btn.style.cssText =
"background:#fff;padding:4px 8px;font-size:12px;cursor:pointer;font-weight:600;"
L.DomEvent.disableClickPropagation(btn)
btn.onclick = () => {
this.gridVisible = !this.gridVisible
if (this.gridVisible) {
this.gridLayer.addTo(map)
updateGridOverlay(map, this.gridLayer)
btn.style.opacity = "1"
} else {
this.gridLayer.remove()
btn.style.opacity = "0.5"
}
}
return btn
}
})
new GridToggle().addTo(map)
// LiveView reconnect / tab visibility — Leaflet needs invalidateSize.
this.visibilityHandler = () => {
if (document.visibilityState === "visible") this.map.invalidateSize()