diff --git a/src/PageRouter.tsx b/src/PageRouter.tsx index 04e42e75..40076ea9 100644 --- a/src/PageRouter.tsx +++ b/src/PageRouter.tsx @@ -8,6 +8,7 @@ import { InfoPage } from "@pages/Info.js"; import { MapPage } from "@pages/Map.js"; import { MessagesPage } from "@pages/Messages.js"; +import { LogsPage } from "./pages/Logs.js"; import { PeersPage } from "./pages/Peers.js"; export const PageRouter = (): JSX.Element => { @@ -21,6 +22,7 @@ export const PageRouter = (): JSX.Element => { {activePage === "channels" && } {activePage === "peers" && } {activePage === "info" && } + {activePage === "logs" && } ); }; diff --git a/src/components/CommandPalette/Index.tsx b/src/components/CommandPalette/Index.tsx index 73235c8b..e84231bd 100644 --- a/src/components/CommandPalette/Index.tsx +++ b/src/components/CommandPalette/Index.tsx @@ -28,6 +28,7 @@ import { Cog8ToothIcon, CubeTransparentIcon, DevicePhoneMobileIcon, + DocumentTextIcon, IdentificationIcon, InboxIcon, LinkIcon, @@ -120,6 +121,13 @@ export const CommandPalette = (): JSX.Element => { setActivePage("info"); }, }, + { + name: "Logs", + icon: DocumentTextIcon, + action() { + setActivePage("logs"); + }, + }, ], }, { diff --git a/src/components/PageNav.tsx b/src/components/PageNav.tsx index df5757b0..cf0d5714 100644 --- a/src/components/PageNav.tsx +++ b/src/components/PageNav.tsx @@ -5,6 +5,7 @@ import type { Page } from "@app/core/stores/deviceStore.js"; import { BeakerIcon, Cog8ToothIcon, + DocumentTextIcon, IdentificationIcon, InboxIcon, MapIcon, @@ -57,6 +58,11 @@ export const PageNav = (): JSX.Element => { icon: , page: "info", }, + { + name: "Logs", + icon: , + page: "logs", + }, ]; return ( diff --git a/src/core/stores/deviceStore.ts b/src/core/stores/deviceStore.ts index 5c3126d0..3c460e12 100644 --- a/src/core/stores/deviceStore.ts +++ b/src/core/stores/deviceStore.ts @@ -12,7 +12,8 @@ export type Page = | "config" | "channels" | "peers" - | "info"; + | "info" + | "logs"; export interface MessageWithAck extends Types.MessagePacket { ack: boolean; diff --git a/src/pages/Info.tsx b/src/pages/Info.tsx index 9fc2d897..ac63c875 100644 --- a/src/pages/Info.tsx +++ b/src/pages/Info.tsx @@ -10,8 +10,15 @@ import { useDevice } from "@core/providers/useDevice.js"; import { EyeIcon } from "@heroicons/react/24/outline"; export const InfoPage = (): JSX.Element => { - const { channels, config, moduleConfig, hardware, nodes, waypoints } = - useDevice(); + const { + channels, + config, + moduleConfig, + hardware, + nodes, + waypoints, + connection, + } = useDevice(); const tabs: TabType[] = [ { @@ -44,6 +51,11 @@ export const InfoPage = (): JSX.Element => { icon: , element: () => , }, + { + name: "Connection", + icon: , + element: () => , + }, ]; return ; diff --git a/src/pages/Logs.tsx b/src/pages/Logs.tsx new file mode 100644 index 00000000..38b76381 --- /dev/null +++ b/src/pages/Logs.tsx @@ -0,0 +1,77 @@ +import type React from "react"; +import { useEffect, useState } from "react"; + +import { Mono } from "@app/components/Mono.js"; +import { useDevice } from "@core/providers/useDevice.js"; +import { Protobuf, Types } from "@meshtastic/meshtasticjs"; + +export const LogsPage = (): JSX.Element => { + const { connection } = useDevice(); + const [logs, setLogs] = useState([]); + + useEffect(() => { + connection?.onLogEvent.subscribe((log) => { + setLogs([...logs, log]); + }); + }, [connection, setLogs, logs]); + + return ( +
+
+ + + + + + + + + + + {logs.map((log, index) => ( + + + + + + + ))} + +
+ Emitter + + Level + + Message + + Scope +
+ {Types.Emitter[log.emitter]} + + + {[Protobuf.LogRecord_Level[log.level]]} + + + {log.message} + + {Types.EmitterScope[log.scope]} +
+
+
+ ); +};