Update descriptions, protobufs & bugfixes
This commit is contained in:
+7
-5
@@ -8,7 +8,8 @@
|
|||||||
"build": "tsc && vite build",
|
"build": "tsc && vite build",
|
||||||
"preview": "vite preview",
|
"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/)",
|
"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": "prettier --write 'src/**/*.{ts,tsx}' && eslint src/*.{ts,tsx}"
|
"format": "prettier --write 'src/**/*.{ts,tsx}' && eslint src/*.{ts,tsx}",
|
||||||
|
"check:unimported": "unimported"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -20,11 +21,11 @@
|
|||||||
"homepage": "https://meshtastic.org",
|
"homepage": "https://meshtastic.org",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emeraldpay/hashicon-react": "^0.5.2",
|
"@emeraldpay/hashicon-react": "^0.5.2",
|
||||||
"@headlessui/react": "^1.7.2",
|
"@headlessui/react": "^1.7.3",
|
||||||
"@heroicons/react": "^2.0.11",
|
"@heroicons/react": "^2.0.11",
|
||||||
"@hookform/resolvers": "^2.9.8",
|
"@hookform/resolvers": "^2.9.8",
|
||||||
"@meshtastic/eslint-config": "^1.0.8",
|
"@meshtastic/eslint-config": "^1.0.8",
|
||||||
"@meshtastic/meshtasticjs": "^0.6.103",
|
"@meshtastic/meshtasticjs": "^0.6.104",
|
||||||
"@tailwindcss/line-clamp": "^0.4.2",
|
"@tailwindcss/line-clamp": "^0.4.2",
|
||||||
"@tailwindcss/typography": "^0.5.7",
|
"@tailwindcss/typography": "^0.5.7",
|
||||||
"base64-js": "^1.5.1",
|
"base64-js": "^1.5.1",
|
||||||
@@ -47,7 +48,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/chrome": "^0.0.197",
|
"@types/chrome": "^0.0.197",
|
||||||
"@types/geodesy": "^2.2.3",
|
"@types/geodesy": "^2.2.3",
|
||||||
"@types/node": "^18.7.23",
|
"@types/node": "^18.8.0",
|
||||||
"@types/react": "^18.0.21",
|
"@types/react": "^18.0.21",
|
||||||
"@types/react-dom": "^18.0.6",
|
"@types/react-dom": "^18.0.6",
|
||||||
"@types/w3c-web-serial": "^1.0.2",
|
"@types/w3c-web-serial": "^1.0.2",
|
||||||
@@ -55,7 +56,7 @@
|
|||||||
"@vitejs/plugin-react": "^2.1.0",
|
"@vitejs/plugin-react": "^2.1.0",
|
||||||
"autoprefixer": "^10.4.12",
|
"autoprefixer": "^10.4.12",
|
||||||
"gzipper": "^7.1.0",
|
"gzipper": "^7.1.0",
|
||||||
"postcss": "^8.4.16",
|
"postcss": "^8.4.17",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.7.1",
|
||||||
"prettier-plugin-tailwindcss": "^0.1.13",
|
"prettier-plugin-tailwindcss": "^0.1.13",
|
||||||
"rollup-plugin-visualizer": "^5.8.2",
|
"rollup-plugin-visualizer": "^5.8.2",
|
||||||
@@ -63,6 +64,7 @@
|
|||||||
"tar": "^6.1.11",
|
"tar": "^6.1.11",
|
||||||
"tslib": "^2.4.0",
|
"tslib": "^2.4.0",
|
||||||
"typescript": "^4.8.4",
|
"typescript": "^4.8.4",
|
||||||
|
"unimported": "^1.22.0",
|
||||||
"vite": "^3.1.4",
|
"vite": "^3.1.4",
|
||||||
"vite-plugin-environment": "^1.1.2"
|
"vite-plugin-environment": "^1.1.2"
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+640
-126
File diff suppressed because it is too large
Load Diff
@@ -3,25 +3,36 @@ import type React from "react";
|
|||||||
import { Disclosure } from "@headlessui/react";
|
import { Disclosure } from "@headlessui/react";
|
||||||
import { ChevronDownIcon, ChevronUpIcon } from "@heroicons/react/24/outline";
|
import { ChevronDownIcon, ChevronUpIcon } from "@heroicons/react/24/outline";
|
||||||
|
|
||||||
|
import { Mono } from "./Mono.js";
|
||||||
|
|
||||||
export interface DropdownProps {
|
export interface DropdownProps {
|
||||||
title: string;
|
title: string;
|
||||||
|
stat?: number;
|
||||||
icon: JSX.Element;
|
icon: JSX.Element;
|
||||||
|
defaultOpen?: boolean;
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Dropdown = ({
|
export const Dropdown = ({
|
||||||
title,
|
title,
|
||||||
|
stat,
|
||||||
icon,
|
icon,
|
||||||
|
defaultOpen,
|
||||||
children,
|
children,
|
||||||
}: DropdownProps): JSX.Element => {
|
}: DropdownProps): JSX.Element => {
|
||||||
return (
|
return (
|
||||||
<Disclosure defaultOpen>
|
<Disclosure defaultOpen={defaultOpen}>
|
||||||
{({ open }) => (
|
{({ open }) => (
|
||||||
<>
|
<>
|
||||||
<Disclosure.Button className="flex h-8 justify-between bg-slate-100 px-2 hover:bg-slate-200">
|
<Disclosure.Button className="group flex h-8 justify-between bg-slate-100 px-2 hover:bg-slate-200">
|
||||||
<div className="my-auto flex gap-2 text-slate-700">
|
<div className="my-auto flex gap-2 text-slate-700">
|
||||||
<div className="my-auto">{icon}</div>
|
<div className="my-auto">{icon}</div>
|
||||||
<span className="text-lg font-medium">{title}</span>
|
<span className="text-lg font-medium">{title}</span>
|
||||||
|
{stat !== undefined && (
|
||||||
|
<span className="my-auto flex rounded-full bg-slate-200 px-3 py-0.5 group-hover:bg-slate-300">
|
||||||
|
<Mono>{stat}</Mono>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="my-auto text-slate-600">
|
<div className="my-auto text-slate-600">
|
||||||
{open ? (
|
{open ? (
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export const Device = (): JSX.Element => {
|
|||||||
>
|
>
|
||||||
<Select
|
<Select
|
||||||
label="Role"
|
label="Role"
|
||||||
description="This is a description."
|
description="What role the device performs on the mesh"
|
||||||
{...register("role", { valueAsNumber: true })}
|
{...register("role", { valueAsNumber: true })}
|
||||||
>
|
>
|
||||||
{renderOptions(Protobuf.Config_DeviceConfig_Role)}
|
{renderOptions(Protobuf.Config_DeviceConfig_Role)}
|
||||||
@@ -69,7 +69,7 @@ export const Device = (): JSX.Element => {
|
|||||||
render={({ field: { value, ...rest } }) => (
|
render={({ field: { value, ...rest } }) => (
|
||||||
<Toggle
|
<Toggle
|
||||||
label="Serial Output Enabled"
|
label="Serial Output Enabled"
|
||||||
description="Description"
|
description="Disable the device's serial console"
|
||||||
checked={value}
|
checked={value}
|
||||||
{...rest}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
@@ -81,7 +81,7 @@ export const Device = (): JSX.Element => {
|
|||||||
render={({ field: { value, ...rest } }) => (
|
render={({ field: { value, ...rest } }) => (
|
||||||
<Toggle
|
<Toggle
|
||||||
label="Enabled Debug Log"
|
label="Enabled Debug Log"
|
||||||
description="Description"
|
description="Output debugging information to the device's serial port (auto disables when serial client is connected)"
|
||||||
checked={value}
|
checked={value}
|
||||||
{...rest}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -58,21 +58,21 @@ export const Display = (): JSX.Element => {
|
|||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
label="Screen Timeout"
|
label="Screen Timeout"
|
||||||
description="This is a description."
|
description="Turn off the display after this long"
|
||||||
suffix="Seconds"
|
suffix="Seconds"
|
||||||
type="number"
|
type="number"
|
||||||
{...register("screenOnSecs", { valueAsNumber: true })}
|
{...register("screenOnSecs", { valueAsNumber: true })}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
label="Carousel Delay"
|
label="Carousel Delay"
|
||||||
description="This is a description."
|
description="How fast to cycle through windows"
|
||||||
suffix="Seconds"
|
suffix="Seconds"
|
||||||
type="number"
|
type="number"
|
||||||
{...register("autoScreenCarouselSecs", { valueAsNumber: true })}
|
{...register("autoScreenCarouselSecs", { valueAsNumber: true })}
|
||||||
/>
|
/>
|
||||||
<Select
|
<Select
|
||||||
label="GPS Display Units"
|
label="GPS Display Units"
|
||||||
description="This is a description."
|
description="Coordinate display format"
|
||||||
{...register("gpsFormat", { valueAsNumber: true })}
|
{...register("gpsFormat", { valueAsNumber: true })}
|
||||||
>
|
>
|
||||||
{renderOptions(Protobuf.Config_DisplayConfig_GpsCoordinateFormat)}
|
{renderOptions(Protobuf.Config_DisplayConfig_GpsCoordinateFormat)}
|
||||||
@@ -83,7 +83,7 @@ export const Display = (): JSX.Element => {
|
|||||||
render={({ field: { value, ...rest } }) => (
|
render={({ field: { value, ...rest } }) => (
|
||||||
<Toggle
|
<Toggle
|
||||||
label="Compass North Top"
|
label="Compass North Top"
|
||||||
description="Description"
|
description="Fix north to the top of compass"
|
||||||
checked={value}
|
checked={value}
|
||||||
{...rest}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
@@ -95,7 +95,7 @@ export const Display = (): JSX.Element => {
|
|||||||
render={({ field: { value, ...rest } }) => (
|
render={({ field: { value, ...rest } }) => (
|
||||||
<Toggle
|
<Toggle
|
||||||
label="Flip Screen"
|
label="Flip Screen"
|
||||||
description="Description"
|
description="Flip display 180 degrees"
|
||||||
checked={value}
|
checked={value}
|
||||||
{...rest}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
@@ -103,7 +103,7 @@ export const Display = (): JSX.Element => {
|
|||||||
/>
|
/>
|
||||||
<Select
|
<Select
|
||||||
label="Display Units"
|
label="Display Units"
|
||||||
description="This is a description."
|
description="Display metric or imperial units"
|
||||||
{...register("units", { valueAsNumber: true })}
|
{...register("units", { valueAsNumber: true })}
|
||||||
>
|
>
|
||||||
{renderOptions(Protobuf.Config_DisplayConfig_DisplayUnits)}
|
{renderOptions(Protobuf.Config_DisplayConfig_DisplayUnits)}
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ export const LoRa = (): JSX.Element => {
|
|||||||
render={({ field: { value, ...rest } }) => (
|
render={({ field: { value, ...rest } }) => (
|
||||||
<Toggle
|
<Toggle
|
||||||
label="Use Preset"
|
label="Use Preset"
|
||||||
description="Description"
|
description="Use one of the predefined modem presets"
|
||||||
checked={value}
|
checked={value}
|
||||||
{...rest}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
@@ -78,7 +78,7 @@ export const LoRa = (): JSX.Element => {
|
|||||||
/>
|
/>
|
||||||
<Select
|
<Select
|
||||||
label="Preset"
|
label="Preset"
|
||||||
description="This is a description."
|
description="Modem preset to use"
|
||||||
disabled={!usePreset}
|
disabled={!usePreset}
|
||||||
{...register("modemPreset", { valueAsNumber: true })}
|
{...register("modemPreset", { valueAsNumber: true })}
|
||||||
>
|
>
|
||||||
@@ -159,6 +159,13 @@ export const LoRa = (): JSX.Element => {
|
|||||||
error={errors.txPower?.message}
|
error={errors.txPower?.message}
|
||||||
{...register("txPower", { valueAsNumber: true })}
|
{...register("txPower", { valueAsNumber: true })}
|
||||||
/>
|
/>
|
||||||
|
<Input
|
||||||
|
label="Channel Number"
|
||||||
|
description="LoRa channel number"
|
||||||
|
type="number"
|
||||||
|
error={errors.channelNum?.message}
|
||||||
|
{...register("channelNum", { valueAsNumber: true })}
|
||||||
|
/>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ export const Network = (): JSX.Element => {
|
|||||||
render={({ field: { value, ...rest } }) => (
|
render={({ field: { value, ...rest } }) => (
|
||||||
<Toggle
|
<Toggle
|
||||||
label="WiFi Enabled"
|
label="WiFi Enabled"
|
||||||
description="Description"
|
description="Enable or disbale the WiFi radio"
|
||||||
checked={value}
|
checked={value}
|
||||||
{...rest}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
@@ -77,7 +77,7 @@ export const Network = (): JSX.Element => {
|
|||||||
/>
|
/>
|
||||||
<Select
|
<Select
|
||||||
label="WiFi Mode"
|
label="WiFi Mode"
|
||||||
description="This is a description."
|
description="How the WiFi radio should be used"
|
||||||
disabled={!wifiEnabled}
|
disabled={!wifiEnabled}
|
||||||
{...register("wifiMode", { valueAsNumber: true })}
|
{...register("wifiMode", { valueAsNumber: true })}
|
||||||
>
|
>
|
||||||
@@ -85,7 +85,7 @@ export const Network = (): JSX.Element => {
|
|||||||
</Select>
|
</Select>
|
||||||
<Input
|
<Input
|
||||||
label="SSID"
|
label="SSID"
|
||||||
description="This is a description."
|
description="Network name"
|
||||||
error={errors.wifiSsid?.message}
|
error={errors.wifiSsid?.message}
|
||||||
disabled={!wifiEnabled}
|
disabled={!wifiEnabled}
|
||||||
{...register("wifiSsid")}
|
{...register("wifiSsid")}
|
||||||
@@ -93,14 +93,14 @@ export const Network = (): JSX.Element => {
|
|||||||
<Input
|
<Input
|
||||||
label="PSK"
|
label="PSK"
|
||||||
type="password"
|
type="password"
|
||||||
description="This is a description."
|
description="Network password"
|
||||||
error={errors.wifiPsk?.message}
|
error={errors.wifiPsk?.message}
|
||||||
disabled={!wifiEnabled}
|
disabled={!wifiEnabled}
|
||||||
{...register("wifiPsk")}
|
{...register("wifiPsk")}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
label="NTP Server"
|
label="NTP Server"
|
||||||
description="This is a description."
|
description="NTP server for time synchronization"
|
||||||
error={errors.ntpServer?.message}
|
error={errors.ntpServer?.message}
|
||||||
{...register("ntpServer")}
|
{...register("ntpServer")}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ export const Position = (): JSX.Element => {
|
|||||||
<Input
|
<Input
|
||||||
suffix="Seconds"
|
suffix="Seconds"
|
||||||
label="Broadcast Interval"
|
label="Broadcast Interval"
|
||||||
description="This is a description."
|
description="How often your position is sent out over the mesh"
|
||||||
type="number"
|
type="number"
|
||||||
error={errors.positionBroadcastSecs?.message}
|
error={errors.positionBroadcastSecs?.message}
|
||||||
{...register("positionBroadcastSecs", { valueAsNumber: true })}
|
{...register("positionBroadcastSecs", { valueAsNumber: true })}
|
||||||
@@ -68,7 +68,7 @@ export const Position = (): JSX.Element => {
|
|||||||
render={({ field: { value, ...rest } }) => (
|
render={({ field: { value, ...rest } }) => (
|
||||||
<Toggle
|
<Toggle
|
||||||
label="Enable Smart Position"
|
label="Enable Smart Position"
|
||||||
description="Description"
|
description="Only send position when there has been a meaningfull change in location"
|
||||||
checked={value}
|
checked={value}
|
||||||
{...rest}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
@@ -80,7 +80,7 @@ export const Position = (): JSX.Element => {
|
|||||||
render={({ field: { value, ...rest } }) => (
|
render={({ field: { value, ...rest } }) => (
|
||||||
<Toggle
|
<Toggle
|
||||||
label="Use Fixed Position"
|
label="Use Fixed Position"
|
||||||
description="Description"
|
description="Don't report GPS position, but a manually specified one"
|
||||||
checked={value}
|
checked={value}
|
||||||
{...rest}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
@@ -92,7 +92,7 @@ export const Position = (): JSX.Element => {
|
|||||||
render={({ field: { value, ...rest } }) => (
|
render={({ field: { value, ...rest } }) => (
|
||||||
<Toggle
|
<Toggle
|
||||||
label="GPS Enabled"
|
label="GPS Enabled"
|
||||||
description="Description"
|
description="Enable the internal GPS module"
|
||||||
checked={value}
|
checked={value}
|
||||||
{...rest}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
@@ -101,14 +101,14 @@ export const Position = (): JSX.Element => {
|
|||||||
<Input
|
<Input
|
||||||
suffix="Seconds"
|
suffix="Seconds"
|
||||||
label="GPS Update Interval"
|
label="GPS Update Interval"
|
||||||
description="This is a description."
|
description="How often a GPS fix should be acquired"
|
||||||
type="number"
|
type="number"
|
||||||
error={errors.gpsUpdateInterval?.message}
|
error={errors.gpsUpdateInterval?.message}
|
||||||
{...register("gpsUpdateInterval", { valueAsNumber: true })}
|
{...register("gpsUpdateInterval", { valueAsNumber: true })}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
label="Last GPS Attempt"
|
label="Fix Attempt Duration"
|
||||||
description="This is a description."
|
description="How long the device will try to get a fix for"
|
||||||
type="number"
|
type="number"
|
||||||
error={errors.gpsAttemptTime?.message}
|
error={errors.gpsAttemptTime?.message}
|
||||||
{...register("gpsAttemptTime", { valueAsNumber: true })}
|
{...register("gpsAttemptTime", { valueAsNumber: true })}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ export const Power = (): JSX.Element => {
|
|||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
label="Shutdown on battery delay"
|
label="Shutdown on battery delay"
|
||||||
description="This is a description."
|
description="Automatically shutdown node after this long when on battery, 0 for indefinite"
|
||||||
suffix="Seconds"
|
suffix="Seconds"
|
||||||
type="number"
|
type="number"
|
||||||
error={errors.onBatteryShutdownAfterSecs?.message}
|
error={errors.onBatteryShutdownAfterSecs?.message}
|
||||||
@@ -66,7 +66,7 @@ export const Power = (): JSX.Element => {
|
|||||||
control={control}
|
control={control}
|
||||||
render={({ field: { value, ...rest } }) => (
|
render={({ field: { value, ...rest } }) => (
|
||||||
<Toggle
|
<Toggle
|
||||||
label="Power Saving"
|
label="Enable power saving mode"
|
||||||
description="Description"
|
description="Description"
|
||||||
checked={value}
|
checked={value}
|
||||||
{...rest}
|
{...rest}
|
||||||
@@ -75,14 +75,14 @@ export const Power = (): JSX.Element => {
|
|||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
label="ADC Multiplier Override ratio"
|
label="ADC Multiplier Override ratio"
|
||||||
description="This is a description."
|
description="Used for tweaking battery voltage reading"
|
||||||
type="number"
|
type="number"
|
||||||
error={errors.adcMultiplierOverride?.message}
|
error={errors.adcMultiplierOverride?.message}
|
||||||
{...register("adcMultiplierOverride", { valueAsNumber: true })}
|
{...register("adcMultiplierOverride", { valueAsNumber: true })}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
label="Minimum Wake Time"
|
label="Minimum Wake Time"
|
||||||
description="This is a description."
|
description="Minimum amount of time the device will stay away for after recieving a packet"
|
||||||
suffix="Seconds"
|
suffix="Seconds"
|
||||||
type="number"
|
type="number"
|
||||||
error={errors.minWakeSecs?.message}
|
error={errors.minWakeSecs?.message}
|
||||||
@@ -90,31 +90,31 @@ export const Power = (): JSX.Element => {
|
|||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
label="Mesh SDS Timeout"
|
label="Mesh SDS Timeout"
|
||||||
description="This is a description."
|
description="The device will enter super deep sleep after this time"
|
||||||
suffix="Seconds"
|
suffix="Seconds"
|
||||||
type="number"
|
type="number"
|
||||||
error={errors.meshSdsTimeoutSecs?.message}
|
error={errors.meshSdsTimeoutSecs?.message}
|
||||||
{...register("meshSdsTimeoutSecs", { valueAsNumber: true })}
|
{...register("meshSdsTimeoutSecs", { valueAsNumber: true })}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
label="SDS"
|
label="Super Deep Sleep Duration"
|
||||||
description="This is a description."
|
description="How long the device will be in super deep sleep for"
|
||||||
suffix="Seconds"
|
suffix="Seconds"
|
||||||
type="number"
|
type="number"
|
||||||
error={errors.sdsSecs?.message}
|
error={errors.sdsSecs?.message}
|
||||||
{...register("sdsSecs", { valueAsNumber: true })}
|
{...register("sdsSecs", { valueAsNumber: true })}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
label="LS"
|
label="Light Sleep Duration"
|
||||||
description="This is a description."
|
description="How long the device will be in light sleep for"
|
||||||
suffix="Seconds"
|
suffix="Seconds"
|
||||||
type="number"
|
type="number"
|
||||||
error={errors.lsSecs?.message}
|
error={errors.lsSecs?.message}
|
||||||
{...register("lsSecs", { valueAsNumber: true })}
|
{...register("lsSecs", { valueAsNumber: true })}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
label="Wait Bluetooth"
|
label="No Connection Bluetooth Disabled"
|
||||||
description="This is a description."
|
description="If the device does not revieve a bluetooth connection, the BLE radio will be disabled after this long"
|
||||||
suffix="Seconds"
|
suffix="Seconds"
|
||||||
type="number"
|
type="number"
|
||||||
error={errors.waitBluetoothSecs?.message}
|
error={errors.waitBluetoothSecs?.message}
|
||||||
|
|||||||
@@ -80,13 +80,13 @@ export const User = (): JSX.Element => {
|
|||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
label="Short Name"
|
label="Short Name"
|
||||||
description="This is a description."
|
description="Shown on small screens."
|
||||||
maxLength={3}
|
maxLength={3}
|
||||||
{...register("shortName")}
|
{...register("shortName")}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
label="Mac Address"
|
label="Mac Address"
|
||||||
description="This is a description."
|
description="Hardware address for this node."
|
||||||
disabled
|
disabled
|
||||||
value={
|
value={
|
||||||
base16
|
base16
|
||||||
@@ -97,7 +97,7 @@ export const User = (): JSX.Element => {
|
|||||||
/>
|
/>
|
||||||
<Select
|
<Select
|
||||||
label="Hardware"
|
label="Hardware"
|
||||||
description="This is a description."
|
description="Hardware model of this device."
|
||||||
disabled
|
disabled
|
||||||
value={myNode?.data.user?.hwModel}
|
value={myNode?.data.user?.hwModel}
|
||||||
>
|
>
|
||||||
@@ -109,7 +109,7 @@ export const User = (): JSX.Element => {
|
|||||||
render={({ field: { value, ...rest } }) => (
|
render={({ field: { value, ...rest } }) => (
|
||||||
<Toggle
|
<Toggle
|
||||||
label="Licenced Operator?"
|
label="Licenced Operator?"
|
||||||
description="Description"
|
description="Remove bandwidth restrictions in certain regions (HAM license required)"
|
||||||
checked={value}
|
checked={value}
|
||||||
{...rest}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import type React from "react";
|
import type React from "react";
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
|
|
||||||
|
import { Mono } from "@app/components/Mono.js";
|
||||||
import { Button } from "@components/Button.js";
|
import { Button } from "@components/Button.js";
|
||||||
import { useAppStore } from "@core/stores/appStore.js";
|
import { useAppStore } from "@core/stores/appStore.js";
|
||||||
import { useDeviceStore } from "@core/stores/deviceStore.js";
|
import { useDeviceStore } from "@core/stores/deviceStore.js";
|
||||||
@@ -48,6 +49,9 @@ export const BLE = (): JSX.Element => {
|
|||||||
{device.name}
|
{device.name}
|
||||||
</Button>
|
</Button>
|
||||||
))}
|
))}
|
||||||
|
{bleDevices.length === 0 && (
|
||||||
|
<Mono className="m-auto">No devices paired yet.</Mono>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
iconBefore={<PlusCircleIcon className="w-4" />}
|
iconBefore={<PlusCircleIcon className="w-4" />}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import type React from "react";
|
import type React from "react";
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
|
|
||||||
|
import { Mono } from "@app/components/Mono.js";
|
||||||
import { Button } from "@components/Button.js";
|
import { Button } from "@components/Button.js";
|
||||||
import { useAppStore } from "@core/stores/appStore.js";
|
import { useAppStore } from "@core/stores/appStore.js";
|
||||||
import { useDeviceStore } from "@core/stores/deviceStore.js";
|
import { useDeviceStore } from "@core/stores/deviceStore.js";
|
||||||
@@ -59,6 +60,9 @@ export const Serial = (): JSX.Element => {
|
|||||||
{port.getInfo().usbVendorId} - {port.getInfo().usbProductId}
|
{port.getInfo().usbVendorId} - {port.getInfo().usbProductId}
|
||||||
</Button>
|
</Button>
|
||||||
))}
|
))}
|
||||||
|
{serialPorts.length === 0 && (
|
||||||
|
<Mono className="m-auto">No devices paired yet.</Mono>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
iconBefore={<PlusCircleIcon className="w-4" />}
|
iconBefore={<PlusCircleIcon className="w-4" />}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export const BatteryWidget = ({
|
|||||||
}: BatteryWidgetProps): JSX.Element => {
|
}: BatteryWidgetProps): JSX.Element => {
|
||||||
return (
|
return (
|
||||||
<Card className="flex-col">
|
<Card className="flex-col">
|
||||||
<Dropdown title="Position" icon={<BoltIcon className="h-4" />}>
|
<Dropdown title="Battery" icon={<BoltIcon className="h-4" />}>
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<div className="flex w-20 bg-slate-700 p-3">
|
<div className="flex w-20 bg-slate-700 p-3">
|
||||||
<Battery100Icon className="m-auto h-12 text-white" />
|
<Battery100Icon className="m-auto h-12 text-white" />
|
||||||
@@ -27,7 +27,7 @@ export const BatteryWidget = ({
|
|||||||
<Mono>%</Mono>
|
<Mono>%</Mono>
|
||||||
</span>
|
</span>
|
||||||
<span className="m-auto text-lg">
|
<span className="m-auto text-lg">
|
||||||
{voltage}
|
{voltage.toPrecision(2)}
|
||||||
<Mono>v</Mono>
|
<Mono>v</Mono>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export const DeviceWidget = ({
|
|||||||
reconnect,
|
reconnect,
|
||||||
}: DeviceWidgetProps): JSX.Element => {
|
}: DeviceWidgetProps): JSX.Element => {
|
||||||
return (
|
return (
|
||||||
<Card className="relative flex-col">
|
<Card className="relative shrink-0 flex-col">
|
||||||
<div className="absolute bottom-20 h-full w-full">
|
<div className="absolute bottom-20 h-full w-full">
|
||||||
<Hashicon size={350} value={nodeNum} />
|
<Hashicon size={350} value={nodeNum} />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -21,8 +21,12 @@ export interface PeersWidgetProps {
|
|||||||
export const PeersWidget = ({ peers }: PeersWidgetProps): JSX.Element => {
|
export const PeersWidget = ({ peers }: PeersWidgetProps): JSX.Element => {
|
||||||
return (
|
return (
|
||||||
<Card className="flex-col">
|
<Card className="flex-col">
|
||||||
<Dropdown title="Peers" icon={<UserGroupIcon className="h-4" />}>
|
<Dropdown
|
||||||
<div className="p-3">
|
title="Peers"
|
||||||
|
stat={peers.length}
|
||||||
|
icon={<UserGroupIcon className="h-4" />}
|
||||||
|
>
|
||||||
|
<div className="flex flex-col p-3">
|
||||||
{peers.map((peer) => (
|
{peers.map((peer) => (
|
||||||
<div
|
<div
|
||||||
className="flex gap-2 rounded-md p-2 hover:bg-slate-100"
|
className="flex gap-2 rounded-md p-2 hover:bg-slate-100"
|
||||||
@@ -49,6 +53,9 @@ export const PeersWidget = ({ peers }: PeersWidgetProps): JSX.Element => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
{peers.length === 0 && (
|
||||||
|
<Mono className="m-auto">No devices discovered yet.</Mono>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -43,9 +43,7 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
|
|||||||
<label htmlFor="comments" className="font-medium text-gray-700">
|
<label htmlFor="comments" className="font-medium text-gray-700">
|
||||||
{label}
|
{label}
|
||||||
</label>
|
</label>
|
||||||
<p id="comments-description" className="text-gray-500">
|
<p className="text-gray-500">{description}</p>
|
||||||
{description}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -39,9 +39,7 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(function Input(
|
|||||||
/>
|
/>
|
||||||
{suffix && (
|
{suffix && (
|
||||||
<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3 font-mono">
|
<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3 font-mono">
|
||||||
<span className="text-gray-500 sm:text-sm" id="price-currency">
|
<span className="text-gray-500 sm:text-sm">{suffix}</span>
|
||||||
{suffix}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{action && (
|
{action && (
|
||||||
@@ -60,15 +58,9 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(function Input(
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{description && (
|
{description && (
|
||||||
<p className="mt-2 text-sm text-gray-500" id="email-description">
|
<p className="mt-2 text-sm text-gray-500">{description}</p>
|
||||||
{description}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
{error && (
|
|
||||||
<p className="mt-2 text-sm text-red-600" id="email-error">
|
|
||||||
{error}
|
|
||||||
</p>
|
|
||||||
)}
|
)}
|
||||||
|
{error && <p className="mt-2 text-sm text-red-600">{error}</p>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export const Select = forwardRef<HTMLSelectElement, SelectProps>(function Input(
|
|||||||
suffix,
|
suffix,
|
||||||
action,
|
action,
|
||||||
error,
|
error,
|
||||||
|
disabled,
|
||||||
children,
|
children,
|
||||||
...rest
|
...rest
|
||||||
}: SelectProps,
|
}: SelectProps,
|
||||||
@@ -41,7 +42,10 @@ export const Select = forwardRef<HTMLSelectElement, SelectProps>(function Input(
|
|||||||
ref={ref}
|
ref={ref}
|
||||||
className={`flex h-10 w-full rounded-md bg-orange-100 px-3 text-sm focus:outline-none focus:ring-2 focus:ring-orange-500 ${
|
className={`flex h-10 w-full rounded-md bg-orange-100 px-3 text-sm focus:outline-none focus:ring-2 focus:ring-orange-500 ${
|
||||||
prefix ? "rounded-l-none" : ""
|
prefix ? "rounded-l-none" : ""
|
||||||
} ${action ? "rounded-r-none" : ""}`}
|
} ${action ? "rounded-r-none" : ""} ${
|
||||||
|
disabled ? "cursor-not-allowed" : ""
|
||||||
|
}`}
|
||||||
|
disabled={disabled}
|
||||||
{...rest}
|
{...rest}
|
||||||
>
|
>
|
||||||
{options &&
|
{options &&
|
||||||
@@ -60,6 +64,9 @@ export const Select = forwardRef<HTMLSelectElement, SelectProps>(function Input(
|
|||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
{description && (
|
||||||
|
<p className="mt-2 text-sm text-gray-500">{description}</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
+1
-10
@@ -7,11 +7,7 @@ import {
|
|||||||
} from "@components/layout/page/TabbedContent.js";
|
} from "@components/layout/page/TabbedContent.js";
|
||||||
import { ChannelChat } from "@components/PageComponents/Messages/ChannelChat.js";
|
import { ChannelChat } from "@components/PageComponents/Messages/ChannelChat.js";
|
||||||
import { useDevice } from "@core/providers/useDevice.js";
|
import { useDevice } from "@core/providers/useDevice.js";
|
||||||
import {
|
import { PencilIcon } from "@heroicons/react/24/outline";
|
||||||
EllipsisHorizontalCircleIcon,
|
|
||||||
PencilIcon,
|
|
||||||
XCircleIcon,
|
|
||||||
} from "@heroicons/react/24/outline";
|
|
||||||
import { Protobuf } from "@meshtastic/meshtasticjs";
|
import { Protobuf } from "@meshtastic/meshtasticjs";
|
||||||
|
|
||||||
export const MessagesPage = (): JSX.Element => {
|
export const MessagesPage = (): JSX.Element => {
|
||||||
@@ -24,11 +20,6 @@ export const MessagesPage = (): JSX.Element => {
|
|||||||
: channel.config.index === 0
|
: channel.config.index === 0
|
||||||
? "Primary"
|
? "Primary"
|
||||||
: `Ch ${channel.config.index}`,
|
: `Ch ${channel.config.index}`,
|
||||||
icon: channel.messages.length ? (
|
|
||||||
<EllipsisHorizontalCircleIcon className="h-4" />
|
|
||||||
) : (
|
|
||||||
<XCircleIcon className="h-4" />
|
|
||||||
),
|
|
||||||
element: () => <ChannelChat channel={channel} />,
|
element: () => <ChannelChat channel={channel} />,
|
||||||
disabled: channel.config.role === Protobuf.Channel_Role.DISABLED,
|
disabled: channel.config.role === Protobuf.Channel_Role.DISABLED,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,10 +2,9 @@ import { IsBoolean, IsInt, Length } from "class-validator";
|
|||||||
|
|
||||||
import type { Protobuf } from "@meshtastic/meshtasticjs";
|
import type { Protobuf } from "@meshtastic/meshtasticjs";
|
||||||
|
|
||||||
export class ChannelSettingsValidation implements Protobuf.ChannelSettings {
|
export class ChannelSettingsValidation
|
||||||
@IsInt()
|
implements Omit<Protobuf.ChannelSettings, "channelNum">
|
||||||
channelNum: number;
|
{
|
||||||
|
|
||||||
psk: Uint8Array;
|
psk: Uint8Array;
|
||||||
|
|
||||||
@Length(1, 30)
|
@Length(1, 30)
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ export class LoRaValidation implements Protobuf.Config_LoRaConfig {
|
|||||||
@Min(0)
|
@Min(0)
|
||||||
txPower: number;
|
txPower: number;
|
||||||
|
|
||||||
|
@IsInt()
|
||||||
|
channelNum: number;
|
||||||
|
|
||||||
@IsArray()
|
@IsArray()
|
||||||
ignoreIncoming: number[];
|
ignoreIncoming: number[];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user