diff --git a/web/src/components/PacketList.tsx b/web/src/components/PacketList.tsx index 9a5c5b9..4ff77a9 100644 --- a/web/src/components/PacketList.tsx +++ b/web/src/components/PacketList.tsx @@ -43,66 +43,40 @@ export const PacketList: React.FC = () => { }, [hashString] ); - + // Get the earliest reception time from the packets const getEarliestTime = useCallback((): string => { if (packets.length === 0) return ""; - + // Find the packet with the earliest rxTime or time let earliestTime: number | undefined; - - packets.forEach(packet => { + + packets.forEach((packet) => { // Check for rxTime first, then fall back to other timestamp fields - const packetTime = packet.data.rxTime || - (packet.data.telemetry?.time) || - undefined; - + const packetTime = + packet.data.rxTime || packet.data.telemetry?.time || undefined; + if (packetTime && (!earliestTime || packetTime < earliestTime)) { earliestTime = packetTime; } }); - + if (!earliestTime) { return "unknown time"; } - + // Format the time in a nice way const date = new Date(earliestTime * 1000); return date.toLocaleTimeString([], { - hour: '2-digit', - minute: '2-digit' + hour: "2-digit", + minute: "2-digit", }); }, [packets]); // We don't need to track packet keys in state anymore since we use data.id // and it's deterministic - removing this effect to prevent the infinite loop issue - if (loading) { - return ( -
- - Loading... -
- ); - } - - if (error) { - return ( -
- Error: {error} -
- ); - } - - if (packets.length === 0 && bufferedPackets.length === 0) { - return ( -
- No packets received yet -
- ); - } - - // Calculate pagination + // Calculate pagination regardless of state const totalPages = Math.ceil(packets.length / PACKETS_PER_PAGE); const startIndex = (currentPage - 1) * PACKETS_PER_PAGE; const endIndex = startIndex + PACKETS_PER_PAGE; @@ -129,102 +103,128 @@ export const PacketList: React.FC = () => { }; return ( -
-
-
- {packets.length} packets received - {packets.length > 0 && ( - <> - , since {getEarliestTime()} - - )} +
+
+
+
+ {packets.length} packets received + {packets.length > 0 && <>, since {getEarliestTime()}} +
+
+ {/* Show buffered count when paused */} + {streamPaused && bufferedPackets.length > 0 && ( +
+ + {bufferedPackets.length} new +
+ )} + + {/* Stream control toggle */} + + + {/* Clear button */} + +
-
- {/* Show buffered count when paused */} - {streamPaused && bufferedPackets.length > 0 && ( -
- - {bufferedPackets.length} new + +
+ +
+ {loading && ( +
+ + Loading... +
+ )} + + {error && ( +
+ Error: {error} +
+ )} + + {!loading && + !error && + packets.length === 0 && + bufferedPackets.length === 0 && ( +
+ Waiting for packets
)} - {/* Stream control toggle */} - - - {/* Clear button */} - -
+ {!loading && !error && packets.length > 0 && ( +
    + {currentPackets.map((packet, index) => ( +
  • + +
  • + ))} +
+ )}
- -
    - {currentPackets.map((packet, index) => ( -
  • - -
  • - ))} -
- - {/* Empty state when no packets are visible but stream is paused */} - {packets.length === 0 && streamPaused && bufferedPackets.length > 0 && ( -
- Stream is paused with {bufferedPackets.length} buffered messages. - -
- )} - - {/* Pagination */} - {totalPages > 1 && ( -
- - -
- Page {currentPage} of {totalPages} +
+ {/* Empty state when no packets are visible but stream is paused */} + {packets.length === 0 && streamPaused && bufferedPackets.length > 0 && ( +
+ Stream is paused with {bufferedPackets.length} buffered messages. +
+ )} - -
- )} + {/* Pagination */} + {totalPages > 1 && ( +
+ + +
+ Page {currentPage} of {totalPages} +
+ + +
+ )} +
); }; diff --git a/web/src/components/PageWrapper.tsx b/web/src/components/PageWrapper.tsx index 4fb2fe3..51f2bbf 100644 --- a/web/src/components/PageWrapper.tsx +++ b/web/src/components/PageWrapper.tsx @@ -9,7 +9,7 @@ interface PageWrapperProps { */ export const PageWrapper: React.FC = ({ children }) => { return ( -
+
{children}
); diff --git a/web/src/components/packets/GenericPacket.tsx b/web/src/components/packets/GenericPacket.tsx index 1242fb6..10b7a5a 100644 --- a/web/src/components/packets/GenericPacket.tsx +++ b/web/src/components/packets/GenericPacket.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { Packet, PortNum, PortNumByName } from "../../lib/types"; +import { Packet, PortNum } from "../../lib/types"; import { Package } from "lucide-react"; import { PacketCard } from "./PacketCard"; import { KeyValueGrid, KeyValuePair } from "./KeyValuePair"; diff --git a/web/src/components/packets/PacketCard.tsx b/web/src/components/packets/PacketCard.tsx index a5dc5d1..1b6503f 100644 --- a/web/src/components/packets/PacketCard.tsx +++ b/web/src/components/packets/PacketCard.tsx @@ -8,7 +8,6 @@ interface PacketCardProps { iconBgColor: string; label: string; children: ReactNode; - backgroundColor?: string; } export const PacketCard: React.FC = ({ @@ -17,12 +16,11 @@ export const PacketCard: React.FC = ({ iconBgColor, label, children, - backgroundColor = "bg-neutral-500/5", }) => { const { data } = packet; return ( -
+
{/* Card Header with all metadata */}
@@ -60,8 +58,8 @@ export const PacketCard: React.FC = ({ {data.rxTime && ( {new Date(data.rxTime * 1000).toLocaleTimeString([], { - hour: '2-digit', - minute: '2-digit' + hour: "2-digit", + minute: "2-digit", })} )} diff --git a/web/src/components/packets/PacketRenderer.tsx b/web/src/components/packets/PacketRenderer.tsx index 2b0da51..c4b17ce 100644 --- a/web/src/components/packets/PacketRenderer.tsx +++ b/web/src/components/packets/PacketRenderer.tsx @@ -4,8 +4,6 @@ import { TextMessagePacket } from "./TextMessagePacket"; import { PositionPacket } from "./PositionPacket"; import { NodeInfoPacket } from "./NodeInfoPacket"; import { TelemetryPacket } from "./TelemetryPacket"; -import { DeviceMetricsPacket } from "./DeviceMetricsPacket"; -import { EnvironmentMetricsPacket } from "./EnvironmentMetricsPacket"; import { ErrorPacket } from "./ErrorPacket"; import { WaypointPacket } from "./WaypointPacket"; import { MapReportPacket } from "./MapReportPacket"; diff --git a/web/src/lib/types.ts b/web/src/lib/types.ts index c4f82a0..ba592af 100644 --- a/web/src/lib/types.ts +++ b/web/src/lib/types.ts @@ -189,6 +189,7 @@ export interface NeighborInfo { export interface MapReport { // This would need to be defined based on the actual data structure // Currently not defined in the proto files + [key: string]: unknown; } export interface HardwareMessage { @@ -228,11 +229,13 @@ export interface Routing { export interface AdminMessage { // This would need to be defined based on the admin.proto // Only include what's actually used in your application + [key: string]: unknown; } export interface Paxcount { // This would need to be defined based on the paxcount.proto // Only include what's actually used in your application + [key: string]: unknown; } // TopicInfo contains parsed information about a Meshtastic MQTT topic diff --git a/web/src/routes/__root.tsx b/web/src/routes/__root.tsx index 1a0eab9..d64716c 100644 --- a/web/src/routes/__root.tsx +++ b/web/src/routes/__root.tsx @@ -28,12 +28,12 @@ export default function Root() { }, []); return ( -
+
{/* Sidebar Navigation */}
diff --git a/web/src/routes/home.tsx b/web/src/routes/home.tsx index 8c34d14..93bc494 100644 --- a/web/src/routes/home.tsx +++ b/web/src/routes/home.tsx @@ -1,5 +1,4 @@ import { InfoMessage, Separator, PageWrapper } from "../components"; -import { SITE_TITLE } from "../lib/config"; export function IndexPage() { return ( diff --git a/web/src/styles/index.css b/web/src/styles/index.css index 30aef0d..32f3758 100644 --- a/web/src/styles/index.css +++ b/web/src/styles/index.css @@ -1,7 +1,5 @@ @import "tailwindcss"; -@tailwind base; -@tailwind components; @tailwind utilities; /* Set default background and text colors and font family */