Compat with latest JS lib
This commit is contained in:
Vendored
+2
-4
@@ -1,6 +1,4 @@
|
||||
{
|
||||
"css.validate": false,
|
||||
"editor.quickSuggestions": {
|
||||
"strings": true
|
||||
}
|
||||
"editor.defaultFormatter": "trunk.io",
|
||||
"editor.formatOnSave": true
|
||||
}
|
||||
|
||||
+20
-22
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "meshtastic-web",
|
||||
"version": "1.0.0",
|
||||
"version": "2.0.13-0",
|
||||
"type": "module",
|
||||
"description": "Meshtastic web client",
|
||||
"license": "GPL-3.0-only",
|
||||
@@ -9,9 +9,6 @@
|
||||
"build": "tsc && vite build",
|
||||
"preview": "vite preview",
|
||||
"package": "gzipper c -i html,js,css,png,ico,svg,webmanifest,txt dist dist/output && tar -cvf dist/build.tar -C ./dist/output/ $(ls ./dist/output/)",
|
||||
"format:check": "prettier --check . && eslint",
|
||||
"format:fix": "prettier --write . && eslint --fix",
|
||||
"check:unimported": "unimported"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -27,62 +24,63 @@
|
||||
"@heroicons/react": "^2.0.13",
|
||||
"@hookform/error-message": "^2.0.1",
|
||||
"@hookform/resolvers": "^2.9.10",
|
||||
"@meshtastic/meshtasticjs": "^2.0.12",
|
||||
"@primer/octicons-react": "^17.10.1",
|
||||
"@tailwindcss/typography": "^0.5.8",
|
||||
"@meshtastic/meshtasticjs": "2.0.13-5",
|
||||
"@primer/octicons-react": "^17.10.2",
|
||||
"@tailwindcss/typography": "^0.5.9",
|
||||
"@turf/turf": "^6.5.0",
|
||||
"base64-js": "^1.5.1",
|
||||
"chart.js": "^4.1.2",
|
||||
"chart.js": "^4.2.0",
|
||||
"chartjs-adapter-date-fns": "^3.0.0",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.14.0",
|
||||
"date-fns": "^2.29.3",
|
||||
"geodesy": "^2.4.0",
|
||||
"immer": "^9.0.17",
|
||||
"i18next": "^22.4.9",
|
||||
"immer": "^9.0.18",
|
||||
"mapbox-gl": "npm:empty-npm-package@^1.0.0",
|
||||
"maplibre-gl": "2.4.0",
|
||||
"pretty-ms": "^8.0.0",
|
||||
"react": "^18.2.0",
|
||||
"react-chartjs-2": "^5.1.0",
|
||||
"react-chartjs-2": "^5.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-hook-form": "^7.41.5",
|
||||
"react-hook-form": "^7.42.1",
|
||||
"react-hot-toast": "^2.4.0",
|
||||
"react-i18next": "^12.1.4",
|
||||
"react-json-tree": "^0.18.0",
|
||||
"react-map-gl": "^7.0.21",
|
||||
"react-qrcode-logo": "^2.8.0",
|
||||
"rfc4648": "^1.5.2",
|
||||
"timeago-react": "^3.0.5",
|
||||
"zustand": "4.2.0"
|
||||
"zustand": "4.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/forms": "^0.5.3",
|
||||
"@types/chrome": "^0.0.206",
|
||||
"@types/chrome": "^0.0.209",
|
||||
"@types/geodesy": "^2.2.3",
|
||||
"@types/node": "^18.11.18",
|
||||
"@types/react": "^18.0.26",
|
||||
"@types/react": "^18.0.27",
|
||||
"@types/react-dom": "^18.0.10",
|
||||
"@types/w3c-web-serial": "^1.0.3",
|
||||
"@types/web-bluetooth": "^0.0.16",
|
||||
"@typescript-eslint/eslint-plugin": "^5.48.0",
|
||||
"@typescript-eslint/parser": "^5.48.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.48.2",
|
||||
"@typescript-eslint/parser": "^5.48.2",
|
||||
"@vitejs/plugin-react": "^3.0.1",
|
||||
"autoprefixer": "^10.4.13",
|
||||
"eslint": "^8.31.0",
|
||||
"eslint": "^8.32.0",
|
||||
"eslint-config-prettier": "^8.6.0",
|
||||
"eslint-import-resolver-typescript": "^3.5.2",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-react": "^7.31.11",
|
||||
"eslint-import-resolver-typescript": "^3.5.3",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-react": "^7.32.1",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"gzipper": "^7.2.0",
|
||||
"postcss": "^8.4.21",
|
||||
"prettier": "^2.8.2",
|
||||
"prettier": "^2.8.3",
|
||||
"prettier-plugin-tailwindcss": "^0.2.1",
|
||||
"rollup-plugin-visualizer": "^5.9.0",
|
||||
"tailwindcss": "^3.2.4",
|
||||
"tar": "^6.1.13",
|
||||
"tslib": "^2.4.1",
|
||||
"typescript": "^4.9.4",
|
||||
"unimported": "^1.24.0",
|
||||
"vite": "^4.0.4",
|
||||
"vite-plugin-environment": "^1.1.3",
|
||||
"vite-plugin-pwa": "^0.14.1"
|
||||
|
||||
Generated
+338
-648
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 3.1 KiB |
@@ -49,27 +49,27 @@ export const ImportDialog = ({
|
||||
|
||||
const apply = () => {
|
||||
channelSet?.settings.map((ch, index) => {
|
||||
connection?.setChannel({
|
||||
channel: {
|
||||
connection?.setChannel(
|
||||
new Protobuf.Channel({
|
||||
index,
|
||||
role:
|
||||
index === 0
|
||||
? Protobuf.Channel_Role.PRIMARY
|
||||
: Protobuf.Channel_Role.SECONDARY,
|
||||
settings: ch
|
||||
}
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
if (channelSet?.loraConfig) {
|
||||
connection?.setConfig({
|
||||
config: {
|
||||
connection?.setConfig(
|
||||
new Protobuf.Config({
|
||||
payloadVariant: {
|
||||
oneofKind: "lora",
|
||||
lora: channelSet.loraConfig
|
||||
case: "lora",
|
||||
value: channelSet.loraConfig
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -32,13 +32,13 @@ export const QRDialog = ({
|
||||
.filter((channel) => selectedChannels.includes(channel.index))
|
||||
.map((channel) => channel.settings)
|
||||
.filter((ch): ch is Protobuf.ChannelSettings => !!ch);
|
||||
const encoded = Protobuf.ChannelSet.toBinary(
|
||||
Protobuf.ChannelSet.create({
|
||||
const encoded = new Protobuf.ChannelSet(
|
||||
new Protobuf.ChannelSet({
|
||||
loraConfig,
|
||||
settings: channelsToEncode
|
||||
})
|
||||
);
|
||||
const base64 = fromByteArray(encoded)
|
||||
const base64 = fromByteArray(encoded.toBinary())
|
||||
.replace(/=/g, "")
|
||||
.replace(/\+/g, "-")
|
||||
.replace(/\//g, "_");
|
||||
|
||||
@@ -37,9 +37,7 @@ export const RebootDialog = ({
|
||||
icon: <ClockIcon className="w-4" />,
|
||||
action() {
|
||||
connection
|
||||
?.reboot({
|
||||
time: time * 60
|
||||
})
|
||||
?.reboot(time * 60)
|
||||
.then(() => setRebootDialogOpen(false));
|
||||
}
|
||||
}}
|
||||
@@ -48,11 +46,7 @@ export const RebootDialog = ({
|
||||
className="w-24"
|
||||
iconBefore={<ArrowPathIcon className="w-4" />}
|
||||
onClick={() => {
|
||||
connection
|
||||
?.reboot({
|
||||
time: 0
|
||||
})
|
||||
.then(() => setRebootDialogOpen(false));
|
||||
connection?.reboot(2).then(() => setRebootDialogOpen(false));
|
||||
}}
|
||||
>
|
||||
Now
|
||||
|
||||
@@ -37,9 +37,7 @@ export const ShutdownDialog = ({
|
||||
icon: <ClockIcon className="w-4" />,
|
||||
action() {
|
||||
connection
|
||||
?.shutdown({
|
||||
time: time * 60
|
||||
})
|
||||
?.shutdown(time * 60)
|
||||
.then(() => setShutdownDialogOpen(false));
|
||||
}
|
||||
}}
|
||||
@@ -48,11 +46,7 @@ export const ShutdownDialog = ({
|
||||
className="w-24"
|
||||
iconBefore={<PowerIcon className="w-4" />}
|
||||
onClick={() => {
|
||||
connection
|
||||
?.shutdown({
|
||||
time: 0
|
||||
})
|
||||
.then(() => setShutdownDialogOpen(false));
|
||||
connection?.shutdown(2).then(() => setShutdownDialogOpen(false));
|
||||
}}
|
||||
>
|
||||
Now
|
||||
|
||||
@@ -81,7 +81,7 @@ export const Metrics = (): JSX.Element => {
|
||||
data: myNode?.deviceMetrics.map((metric) => {
|
||||
return {
|
||||
x: metric.timestamp,
|
||||
y: metric.airUtilTx
|
||||
y: metric.metric.airUtilTx
|
||||
};
|
||||
}),
|
||||
backgroundColor: "rgba(102, 126, 234, 0.25)",
|
||||
@@ -95,7 +95,7 @@ export const Metrics = (): JSX.Element => {
|
||||
data: myNode?.deviceMetrics.map((metric) => {
|
||||
return {
|
||||
x: metric.timestamp,
|
||||
y: metric.channelUtilization
|
||||
y: metric.metric.channelUtilization
|
||||
};
|
||||
}),
|
||||
backgroundColor: "rgba(237, 100, 166, 0.25)",
|
||||
@@ -109,7 +109,7 @@ export const Metrics = (): JSX.Element => {
|
||||
data: myNode?.deviceMetrics.map((metric) => {
|
||||
return {
|
||||
x: metric.timestamp,
|
||||
y: metric.batteryLevel
|
||||
y: metric.metric.batteryLevel
|
||||
};
|
||||
}),
|
||||
backgroundColor: "rgba(113, 234, 102, 0.25)",
|
||||
@@ -123,7 +123,7 @@ export const Metrics = (): JSX.Element => {
|
||||
data: myNode?.deviceMetrics.map((metric) => {
|
||||
return {
|
||||
x: metric.timestamp,
|
||||
y: metric.voltage
|
||||
y: metric.metric.voltage
|
||||
};
|
||||
}),
|
||||
backgroundColor: "rgba(234, 166, 102, 0.25)",
|
||||
|
||||
@@ -87,7 +87,7 @@ export const Sensor = (): JSX.Element => {
|
||||
data: myNode?.environmentMetrics.map((metric) => {
|
||||
return {
|
||||
x: metric.timestamp,
|
||||
y: metric.barometricPressure
|
||||
y: metric.metric.barometricPressure
|
||||
};
|
||||
}),
|
||||
backgroundColor: "rgba(102, 126, 234, 0.25)",
|
||||
@@ -101,7 +101,7 @@ export const Sensor = (): JSX.Element => {
|
||||
data: myNode?.environmentMetrics.map((metric) => {
|
||||
return {
|
||||
x: metric.timestamp,
|
||||
y: metric.current
|
||||
y: metric.metric.current
|
||||
};
|
||||
}),
|
||||
backgroundColor: "rgba(237, 100, 166, 0.25)",
|
||||
@@ -115,7 +115,7 @@ export const Sensor = (): JSX.Element => {
|
||||
data: myNode?.environmentMetrics.map((metric) => {
|
||||
return {
|
||||
x: metric.timestamp,
|
||||
y: metric.gasResistance
|
||||
y: metric.metric.gasResistance
|
||||
};
|
||||
}),
|
||||
backgroundColor: "rgba(113, 234, 102, 0.25)",
|
||||
@@ -129,7 +129,7 @@ export const Sensor = (): JSX.Element => {
|
||||
data: myNode?.environmentMetrics.map((metric) => {
|
||||
return {
|
||||
x: metric.timestamp,
|
||||
y: metric.relativeHumidity
|
||||
y: metric.metric.relativeHumidity
|
||||
};
|
||||
}),
|
||||
backgroundColor: "rgba(234, 166, 102, 0.25)",
|
||||
@@ -143,7 +143,7 @@ export const Sensor = (): JSX.Element => {
|
||||
data: myNode?.environmentMetrics.map((metric) => {
|
||||
return {
|
||||
x: metric.timestamp,
|
||||
y: metric.temperature
|
||||
y: metric.metric.temperature
|
||||
};
|
||||
}),
|
||||
backgroundColor: "rgba(38, 255, 212, 0.25)",
|
||||
@@ -157,7 +157,7 @@ export const Sensor = (): JSX.Element => {
|
||||
data: myNode?.environmentMetrics.map((metric) => {
|
||||
return {
|
||||
x: metric.timestamp,
|
||||
y: metric.voltage
|
||||
y: metric.metric.voltage
|
||||
};
|
||||
}),
|
||||
backgroundColor: "rgba(247, 255, 15, 0.25)",
|
||||
|
||||
@@ -66,8 +66,8 @@ export const Channel = ({ channel }: SettingsPanelProps): JSX.Element => {
|
||||
if (connection) {
|
||||
void toast.promise(
|
||||
connection
|
||||
.setChannel({
|
||||
channel: {
|
||||
.setChannel(
|
||||
new Protobuf.Channel({
|
||||
role:
|
||||
channel?.role === Protobuf.Channel_Role.PRIMARY
|
||||
? Protobuf.Channel_Role.PRIMARY
|
||||
@@ -79,18 +79,18 @@ export const Channel = ({ channel }: SettingsPanelProps): JSX.Element => {
|
||||
...data,
|
||||
psk: toByteArray(data.psk ?? "")
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
.then(() =>
|
||||
addChannel({
|
||||
config: {
|
||||
config: new Protobuf.Channel({
|
||||
index: channel.index,
|
||||
role: channel.role,
|
||||
settings: {
|
||||
...data,
|
||||
psk: toByteArray(data.psk ?? "")
|
||||
}
|
||||
},
|
||||
}),
|
||||
lastInterraction: new Date(),
|
||||
messages: []
|
||||
})
|
||||
|
||||
@@ -36,21 +36,23 @@ export const Bluetooth = (): JSX.Element => {
|
||||
if (connection) {
|
||||
void toast.promise(
|
||||
connection
|
||||
.setConfig({
|
||||
config: {
|
||||
.setConfig(
|
||||
new Protobuf.Config({
|
||||
payloadVariant: {
|
||||
oneofKind: "bluetooth",
|
||||
bluetooth: data
|
||||
}
|
||||
case: "bluetooth",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
.then(() =>
|
||||
setConfig({
|
||||
setConfig(
|
||||
new Protobuf.Config({
|
||||
payloadVariant: {
|
||||
oneofKind: "bluetooth",
|
||||
bluetooth: data
|
||||
case: "bluetooth",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
),
|
||||
{
|
||||
loading: "Saving...",
|
||||
|
||||
@@ -35,21 +35,23 @@ export const Device = (): JSX.Element => {
|
||||
if (connection) {
|
||||
void toast.promise(
|
||||
connection
|
||||
.setConfig({
|
||||
config: {
|
||||
.setConfig(
|
||||
new Protobuf.Config({
|
||||
payloadVariant: {
|
||||
oneofKind: "device",
|
||||
device: data
|
||||
}
|
||||
case: "device",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
.then(() =>
|
||||
setConfig({
|
||||
setConfig(
|
||||
new Protobuf.Config({
|
||||
payloadVariant: {
|
||||
oneofKind: "device",
|
||||
device: data
|
||||
case: "device",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
),
|
||||
{
|
||||
loading: "Saving...",
|
||||
|
||||
@@ -35,21 +35,23 @@ export const Display = (): JSX.Element => {
|
||||
if (connection) {
|
||||
void toast.promise(
|
||||
connection
|
||||
.setConfig({
|
||||
config: {
|
||||
.setConfig(
|
||||
new Protobuf.Config({
|
||||
payloadVariant: {
|
||||
oneofKind: "display",
|
||||
display: data
|
||||
}
|
||||
case: "display",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
.then(() =>
|
||||
setConfig({
|
||||
setConfig(
|
||||
new Protobuf.Config({
|
||||
payloadVariant: {
|
||||
oneofKind: "display",
|
||||
display: data
|
||||
case: "display",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
),
|
||||
{
|
||||
loading: "Saving...",
|
||||
@@ -127,6 +129,25 @@ export const Display = (): JSX.Element => {
|
||||
>
|
||||
{renderOptions(Protobuf.Config_DisplayConfig_OledType)}
|
||||
</Select>
|
||||
<Select
|
||||
label="Display Mode"
|
||||
description="Screen layout variant"
|
||||
{...register("displaymode", { valueAsNumber: true })}
|
||||
>
|
||||
{renderOptions(Protobuf.Config_DisplayConfig_DisplayMode)}
|
||||
</Select>
|
||||
<Controller
|
||||
name="headingBold"
|
||||
control={control}
|
||||
render={({ field: { value, ...rest } }) => (
|
||||
<Toggle
|
||||
label="Bold Heading"
|
||||
description="Bolden the heading text"
|
||||
checked={value}
|
||||
{...rest}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -43,21 +43,23 @@ export const LoRa = (): JSX.Element => {
|
||||
if (connection) {
|
||||
void toast.promise(
|
||||
connection
|
||||
.setConfig({
|
||||
config: {
|
||||
.setConfig(
|
||||
new Protobuf.Config({
|
||||
payloadVariant: {
|
||||
oneofKind: "lora",
|
||||
lora: data
|
||||
}
|
||||
case: "lora",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
.then(() =>
|
||||
setConfig({
|
||||
setConfig(
|
||||
new Protobuf.Config({
|
||||
payloadVariant: {
|
||||
oneofKind: "lora",
|
||||
lora: data
|
||||
case: "lora",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
),
|
||||
{
|
||||
loading: "Saving...",
|
||||
|
||||
@@ -56,21 +56,23 @@ export const Network = (): JSX.Element => {
|
||||
if (connection) {
|
||||
void toast.promise(
|
||||
connection
|
||||
.setConfig({
|
||||
config: {
|
||||
.setConfig(
|
||||
new Protobuf.Config({
|
||||
payloadVariant: {
|
||||
oneofKind: "network",
|
||||
network: Protobuf.Config_NetworkConfig.create(data)
|
||||
}
|
||||
case: "network",
|
||||
value: new Protobuf.Config_NetworkConfig(data)
|
||||
}
|
||||
})
|
||||
)
|
||||
.then(() =>
|
||||
setConfig({
|
||||
setConfig(
|
||||
new Protobuf.Config({
|
||||
payloadVariant: {
|
||||
oneofKind: "network",
|
||||
network: data
|
||||
case: "network",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
),
|
||||
{
|
||||
loading: "Saving...",
|
||||
|
||||
@@ -55,19 +55,19 @@ export const Position = (): JSX.Element => {
|
||||
|
||||
const configHasChanged = !Protobuf.Config_PositionConfig.equals(
|
||||
config.position,
|
||||
Protobuf.Config_PositionConfig.create(rest)
|
||||
new Protobuf.Config_PositionConfig(rest)
|
||||
);
|
||||
|
||||
if (connection) {
|
||||
void toast.promise(
|
||||
connection
|
||||
.setPosition({
|
||||
position: Protobuf.Position.create({
|
||||
.setPosition(
|
||||
new Protobuf.Position({
|
||||
altitude: fixedAlt,
|
||||
latitudeI: fixedLat * 1e7,
|
||||
longitudeI: fixedLng * 1e7
|
||||
})
|
||||
})
|
||||
)
|
||||
.then(() => reset({ ...data })),
|
||||
{
|
||||
loading: "Saving...",
|
||||
@@ -78,21 +78,23 @@ export const Position = (): JSX.Element => {
|
||||
if (configHasChanged) {
|
||||
void toast.promise(
|
||||
connection
|
||||
.setConfig({
|
||||
config: {
|
||||
.setConfig(
|
||||
new Protobuf.Config({
|
||||
payloadVariant: {
|
||||
oneofKind: "position",
|
||||
position: rest
|
||||
}
|
||||
case: "position",
|
||||
value: rest
|
||||
}
|
||||
})
|
||||
)
|
||||
.then(() =>
|
||||
setConfig({
|
||||
setConfig(
|
||||
new Protobuf.Config({
|
||||
payloadVariant: {
|
||||
oneofKind: "position",
|
||||
position: data
|
||||
case: "position",
|
||||
value: rest
|
||||
}
|
||||
})
|
||||
)
|
||||
),
|
||||
{
|
||||
loading: "Saving...",
|
||||
|
||||
@@ -11,6 +11,7 @@ import { PowerValidation } from "@app/validation/config/power.js";
|
||||
import { Form } from "@components/form/Form";
|
||||
import { useDevice } from "@core/providers/useDevice.js";
|
||||
import { classValidatorResolver } from "@hookform/resolvers/class-validator";
|
||||
import { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export const Power = (): JSX.Element => {
|
||||
const { config, connection, setConfig } = useDevice();
|
||||
@@ -33,21 +34,23 @@ export const Power = (): JSX.Element => {
|
||||
if (connection) {
|
||||
void toast.promise(
|
||||
connection
|
||||
.setConfig({
|
||||
config: {
|
||||
.setConfig(
|
||||
new Protobuf.Config({
|
||||
payloadVariant: {
|
||||
oneofKind: "power",
|
||||
power: data
|
||||
}
|
||||
case: "power",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
.then(() =>
|
||||
setConfig({
|
||||
setConfig(
|
||||
new Protobuf.Config({
|
||||
payloadVariant: {
|
||||
oneofKind: "power",
|
||||
power: data
|
||||
case: "power",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
),
|
||||
{
|
||||
loading: "Saving...",
|
||||
|
||||
@@ -44,9 +44,12 @@ export const User = (): JSX.Element => {
|
||||
if (connection && myNode?.data.user) {
|
||||
void toast.promise(
|
||||
connection
|
||||
.setOwner({
|
||||
owner: { ...myNode.data.user, ...data }
|
||||
.setOwner(
|
||||
new Protobuf.User({
|
||||
...myNode.data.user,
|
||||
...data
|
||||
})
|
||||
)
|
||||
.then(() => reset({ ...data })),
|
||||
{
|
||||
loading: "Saving...",
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { useMap } from "react-map-gl";
|
||||
import { lineString, bbox } from "@turf/turf";
|
||||
import { useEffect } from "react";
|
||||
|
||||
import { useMap } from "react-map-gl";
|
||||
|
||||
import { useDevice } from "@app/core/providers/useDevice.js";
|
||||
import {
|
||||
MagnifyingGlassMinusIcon,
|
||||
MagnifyingGlassPlusIcon,
|
||||
ShareIcon
|
||||
} from "@heroicons/react/24/outline";
|
||||
import { useDevice } from "@app/core/providers/useDevice.js";
|
||||
import { useEffect } from "react";
|
||||
import { bbox, lineString } from "@turf/turf";
|
||||
|
||||
export const MapControlls = (): JSX.Element => {
|
||||
const { current: map } = useMap();
|
||||
@@ -15,36 +16,23 @@ export const MapControlls = (): JSX.Element => {
|
||||
|
||||
const getBBox = () => {
|
||||
const nodesWithPosition = nodes.filter((n) => n.data.position?.latitudeI);
|
||||
|
||||
if (nodesWithPosition.length > 1) {
|
||||
if (!nodesWithPosition.length) return;
|
||||
const line = lineString(
|
||||
nodesWithPosition.map((n) => [
|
||||
(n.data.position?.latitudeI ?? 0) / 1e7,
|
||||
(n.data.position?.longitudeI ?? 0) / 1e7
|
||||
])
|
||||
);
|
||||
|
||||
const bounds = bbox(line);
|
||||
|
||||
const center = map?.cameraForBounds(
|
||||
[
|
||||
[bounds[1], bounds[0]],
|
||||
[bounds[3], bounds[2]]
|
||||
],
|
||||
{
|
||||
padding: {
|
||||
top: 10,
|
||||
bottom: 10,
|
||||
left: 10,
|
||||
right: 10
|
||||
}
|
||||
}
|
||||
{ padding: { top: 10, bottom: 10, left: 10, right: 10 } }
|
||||
);
|
||||
|
||||
if (center) {
|
||||
map?.easeTo(center);
|
||||
}
|
||||
} else if (nodesWithPosition.length === 1) {
|
||||
if (center) map?.easeTo(center);
|
||||
else if (nodesWithPosition.length === 1)
|
||||
map?.easeTo({
|
||||
zoom: 12,
|
||||
center: [
|
||||
@@ -52,7 +40,6 @@ export const MapControlls = (): JSX.Element => {
|
||||
(nodesWithPosition[0].data.position?.latitudeI ?? 0) / 1e7
|
||||
]
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -17,11 +17,12 @@ export const MessageInput = ({ channel }: MessageInputProps): JSX.Element => {
|
||||
|
||||
const sendText = async (message: string) => {
|
||||
await connection
|
||||
?.sendText({
|
||||
text: message,
|
||||
wantAck: true,
|
||||
channel: channel.config.index as Types.ChannelNumber
|
||||
})
|
||||
?.sendText(
|
||||
message,
|
||||
"broadcast",
|
||||
true,
|
||||
channel.config.index as Types.ChannelNumber
|
||||
)
|
||||
.then((id) => setMessageState(channel.config.index, id, "ack"))
|
||||
.catch((e: Types.PacketError) =>
|
||||
setMessageState(channel.config.index, e.id, e.error)
|
||||
|
||||
@@ -31,15 +31,15 @@ export const NewLocationMessage = (): JSX.Element => {
|
||||
<Input label="Coordinates" />
|
||||
<Button
|
||||
onClick={() => {
|
||||
void connection?.sendWaypoint({
|
||||
waypoint: Protobuf.Waypoint.create({
|
||||
void connection?.sendWaypoint(
|
||||
new Protobuf.Waypoint({
|
||||
latitudeI: Math.floor(3.89103 * 1e7),
|
||||
longitudeI: Math.floor(105.87005 * 1e7),
|
||||
name: "TEST",
|
||||
description: "This is a description"
|
||||
}),
|
||||
destination: "broadcast"
|
||||
});
|
||||
"broadcast"
|
||||
);
|
||||
}}
|
||||
>
|
||||
Send
|
||||
|
||||
@@ -35,21 +35,23 @@ export const Audio = (): JSX.Element => {
|
||||
if (connection) {
|
||||
void toast.promise(
|
||||
connection
|
||||
.setModuleConfig({
|
||||
moduleConfig: {
|
||||
.setModuleConfig(
|
||||
new Protobuf.ModuleConfig({
|
||||
payloadVariant: {
|
||||
oneofKind: "audio",
|
||||
audio: data
|
||||
}
|
||||
case: "audio",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
.then(() =>
|
||||
setModuleConfig({
|
||||
setModuleConfig(
|
||||
new Protobuf.ModuleConfig({
|
||||
payloadVariant: {
|
||||
oneofKind: "audio",
|
||||
audio: data
|
||||
case: "audio",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
),
|
||||
{
|
||||
loading: "Saving...",
|
||||
@@ -97,25 +99,25 @@ export const Audio = (): JSX.Element => {
|
||||
label="i2SWs"
|
||||
description="Enter a description."
|
||||
type="number"
|
||||
{...register("i2SWs", { valueAsNumber: true })}
|
||||
{...register("i2sWs", { valueAsNumber: true })}
|
||||
/>
|
||||
<Input
|
||||
label="i2SSd"
|
||||
description="Enter a description."
|
||||
type="number"
|
||||
{...register("i2SSd", { valueAsNumber: true })}
|
||||
{...register("i2sSd", { valueAsNumber: true })}
|
||||
/>
|
||||
<Input
|
||||
label="i2SDin"
|
||||
description="Enter a description."
|
||||
type="number"
|
||||
{...register("i2SDin", { valueAsNumber: true })}
|
||||
{...register("i2sDin", { valueAsNumber: true })}
|
||||
/>
|
||||
<Input
|
||||
label="i2SSck"
|
||||
description="Enter a description."
|
||||
type="number"
|
||||
{...register("i2SSck", { valueAsNumber: true })}
|
||||
{...register("i2sSck", { valueAsNumber: true })}
|
||||
/>
|
||||
</Form>
|
||||
);
|
||||
|
||||
@@ -41,21 +41,23 @@ export const CannedMessage = (): JSX.Element => {
|
||||
if (connection) {
|
||||
void toast.promise(
|
||||
connection
|
||||
.setModuleConfig({
|
||||
moduleConfig: {
|
||||
.setModuleConfig(
|
||||
new Protobuf.ModuleConfig({
|
||||
payloadVariant: {
|
||||
oneofKind: "cannedMessage",
|
||||
cannedMessage: data
|
||||
}
|
||||
case: "cannedMessage",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
.then(() =>
|
||||
setModuleConfig({
|
||||
setModuleConfig(
|
||||
new Protobuf.ModuleConfig({
|
||||
payloadVariant: {
|
||||
oneofKind: "cannedMessage",
|
||||
cannedMessage: data
|
||||
case: "cannedMessage",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
),
|
||||
{
|
||||
loading: "Saving...",
|
||||
|
||||
@@ -10,6 +10,7 @@ import { ExternalNotificationValidation } from "@app/validation/moduleConfig/ext
|
||||
import { Form } from "@components/form/Form";
|
||||
import { useDevice } from "@core/providers/useDevice.js";
|
||||
import { classValidatorResolver } from "@hookform/resolvers/class-validator";
|
||||
import { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export const ExternalNotification = (): JSX.Element => {
|
||||
const { moduleConfig, connection, setModuleConfig } = useDevice();
|
||||
@@ -31,21 +32,23 @@ export const ExternalNotification = (): JSX.Element => {
|
||||
if (connection) {
|
||||
void toast.promise(
|
||||
connection
|
||||
.setModuleConfig({
|
||||
moduleConfig: {
|
||||
.setModuleConfig(
|
||||
new Protobuf.ModuleConfig({
|
||||
payloadVariant: {
|
||||
oneofKind: "externalNotification",
|
||||
externalNotification: data
|
||||
}
|
||||
case: "externalNotification",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
.then(() =>
|
||||
setModuleConfig({
|
||||
setModuleConfig(
|
||||
new Protobuf.ModuleConfig({
|
||||
payloadVariant: {
|
||||
oneofKind: "externalNotification",
|
||||
externalNotification: data
|
||||
case: "externalNotification",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
),
|
||||
{
|
||||
loading: "Saving...",
|
||||
|
||||
@@ -10,6 +10,7 @@ import { MQTTValidation } from "@app/validation/moduleConfig/mqtt.js";
|
||||
import { Form } from "@components/form/Form";
|
||||
import { useDevice } from "@core/providers/useDevice.js";
|
||||
import { classValidatorResolver } from "@hookform/resolvers/class-validator";
|
||||
import { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export const MQTT = (): JSX.Element => {
|
||||
const { moduleConfig, connection, setModuleConfig } = useDevice();
|
||||
@@ -38,21 +39,23 @@ export const MQTT = (): JSX.Element => {
|
||||
if (connection) {
|
||||
void toast.promise(
|
||||
connection
|
||||
.setModuleConfig({
|
||||
moduleConfig: {
|
||||
.setModuleConfig(
|
||||
new Protobuf.ModuleConfig({
|
||||
payloadVariant: {
|
||||
oneofKind: "mqtt",
|
||||
mqtt: data
|
||||
}
|
||||
case: "mqtt",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
.then(() =>
|
||||
setModuleConfig({
|
||||
setModuleConfig(
|
||||
new Protobuf.ModuleConfig({
|
||||
payloadVariant: {
|
||||
oneofKind: "mqtt",
|
||||
mqtt: data
|
||||
case: "mqtt",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
),
|
||||
{
|
||||
loading: "Saving...",
|
||||
|
||||
@@ -10,6 +10,7 @@ import { RangeTestValidation } from "@app/validation/moduleConfig/rangeTest.js";
|
||||
import { Form } from "@components/form/Form";
|
||||
import { useDevice } from "@core/providers/useDevice.js";
|
||||
import { classValidatorResolver } from "@hookform/resolvers/class-validator";
|
||||
import { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export const RangeTest = (): JSX.Element => {
|
||||
const { moduleConfig, connection, setModuleConfig } = useDevice();
|
||||
@@ -32,21 +33,23 @@ export const RangeTest = (): JSX.Element => {
|
||||
if (connection) {
|
||||
void toast.promise(
|
||||
connection
|
||||
.setModuleConfig({
|
||||
moduleConfig: {
|
||||
.setModuleConfig(
|
||||
new Protobuf.ModuleConfig({
|
||||
payloadVariant: {
|
||||
oneofKind: "rangeTest",
|
||||
rangeTest: data
|
||||
}
|
||||
case: "rangeTest",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
.then(() =>
|
||||
setModuleConfig({
|
||||
setModuleConfig(
|
||||
new Protobuf.ModuleConfig({
|
||||
payloadVariant: {
|
||||
oneofKind: "rangeTest",
|
||||
rangeTest: data
|
||||
case: "rangeTest",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
),
|
||||
{
|
||||
loading: "Saving...",
|
||||
|
||||
@@ -35,21 +35,23 @@ export const Serial = (): JSX.Element => {
|
||||
if (connection) {
|
||||
void toast.promise(
|
||||
connection
|
||||
.setModuleConfig({
|
||||
moduleConfig: {
|
||||
.setModuleConfig(
|
||||
new Protobuf.ModuleConfig({
|
||||
payloadVariant: {
|
||||
oneofKind: "serial",
|
||||
serial: data
|
||||
}
|
||||
case: "serial",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
.then(() =>
|
||||
setModuleConfig({
|
||||
setModuleConfig(
|
||||
new Protobuf.ModuleConfig({
|
||||
payloadVariant: {
|
||||
oneofKind: "serial",
|
||||
serial: data
|
||||
case: "serial",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
),
|
||||
{
|
||||
loading: "Saving...",
|
||||
|
||||
@@ -10,6 +10,7 @@ import { StoreForwardValidation } from "@app/validation/moduleConfig/storeForwar
|
||||
import { Form } from "@components/form/Form";
|
||||
import { useDevice } from "@core/providers/useDevice.js";
|
||||
import { classValidatorResolver } from "@hookform/resolvers/class-validator";
|
||||
import { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export const StoreForward = (): JSX.Element => {
|
||||
const { moduleConfig, connection, setModuleConfig } = useDevice();
|
||||
@@ -32,21 +33,23 @@ export const StoreForward = (): JSX.Element => {
|
||||
if (connection) {
|
||||
void toast.promise(
|
||||
connection
|
||||
.setModuleConfig({
|
||||
moduleConfig: {
|
||||
.setModuleConfig(
|
||||
new Protobuf.ModuleConfig({
|
||||
payloadVariant: {
|
||||
oneofKind: "storeForward",
|
||||
storeForward: data
|
||||
}
|
||||
case: "storeForward",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
.then(() =>
|
||||
setModuleConfig({
|
||||
setModuleConfig(
|
||||
new Protobuf.ModuleConfig({
|
||||
payloadVariant: {
|
||||
oneofKind: "storeForward",
|
||||
storeForward: data
|
||||
case: "storeForward",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
),
|
||||
{
|
||||
loading: "Saving...",
|
||||
|
||||
@@ -10,6 +10,7 @@ import { TelemetryValidation } from "@app/validation/moduleConfig/telemetry.js";
|
||||
import { Form } from "@components/form/Form";
|
||||
import { useDevice } from "@core/providers/useDevice.js";
|
||||
import { classValidatorResolver } from "@hookform/resolvers/class-validator";
|
||||
import { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export const Telemetry = (): JSX.Element => {
|
||||
const { moduleConfig, connection, setModuleConfig } = useDevice();
|
||||
@@ -32,21 +33,23 @@ export const Telemetry = (): JSX.Element => {
|
||||
if (connection) {
|
||||
void toast.promise(
|
||||
connection
|
||||
.setModuleConfig({
|
||||
moduleConfig: {
|
||||
.setModuleConfig(
|
||||
new Protobuf.ModuleConfig({
|
||||
payloadVariant: {
|
||||
oneofKind: "telemetry",
|
||||
telemetry: data
|
||||
}
|
||||
case: "telemetry",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
.then(() =>
|
||||
setModuleConfig({
|
||||
setModuleConfig(
|
||||
new Protobuf.ModuleConfig({
|
||||
payloadVariant: {
|
||||
oneofKind: "telemetry",
|
||||
telemetry: data
|
||||
case: "telemetry",
|
||||
value: data
|
||||
}
|
||||
})
|
||||
)
|
||||
),
|
||||
{
|
||||
loading: "Saving...",
|
||||
|
||||
@@ -30,12 +30,12 @@ export const BatteryWidget = ({
|
||||
let previousStat: number | undefined = undefined;
|
||||
let previousTime = new Date();
|
||||
for (const stat of [...stats].reverse()) {
|
||||
if (stat.batteryLevel) {
|
||||
if (stat.metric.batteryLevel) {
|
||||
if (!currentStat) {
|
||||
currentStat = stat.batteryLevel;
|
||||
currentStat = stat.metric.batteryLevel;
|
||||
currentTime = stat.timestamp;
|
||||
} else {
|
||||
previousStat = stat.batteryLevel;
|
||||
previousStat = stat.metric.batteryLevel;
|
||||
previousTime = stat.timestamp;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { produce } from "immer";
|
||||
import create from "zustand";
|
||||
import { create } from "zustand";
|
||||
|
||||
export interface RasterSource {
|
||||
enabled: boolean;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createContext } from "react";
|
||||
|
||||
import { produce } from "immer";
|
||||
import create from "zustand";
|
||||
import { create } from "zustand";
|
||||
|
||||
import { Protobuf, Types } from "@meshtastic/meshtasticjs";
|
||||
|
||||
@@ -34,8 +34,14 @@ export interface Channel {
|
||||
}
|
||||
|
||||
export interface Node {
|
||||
deviceMetrics: (Protobuf.DeviceMetrics & { timestamp: Date })[];
|
||||
environmentMetrics: (Protobuf.EnvironmentMetrics & { timestamp: Date })[];
|
||||
deviceMetrics: {
|
||||
metric: Protobuf.DeviceMetrics;
|
||||
timestamp: Date;
|
||||
}[];
|
||||
environmentMetrics: {
|
||||
metric: Protobuf.EnvironmentMetrics;
|
||||
timestamp: Date;
|
||||
}[];
|
||||
metadata?: Protobuf.DeviceMetadata;
|
||||
data: Protobuf.NodeInfo;
|
||||
}
|
||||
@@ -125,9 +131,9 @@ export const useDeviceStore = create<DeviceState>((set, get) => ({
|
||||
ready: false,
|
||||
status: Types.DeviceStatusEnum.DEVICE_DISCONNECTED,
|
||||
channels: [],
|
||||
config: Protobuf.LocalConfig.create(),
|
||||
moduleConfig: Protobuf.LocalModuleConfig.create(),
|
||||
hardware: Protobuf.MyNodeInfo.create(),
|
||||
config: new Protobuf.LocalConfig(),
|
||||
moduleConfig: new Protobuf.LocalModuleConfig(),
|
||||
hardware: new Protobuf.MyNodeInfo(),
|
||||
nodes: [],
|
||||
connection: undefined,
|
||||
activePage: "messages",
|
||||
@@ -135,7 +141,7 @@ export const useDeviceStore = create<DeviceState>((set, get) => ({
|
||||
activePeer: 0,
|
||||
waypoints: [],
|
||||
regionUnset: false,
|
||||
currentMetrics: Protobuf.DeviceMetrics.create(),
|
||||
currentMetrics: new Protobuf.DeviceMetrics(),
|
||||
importDialogOpen: false,
|
||||
QRDialogOpen: false,
|
||||
shutdownDialogOpen: false,
|
||||
@@ -169,30 +175,30 @@ export const useDeviceStore = create<DeviceState>((set, get) => ({
|
||||
const device = draft.devices.get(id);
|
||||
|
||||
if (device) {
|
||||
switch (config.payloadVariant.oneofKind) {
|
||||
switch (config.payloadVariant.case) {
|
||||
case "device":
|
||||
device.config.device = config.payloadVariant.device;
|
||||
device.config.device = config.payloadVariant.value;
|
||||
break;
|
||||
case "position":
|
||||
device.config.position = config.payloadVariant.position;
|
||||
device.config.position = config.payloadVariant.value;
|
||||
break;
|
||||
case "power":
|
||||
device.config.power = config.payloadVariant.power;
|
||||
device.config.power = config.payloadVariant.value;
|
||||
break;
|
||||
case "network":
|
||||
device.config.network = config.payloadVariant.network;
|
||||
device.config.network = config.payloadVariant.value;
|
||||
break;
|
||||
case "display":
|
||||
device.config.display = config.payloadVariant.display;
|
||||
device.config.display = config.payloadVariant.value;
|
||||
break;
|
||||
case "lora":
|
||||
device.config.lora = config.payloadVariant.lora;
|
||||
device.config.lora = config.payloadVariant.value;
|
||||
device.regionUnset =
|
||||
config.payloadVariant.lora.region ===
|
||||
config.payloadVariant.value.region ===
|
||||
Protobuf.Config_LoRaConfig_RegionCode.UNSET;
|
||||
break;
|
||||
case "bluetooth":
|
||||
device.config.bluetooth = config.payloadVariant.bluetooth;
|
||||
device.config.bluetooth = config.payloadVariant.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -205,35 +211,35 @@ export const useDeviceStore = create<DeviceState>((set, get) => ({
|
||||
const device = draft.devices.get(id);
|
||||
|
||||
if (device) {
|
||||
switch (config.payloadVariant.oneofKind) {
|
||||
switch (config.payloadVariant.case) {
|
||||
case "mqtt":
|
||||
device.moduleConfig.mqtt = config.payloadVariant.mqtt;
|
||||
device.moduleConfig.mqtt = config.payloadVariant.value;
|
||||
break;
|
||||
case "serial":
|
||||
device.moduleConfig.serial = config.payloadVariant.serial;
|
||||
device.moduleConfig.serial = config.payloadVariant.value;
|
||||
break;
|
||||
case "externalNotification":
|
||||
device.moduleConfig.externalNotification =
|
||||
config.payloadVariant.externalNotification;
|
||||
config.payloadVariant.value;
|
||||
break;
|
||||
case "storeForward":
|
||||
device.moduleConfig.storeForward =
|
||||
config.payloadVariant.storeForward;
|
||||
config.payloadVariant.value;
|
||||
break;
|
||||
case "rangeTest":
|
||||
device.moduleConfig.rangeTest =
|
||||
config.payloadVariant.rangeTest;
|
||||
config.payloadVariant.value;
|
||||
break;
|
||||
case "telemetry":
|
||||
device.moduleConfig.telemetry =
|
||||
config.payloadVariant.telemetry;
|
||||
config.payloadVariant.value;
|
||||
break;
|
||||
case "cannedMessage":
|
||||
device.moduleConfig.cannedMessage =
|
||||
config.payloadVariant.cannedMessage;
|
||||
config.payloadVariant.value;
|
||||
break;
|
||||
case "audio":
|
||||
device.moduleConfig.audio = config.payloadVariant.audio;
|
||||
device.moduleConfig.audio = config.payloadVariant.value;
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -257,36 +263,34 @@ export const useDeviceStore = create<DeviceState>((set, get) => ({
|
||||
(n) => n.data.num === metrics.from
|
||||
);
|
||||
if (node) {
|
||||
switch (metrics.data.variant.oneofKind) {
|
||||
switch (metrics.data.variant.case) {
|
||||
case "deviceMetrics":
|
||||
if (device) {
|
||||
if (metrics.data.variant.deviceMetrics.batteryLevel) {
|
||||
if (metrics.data.variant.value.batteryLevel) {
|
||||
device.currentMetrics.batteryLevel =
|
||||
metrics.data.variant.deviceMetrics.batteryLevel;
|
||||
metrics.data.variant.value.batteryLevel;
|
||||
}
|
||||
if (metrics.data.variant.deviceMetrics.voltage) {
|
||||
if (metrics.data.variant.value.voltage) {
|
||||
device.currentMetrics.voltage =
|
||||
metrics.data.variant.deviceMetrics.voltage;
|
||||
metrics.data.variant.value.voltage;
|
||||
}
|
||||
if (metrics.data.variant.deviceMetrics.airUtilTx) {
|
||||
if (metrics.data.variant.value.airUtilTx) {
|
||||
device.currentMetrics.airUtilTx =
|
||||
metrics.data.variant.deviceMetrics.airUtilTx;
|
||||
metrics.data.variant.value.airUtilTx;
|
||||
}
|
||||
if (
|
||||
metrics.data.variant.deviceMetrics.channelUtilization
|
||||
) {
|
||||
if (metrics.data.variant.value.channelUtilization) {
|
||||
device.currentMetrics.channelUtilization =
|
||||
metrics.data.variant.deviceMetrics.channelUtilization;
|
||||
metrics.data.variant.value.channelUtilization;
|
||||
}
|
||||
}
|
||||
node.deviceMetrics.push({
|
||||
...metrics.data.variant.deviceMetrics,
|
||||
metric: metrics.data.variant.value,
|
||||
timestamp: metrics.rxTime
|
||||
});
|
||||
break;
|
||||
case "environmentMetrics":
|
||||
node.environmentMetrics.push({
|
||||
...metrics.data.variant.environmentMetrics,
|
||||
metric: metrics.data.variant.value,
|
||||
timestamp: metrics.rxTime
|
||||
});
|
||||
break;
|
||||
@@ -532,7 +536,7 @@ export const useDeviceStore = create<DeviceState>((set, get) => ({
|
||||
const node = device.nodes.find((n) => n.data.num === data.from);
|
||||
if (!node) {
|
||||
device.nodes.push({
|
||||
data: Protobuf.NodeInfo.create({
|
||||
data: new Protobuf.NodeInfo({
|
||||
num: data.from,
|
||||
lastHeard: data.time,
|
||||
snr: data.snr
|
||||
|
||||
@@ -17,16 +17,14 @@ export const subscribeAll = (
|
||||
});
|
||||
|
||||
connection.events.onRoutingPacket.subscribe((routingPacket) => {
|
||||
switch (routingPacket.data.variant.oneofKind) {
|
||||
switch (routingPacket.data.variant.case) {
|
||||
case "errorReason":
|
||||
if (
|
||||
routingPacket.data.variant.errorReason === Protobuf.Routing_Error.NONE
|
||||
) {
|
||||
if (routingPacket.data.variant.value === Protobuf.Routing_Error.NONE) {
|
||||
return;
|
||||
}
|
||||
toast.error(
|
||||
`Routing error: ${
|
||||
Protobuf.Routing_Error[routingPacket.data.variant.errorReason]
|
||||
Protobuf.Routing_Error[routingPacket.data.variant.value]
|
||||
}`,
|
||||
{
|
||||
icon: "❌"
|
||||
@@ -34,12 +32,12 @@ export const subscribeAll = (
|
||||
);
|
||||
break;
|
||||
case "routeReply":
|
||||
toast(`Route Reply: ${routingPacket.data.variant.routeReply}`, {
|
||||
toast(`Route Reply: ${routingPacket.data.variant.value}`, {
|
||||
icon: "✅"
|
||||
});
|
||||
break;
|
||||
case "routeRequest":
|
||||
toast(`Route Request: ${routingPacket.data.variant.routeRequest}`, {
|
||||
toast(`Route Request: ${routingPacket.data.variant.value}`, {
|
||||
icon: "✅"
|
||||
});
|
||||
break;
|
||||
|
||||
@@ -3,7 +3,8 @@ import { IsBoolean, IsInt, IsNumber, IsString, Length } from "class-validator";
|
||||
import type { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export class ChannelSettingsValidation
|
||||
implements Omit<Protobuf.ChannelSettings, "psk">
|
||||
implements
|
||||
Omit<Protobuf.ChannelSettings, keyof Protobuf.native.Message | "psk">
|
||||
{
|
||||
@IsBoolean()
|
||||
enabled: boolean;
|
||||
|
||||
@@ -2,7 +2,10 @@ import { IsBoolean, IsEnum, IsInt } from "class-validator";
|
||||
|
||||
import { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export class BluetoothValidation implements Protobuf.Config_BluetoothConfig {
|
||||
export class BluetoothValidation
|
||||
implements
|
||||
Omit<Protobuf.Config_BluetoothConfig, keyof Protobuf.native.Message>
|
||||
{
|
||||
@IsBoolean()
|
||||
enabled: boolean;
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@ import { IsBoolean, IsEnum, IsInt } from "class-validator";
|
||||
|
||||
import { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export class DeviceValidation implements Protobuf.Config_DeviceConfig {
|
||||
export class DeviceValidation
|
||||
implements Omit<Protobuf.Config_DeviceConfig, keyof Protobuf.native.Message>
|
||||
{
|
||||
@IsEnum(Protobuf.Config_DeviceConfig_Role)
|
||||
role: Protobuf.Config_DeviceConfig_Role;
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@ import { IsBoolean, IsEnum, IsInt } from "class-validator";
|
||||
|
||||
import { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export class DisplayValidation implements Protobuf.Config_DisplayConfig {
|
||||
export class DisplayValidation
|
||||
implements Omit<Protobuf.Config_DisplayConfig, keyof Protobuf.native.Message>
|
||||
{
|
||||
@IsInt()
|
||||
screenOnSecs: number;
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@ import { IsArray, IsBoolean, IsEnum, IsInt, Max, Min } from "class-validator";
|
||||
|
||||
import { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export class LoRaValidation implements Protobuf.Config_LoRaConfig {
|
||||
export class LoRaValidation
|
||||
implements Omit<Protobuf.Config_LoRaConfig, keyof Protobuf.native.Message>
|
||||
{
|
||||
@IsBoolean()
|
||||
usePreset: boolean;
|
||||
|
||||
|
||||
@@ -2,7 +2,13 @@ import { IsBoolean, IsEnum, IsIP, IsOptional, Length } from "class-validator";
|
||||
|
||||
import { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export class NetworkValidation implements Protobuf.Config_NetworkConfig {
|
||||
export class NetworkValidation
|
||||
implements
|
||||
Omit<
|
||||
Protobuf.Config_NetworkConfig,
|
||||
keyof Protobuf.native.Message | "ipv4Config"
|
||||
>
|
||||
{
|
||||
@IsBoolean()
|
||||
wifiEnabled: boolean;
|
||||
|
||||
@@ -21,14 +27,17 @@ export class NetworkValidation implements Protobuf.Config_NetworkConfig {
|
||||
ethEnabled: boolean;
|
||||
|
||||
@IsEnum(Protobuf.Config_NetworkConfig_AddressMode)
|
||||
// @IsOptional()
|
||||
addressMode: Protobuf.Config_NetworkConfig_AddressMode;
|
||||
|
||||
ipv4Config: NetworkValidation_IpV4Config;
|
||||
}
|
||||
|
||||
export class NetworkValidation_IpV4Config
|
||||
implements Protobuf.Config_NetworkConfig_IpV4Config
|
||||
implements
|
||||
Omit<
|
||||
Protobuf.Config_NetworkConfig_IpV4Config,
|
||||
keyof Protobuf.native.Message
|
||||
>
|
||||
{
|
||||
@IsIP()
|
||||
@IsOptional()
|
||||
|
||||
@@ -2,7 +2,10 @@ import { IsBoolean, IsInt, IsNumber } from "class-validator";
|
||||
|
||||
import type { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export class PositionValidation implements Protobuf.Config_PositionConfig {
|
||||
export class PositionValidation
|
||||
implements
|
||||
Omit<Protobuf.Config_PositionConfig, keyof Protobuf.native.Message>
|
||||
{
|
||||
@IsInt()
|
||||
positionBroadcastSecs: number;
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@ import { IsBoolean, IsInt, Max, Min } from "class-validator";
|
||||
|
||||
import type { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export class PowerValidation implements Protobuf.Config_PowerConfig {
|
||||
export class PowerValidation
|
||||
implements Omit<Protobuf.Config_PowerConfig, keyof Protobuf.native.Message>
|
||||
{
|
||||
@IsBoolean()
|
||||
isPowerSaving: boolean;
|
||||
|
||||
|
||||
@@ -3,7 +3,11 @@ import { IsBoolean, IsOptional, IsString, Length } from "class-validator";
|
||||
import type { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export class UserValidation
|
||||
implements Omit<Protobuf.User, "ID" | "macaddr" | "hwModel">
|
||||
implements
|
||||
Omit<
|
||||
Protobuf.User,
|
||||
keyof Protobuf.native.Message | "ID" | "macaddr" | "hwModel"
|
||||
>
|
||||
{
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
|
||||
@@ -2,7 +2,10 @@ import { IsBoolean, IsEnum, IsInt } from "class-validator";
|
||||
|
||||
import { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export class AudioValidation implements Protobuf.ModuleConfig_AudioConfig {
|
||||
export class AudioValidation
|
||||
implements
|
||||
Omit<Protobuf.ModuleConfig_AudioConfig, keyof Protobuf.native.Message>
|
||||
{
|
||||
@IsBoolean()
|
||||
codec2Enabled: boolean;
|
||||
|
||||
@@ -13,14 +16,14 @@ export class AudioValidation implements Protobuf.ModuleConfig_AudioConfig {
|
||||
bitrate: Protobuf.ModuleConfig_AudioConfig_Audio_Baud;
|
||||
|
||||
@IsInt()
|
||||
i2SWs: number;
|
||||
i2sWs: number;
|
||||
|
||||
@IsInt()
|
||||
i2SSd: number;
|
||||
i2sSd: number;
|
||||
|
||||
@IsInt()
|
||||
i2SDin: number;
|
||||
i2sDin: number;
|
||||
|
||||
@IsInt()
|
||||
i2SSck: number;
|
||||
i2sSck: number;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,11 @@ import { IsBoolean, IsEnum, IsInt, Length } from "class-validator";
|
||||
import { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export class CannedMessageValidation
|
||||
implements Protobuf.ModuleConfig_CannedMessageConfig
|
||||
implements
|
||||
Omit<
|
||||
Protobuf.ModuleConfig_CannedMessageConfig,
|
||||
keyof Protobuf.native.Message
|
||||
>
|
||||
{
|
||||
@IsBoolean()
|
||||
rotary1Enabled: boolean;
|
||||
|
||||
@@ -3,7 +3,11 @@ import { IsBoolean, IsInt } from "class-validator";
|
||||
import type { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export class ExternalNotificationValidation
|
||||
implements Protobuf.ModuleConfig_ExternalNotificationConfig
|
||||
implements
|
||||
Omit<
|
||||
Protobuf.ModuleConfig_ExternalNotificationConfig,
|
||||
keyof Protobuf.native.Message
|
||||
>
|
||||
{
|
||||
@IsBoolean()
|
||||
enabled: boolean;
|
||||
|
||||
@@ -2,7 +2,10 @@ import { IsBoolean, Length } from "class-validator";
|
||||
|
||||
import type { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export class MQTTValidation implements Protobuf.ModuleConfig_MQTTConfig {
|
||||
export class MQTTValidation
|
||||
implements
|
||||
Omit<Protobuf.ModuleConfig_MQTTConfig, keyof Protobuf.native.Message>
|
||||
{
|
||||
@IsBoolean()
|
||||
enabled: boolean;
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@ import { IsBoolean, IsInt } from "class-validator";
|
||||
import type { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export class RangeTestValidation
|
||||
implements Protobuf.ModuleConfig_RangeTestConfig
|
||||
implements
|
||||
Omit<Protobuf.ModuleConfig_RangeTestConfig, keyof Protobuf.native.Message>
|
||||
{
|
||||
@IsBoolean()
|
||||
enabled: boolean;
|
||||
|
||||
@@ -2,7 +2,10 @@ import { IsBoolean, IsEnum, IsInt } from "class-validator";
|
||||
|
||||
import { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export class SerialValidation implements Protobuf.ModuleConfig_SerialConfig {
|
||||
export class SerialValidation
|
||||
implements
|
||||
Omit<Protobuf.ModuleConfig_SerialConfig, keyof Protobuf.native.Message>
|
||||
{
|
||||
@IsBoolean()
|
||||
enabled: boolean;
|
||||
|
||||
|
||||
@@ -3,7 +3,11 @@ import { IsBoolean, IsInt } from "class-validator";
|
||||
import type { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export class StoreForwardValidation
|
||||
implements Protobuf.ModuleConfig_StoreForwardConfig
|
||||
implements
|
||||
Omit<
|
||||
Protobuf.ModuleConfig_StoreForwardConfig,
|
||||
keyof Protobuf.native.Message
|
||||
>
|
||||
{
|
||||
@IsBoolean()
|
||||
enabled: boolean;
|
||||
|
||||
@@ -3,7 +3,8 @@ import { IsBoolean, IsInt } from "class-validator";
|
||||
import type { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
export class TelemetryValidation
|
||||
implements Protobuf.ModuleConfig_TelemetryConfig
|
||||
implements
|
||||
Omit<Protobuf.ModuleConfig_TelemetryConfig, keyof Protobuf.native.Message>
|
||||
{
|
||||
@IsInt()
|
||||
deviceUpdateInterval: number;
|
||||
|
||||
Reference in New Issue
Block a user