Browse Source

Update node view and support hosted version

pull/2/head
Sacha Weatherstone 5 years ago
parent
commit
c3a4f81b1c
  1. 2
      src/App.tsx
  2. 39
      src/components/Connection.tsx
  3. 3
      src/core/connection.ts
  4. 22
      src/pages/Nodes/Index.tsx
  5. 28
      src/pages/Nodes/NodeCard.tsx

2
src/App.tsx

@ -1,4 +1,4 @@
import React from 'react'; import type React from 'react';
import { DeviceStatus } from '@app/components/menu/buttons/DeviceStatus'; import { DeviceStatus } from '@app/components/menu/buttons/DeviceStatus';
import { useAppSelector } from '@app/hooks/redux'; import { useAppSelector } from '@app/hooks/redux';

39
src/components/Connection.tsx

@ -7,19 +7,13 @@ import { Card } from '@components/generic/Card';
import { Select } from '@components/generic/form/Select'; import { Select } from '@components/generic/form/Select';
import { Modal } from '@components/generic/Modal'; import { Modal } from '@components/generic/Modal';
import { DeviceStatus } from '@components/menu/buttons/DeviceStatus'; import { DeviceStatus } from '@components/menu/buttons/DeviceStatus';
import { import { connection, connectionUrl, setConnection } from '@core/connection';
cleanupListeners,
connection,
connectionUrl,
setConnection,
} from '@core/connection';
import { import {
closeConnectionModal, closeConnectionModal,
connType, connType,
setConnectionParams, setConnectionParams,
setConnType, setConnType,
} from '@core/slices/appSlice'; } from '@core/slices/appSlice';
import { resetState } from '@core/slices/meshtasticSlice';
import { Types } from '@meshtastic/meshtasticjs'; import { Types } from '@meshtastic/meshtasticjs';
import { BLE } from './connection/BLE'; import { BLE } from './connection/BLE';
@ -32,18 +26,20 @@ export const Connection = (): JSX.Element => {
const appState = useAppSelector((state) => state.app); const appState = useAppSelector((state) => state.app);
React.useEffect(() => { React.useEffect(() => {
dispatch( if (!import.meta.env.VITE_PUBLIC_HOSTED) {
setConnectionParams({ dispatch(
type: connType.HTTP, setConnectionParams({
params: { type: connType.HTTP,
address: connectionUrl, params: {
tls: false, address: connectionUrl,
receiveBatchRequests: false, tls: false,
fetchInterval: 2000, receiveBatchRequests: false,
}, fetchInterval: 2000,
}), },
); }),
void setConnection(connType.HTTP); );
void setConnection(connType.HTTP);
}
}, [dispatch]); }, [dispatch]);
React.useEffect(() => { React.useEffect(() => {
@ -56,7 +52,6 @@ export const Connection = (): JSX.Element => {
<Modal <Modal
className="w-full max-w-3xl" className="w-full max-w-3xl"
open={appState.connectionModalOpen} open={appState.connectionModalOpen}
// open={true}
onClose={(): void => { onClose={(): void => {
dispatch(closeConnectionModal()); dispatch(closeConnectionModal());
}} }}
@ -84,9 +79,7 @@ export const Connection = (): JSX.Element => {
padding={2} padding={2}
border border
onClick={async (): Promise<void> => { onClick={async (): Promise<void> => {
dispatch(resetState());
await connection.disconnect(); await connection.disconnect();
cleanupListeners();
}} }}
> >
Disconnect Disconnect
@ -102,8 +95,6 @@ export const Connection = (): JSX.Element => {
optionsEnum={connType} optionsEnum={connType}
value={appState.connType} value={appState.connType}
onChange={(e): void => { onChange={(e): void => {
console.log(e.target.value);
dispatch(setConnType(parseInt(e.target.value))); dispatch(setConnType(parseInt(e.target.value)));
}} }}
/> />

3
src/core/connection.ts

@ -5,6 +5,7 @@ import {
addNode, addNode,
addPosition, addPosition,
addUser, addUser,
resetState,
setDeviceStatus, setDeviceStatus,
setLastMeshInterraction, setLastMeshInterraction,
setMyNodeInfo, setMyNodeInfo,
@ -94,6 +95,8 @@ const registerListeners = (): void => {
} }
if (status === Types.DeviceStatusEnum.DEVICE_DISCONNECTED) { if (status === Types.DeviceStatusEnum.DEVICE_DISCONNECTED) {
store.dispatch(setReady(false)); store.dispatch(setReady(false));
store.dispatch(resetState());
cleanupListeners();
} }
}); });

22
src/pages/Nodes/Index.tsx

@ -11,16 +11,17 @@ import { Map } from '@components/Map';
import { NodeCard } from './NodeCard'; import { NodeCard } from './NodeCard';
export const Nodes = (): JSX.Element => { export const Nodes = (): JSX.Element => {
const myNodeNum = useAppSelector( const myNodeInfo = useAppSelector((state) => state.meshtastic.radio.hardware);
(state) => state.meshtastic.radio.hardware,
).myNodeNum;
const nodes = useAppSelector((state) => state.meshtastic.nodes) const nodes = useAppSelector((state) => state.meshtastic.nodes)
.slice() .slice()
.sort((a, b) => .sort((a, b) =>
a.number === myNodeNum a.number === myNodeInfo.myNodeNum
? 1 ? 1
: b?.lastHeard.getTime() - a?.lastHeard.getTime(), : b?.lastHeard.getTime() - a?.lastHeard.getTime(),
); );
const myNode = nodes.find((node) => node.number === myNodeInfo.myNodeNum);
const [navOpen, setNavOpen] = React.useState(false); const [navOpen, setNavOpen] = React.useState(false);
const { breakpoint } = useBreakpoint(); const { breakpoint } = useBreakpoint();
@ -52,13 +53,12 @@ export const Nodes = (): JSX.Element => {
No nodes found. No nodes found.
</span> </span>
)} )}
{nodes.map((node) => ( {myNode && <NodeCard node={myNode} myNodeInfo={myNodeInfo} />}
<NodeCard {nodes
key={node.number} .filter((node) => node.number !== myNodeInfo.myNodeNum)
node={node} .map((node) => (
isMyNode={node.number === myNodeNum} <NodeCard key={node.number} node={node} />
/> ))}
))}
</Drawer> </Drawer>
<Map /> <Map />
</div> </div>

28
src/pages/Nodes/NodeCard.tsx

@ -2,6 +2,7 @@ import React from 'react';
import { FaSatellite } from 'react-icons/fa'; import { FaSatellite } from 'react-icons/fa';
import { FiCode } from 'react-icons/fi'; import { FiCode } from 'react-icons/fi';
import { GiLightningFrequency } from 'react-icons/gi';
import { import {
MdAccountCircle, MdAccountCircle,
MdArrowDropDown, MdArrowDropDown,
@ -9,6 +10,7 @@ import {
MdGpsFixed, MdGpsFixed,
MdGpsNotFixed, MdGpsNotFixed,
MdGpsOff, MdGpsOff,
MdSdStorage,
MdSignalCellularAlt, MdSignalCellularAlt,
} from 'react-icons/md'; } from 'react-icons/md';
import TimeAgo from 'timeago-react'; import TimeAgo from 'timeago-react';
@ -20,10 +22,10 @@ import { Protobuf } from '@meshtastic/meshtasticjs';
export interface NodeCardProps { export interface NodeCardProps {
node: Node; node: Node;
isMyNode: boolean; myNodeInfo?: Protobuf.MyNodeInfo;
} }
export const NodeCard = ({ node, isMyNode }: NodeCardProps): JSX.Element => { export const NodeCard = ({ node, myNodeInfo }: NodeCardProps): JSX.Element => {
const [snrAverage, setSnrAverage] = React.useState(0); const [snrAverage, setSnrAverage] = React.useState(0);
const [satsAverage, setSatsAverage] = React.useState(0); const [satsAverage, setSatsAverage] = React.useState(0);
React.useEffect(() => { React.useEffect(() => {
@ -51,7 +53,7 @@ export const NodeCard = ({ node, isMyNode }: NodeCardProps): JSX.Element => {
className="m-2 rounded-md shadow-md bg-gray-50 dark:bg-gray-700" className="m-2 rounded-md shadow-md bg-gray-50 dark:bg-gray-700"
> >
<Disclosure.Button className="flex w-full gap-2 p-2 bg-gray-100 rounded-md shadow-md dark:bg-primaryDark"> <Disclosure.Button className="flex w-full gap-2 p-2 bg-gray-100 rounded-md shadow-md dark:bg-primaryDark">
{isMyNode ? ( {myNodeInfo ? (
<MdAccountCircle className="my-auto" /> <MdAccountCircle className="my-auto" />
) : ( ) : (
<div <div
@ -69,7 +71,7 @@ export const NodeCard = ({ node, isMyNode }: NodeCardProps): JSX.Element => {
<div className="my-auto">{node.user?.longName}</div> <div className="my-auto">{node.user?.longName}</div>
<div className="my-auto ml-auto text-xs font-semibold"> <div className="my-auto ml-auto text-xs font-semibold">
{!isMyNode && ( {!myNodeInfo && (
<span> <span>
{node.lastHeard.getTime() ? ( {node.lastHeard.getTime() ? (
<TimeAgo datetime={node.lastHeard} /> <TimeAgo datetime={node.lastHeard} />
@ -92,6 +94,24 @@ export const NodeCard = ({ node, isMyNode }: NodeCardProps): JSX.Element => {
)} )}
</Disclosure.Button> </Disclosure.Button>
<Disclosure.Panel className="p-2"> <Disclosure.Panel className="p-2">
{myNodeInfo && (
<div>
<div className="flex justify-between">
<span className="flex">
<MdSdStorage className="my-auto" />
Firmware Ver:
</span>
<span>{myNodeInfo.firmwareVersion}</span>
</div>
<div className="flex justify-between">
<span className="flex">
<GiLightningFrequency className="my-auto" />
Freq Bands:
</span>
<span>{myNodeInfo.numBands}</span>
</div>
</div>
)}
<div className="flex"> <div className="flex">
<div className="my-auto"> <div className="my-auto">
{Protobuf.HardwareModel[node.user?.hwModel ?? 0]} {Protobuf.HardwareModel[node.user?.hwModel ?? 0]}

Loading…
Cancel
Save