diff --git a/main.go b/main.go index 15bc98f..5173fb2 100644 --- a/main.go +++ b/main.go @@ -17,7 +17,7 @@ const ( mqttBroker = "mqtt.bayme.sh" mqttUsername = "meshdev" mqttPassword = "large4cats" - mqttTopicPrefix = "msh/US/CA" + mqttTopicPrefix = "msh/US/CA/Motherlode" // Web server configuration serverHost = "localhost" diff --git a/server/server.go b/server/server.go index 994c71c..efcaf87 100644 --- a/server/server.go +++ b/server/server.go @@ -139,10 +139,25 @@ func (s *Server) handleStream(w http.ResponseWriter, r *http.Request) { // Signal when the client disconnects notify := ctx.Done() - // Send an initial message - fmt.Fprintf(w, "event: info\ndata: Connected to Meshtastic stream\n\n") + // Send an initial message with an additional 1.5k payload. This force buffer + // flush so the client knows the connection is open. + w.WriteHeader(http.StatusOK) + + initialMessage := "Connected to Meshtastic stream" + paddingSize := 1500 + padding := make([]byte, paddingSize) + for i := 0; i < paddingSize; i++ { + padding[i] = byte('A' + (i % 26)) + } + + // Send the event with the padded data + fmt.Fprintf(w, "event: info\ndata: %s\n\n", initialMessage) + fmt.Fprintf(w, "event: info\ndata: %s\n\n", padding) flusher.Flush() + // Log that we sent the large initial message + logger.Debug("Sent large initial message to force buffer flush") + // Stream messages to the client for { select { diff --git a/web/src/components/dashboard/GatewayList.tsx b/web/src/components/dashboard/GatewayList.tsx index ade1f14..1ca94c3 100644 --- a/web/src/components/dashboard/GatewayList.tsx +++ b/web/src/components/dashboard/GatewayList.tsx @@ -1,10 +1,12 @@ import React from "react"; +import { useNavigate } from "@tanstack/react-router"; import { useAppSelector } from "../../hooks"; import { RefreshCw } from "lucide-react"; import { MeshCard } from "./MeshCard"; export const GatewayList: React.FC = () => { const { gateways, nodes } = useAppSelector((state) => state.aggregator); + const navigate = useNavigate(); // Convert gateways object to array for sorting const gatewayArray = Object.values(gateways); @@ -59,6 +61,10 @@ export const GatewayList: React.FC = () => { const isRecent = secondsSinceLastHeard < 300; // 5 minutes for gateways const isActive = !isRecent && secondsSinceLastHeard < 900; // 5-15 minutes for gateways + const handleNodeClick = (clickedNodeId: number) => { + navigate({ to: "/node/$nodeId", params: { nodeId: clickedNodeId.toString(16) } }); + }; + return ( { }} gatewayId={gateway.gatewayId} observedNodes={gateway.observedNodes} + onClick={handleNodeClick} isRecent={isRecent} isActive={isActive} lastHeard={gateway.lastHeard} diff --git a/web/src/components/dashboard/NodeDetail.tsx b/web/src/components/dashboard/NodeDetail.tsx index 7badf44..bca202e 100644 --- a/web/src/components/dashboard/NodeDetail.tsx +++ b/web/src/components/dashboard/NodeDetail.tsx @@ -291,7 +291,7 @@ export const NodeDetail: React.FC = ({ nodeId }) => {
- ID: {nodeId.toString(16)} + ID: !{nodeId.toString(16)}
diff --git a/web/src/components/dashboard/NodeList.tsx b/web/src/components/dashboard/NodeList.tsx index 47c9510..6ffec26 100644 --- a/web/src/components/dashboard/NodeList.tsx +++ b/web/src/components/dashboard/NodeList.tsx @@ -15,7 +15,7 @@ export const NodeList: React.FC = () => { const sortedNodes = nodeArray.sort((a, b) => a.nodeId - b.nodeId); const handleNodeClick = (nodeId: number) => { - navigate({ to: "/node/$nodeId", params: { nodeId: nodeId.toString() } }); + navigate({ to: "/node/$nodeId", params: { nodeId: nodeId.toString(16) } }); }; if (nodeArray.length === 0) { diff --git a/web/src/routes/node.$nodeId.tsx b/web/src/routes/node.$nodeId.tsx index 18f3225..eff88c7 100644 --- a/web/src/routes/node.$nodeId.tsx +++ b/web/src/routes/node.$nodeId.tsx @@ -9,8 +9,8 @@ function NodePage() { // Get the node ID from the route params const { nodeId } = Route.useParams(); - // Convert nodeId string to number - const nodeIdNum = parseInt(nodeId, 10); + // Convert nodeId hex string to number + const nodeIdNum = parseInt(nodeId, 16); return (