WIP 1.3
This commit is contained in:
@@ -24,6 +24,7 @@ export const Connection = (): JSX.Element => {
|
||||
|
||||
const meshtasticState = useAppSelector((state) => state.meshtastic);
|
||||
const appState = useAppSelector((state) => state.app);
|
||||
const chromiunm = !!window.chrome;
|
||||
|
||||
useEffect(() => {
|
||||
if (!import.meta.env.VITE_PUBLIC_HOSTED) {
|
||||
@@ -79,22 +80,36 @@ export const Connection = (): JSX.Element => {
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{appState.connType === connType.BLE && (
|
||||
<BLE
|
||||
connecting={
|
||||
meshtasticState.deviceStatus ===
|
||||
Types.DeviceStatusEnum.DEVICE_CONNECTED
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{appState.connType === connType.SERIAL && (
|
||||
<Serial
|
||||
connecting={
|
||||
meshtasticState.deviceStatus ===
|
||||
Types.DeviceStatusEnum.DEVICE_CONNECTED
|
||||
}
|
||||
/>
|
||||
)}
|
||||
|
||||
{appState.connType === connType.BLE &&
|
||||
(chromiunm ? (
|
||||
<BLE
|
||||
connecting={
|
||||
meshtasticState.deviceStatus ===
|
||||
Types.DeviceStatusEnum.DEVICE_CONNECTED
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<div className="rounded-md border border-red-500 bg-red-500 bg-opacity-10 p-8 dark:text-white">
|
||||
<p>Unsupported.</p>
|
||||
<p>Please use a Chromium based browser.</p>
|
||||
</div>
|
||||
))}
|
||||
|
||||
{appState.connType === connType.SERIAL &&
|
||||
(chromiunm ? (
|
||||
<Serial
|
||||
connecting={
|
||||
meshtasticState.deviceStatus ===
|
||||
Types.DeviceStatusEnum.DEVICE_CONNECTED
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<div className="rounded-md border border-red-500 bg-red-500 bg-opacity-10 p-8 dark:text-white">
|
||||
<p>Unsupported.</p>
|
||||
<p>Please use a Chromium based browser.</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="md:w-1/2">
|
||||
|
||||
@@ -8,7 +8,6 @@ import { Checkbox } from '@components/generic/form/Checkbox';
|
||||
import { Form } from '@components/generic/form/Form';
|
||||
import { Input } from '@components/generic/form/Input';
|
||||
import { Label } from '@components/generic/form/Label';
|
||||
import { Select } from '@components/generic/form/Select';
|
||||
import { connection } from '@core/connection';
|
||||
import { bitwiseDecode, bitwiseEncode } from '@core/utils/bitwise';
|
||||
import { useAppSelector } from '@hooks/useAppSelector';
|
||||
@@ -25,7 +24,7 @@ export const GPS = (): JSX.Element => {
|
||||
...preferences,
|
||||
positionBroadcastSecs:
|
||||
preferences.positionBroadcastSecs === 0
|
||||
? preferences.isRouter
|
||||
? preferences.role === Protobuf.Role.Router
|
||||
? 43200
|
||||
: 900
|
||||
: preferences.positionBroadcastSecs,
|
||||
@@ -54,20 +53,15 @@ export const GPS = (): JSX.Element => {
|
||||
{...register('positionBroadcastSecs', { valueAsNumber: true })}
|
||||
/>
|
||||
<Checkbox
|
||||
label="Use Smart Position"
|
||||
{...register('positionBroadcastSmart')}
|
||||
label="Disable Smart Position"
|
||||
{...register('positionBroadcastSmartDisabled')}
|
||||
/>
|
||||
<Checkbox label="Use Fixed Position" {...register('fixedPosition')} />
|
||||
<Select
|
||||
label="Location Sharing"
|
||||
optionsEnum={Protobuf.LocationSharing}
|
||||
{...register('locationShare', { valueAsNumber: true })}
|
||||
/>
|
||||
<Select
|
||||
label="GPS Mode"
|
||||
optionsEnum={Protobuf.GpsOperation}
|
||||
{...register('gpsOperation', { valueAsNumber: true })}
|
||||
<Checkbox
|
||||
label="Disable Location Sharing"
|
||||
{...register('locationShareDisabled')}
|
||||
/>
|
||||
<Checkbox label="Disable GPS" {...register('gpsDisabled')} />
|
||||
<Input
|
||||
label="GPS Update Interval"
|
||||
type="number"
|
||||
|
||||
@@ -51,7 +51,7 @@ export const Settings = ({ open, setOpen }: SettingsProps): JSX.Element => {
|
||||
const {
|
||||
rangeTestModuleEnabled,
|
||||
extNotificationModuleEnabled,
|
||||
serialmoduleEnabled,
|
||||
serialModuleEnabled,
|
||||
storeForwardModuleEnabled,
|
||||
mqttDisabled,
|
||||
cannedMessageModuleEnabled,
|
||||
@@ -132,7 +132,7 @@ export const Settings = ({ open, setOpen }: SettingsProps): JSX.Element => {
|
||||
<CollapsibleSection
|
||||
icon={<FiAlignLeft />}
|
||||
title="Serial"
|
||||
status={serialmoduleEnabled}
|
||||
status={serialModuleEnabled}
|
||||
>
|
||||
<SerialSettingsPanel />
|
||||
</CollapsibleSection>
|
||||
|
||||
@@ -42,7 +42,11 @@ export const LoRa = (): JSX.Element => {
|
||||
{...register('hopLimit', { valueAsNumber: true })}
|
||||
/>
|
||||
<Checkbox label="Transmit Disabled" {...register('isLoraTxDisabled')} />
|
||||
<Checkbox label="Router Mode" {...register('isRouter')} />
|
||||
<Select
|
||||
label="Operating Role"
|
||||
optionsEnum={Protobuf.Role}
|
||||
{...register('role')}
|
||||
/>
|
||||
<Input
|
||||
label="Send Owner Interval"
|
||||
type="number"
|
||||
|
||||
@@ -20,7 +20,10 @@ export const Power = (): JSX.Element => {
|
||||
useForm<Protobuf.RadioConfig_UserPreferences>({
|
||||
defaultValues: {
|
||||
...preferences,
|
||||
isLowPower: preferences.isRouter ? true : preferences.isLowPower,
|
||||
isLowPower:
|
||||
preferences.role === Protobuf.Role.Router
|
||||
? true
|
||||
: preferences.isLowPower,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -45,9 +48,11 @@ export const Power = (): JSX.Element => {
|
||||
/>
|
||||
<Checkbox
|
||||
label="Powered by low power source (solar)"
|
||||
disabled={preferences.isRouter}
|
||||
disabled={preferences.role === Protobuf.Role.Router}
|
||||
validationMessage={
|
||||
preferences.isRouter ? 'Enabled by default in router mode' : ''
|
||||
preferences.role === Protobuf.Role.Router
|
||||
? 'Enabled by default in router mode'
|
||||
: ''
|
||||
}
|
||||
{...register('isLowPower')}
|
||||
/>
|
||||
|
||||
@@ -18,7 +18,7 @@ export const User = (): JSX.Element => {
|
||||
(state) => state.meshtastic.radio.hardware,
|
||||
).myNodeNum;
|
||||
const node = useAppSelector((state) => state.meshtastic.nodes).find(
|
||||
(node) => node.number === myNodeNum,
|
||||
(node) => node.num === myNodeNum,
|
||||
);
|
||||
const { register, handleSubmit, formState, reset } = useForm<{
|
||||
longName: string;
|
||||
|
||||
@@ -37,24 +37,24 @@ export const SerialSettingsPanel = (): JSX.Element => {
|
||||
|
||||
const moduleEnabled = useWatch({
|
||||
control,
|
||||
name: 'serialmoduleEnabled',
|
||||
name: 'serialModuleEnabled',
|
||||
defaultValue: false,
|
||||
});
|
||||
|
||||
return (
|
||||
<Form loading={loading} dirty={!formState.isDirty} submit={onSubmit}>
|
||||
<Checkbox label="Module Enabled" {...register('serialmoduleEnabled')} />
|
||||
<Checkbox label="Module Enabled" {...register('serialModuleEnabled')} />
|
||||
<Checkbox
|
||||
label="Echo"
|
||||
disabled={!moduleEnabled}
|
||||
{...register('serialmoduleEcho')}
|
||||
{...register('serialModuleEcho')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
type="number"
|
||||
label="RX"
|
||||
disabled={!moduleEnabled}
|
||||
{...register('serialmoduleRxd', {
|
||||
{...register('serialModuleRxd', {
|
||||
valueAsNumber: true,
|
||||
})}
|
||||
/>
|
||||
@@ -62,7 +62,7 @@ export const SerialSettingsPanel = (): JSX.Element => {
|
||||
type="number"
|
||||
label="TX Pin"
|
||||
disabled={!moduleEnabled}
|
||||
{...register('serialmoduleTxd', {
|
||||
{...register('serialModuleTxd', {
|
||||
valueAsNumber: true,
|
||||
})}
|
||||
/>
|
||||
@@ -70,7 +70,7 @@ export const SerialSettingsPanel = (): JSX.Element => {
|
||||
type="number"
|
||||
label="Baud Rate"
|
||||
disabled={!moduleEnabled}
|
||||
{...register('serialmoduleBaud', {
|
||||
{...register('serialModuleBaud', {
|
||||
valueAsNumber: true,
|
||||
})}
|
||||
/>
|
||||
@@ -78,7 +78,7 @@ export const SerialSettingsPanel = (): JSX.Element => {
|
||||
type="number"
|
||||
label="Timeout"
|
||||
disabled={!moduleEnabled}
|
||||
{...register('serialmoduleTimeout', {
|
||||
{...register('serialModuleTimeout', {
|
||||
valueAsNumber: true,
|
||||
})}
|
||||
/>
|
||||
@@ -86,7 +86,7 @@ export const SerialSettingsPanel = (): JSX.Element => {
|
||||
type="number"
|
||||
label="Mode"
|
||||
disabled={!moduleEnabled}
|
||||
{...register('serialmoduleMode', {
|
||||
{...register('serialModuleMode', {
|
||||
valueAsNumber: true,
|
||||
})}
|
||||
/>
|
||||
|
||||
@@ -68,7 +68,7 @@ export const Telemetry = (): JSX.Element => {
|
||||
/>
|
||||
<Checkbox
|
||||
label="Display Farenheit"
|
||||
{...register('telemetryModuleDisplayFarenheit')}
|
||||
{...register('telemetryModuleDisplayFahrenheit')}
|
||||
/>
|
||||
<Select
|
||||
label="Sensor Type"
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
FiBluetooth,
|
||||
FiCpu,
|
||||
FiGitBranch,
|
||||
FiHexagon,
|
||||
FiMenu,
|
||||
FiMoon,
|
||||
FiSun,
|
||||
@@ -12,6 +13,7 @@ import {
|
||||
FiX,
|
||||
} from 'react-icons/fi';
|
||||
import { MdUpgrade } from 'react-icons/md';
|
||||
import { AiOutlineHeart, AiFillHeart } from 'react-icons/ai';
|
||||
import {
|
||||
RiArrowDownLine,
|
||||
RiArrowUpDownLine,
|
||||
@@ -29,6 +31,13 @@ import {
|
||||
import { useAppDispatch } from '@hooks/useAppDispatch';
|
||||
import { useAppSelector } from '@hooks/useAppSelector';
|
||||
import { Protobuf, Types } from '@meshtastic/meshtasticjs';
|
||||
import {
|
||||
IoBatteryChargingOutline,
|
||||
IoBatteryDeadOutline,
|
||||
IoBatteryFullOutline,
|
||||
IoBatteryHalfOutline,
|
||||
} from 'react-icons/io5';
|
||||
import { FaTrafficLight } from 'react-icons/fa';
|
||||
|
||||
export const BottomNav = (): JSX.Element => {
|
||||
const [showVersionInfo, setShowVersionInfo] = useState(false);
|
||||
@@ -38,6 +47,8 @@ export const BottomNav = (): JSX.Element => {
|
||||
const primaryChannelSettings = useAppSelector(
|
||||
(state) => state.meshtastic.radio.channels,
|
||||
).find((channel) => channel.role === Protobuf.Channel_Role.PRIMARY)?.settings;
|
||||
const telemetry =
|
||||
meshtasticState.nodes[meshtasticState.radio.hardware.myNodeNum]?.telemetry;
|
||||
|
||||
return (
|
||||
<div className="z-20 flex justify-between divide-x divide-gray-400 border-t border-gray-400 bg-white dark:divide-gray-600 dark:border-gray-600 dark:bg-secondaryDark">
|
||||
@@ -78,10 +89,57 @@ export const BottomNav = (): JSX.Element => {
|
||||
)}
|
||||
<div className="truncate text-xs font-medium">
|
||||
{meshtasticState.nodes.find(
|
||||
(node) => node.number === meshtasticState.radio.hardware.myNodeNum,
|
||||
(node) => node.num === meshtasticState.radio.hardware.myNodeNum,
|
||||
)?.user?.longName ?? 'Disconnected'}
|
||||
</div>
|
||||
</BottomNavItem>
|
||||
<BottomNavItem tooltip="Router Heartbeat">
|
||||
{telemetry?.routerHeartbeat ? (
|
||||
<AiFillHeart className="h-4" />
|
||||
) : (
|
||||
<AiOutlineHeart className="h-4" />
|
||||
)}
|
||||
</BottomNavItem>
|
||||
|
||||
<BottomNavItem tooltip="Battery Level">
|
||||
{!telemetry?.batteryLevel ? (
|
||||
<IoBatteryDeadOutline className="h-4" />
|
||||
) : telemetry?.batteryLevel > 50 ? (
|
||||
<IoBatteryFullOutline className="h-4" />
|
||||
) : telemetry?.batteryLevel > 0 ? (
|
||||
<IoBatteryFullOutline className="h-4" />
|
||||
) : (
|
||||
<IoBatteryChargingOutline className="h-4" />
|
||||
)}
|
||||
|
||||
<div className="truncate text-xs font-medium">
|
||||
{telemetry?.batteryLevel
|
||||
? `${telemetry?.batteryLevel}% - ${telemetry?.voltage}v`
|
||||
: 'No Battery'}
|
||||
</div>
|
||||
</BottomNavItem>
|
||||
|
||||
<BottomNavItem tooltip="Network Utilization">
|
||||
<div className="m-auto h-3 w-3 rounded-full bg-primary" />
|
||||
<div className="truncate text-xs font-medium">
|
||||
{`${telemetry?.airUtilTx ?? 0}% - Air`} |
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`m-auto h-3 w-3 rounded-full ${
|
||||
!telemetry?.channelUtilization
|
||||
? 'bg-primary'
|
||||
: telemetry?.channelUtilization > 50
|
||||
? 'bg-red-400'
|
||||
: telemetry?.channelUtilization > 24
|
||||
? 'bg-yellow-400'
|
||||
: 'bg-primary'
|
||||
}`}
|
||||
/>
|
||||
<div className="truncate text-xs font-medium">
|
||||
{`${telemetry?.channelUtilization ?? 0}% - Ch`}
|
||||
</div>
|
||||
</BottomNavItem>
|
||||
|
||||
<BottomNavItem tooltip="MQTT Status">
|
||||
{primaryChannelSettings?.uplinkEnabled &&
|
||||
|
||||
Reference in New Issue
Block a user