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