device store cleanup & peers page improvements

This commit is contained in:
Sacha Weatherstone
2023-01-01 01:23:30 +11:00
parent ec25ec60ee
commit 0fcf27a77f
8 changed files with 132 additions and 146 deletions
@@ -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
@@ -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}
/>
))}
</div>
@@ -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 ? (
<div className="ml-4 flex">
<div className="ml-5 flex">
{message.state === "ack" ? (
<CheckCircleIcon className="my-auto h-4 text-textSecondary" />
) : message.state === "waiting" ? (
@@ -46,7 +46,7 @@ export const Message = ({
message.state === "ack" ? "text-textPrimary" : "text-textSecondary"
}`}
>
{message.text}
{message.data}
</span>
)}
</div>
@@ -63,14 +63,13 @@ export const Message = ({
{sender?.user?.longName ?? "UNK"}
</span>
<span className="mt-1 font-mono text-xs text-textSecondary">
{new Date(message.packet.rxTime).toLocaleTimeString(undefined, {
{message.rxTime.toLocaleTimeString(undefined, {
hour: "2-digit",
minute: "2-digit"
})}
</span>
</div>
<div className="flex">
{/* <ExclamationCircleIcon /> */}
<div className="ml-1 flex">
{message.state === "ack" ? (
<CheckCircleIcon className="my-auto h-4 text-textSecondary" />
) : message.state === "waiting" ? (
@@ -88,7 +87,7 @@ export const Message = ({
: "text-textSecondary"
}`}
>
{message.text}
{message.data}
</span>
)}
</div>
+84 -120
View File
@@ -15,12 +15,12 @@ export type Page =
| "info"
| "logs";
export interface MessageWithState extends Types.MessagePacket {
export interface MessageWithState extends Types.PacketMetadata<string> {
state: MessageState;
}
export interface WaypointIDWithState
extends Omit<Types.WaypointPacket, "data"> {
extends Omit<Types.PacketMetadata<Protobuf.Waypoint>, "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<Protobuf.Telemetry>) => 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<Protobuf.User>) => void;
addPosition: (position: Types.PacketMetadata<Protobuf.Position>) => void;
addConnection: (connection: Types.ConnectionType) => void;
addMessage: (message: MessageWithState) => void;
addWaypointMessage: (message: WaypointIDWithState) => void;
addDeviceMetadataMessage: (metadata: Types.DeviceMetadataPacket) => void;
addDeviceMetadataMessage: (
metadata: Types.PacketMetadata<Protobuf.DeviceMetadata>
) => 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<DeviceState>((set, get) => ({
})
);
},
setMetrics: (metrics: Types.TelemetryPacket) => {
setMetrics: (metrics: Types.PacketMetadata<Protobuf.Telemetry>) => {
set(
produce<DeviceState>((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<DeviceState>((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<DeviceState>((set, get) => ({
set(
produce<DeviceState>((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<DeviceState>((set, get) => ({
set(
produce<DeviceState>((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<DeviceState>((set, get) => ({
set(
produce<DeviceState>((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<DeviceState>((set, get) => ({
set(
produce<DeviceState>((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<DeviceState>((set, get) => ({
set(
produce<DeviceState>((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<DeviceState>((set, get) => ({
set(
produce<DeviceState>((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<DeviceState>((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<DeviceState>((set, get) => ({
}
})
);
},
processPacket(data: processPacketParams) {
set(
produce<DeviceState>((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
};
}
})
);
}
});
})
+14 -6
View File
@@ -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
});
});
};
+5 -1
View File
@@ -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 => {
)}
</td>
<td className="whitespace-nowrap py-2 text-sm text-textSecondary">
{new Date(node.data.lastHeard).toLocaleTimeString()}
<TimeAgo
datetime={node.data.lastHeard * 1000}
opts={{ minInterval: 10 }}
/>
</td>
<td className="whitespace-nowrap py-2 text-sm text-textSecondary">
<Mono>{node.data.snr}db</Mono>