Layers
-
-
-
-
-
{filters.betaPaths && (
Beta Confidence: {confidenceLabel}
@@ -123,6 +101,7 @@ export const FilterPanel: React.FC = ({ filters, onChange, bet
)}
))}
+
);
};
diff --git a/frontend/src/components/Map/MapView.tsx b/frontend/src/components/Map/MapView.tsx
index 93d5243..523793d 100644
--- a/frontend/src/components/Map/MapView.tsx
+++ b/frontend/src/components/Map/MapView.tsx
@@ -1,5 +1,5 @@
import React, { useState, useCallback, useMemo, useEffect, useRef } from 'react';
-import { MapContainer, TileLayer, useMap, Pane, Polygon, Polyline, Tooltip } from 'react-leaflet';
+import { MapContainer, TileLayer, useMap, Pane, Polygon, Polyline } from 'react-leaflet';
import type { LatLngExpression, Map as LeafletMap, Polyline as LeafletPolyline } from 'leaflet';
import type { MeshNode, PacketArc } from '../../hooks/useNodes.js';
import type { NodeCoverage } from '../../hooks/useCoverage.js';
@@ -294,16 +294,8 @@ export const MapView: React.FC
= ({
weight,
opacity,
}}
- interactive
- >
-
-
-
Seen{line.observedCount}
-
Path Loss{line.pathLossDb == null ? 'unknown' : `${Math.round(line.pathLossDb)} dB`}
-
A→B / B→A{line.countAToB} / {line.countBToA}
-
-
-
+ interactive={false}
+ />
);
})}
@@ -358,16 +350,6 @@ export const MapView: React.FC = ({
)}
- {showLinks && (
-
-
Links Legend
-
Good (≤120 dB)
-
Marginal (121-135 dB)
-
Weak (>135 dB)
-
Unknown (no dB yet)
-
- )}
-
{/* deck.gl overlay — arcs only */}
= {
@@ -21,27 +21,14 @@ interface Props {
pinnedPacketId?: string | null;
}
-const ROW_HEIGHT = 32;
const VISIBLE_ROWS = 8;
-const OVERSCAN = 4;
export const PacketFeed: React.FC = React.memo(({ packets, nodes, onPacketClick, pinnedPacketId }) => {
- const [scrollTop, setScrollTop] = useState(0);
- const total = packets.length;
- const start = Math.max(0, Math.floor(scrollTop / ROW_HEIGHT) - OVERSCAN);
- const end = Math.min(total, start + VISIBLE_ROWS + OVERSCAN * 2);
- const visible = useMemo(
- () => packets.slice(start, end).map((packet, idx) => ({ packet, index: start + idx })),
- [packets, start, end],
- );
+ const visible = useMemo(() => packets.slice(0, VISIBLE_ROWS), [packets]);
return (
- = VISIBLE_ROWS ? ' packet-feed--overflow' : ''}`}
- onScroll={(e) => setScrollTop((e.target as HTMLDivElement).scrollTop)}
- >
-
- {visible.map(({ packet: p, index }) => {
+
+ {visible.map((p) => {
const typeLabel = p.packetType !== undefined
? (TYPE_LABELS[p.packetType] ?? `T${p.packetType}`)
: '???';
@@ -63,7 +50,6 @@ export const PacketFeed: React.FC
= React.memo(({ packets, nodes, onPacke
onPacketClick?.(p)}
role="button"
tabIndex={0}
@@ -87,7 +73,6 @@ export const PacketFeed: React.FC
= React.memo(({ packets, nodes, onPacke
);
})}
-
);
});
diff --git a/frontend/src/components/app/MobileControls.tsx b/frontend/src/components/app/MobileControls.tsx
index dc7e52d..d5c9ad9 100644
--- a/frontend/src/components/app/MobileControls.tsx
+++ b/frontend/src/components/app/MobileControls.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import type { Map as LeafletMap } from 'leaflet';
import { NodeSearch } from '../Map/NodeSearch.js';
-import { FILTER_ROWS, type Filters } from '../FilterPanel/FilterPanel.js';
+import { FILTER_ROWS, LinksLegend, type Filters } from '../FilterPanel/FilterPanel.js';
import type { MeshNode } from '../../hooks/useNodes.js';
type MobileControlsProps = {
@@ -42,9 +42,11 @@ export const MobileControls: React.FC
= ({
))}
+