diff --git a/package.json b/package.json
index cce101d6..cb7b69d2 100644
--- a/package.json
+++ b/package.json
@@ -27,7 +27,7 @@
"@heroicons/react": "^2.0.13",
"@hookform/error-message": "^2.0.1",
"@hookform/resolvers": "^2.9.10",
- "@meshtastic/meshtasticjs": "^0.9.2",
+ "@meshtastic/meshtasticjs": "^0.9.7",
"@tailwindcss/line-clamp": "^0.4.2",
"@tailwindcss/typography": "^0.5.8",
"@turf/turf": "^6.5.0",
@@ -52,6 +52,7 @@
"react-map-gl": "^7.0.20",
"react-qrcode-logo": "^2.8.0",
"rfc4648": "^1.5.2",
+ "timeago-react": "^3.0.5",
"zustand": "4.1.5"
},
"devDependencies": {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 89a6d4f9..233f15b9 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -6,7 +6,7 @@ specifiers:
'@heroicons/react': ^2.0.13
'@hookform/error-message': ^2.0.1
'@hookform/resolvers': ^2.9.10
- '@meshtastic/meshtasticjs': ^0.9.2
+ '@meshtastic/meshtasticjs': ^0.9.7
'@tailwindcss/forms': ^0.5.3
'@tailwindcss/line-clamp': ^0.4.2
'@tailwindcss/typography': ^0.5.8
@@ -56,6 +56,7 @@ specifiers:
rollup-plugin-visualizer: ^5.9.0
tailwindcss: ^3.2.4
tar: ^6.1.13
+ timeago-react: ^3.0.5
tslib: ^2.4.1
typescript: ^4.9.4
unimported: ^1.24.0
@@ -70,7 +71,7 @@ dependencies:
'@heroicons/react': 2.0.13_react@18.2.0
'@hookform/error-message': 2.0.1_7yhncxxycytkes3mwygyjxyp6u
'@hookform/resolvers': 2.9.10_react-hook-form@7.41.3
- '@meshtastic/meshtasticjs': 0.9.2
+ '@meshtastic/meshtasticjs': 0.9.7
'@tailwindcss/line-clamp': 0.4.2_tailwindcss@3.2.4
'@tailwindcss/typography': 0.5.8_tailwindcss@3.2.4
'@turf/turf': 6.5.0
@@ -95,6 +96,7 @@ dependencies:
react-map-gl: 7.0.20_6eczaga5xxiwzxtfiyk6fioasq
react-qrcode-logo: 2.8.0_biqbaboplfbrettd7655fr4n2y
rfc4648: 1.5.2
+ timeago-react: 3.0.5_react@18.2.0
zustand: 4.1.5_immer@9.0.16+react@18.2.0
devDependencies:
@@ -1710,8 +1712,8 @@ packages:
engines: {node: '>=6.0.0'}
dev: false
- /@meshtastic/meshtasticjs/0.9.2:
- resolution: {integrity: sha512-rS/dK3RekRC9R930/RbNgdcktQ/XZv/bPpFZ6/6PJ61+8NjguN6SeNE3GP007TS5GSkp0zu3IgfOHn+pEL94KA==}
+ /@meshtastic/meshtasticjs/0.9.7:
+ resolution: {integrity: sha512-FQAfgJ2FeC55HbmOR1Z7Y3iIyXN32YO5OmtsviPolaZWivE7cCCfwSQGOHrtQUwXUSRv6Up0ucJ0eW7teaXxhA==}
dependencies:
'@protobuf-ts/runtime': 2.8.2
glob: 8.0.3
@@ -6430,6 +6432,19 @@ packages:
readable-stream: 3.6.0
dev: true
+ /timeago-react/3.0.5_react@18.2.0:
+ resolution: {integrity: sha512-1k/aDt+ADpcABCmg3BIBuZSa7aSxolmuYFkdcpL7mlNkFcDAK/KwuxLf68gowhM7Oq3vWTE7LPeq3kLkSt45Jg==}
+ peerDependencies:
+ react: ^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0
+ dependencies:
+ react: 18.2.0
+ timeago.js: 4.0.2
+ dev: false
+
+ /timeago.js/4.0.2:
+ resolution: {integrity: sha512-a7wPxPdVlQL7lqvitHGGRsofhdwtkoSXPGATFuSOA2i1ZNQEPLrGnj68vOp2sOJTCFAQVXPeNMX/GctBaO9L2w==}
+ dev: false
+
/tiny-glob/0.2.9:
resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==}
dependencies:
diff --git a/src/components/PageComponents/Config/Network.tsx b/src/components/PageComponents/Config/Network.tsx
index df6abb12..17c0e12a 100644
--- a/src/components/PageComponents/Config/Network.tsx
+++ b/src/components/PageComponents/Config/Network.tsx
@@ -52,8 +52,6 @@ export const Network = (): JSX.Element => {
}, [reset, config.network]);
const onSubmit = handleSubmit((data) => {
- console.log(data);
-
if (connection) {
void toast.promise(
connection
diff --git a/src/components/PageComponents/Messages/ChannelChat.tsx b/src/components/PageComponents/Messages/ChannelChat.tsx
index bd692a64..7e57fd88 100644
--- a/src/components/PageComponents/Messages/ChannelChat.tsx
+++ b/src/components/PageComponents/Messages/ChannelChat.tsx
@@ -22,12 +22,9 @@ export const ChannelChat = ({ channel }: ChannelChatProps): JSX.Element => {
lastMsgSameUser={
index === 0
? false
- : channel.messages[index - 1].packet.from ===
- message.packet.from
- }
- sender={
- nodes.find((node) => node.data.num === message.packet.from)?.data
+ : channel.messages[index - 1].from === message.from
}
+ sender={nodes.find((node) => node.data.num === message.from)?.data}
/>
))}
diff --git a/src/components/PageComponents/Messages/Message.tsx b/src/components/PageComponents/Messages/Message.tsx
index 3b8857d2..57ecba7d 100644
--- a/src/components/PageComponents/Messages/Message.tsx
+++ b/src/components/PageComponents/Messages/Message.tsx
@@ -25,12 +25,12 @@ export const Message = ({
const { setPeerInfoOpen, setActivePeer, connection } = useDevice();
const openPeer = (): void => {
- setActivePeer(message.packet.from);
+ setActivePeer(message.from);
setPeerInfoOpen(true);
};
return lastMsgSameUser ? (
-
+
{message.state === "ack" ? (
) : message.state === "waiting" ? (
@@ -46,7 +46,7 @@ export const Message = ({
message.state === "ack" ? "text-textPrimary" : "text-textSecondary"
}`}
>
- {message.text}
+ {message.data}
)}
@@ -63,14 +63,13 @@ export const Message = ({
{sender?.user?.longName ?? "UNK"}
- {new Date(message.packet.rxTime).toLocaleTimeString(undefined, {
+ {message.rxTime.toLocaleTimeString(undefined, {
hour: "2-digit",
minute: "2-digit"
})}
-
- {/*
*/}
+
{message.state === "ack" ? (
) : message.state === "waiting" ? (
@@ -88,7 +87,7 @@ export const Message = ({
: "text-textSecondary"
}`}
>
- {message.text}
+ {message.data}
)}
diff --git a/src/core/stores/deviceStore.ts b/src/core/stores/deviceStore.ts
index 2a13348a..860ca1b5 100644
--- a/src/core/stores/deviceStore.ts
+++ b/src/core/stores/deviceStore.ts
@@ -15,12 +15,12 @@ export type Page =
| "info"
| "logs";
-export interface MessageWithState extends Types.MessagePacket {
+export interface MessageWithState extends Types.PacketMetadata
{
state: MessageState;
}
export interface WaypointIDWithState
- extends Omit {
+ extends Omit, "data"> {
waypointID: number;
state: MessageState;
}
@@ -42,6 +42,12 @@ export interface Node {
data: Protobuf.NodeInfo;
}
+export interface processPacketParams {
+ from: number;
+ snr: number;
+ time: number;
+}
+
export interface Device {
id: number;
ready: boolean;
@@ -69,20 +75,22 @@ export interface Device {
setConfig: (config: Protobuf.Config) => void;
setModuleConfig: (config: Protobuf.ModuleConfig) => void;
setHardware: (hardware: Protobuf.MyNodeInfo) => void;
- setMetrics: (metrics: Types.TelemetryPacket) => void;
+ setMetrics: (metrics: Types.PacketMetadata) => void;
setActivePage: (page: Page) => void;
setPeerInfoOpen: (open: boolean) => void;
setActivePeer: (peer: number) => void;
setPendingSettingsChanges: (state: boolean) => void;
addChannel: (channel: Channel) => void;
addWaypoint: (waypoint: Protobuf.Waypoint) => void;
- addNodeInfo: (nodeInfo: Types.NodeInfoPacket) => void;
- addUser: (user: Types.UserPacket) => void;
- addPosition: (position: Types.PositionPacket) => void;
+ addNodeInfo: (nodeInfo: Protobuf.NodeInfo) => void;
+ addUser: (user: Types.PacketMetadata) => void;
+ addPosition: (position: Types.PacketMetadata) => void;
addConnection: (connection: Types.ConnectionType) => void;
addMessage: (message: MessageWithState) => void;
addWaypointMessage: (message: WaypointIDWithState) => void;
- addDeviceMetadataMessage: (metadata: Types.DeviceMetadataPacket) => void;
+ addDeviceMetadataMessage: (
+ metadata: Types.PacketMetadata
+ ) => void;
setMessageState: (
channelIndex: number,
messageId: number,
@@ -92,6 +100,7 @@ export interface Device {
setQRDialogOpen: (open: boolean) => void;
setShutdownDialogOpen: (open: boolean) => void;
setRebootDialogOpen: (open: boolean) => void;
+ processPacket: (data: processPacketParams) => void;
}
export interface DeviceState {
@@ -237,27 +246,13 @@ export const useDeviceStore = create((set, get) => ({
})
);
},
- setMetrics: (metrics: Types.TelemetryPacket) => {
+ setMetrics: (metrics: Types.PacketMetadata) => {
set(
produce((draft) => {
const device = draft.devices.get(id);
let node = device?.nodes.find(
- (n) => n.data.num === metrics.packet.from
+ (n) => n.data.num === metrics.from
);
- if (device && !node) {
- node = {
- data: Protobuf.NodeInfo.create({
- num: metrics.packet.from,
- snr: metrics.packet.rxSnr,
- lastHeard: Date.now()
- }),
- metadata: undefined,
- deviceMetrics: [],
- environmentMetrics: []
- };
-
- device.nodes.push(node);
- }
if (node) {
switch (metrics.data.variant.oneofKind) {
case "deviceMetrics":
@@ -283,19 +278,13 @@ export const useDeviceStore = create((set, get) => ({
}
node.deviceMetrics.push({
...metrics.data.variant.deviceMetrics,
- timestamp:
- metrics.packet.rxTime === 0
- ? new Date()
- : new Date(metrics.packet.rxTime * 1000)
+ timestamp: metrics.rxTime
});
break;
case "environmentMetrics":
node.environmentMetrics.push({
...metrics.data.variant.environmentMetrics,
- timestamp:
- metrics.packet.rxTime === 0
- ? new Date()
- : new Date(metrics.packet.rxTime * 1000)
+ timestamp: metrics.rxTime
});
break;
}
@@ -364,30 +353,18 @@ export const useDeviceStore = create((set, get) => ({
set(
produce((draft) => {
const device = draft.devices.get(id);
- if (device) {
- const node = device.nodes.find(
- (node) => node.data.num === nodeInfo.data.num
- );
- if (node) {
- node.data = nodeInfo.data;
- node.data.lastHeard =
- nodeInfo.packet.rxTime !== 0
- ? nodeInfo.packet.rxTime * 1000
- : Date.now();
- } else {
- device.nodes.push({
- data: Protobuf.NodeInfo.create({
- ...nodeInfo.data,
- lastHeard:
- nodeInfo.packet.rxTime !== 0
- ? nodeInfo.packet.rxTime * 1000
- : Date.now()
- }),
- metadata: undefined,
- deviceMetrics: [],
- environmentMetrics: []
- });
- }
+ const node = device?.nodes.find(
+ (node) => node.data.num === nodeInfo.num
+ );
+ if (node) {
+ node.data = nodeInfo;
+ } else {
+ device?.nodes.push({
+ data: nodeInfo,
+ metadata: undefined,
+ deviceMetrics: [],
+ environmentMetrics: []
+ });
}
})
);
@@ -416,29 +393,11 @@ export const useDeviceStore = create((set, get) => ({
set(
produce((draft) => {
const device = draft.devices.get(id);
- if (device) {
- const node = device.nodes.find(
- (node) => node.data.num === user.packet.from
- );
- if (node) {
- node.data.user = user.data;
- // if (action.payload.packet.rxTime) {
- // node.data.lastHeard = new Date(
- // action.payload.packet.rxTime * 1000,
- // ).getTime();
- // }
- } else {
- device.nodes.push({
- data: Protobuf.NodeInfo.create({
- num: user.packet.from,
- snr: user.packet.rxSnr,
- user: user.data
- }),
- metadata: undefined,
- deviceMetrics: [],
- environmentMetrics: []
- });
- }
+ const node = device?.nodes.find(
+ (node) => node.data.num === user.from
+ );
+ if (node) {
+ node.data.user = user.data;
}
})
);
@@ -447,28 +406,11 @@ export const useDeviceStore = create((set, get) => ({
set(
produce((draft) => {
const device = draft.devices.get(id);
- if (device) {
- const node = device.nodes.find(
- (node) => node.data.num === position.packet.from
- );
- if (node) {
- node.data.position = position.data;
- // if (action.payload.packet.rxTime) {
- // node.data.lastHeard = new Date(
- // action.payload.packet.rxTime * 1000,
- // ).getTime();
- // }
- } else {
- device.nodes.push({
- data: Protobuf.NodeInfo.create({
- num: position.packet.from,
- position: position.data
- }),
- metadata: undefined,
- deviceMetrics: [],
- environmentMetrics: []
- });
- }
+ const node = device?.nodes.find(
+ (node) => node.data.num === position.from
+ );
+ if (node) {
+ node.data.position = position.data;
}
})
);
@@ -487,11 +429,9 @@ export const useDeviceStore = create((set, get) => ({
set(
produce((draft) => {
const device = draft.devices.get(id);
- if (device) {
- device.channels
- .find((ch) => ch.config.index === message.packet.channel)
- ?.messages.push(message);
- }
+ device?.channels
+ .find((ch) => ch.config.index === message.channel)
+ ?.messages.push(message);
})
);
},
@@ -499,11 +439,9 @@ export const useDeviceStore = create((set, get) => ({
set(
produce((draft) => {
const device = draft.devices.get(id);
- if (device) {
- device.channels
- .find((ch) => ch.config.index === waypointID.packet.channel)
- ?.messages.push(waypointID);
- }
+ device?.channels
+ .find((ch) => ch.config.index === waypointID.channel)
+ ?.messages.push(waypointID);
})
);
},
@@ -511,15 +449,11 @@ export const useDeviceStore = create((set, get) => ({
set(
produce((draft) => {
const device = draft.devices.get(id);
- if (device) {
- const node = device.nodes.find(
- (n) => n.data.num === metadata.packet.from
- );
- if (node) {
- node.metadata = metadata.data;
- } else {
- console.log("Node not found!");
- }
+ const node = device?.nodes.find(
+ (n) => n.data.num === metadata.from
+ );
+ if (node) {
+ node.metadata = metadata.data;
}
})
);
@@ -537,7 +471,7 @@ export const useDeviceStore = create((set, get) => ({
(ch) => ch.config.index === channelIndex
);
const message = channel?.messages.find(
- (msg) => msg.packet.id === messageId
+ (msg) => msg.id === messageId
);
if (message) {
message.state = state;
@@ -584,6 +518,36 @@ export const useDeviceStore = create((set, get) => ({
}
})
);
+ },
+ processPacket(data: processPacketParams) {
+ set(
+ produce((draft) => {
+ const device = draft.devices.get(id);
+ if (!device) {
+ return;
+ }
+ const node = device.nodes.find((n) => n.data.num === data.from);
+ if (!node) {
+ device.nodes.push({
+ data: Protobuf.NodeInfo.create({
+ num: data.from,
+ lastHeard: data.time,
+ snr: data.snr
+ }),
+ metadata: undefined,
+ deviceMetrics: [],
+ environmentMetrics: []
+ });
+ return;
+ } else {
+ node.data = {
+ ...node.data,
+ lastHeard: data.time,
+ snr: data.snr
+ };
+ }
+ })
+ );
}
});
})
diff --git a/src/core/subscriptions.ts b/src/core/subscriptions.ts
index 36964d59..22322289 100644
--- a/src/core/subscriptions.ts
+++ b/src/core/subscriptions.ts
@@ -65,7 +65,7 @@ export const subscribeAll = (
device.addWaypoint(data);
device.addWaypointMessage({
waypointID: data.id,
- state: rest.packet.from !== myNodeNum ? "ack" : "waiting",
+ state: rest.from !== myNodeNum ? "ack" : "waiting",
...rest
});
});
@@ -84,7 +84,7 @@ export const subscribeAll = (
});
connection.events.onNodeInfoPacket.subscribe((nodeInfo) => {
- toast(`New Node Discovered: ${nodeInfo.data.user?.shortName ?? "UNK"}`, {
+ toast(`New Node Discovered: ${nodeInfo.user?.shortName ?? "UNK"}`, {
icon: "🔎"
});
device.addNodeInfo(nodeInfo);
@@ -92,26 +92,34 @@ export const subscribeAll = (
connection.events.onChannelPacket.subscribe((channel) => {
device.addChannel({
- config: channel.data,
+ config: channel,
lastInterraction: new Date(),
messages: []
});
});
connection.events.onConfigPacket.subscribe((config) => {
- device.setConfig(config.data);
+ device.setConfig(config);
});
connection.events.onModuleConfigPacket.subscribe((moduleConfig) => {
- device.setModuleConfig(moduleConfig.data);
+ device.setModuleConfig(moduleConfig);
});
connection.events.onMessagePacket.subscribe((messagePacket) => {
device.addMessage({
...messagePacket,
- state: messagePacket.packet.from !== myNodeNum ? "ack" : "waiting"
+ state: messagePacket.from !== myNodeNum ? "ack" : "waiting"
});
});
connection.events.onPendingSettingsChange.subscribe((state) => {
device.setPendingSettingsChanges(state);
});
+
+ connection.events.onMeshPacket.subscribe((meshPacket) => {
+ device.processPacket({
+ from: meshPacket.from,
+ snr: meshPacket.rxSnr,
+ time: meshPacket.rxTime
+ });
+ });
};
diff --git a/src/pages/Peers.tsx b/src/pages/Peers.tsx
index 8808e782..b8d0449c 100644
--- a/src/pages/Peers.tsx
+++ b/src/pages/Peers.tsx
@@ -12,6 +12,7 @@ import {
EllipsisHorizontalIcon
} from "@heroicons/react/24/outline";
import { Protobuf } from "@meshtastic/meshtasticjs";
+import TimeAgo from "timeago-react";
export const PeersPage = (): JSX.Element => {
const { connection, nodes } = useDevice();
@@ -98,7 +99,10 @@ export const PeersPage = (): JSX.Element => {
)}
- {new Date(node.data.lastHeard).toLocaleTimeString()}
+
|
{node.data.snr}db
|