update dependencies

This commit is contained in:
Sacha Weatherstone
2025-03-01 13:33:35 +08:00
parent f65f750b7f
commit a5589e232b
30 changed files with 238 additions and 204 deletions
+16 -14
View File
@@ -12,7 +12,7 @@ import { useAppStore } from "@core/stores/appStore.ts";
import { useDeviceStore } from "@core/stores/deviceStore.ts";
import { Dashboard } from "@pages/Dashboard/index.tsx";
import type { JSX } from "react";
import { MapProvider } from "react-map-gl";
import { MapProvider } from "react-map-gl/maplibre";
export const App = (): JSX.Element => {
const { getDevice } = useDeviceStore();
@@ -36,19 +36,21 @@ export const App = (): JSX.Element => {
<div className="flex grow">
<DeviceSelector />
<div className="flex grow flex-col">
{device ? (
<div className="flex h-screen">
<DialogManager />
<KeyBackupReminder />
<CommandPalette />
<PageRouter />
</div>
) : (
<>
<Dashboard />
<Footer />
</>
)}
{device
? (
<div className="flex h-screen">
<DialogManager />
<KeyBackupReminder />
<CommandPalette />
<PageRouter />
</div>
)
: (
<>
<Dashboard />
<Footer />
</>
)}
</div>
</div>
</div>
+2 -1
View File
@@ -12,6 +12,7 @@ import { Input } from "@components/UI/Input.tsx";
import { Label } from "@components/UI/Label.tsx";
import { Protobuf } from "@meshtastic/js";
import { useForm } from "react-hook-form";
import { create } from "@bufbuild/protobuf";
export interface User {
longName: string;
@@ -40,7 +41,7 @@ export const DeviceNameDialog = ({
const onSubmit = handleSubmit((data) => {
connection?.setOwner(
new Protobuf.Mesh.User({
create(Protobuf.Mesh.UserSchema, {
...myNode?.user,
...data,
}),
+18 -11
View File
@@ -1,3 +1,4 @@
import { create, fromBinary } from "@bufbuild/protobuf";
import { Button } from "@components/UI/Button.tsx";
import { Checkbox } from "@components/UI/Checkbox.tsx";
import {
@@ -55,7 +56,10 @@ export const ImportDialog = ({
.replace(/-/g, "+")
.replace(/_/g, "/");
setChannelSet(
Protobuf.AppOnly.ChannelSet.fromBinary(toByteArray(paddedString)),
fromBinary(
Protobuf.AppOnly.ChannelSetSchema,
toByteArray(paddedString),
),
);
setValidUrl(true);
} catch (error) {
@@ -67,12 +71,11 @@ export const ImportDialog = ({
const apply = () => {
channelSet?.settings.map((ch: unknown, index: number) => {
connection?.setChannel(
new Protobuf.Channel.Channel({
create(Protobuf.Channel.ChannelSchema, {
index,
role:
index === 0
? Protobuf.Channel.Channel_Role.PRIMARY
: Protobuf.Channel.Channel_Role.SECONDARY,
role: index === 0
? Protobuf.Channel.Channel_Role.PRIMARY
: Protobuf.Channel.Channel_Role.SECONDARY,
settings: ch,
}),
);
@@ -80,7 +83,7 @@ export const ImportDialog = ({
if (channelSet?.loraConfig) {
connection?.setConfig(
new Protobuf.Config.Config({
create(Protobuf.Config.ConfigSchema, {
payloadVariant: {
case: "lora",
value: channelSet.loraConfig,
@@ -119,21 +122,25 @@ export const ImportDialog = ({
checked={channelSet?.loraConfig?.usePreset ?? true}
/>
</div>
{/* <Select
{
/* <Select
label="Modem Preset"
disabled
value={channelSet?.loraConfig?.modemPreset}
>
{renderOptions(Protobuf.Config_LoRaConfig_ModemPreset)}
</Select> */}
</Select> */
}
</div>
{/* <Select
{
/* <Select
label="Region"
disabled
value={channelSet?.loraConfig?.region}
>
{renderOptions(Protobuf.Config_LoRaConfig_RegionCode)}
</Select> */}
</Select> */
}
<span className="text-md block font-medium text-text-primary">
Channels:
+12 -6
View File
@@ -1,3 +1,4 @@
import { create, toBinary } from "@bufbuild/protobuf";
import { Checkbox } from "@components/UI/Checkbox.tsx";
import {
Dialog,
@@ -39,13 +40,16 @@ export const QRDialog = ({
.filter((ch) => selectedChannels.includes(ch.index))
.map((channel) => channel.settings)
.filter((ch): ch is Protobuf.Channel.ChannelSettings => !!ch);
const encoded = new Protobuf.AppOnly.ChannelSet(
new Protobuf.AppOnly.ChannelSet({
const encoded = create(
Protobuf.AppOnly.ChannelSetSchema,
create(Protobuf.AppOnly.ChannelSetSchema, {
loraConfig,
settings: channelsToEncode,
}),
);
const base64 = fromByteArray(encoded.toBinary())
const base64 = fromByteArray(
toBinary(Protobuf.AppOnly.ChannelSetSchema, encoded),
)
.replace(/=/g, "")
.replace(/\+/g, "-")
.replace(/\//g, "_");
@@ -73,8 +77,8 @@ export const QRDialog = ({
{channel.settings?.name.length
? channel.settings.name
: channel.role === Protobuf.Channel.Channel_Role.PRIMARY
? "Primary"
: `Channel: ${channel.index}`}
? "Primary"
: `Channel: ${channel.index}`}
</Label>
<Checkbox
key={channel.index}
@@ -82,7 +86,9 @@ export const QRDialog = ({
onCheckedChange={() => {
if (selectedChannels.includes(channel.index)) {
setSelectedChannels(
selectedChannels.filter((c) => c !== channel.index),
selectedChannels.filter((c) =>
c !== channel.index
),
);
} else {
setSelectedChannels([
+34 -34
View File
@@ -7,6 +7,7 @@ import { fromByteArray, toByteArray } from "base64-js";
import cryptoRandomString from "crypto-random-string";
import { useState } from "react";
import { PkiRegenerateDialog } from "../Dialog/PkiRegenerateDialog";
import { create } from "@bufbuild/protobuf";
export interface SettingsPanelProps {
channel: Protobuf.Channel.Channel;
@@ -23,11 +24,12 @@ export const Channel = ({ channel }: SettingsPanelProps): JSX.Element => {
channel?.settings?.psk.length ?? 16,
);
const [validationText, setValidationText] = useState<string>();
const [preSharedDialogOpen, setPreSharedDialogOpen] =
useState<boolean>(false);
const [preSharedDialogOpen, setPreSharedDialogOpen] = useState<boolean>(
false,
);
const onSubmit = (data: ChannelValidation) => {
const channel = new Protobuf.Channel.Channel({
const channel = create(Protobuf.Channel.ChannelSchema, {
...data,
settings: {
...data.settings,
@@ -106,7 +108,7 @@ export const Channel = ({ channel }: SettingsPanelProps): JSX.Element => {
channel?.settings?.moduleSettings?.positionPrecision === 32,
positionPrecision:
channel?.settings?.moduleSettings?.positionPrecision ===
undefined
undefined
? 10
: channel?.settings?.moduleSettings?.positionPrecision,
},
@@ -125,10 +127,9 @@ export const Channel = ({ channel }: SettingsPanelProps): JSX.Element => {
description:
"Device telemetry is sent over PRIMARY. Only one PRIMARY allowed",
properties: {
enumValue:
channel.index === 0
? { PRIMARY: 1 }
: { DISABLED: 0, SECONDARY: 2 },
enumValue: channel.index === 0
? { PRIMARY: 1 }
: { DISABLED: 0, SECONDARY: 2 },
},
},
{
@@ -191,32 +192,31 @@ export const Channel = ({ channel }: SettingsPanelProps): JSX.Element => {
description:
"If not sharing precise location, position shared on channel will be accurate within this distance",
properties: {
enumValue:
config.display?.units === 0
? {
"Within 23 km": 10,
"Within 12 km": 11,
"Within 5.8 km": 12,
"Within 2.9 km": 13,
"Within 1.5 km": 14,
"Within 700 m": 15,
"Within 350 m": 16,
"Within 200 m": 17,
"Within 90 m": 18,
"Within 50 m": 19,
}
: {
"Within 15 miles": 10,
"Within 7.3 miles": 11,
"Within 3.6 miles": 12,
"Within 1.8 miles": 13,
"Within 0.9 miles": 14,
"Within 0.5 miles": 15,
"Within 0.2 miles": 16,
"Within 600 feet": 17,
"Within 300 feet": 18,
"Within 150 feet": 19,
},
enumValue: config.display?.units === 0
? {
"Within 23 km": 10,
"Within 12 km": 11,
"Within 5.8 km": 12,
"Within 2.9 km": 13,
"Within 1.5 km": 14,
"Within 700 m": 15,
"Within 350 m": 16,
"Within 200 m": 17,
"Within 90 m": 18,
"Within 50 m": 19,
}
: {
"Within 15 miles": 10,
"Within 7.3 miles": 11,
"Within 3.6 miles": 12,
"Within 1.8 miles": 13,
"Within 0.9 miles": 14,
"Within 0.5 miles": 15,
"Within 0.2 miles": 16,
"Within 600 feet": 17,
"Within 300 feet": 18,
"Within 150 feet": 19,
},
},
},
],
@@ -1,5 +1,6 @@
import { useAppStore } from "@app/core/stores/appStore";
import type { BluetoothValidation } from "@app/validation/config/bluetooth.tsx";
import { create } from "@bufbuild/protobuf";
import { DynamicForm } from "@components/Form/DynamicForm.tsx";
import { useDevice } from "@core/stores/deviceStore.ts";
import { Protobuf } from "@meshtastic/js";
@@ -53,7 +54,7 @@ export const Bluetooth = () => {
}
setWorkingConfig(
new Protobuf.Config.Config({
create(Protobuf.Config.ConfigSchema, {
payloadVariant: {
case: "bluetooth",
value: data,
@@ -110,9 +111,8 @@ export const Bluetooth = () => {
disabledBy: [
{
fieldName: "mode",
selector:
Protobuf.Config.Config_BluetoothConfig_PairingMode
.FIXED_PIN,
selector: Protobuf.Config.Config_BluetoothConfig_PairingMode
.FIXED_PIN,
invert: true,
},
{
@@ -1,4 +1,5 @@
import type { DeviceValidation } from "@app/validation/config/device.tsx";
import { create } from "@bufbuild/protobuf";
import { DynamicForm } from "@components/Form/DynamicForm.tsx";
import { useDevice } from "@core/stores/deviceStore.ts";
import { Protobuf } from "@meshtastic/js";
@@ -8,7 +9,7 @@ export const Device = (): JSX.Element => {
const onSubmit = (data: DeviceValidation) => {
setWorkingConfig(
new Protobuf.Config.Config({
create(Protobuf.Config.ConfigSchema, {
payloadVariant: {
case: "device",
value: data,
@@ -1,4 +1,5 @@
import type { DisplayValidation } from "@app/validation/config/display.tsx";
import { create } from "@bufbuild/protobuf";
import { DynamicForm } from "@components/Form/DynamicForm.tsx";
import { useDevice } from "@core/stores/deviceStore.ts";
import { Protobuf } from "@meshtastic/js";
@@ -8,7 +9,7 @@ export const Display = (): JSX.Element => {
const onSubmit = (data: DisplayValidation) => {
setWorkingConfig(
new Protobuf.Config.Config({
create(Protobuf.Config.ConfigSchema, {
payloadVariant: {
case: "display",
value: data,
@@ -1,4 +1,5 @@
import type { LoRaValidation } from "@app/validation/config/lora.tsx";
import { create } from "@bufbuild/protobuf";
import { DynamicForm } from "@components/Form/DynamicForm.tsx";
import { useDevice } from "@core/stores/deviceStore.ts";
import { Protobuf } from "@meshtastic/js";
@@ -8,7 +9,7 @@ export const LoRa = (): JSX.Element => {
const onSubmit = (data: LoRaValidation) => {
setWorkingConfig(
new Protobuf.Config.Config({
create(Protobuf.Config.ConfigSchema, {
payloadVariant: {
case: "lora",
value: data,
@@ -1,4 +1,5 @@
import type { NetworkValidation } from "@app/validation/config/network.tsx";
import { create } from "@bufbuild/protobuf";
import { DynamicForm } from "@components/Form/DynamicForm.tsx";
import { useDevice } from "@core/stores/deviceStore.ts";
import {
@@ -12,17 +13,20 @@ export const Network = (): JSX.Element => {
const onSubmit = (data: NetworkValidation) => {
setWorkingConfig(
new Protobuf.Config.Config({
create(Protobuf.Config.ConfigSchema, {
payloadVariant: {
case: "network",
value: {
...data,
ipv4Config: new Protobuf.Config.Config_NetworkConfig_IpV4Config({
ip: convertIpAddressToInt(data.ipv4Config.ip) ?? 0,
gateway: convertIpAddressToInt(data.ipv4Config.gateway) ?? 0,
subnet: convertIpAddressToInt(data.ipv4Config.subnet) ?? 0,
dns: convertIpAddressToInt(data.ipv4Config.dns) ?? 0,
}),
ipv4Config: create(
Protobuf.Config.Config_NetworkConfig_IpV4ConfigSchema,
{
ip: convertIpAddressToInt(data.ipv4Config.ip) ?? 0,
gateway: convertIpAddressToInt(data.ipv4Config.gateway) ?? 0,
subnet: convertIpAddressToInt(data.ipv4Config.subnet) ?? 0,
dns: convertIpAddressToInt(data.ipv4Config.dns) ?? 0,
},
),
},
},
}),
@@ -3,6 +3,7 @@ import {
usePositionFlags,
} from "@app/core/hooks/usePositionFlags";
import type { PositionValidation } from "@app/validation/config/position.tsx";
import { create } from "@bufbuild/protobuf";
import { DynamicForm } from "@components/Form/DynamicForm.tsx";
import { useDevice } from "@core/stores/deviceStore.ts";
import { Protobuf } from "@meshtastic/js";
@@ -16,7 +17,7 @@ export const Position = () => {
const onSubmit = (data: PositionValidation) => {
return setWorkingConfig(
new Protobuf.Config.Config({
create(Protobuf.Config.ConfigSchema, {
payloadVariant: {
case: "position",
value: { ...data, positionFlags: flagsValue },
@@ -1,4 +1,5 @@
import type { PowerValidation } from "@app/validation/config/power.tsx";
import { create } from "@bufbuild/protobuf";
import { DynamicForm } from "@components/Form/DynamicForm.tsx";
import { useDevice } from "@core/stores/deviceStore.ts";
import { Protobuf } from "@meshtastic/js";
@@ -8,7 +9,7 @@ export const Power = (): JSX.Element => {
const onSubmit = (data: PowerValidation) => {
setWorkingConfig(
new Protobuf.Config.Config({
create(Protobuf.Config.ConfigSchema, {
payloadVariant: {
case: "power",
value: data,
@@ -12,6 +12,7 @@ import { fromByteArray, toByteArray } from "base64-js";
import { Eye, EyeOff } from "lucide-react";
import { useReducer } from "react";
import { securityReducer } from "./securityReducer";
import { create } from "@bufbuild/protobuf";
export const Security = () => {
const { config, setWorkingConfig, setDialogOpen } = useDevice();
@@ -57,7 +58,9 @@ export const Security = () => {
if (input.length % 4 !== 0) {
addError(
fieldName,
`${fieldName === "privateKey" ? "Private" : "Admin"} Key is required to be a 256 bit pre-shared key (PSK)`,
`${
fieldName === "privateKey" ? "Private" : "Admin"
} Key is required to be a 256 bit pre-shared key (PSK)`,
);
return;
}
@@ -71,7 +74,9 @@ export const Security = () => {
console.error(e);
addError(
fieldName,
`Invalid ${fieldName === "privateKey" ? "Private" : "Admin"} Key format`,
`Invalid ${
fieldName === "privateKey" ? "Private" : "Admin"
} Key format`,
);
}
};
@@ -83,7 +88,7 @@ export const Security = () => {
console.log(toByteArray(state.adminKey));
setWorkingConfig(
new Protobuf.Config.Config({
create(Protobuf.Config.ConfigSchema, {
payloadVariant: {
case: "security",
value: {
@@ -243,7 +248,7 @@ export const Security = () => {
? getErrorMessage("adminKey")
: "",
inputChange: adminKeyInputChangeEvent,
selectChange: () => { },
selectChange: () => {},
bits: [{ text: "256 bit", value: "32", key: "bit256" }],
devicePSKBitCount: state.privateKeyBitCount,
hide: !state.adminKeyVisible,
@@ -303,8 +308,7 @@ export const Security = () => {
<PkiRegenerateDialog
open={state.privateKeyDialogOpen}
onOpenChange={() =>
dispatch({ type: "SHOW_PRIVATE_KEY_DIALOG", payload: false })
}
dispatch({ type: "SHOW_PRIVATE_KEY_DIALOG", payload: false })}
onSubmit={pkiRegenerate}
/>
</>
@@ -1,5 +1,6 @@
import { useDevice } from "@app/core/stores/deviceStore.ts";
import type { AmbientLightingValidation } from "@app/validation/moduleConfig/ambientLighting.tsx";
import { create } from "@bufbuild/protobuf";
import { DynamicForm } from "@components/Form/DynamicForm.tsx";
import { Protobuf } from "@meshtastic/js";
@@ -8,7 +9,7 @@ export const AmbientLighting = (): JSX.Element => {
const onSubmit = (data: AmbientLightingValidation) => {
setWorkingModuleConfig(
new Protobuf.ModuleConfig.ModuleConfig({
create(Protobuf.ModuleConfig.ModuleConfigSchema, {
payloadVariant: {
case: "ambientLighting",
value: data,
@@ -1,4 +1,5 @@
import type { AudioValidation } from "@app/validation/moduleConfig/audio.tsx";
import { create } from "@bufbuild/protobuf";
import { DynamicForm } from "@components/Form/DynamicForm.tsx";
import { useDevice } from "@core/stores/deviceStore.ts";
import { Protobuf } from "@meshtastic/js";
@@ -8,7 +9,7 @@ export const Audio = (): JSX.Element => {
const onSubmit = (data: AudioValidation) => {
setWorkingModuleConfig(
new Protobuf.ModuleConfig.ModuleConfig({
create(Protobuf.ModuleConfig.ModuleConfigSchema, {
payloadVariant: {
case: "audio",
value: data,
@@ -1,4 +1,5 @@
import type { CannedMessageValidation } from "@app/validation/moduleConfig/cannedMessage.tsx";
import { create } from "@bufbuild/protobuf";
import { DynamicForm } from "@components/Form/DynamicForm.tsx";
import { useDevice } from "@core/stores/deviceStore.ts";
import { Protobuf } from "@meshtastic/js";
@@ -8,7 +9,7 @@ export const CannedMessage = (): JSX.Element => {
const onSubmit = (data: CannedMessageValidation) => {
setWorkingModuleConfig(
new Protobuf.ModuleConfig.ModuleConfig({
create(Protobuf.ModuleConfig.ModuleConfigSchema, {
payloadVariant: {
case: "cannedMessage",
value: data,
@@ -62,9 +63,8 @@ export const CannedMessage = (): JSX.Element => {
label: "Clockwise event",
description: "Select input event.",
properties: {
enumValue:
Protobuf.ModuleConfig
.ModuleConfig_CannedMessageConfig_InputEventChar,
enumValue: Protobuf.ModuleConfig
.ModuleConfig_CannedMessageConfig_InputEventChar,
},
},
{
@@ -73,9 +73,8 @@ export const CannedMessage = (): JSX.Element => {
label: "Counter Clockwise event",
description: "Select input event.",
properties: {
enumValue:
Protobuf.ModuleConfig
.ModuleConfig_CannedMessageConfig_InputEventChar,
enumValue: Protobuf.ModuleConfig
.ModuleConfig_CannedMessageConfig_InputEventChar,
},
},
{
@@ -84,9 +83,8 @@ export const CannedMessage = (): JSX.Element => {
label: "Press event",
description: "Select input event",
properties: {
enumValue:
Protobuf.ModuleConfig
.ModuleConfig_CannedMessageConfig_InputEventChar,
enumValue: Protobuf.ModuleConfig
.ModuleConfig_CannedMessageConfig_InputEventChar,
},
},
{
@@ -1,5 +1,6 @@
import { useDevice } from "@app/core/stores/deviceStore.ts";
import type { DetectionSensorValidation } from "@app/validation/moduleConfig/detectionSensor.tsx";
import { create } from "@bufbuild/protobuf";
import { DynamicForm } from "@components/Form/DynamicForm.tsx";
import { Protobuf } from "@meshtastic/js";
@@ -8,7 +9,7 @@ export const DetectionSensor = (): JSX.Element => {
const onSubmit = (data: DetectionSensorValidation) => {
setWorkingModuleConfig(
new Protobuf.ModuleConfig.ModuleConfig({
create(Protobuf.ModuleConfig.ModuleConfigSchema, {
payloadVariant: {
case: "detectionSensor",
value: data,
@@ -1,4 +1,5 @@
import type { ExternalNotificationValidation } from "@app/validation/moduleConfig/externalNotification.tsx";
import { create } from "@bufbuild/protobuf";
import { DynamicForm } from "@components/Form/DynamicForm.tsx";
import { useDevice } from "@core/stores/deviceStore.ts";
import { Protobuf } from "@meshtastic/js";
@@ -8,7 +9,7 @@ export const ExternalNotification = (): JSX.Element => {
const onSubmit = (data: ExternalNotificationValidation) => {
setWorkingModuleConfig(
new Protobuf.ModuleConfig.ModuleConfig({
create(Protobuf.ModuleConfig.ModuleConfigSchema, {
payloadVariant: {
case: "externalNotification",
value: data,
@@ -1,5 +1,6 @@
import { useDevice } from "@app/core/stores/deviceStore.ts";
import type { MqttValidation } from "@app/validation/moduleConfig/mqtt.tsx";
import { create } from "@bufbuild/protobuf";
import { DynamicForm } from "@components/Form/DynamicForm.tsx";
import { Protobuf } from "@meshtastic/js";
@@ -8,15 +9,16 @@ export const MQTT = (): JSX.Element => {
const onSubmit = (data: MqttValidation) => {
setWorkingModuleConfig(
new Protobuf.ModuleConfig.ModuleConfig({
create(Protobuf.ModuleConfig.ModuleConfigSchema, {
payloadVariant: {
case: "mqtt",
value: {
...data,
mapReportSettings:
new Protobuf.ModuleConfig.ModuleConfig_MapReportSettings(
data.mapReportSettings,
),
mapReportSettings: create(
Protobuf.ModuleConfig
.ModuleConfig_MapReportSettingsSchema,
data.mapReportSettings,
),
},
},
}),
@@ -164,32 +166,31 @@ export const MQTT = (): JSX.Element => {
description:
"Position shared will be accurate within this distance",
properties: {
enumValue:
config.display?.units === 0
? {
"Within 23 km": 10,
"Within 12 km": 11,
"Within 5.8 km": 12,
"Within 2.9 km": 13,
"Within 1.5 km": 14,
"Within 700 m": 15,
"Within 350 m": 16,
"Within 200 m": 17,
"Within 90 m": 18,
"Within 50 m": 19,
}
: {
"Within 15 miles": 10,
"Within 7.3 miles": 11,
"Within 3.6 miles": 12,
"Within 1.8 miles": 13,
"Within 0.9 miles": 14,
"Within 0.5 miles": 15,
"Within 0.2 miles": 16,
"Within 600 feet": 17,
"Within 300 feet": 18,
"Within 150 feet": 19,
},
enumValue: config.display?.units === 0
? {
"Within 23 km": 10,
"Within 12 km": 11,
"Within 5.8 km": 12,
"Within 2.9 km": 13,
"Within 1.5 km": 14,
"Within 700 m": 15,
"Within 350 m": 16,
"Within 200 m": 17,
"Within 90 m": 18,
"Within 50 m": 19,
}
: {
"Within 15 miles": 10,
"Within 7.3 miles": 11,
"Within 3.6 miles": 12,
"Within 1.8 miles": 13,
"Within 0.9 miles": 14,
"Within 0.5 miles": 15,
"Within 0.2 miles": 16,
"Within 600 feet": 17,
"Within 300 feet": 18,
"Within 150 feet": 19,
},
},
disabledBy: [
{
@@ -1,5 +1,6 @@
import { useDevice } from "@app/core/stores/deviceStore.ts";
import type { NeighborInfoValidation } from "@app/validation/moduleConfig/neighborInfo.tsx";
import { create } from "@bufbuild/protobuf";
import { DynamicForm } from "@components/Form/DynamicForm.tsx";
import { Protobuf } from "@meshtastic/js";
@@ -8,7 +9,7 @@ export const NeighborInfo = (): JSX.Element => {
const onSubmit = (data: NeighborInfoValidation) => {
setWorkingModuleConfig(
new Protobuf.ModuleConfig.ModuleConfig({
create(Protobuf.ModuleConfig.ModuleConfigSchema, {
payloadVariant: {
case: "neighborInfo",
value: data,
@@ -1,4 +1,5 @@
import type { PaxcounterValidation } from "@app/validation/moduleConfig/paxcounter.tsx";
import { create } from "@bufbuild/protobuf";
import { DynamicForm } from "@components/Form/DynamicForm.tsx";
import { useDevice } from "@core/stores/deviceStore.ts";
import { Protobuf } from "@meshtastic/js";
@@ -8,7 +9,7 @@ export const Paxcounter = (): JSX.Element => {
const onSubmit = (data: PaxcounterValidation) => {
setWorkingModuleConfig(
new Protobuf.ModuleConfig.ModuleConfig({
create(Protobuf.ModuleConfig.ModuleConfigSchema, {
payloadVariant: {
case: "paxcounter",
value: data,
@@ -1,4 +1,5 @@
import type { RangeTestValidation } from "@app/validation/moduleConfig/rangeTest.tsx";
import { create } from "@bufbuild/protobuf";
import { DynamicForm } from "@components/Form/DynamicForm.tsx";
import { useDevice } from "@core/stores/deviceStore.ts";
import { Protobuf } from "@meshtastic/js";
@@ -8,7 +9,7 @@ export const RangeTest = (): JSX.Element => {
const onSubmit = (data: RangeTestValidation) => {
setWorkingModuleConfig(
new Protobuf.ModuleConfig.ModuleConfig({
create(Protobuf.ModuleConfig.ModuleConfigSchema, {
payloadVariant: {
case: "rangeTest",
value: data,
@@ -1,4 +1,5 @@
import type { SerialValidation } from "@app/validation/moduleConfig/serial.tsx";
import { create } from "@bufbuild/protobuf";
import { DynamicForm } from "@components/Form/DynamicForm.tsx";
import { useDevice } from "@core/stores/deviceStore.ts";
import { Protobuf } from "@meshtastic/js";
@@ -8,7 +9,7 @@ export const Serial = (): JSX.Element => {
const onSubmit = (data: SerialValidation) => {
setWorkingModuleConfig(
new Protobuf.ModuleConfig.ModuleConfig({
create(Protobuf.ModuleConfig.ModuleConfigSchema, {
payloadVariant: {
case: "serial",
value: data,
@@ -1,4 +1,5 @@
import type { StoreForwardValidation } from "@app/validation/moduleConfig/storeForward.ts";
import { create } from "@bufbuild/protobuf";
import { DynamicForm } from "@components/Form/DynamicForm.tsx";
import { useDevice } from "@core/stores/deviceStore.ts";
import { Protobuf } from "@meshtastic/js";
@@ -8,7 +9,7 @@ export const StoreForward = (): JSX.Element => {
const onSubmit = (data: StoreForwardValidation) => {
setWorkingModuleConfig(
new Protobuf.ModuleConfig.ModuleConfig({
create(Protobuf.ModuleConfig.ModuleConfigSchema, {
payloadVariant: {
case: "storeForward",
value: data,
@@ -1,4 +1,5 @@
import type { TelemetryValidation } from "@app/validation/moduleConfig/telemetry.tsx";
import { create } from "@bufbuild/protobuf";
import { DynamicForm } from "@components/Form/DynamicForm.tsx";
import { useDevice } from "@core/stores/deviceStore.ts";
import { Protobuf } from "@meshtastic/js";
@@ -8,7 +9,7 @@ export const Telemetry = (): JSX.Element => {
const onSubmit = (data: TelemetryValidation) => {
setWorkingModuleConfig(
new Protobuf.ModuleConfig.ModuleConfig({
create(Protobuf.ModuleConfig.ModuleConfigSchema, {
payloadVariant: {
case: "telemetry",
value: data,
+22 -29
View File
@@ -1,9 +1,8 @@
import { createContext, useContext } from "react";
import { produce } from "immer";
import { create } from "zustand";
import { create as createStore } from "zustand";
import { Protobuf, Types } from "@meshtastic/js";
import { create } from "@bufbuild/protobuf";
export type Page = "messages" | "map" | "config" | "channels" | "nodes";
@@ -111,7 +110,7 @@ export interface DeviceState {
getDevice: (id: number) => Device | undefined;
}
export const useDeviceStore = create<DeviceState>((set, get) => ({
export const useDeviceStore = createStore<DeviceState>((set, get) => ({
devices: new Map(),
remoteDevices: new Map(),
@@ -122,11 +121,11 @@ export const useDeviceStore = create<DeviceState>((set, get) => ({
id,
status: Types.DeviceStatusEnum.DeviceDisconnected,
channels: new Map(),
config: new Protobuf.LocalOnly.LocalConfig(),
moduleConfig: new Protobuf.LocalOnly.LocalModuleConfig(),
config: create(Protobuf.LocalOnly.LocalConfigSchema),
moduleConfig: create(Protobuf.LocalOnly.LocalModuleConfigSchema),
workingConfig: [],
workingModuleConfig: [],
hardware: new Protobuf.Mesh.MyNodeInfo(),
hardware: create(Protobuf.Mesh.MyNodeInfoSchema),
nodes: new Map(),
metadata: new Map(),
messages: {
@@ -138,7 +137,6 @@ export const useDeviceStore = create<DeviceState>((set, get) => ({
activePage: "messages",
activeNode: 0,
waypoints: [],
// currentMetrics: new Protobuf.DeviceMetrics(),
dialog: {
import: false,
QR: false,
@@ -301,11 +299,11 @@ export const useDeviceStore = create<DeviceState>((set, get) => ({
if (!device) {
return;
}
const workingModuleConfigIndex =
device?.workingModuleConfig.findIndex(
const workingModuleConfigIndex = device?.workingModuleConfig
.findIndex(
(wmc) =>
wmc.payloadVariant.case ===
moduleConfig.payloadVariant.case,
moduleConfig.payloadVariant.case,
);
if (workingModuleConfigIndex !== -1) {
device.workingModuleConfig[workingModuleConfigIndex] =
@@ -447,8 +445,8 @@ export const useDeviceStore = create<DeviceState>((set, get) => ({
if (!device) {
return;
}
const currentNode =
device.nodes.get(user.from) ?? new Protobuf.Mesh.NodeInfo();
const currentNode = device.nodes.get(user.from) ??
create(Protobuf.Mesh.NodeInfoSchema);
currentNode.user = user.data;
device.nodes.set(user.from, currentNode);
}),
@@ -461,9 +459,8 @@ export const useDeviceStore = create<DeviceState>((set, get) => ({
if (!device) {
return;
}
const currentNode =
device.nodes.get(position.from) ??
new Protobuf.Mesh.NodeInfo();
const currentNode = device.nodes.get(position.from) ??
create(Protobuf.Mesh.NodeInfoSchema);
currentNode.position = position.data;
device.nodes.set(position.from, currentNode);
}),
@@ -487,12 +484,11 @@ export const useDeviceStore = create<DeviceState>((set, get) => ({
return;
}
const messageGroup = device.messages[message.type];
const messageIndex =
message.type === "direct"
? message.from === device.hardware.myNodeNum
? message.to
: message.from
: message.channel;
const messageIndex = message.type === "direct"
? message.from === device.hardware.myNodeNum
? message.to
: message.from
: message.channel;
const messages = messageGroup.get(messageIndex);
if (messages) {
@@ -565,12 +561,9 @@ export const useDeviceStore = create<DeviceState>((set, get) => ({
}
const messageGroup = device.messages[type];
const messageIndex =
type === "direct"
? from === device.hardware.myNodeNum
? to
: from
: channelIndex;
const messageIndex = type === "direct"
? from === device.hardware.myNodeNum ? to : from
: channelIndex;
const messages = messageGroup.get(messageIndex);
if (!messages) {
@@ -618,7 +611,7 @@ export const useDeviceStore = create<DeviceState>((set, get) => ({
} else {
device.nodes.set(
data.from,
new Protobuf.Mesh.NodeInfo({
create(Protobuf.Mesh.NodeInfoSchema, {
num: data.from,
lastHeard: data.time,
snr: data.snr,
+16 -13
View File
@@ -17,7 +17,7 @@ import {
Popup,
ScaleControl,
useMap,
} from "react-map-gl";
} from "react-map-gl/maplibre";
import MapGl from "react-map-gl/maplibre";
type NodePosition = {
@@ -40,8 +40,9 @@ const MapPage = (): JSX.Element => {
const darkMode = currentTheme === "dark";
const [selectedNode, setSelectedNode] =
useState<Protobuf.Mesh.NodeInfo | null>(null);
const [selectedNode, setSelectedNode] = useState<
Protobuf.Mesh.NodeInfo | null
>(null);
// Filter out nodes without a valid position
const validNodes = useMemo(
@@ -185,16 +186,18 @@ const MapPage = (): JSX.Element => {
</Marker>
))}
{markers}
{selectedNode ? (
<Popup
anchor="top"
longitude={convertToLatLng(selectedNode.position).longitude}
latitude={convertToLatLng(selectedNode.position).latitude}
onClose={() => setSelectedNode(null)}
>
<NodeDetail node={selectedNode} />
</Popup>
) : null}
{selectedNode
? (
<Popup
anchor="top"
longitude={convertToLatLng(selectedNode.position).longitude}
latitude={convertToLatLng(selectedNode.position).latitude}
onClose={() => setSelectedNode(null)}
>
<NodeDetail node={selectedNode} />
</Popup>
)
: null}
</MapGl>
</PageLayout>
</>