Live map follow-ups: stable pin icons, resolved IncidentPanel, filtered rail, weather vs camera dock (#279 #275 #268 #278) #280

Merged
logan merged 1 commits from fix/map-followups into main 2026-10-05 04:02:32 -04:00
Owner

Four small live-map follow-ups.

  • #279 Incident and fan divIcons are cached by their visual inputs (type/severity/precision/pulse; fan = member type:severity list + pulse), so re-renders hand react-leaflet the same icon object and setIcon isn't called. MapView is also React.memo'd, so LiveView's 1s clock no longer re-renders the map tree (MapView keeps its own 10s tick for rail ages). The #277 radar-frame external store is unchanged.
  • #275 IncidentPanel for a resolved incident shows "resolved" (not active / ON AIR), "lasted X" frozen at resolved_at (omitted if resolved_at is missing), "Last on scene", and labels nearest cameras and situational context as live-now, not incident-time.
  • #268 New optional filteredFrom prop. While the wall filter is on, the desktop rail header and mobile drawer read "N of M · filtered". N is the rail's own count, so it includes a selected incident kept on the map outside the filter.
  • #278 While camera tiles are docked bottom-centre, the weather status chip and radar badge (STALE, loop) render inside the dock column under the tiles instead of underneath it.

Verification: frontend tsc --noEmit clean; c2-core pytest 934 passed. Not browser-verified: the pulse completing its 1.8s cycle and the dock/weather layout still need an eyeball.

Closes #279 #275 #268 #278

🤖 Generated with Claude Code

Four small live-map follow-ups. - **#279** Incident and fan `divIcon`s are cached by their visual inputs (type/severity/precision/pulse; fan = member type:severity list + pulse), so re-renders hand react-leaflet the same icon object and `setIcon` isn't called. `MapView` is also `React.memo`'d, so LiveView's 1s clock no longer re-renders the map tree (MapView keeps its own 10s tick for rail ages). The #277 radar-frame external store is unchanged. - **#275** IncidentPanel for a resolved incident shows "resolved" (not active / ON AIR), "lasted X" frozen at `resolved_at` (omitted if `resolved_at` is missing), "Last on scene", and labels nearest cameras and situational context as live-now, not incident-time. - **#268** New optional `filteredFrom` prop. While the wall filter is on, the desktop rail header and mobile drawer read "N of M · filtered". N is the rail's own count, so it includes a selected incident kept on the map outside the filter. - **#278** While camera tiles are docked bottom-centre, the weather status chip and radar badge (STALE, loop) render inside the dock column under the tiles instead of underneath it. Verification: frontend `tsc --noEmit` clean; c2-core pytest 934 passed. Not browser-verified: the pulse completing its 1.8s cycle and the dock/weather layout still need an eyeball. Closes #279 #275 #268 #278 🤖 Generated with [Claude Code](https://claude.com/claude-code)
logan added 1 commit 2026-10-05 04:01:49 -04:00
- #279: cache incident/fan divIcons by their visual inputs and React.memo
  MapView, so LiveView's 1s clock no longer rebuilds icons / calls setIcon
  and the #238 pulse ring completes its cycle.
- #275: IncidentPanel shows "resolved", "lasted X" frozen at resolved_at,
  and labels live cameras/context as current, not incident-time.
- #268: rail header (desktop + mobile drawer) reads "N of M · filtered"
  via a new filteredFrom prop while the wall filter is on.
- #278: while camera tiles are docked bottom-centre, the weather status
  chip and radar badge stack under the tiles inside the dock instead of
  being covered.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
logan merged commit 49166789f4 into main 2026-10-05 04:02:32 -04:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: logan/server-26#280