WIP changes

This commit is contained in:
Sacha Weatherstone
2022-08-12 09:07:06 +10:00
parent 547a7ce1f7
commit e9b168dd18
16 changed files with 292 additions and 84 deletions
+8 -2
View File
@@ -25,7 +25,8 @@ export const PeersDialog = ({
isOpen,
close,
}: PeersDialogProps): JSX.Element => {
const { hardware, nodes, connection } = useDevice();
const { hardware, nodes, connection, setPeerInfoOpen, setActivePeer } =
useDevice();
return (
<Dialog
@@ -48,6 +49,7 @@ export const PeersDialog = ({
SNR
</Table.TextHeaderCell>
<Table.TextHeaderCell>Location</Table.TextHeaderCell>
<Table.TextHeaderCell>Telemetry</Table.TextHeaderCell>
<Table.TextHeaderCell>Last Heard</Table.TextHeaderCell>
<Table.TextHeaderCell>Actions</Table.TextHeaderCell>
</Table.Head>
@@ -58,7 +60,10 @@ export const PeersDialog = ({
<Table.Row
key={node.data.num}
isSelectable
onSelect={() => alert(node.data.num)}
onSelect={() => {
setActivePeer(node.data.num);
setPeerInfoOpen(true);
}}
>
<Table.Cell flexBasis={48} flexShrink={0} flexGrow={0}>
<Hashicon
@@ -81,6 +86,7 @@ export const PeersDialog = ({
node.data.position?.longitudeI
)}
</Table.TextCell>
<Table.TextCell>Tmp</Table.TextCell>
<Table.TextCell>
{new Date(node.data.lastHeard * 1000).toLocaleString()}
</Table.TextCell>
+61
View File
@@ -0,0 +1,61 @@
import type React from "react";
import { useEffect, useState } from "react";
import { GeolocationIcon, Pane, PropertyIcon, SideSheet } from "evergreen-ui";
import { Node, useDevice } from "@app/core/stores/deviceStore.js";
import { Hashicon } from "@emeraldpay/hashicon-react";
import { Protobuf } from "@meshtastic/meshtasticjs";
import { SlideSheetTabbedContent } from "../layout/page/SlideSheetTabbedContent.js";
import type { TabType } from "../layout/page/TabbedContent.js";
import { Location } from "./tabs/nodes/Location.js";
import { Overview } from "./tabs/nodes/Overview.js";
export const PeerInfo = () => {
const { peerInfoOpen, activePeer, setPeerInfoOpen, nodes } = useDevice();
const [selectedTab, setSelectedTab] = useState(0);
const [node, setNode] = useState<Node | undefined>();
useEffect(() => {
setNode(nodes.find((n) => n.data.num === activePeer));
}, [nodes, activePeer]);
const tabs: TabType[] = [
{
name: "Info",
icon: PropertyIcon,
element: () => <Overview node={node} />,
},
{
name: "Location",
icon: GeolocationIcon,
element: () => <Location node={node} />,
},
];
return (
<SideSheet
isShown={peerInfoOpen}
onCloseComplete={() => {
setPeerInfoOpen(false);
}}
containerProps={{
display: "flex",
flex: "1",
flexDirection: "column",
}}
>
<SlideSheetTabbedContent
heading={node?.data.user?.longName ?? "UNK"}
description={Protobuf.HardwareModel[node?.data.user?.hwModel ?? 0]}
tabs={tabs}
tabIcon={
<Pane marginY="auto">
<Hashicon size={32} value={(node?.data.num ?? 0).toString()} />
</Pane>
}
/>
</SideSheet>
);
};
@@ -4,29 +4,23 @@ import { useCallback, useEffect, useState } from "react";
import { Button, majorScale, Pane } from "evergreen-ui";
import { FiPlusCircle } from "react-icons/fi";
import { useAppStore } from "@app/core/stores/appStore.js";
import { useDeviceStore } from "@app/core/stores/deviceStore.js";
import { subscribeAll } from "@app/core/subscriptions.js";
import { randId } from "@app/core/utils/randId.js";
import { Constants, IBLEConnection } from "@meshtastic/meshtasticjs";
import type { CloseProps } from "../SlideSheets/NewDevice.js";
import type { CloseProps } from "../../NewDevice.js";
export const BLE = ({ close }: CloseProps): JSX.Element => {
const [bleDevices, setBleDevices] = useState<BluetoothDevice[]>([]);
const { addDevice } = useDeviceStore();
const { setSelectedDevice } = useAppStore();
const updateBleDeviceList = useCallback(async (): Promise<void> => {
setBleDevices(await navigator.bluetooth.getDevices());
}, []);
navigator.bluetooth.addEventListener("advertisementreceived", (e) => {
console.log(e);
});
navigator.bluetooth.addEventListener("availabilitychanged", (e) => {
console.log(e);
});
useEffect(() => {
void updateBleDeviceList();
}, [updateBleDeviceList]);
@@ -34,6 +28,7 @@ export const BLE = ({ close }: CloseProps): JSX.Element => {
const onConnect = async (BLEDevice: BluetoothDevice) => {
const id = randId();
const device = addDevice(id);
setSelectedDevice(id);
const connection = new IBLEConnection(id);
await connection.connect({
device: BLEDevice,
@@ -4,6 +4,7 @@ import { Button, majorScale, Pane, TextInputField } from "evergreen-ui";
import { useForm } from "react-hook-form";
import { FiPlusCircle } from "react-icons/fi";
import { useAppStore } from "@app/core/stores/appStore.js";
import { useDeviceStore } from "@app/core/stores/deviceStore.js";
import { subscribeAll } from "@app/core/subscriptions.js";
import { randId } from "@app/core/utils/randId.js";
@@ -15,6 +16,7 @@ export interface HTTPProps {
export const HTTP = ({ close }: HTTPProps): JSX.Element => {
const { addDevice } = useDeviceStore();
const { setSelectedDevice } = useAppStore();
const { register, handleSubmit } = useForm<{
ip: string;
tls: boolean;
@@ -25,9 +27,10 @@ export const HTTP = ({ close }: HTTPProps): JSX.Element => {
},
});
const onSubmit = handleSubmit(async (data) => {
const onSubmit = handleSubmit((data) => {
const id = randId();
const device = addDevice(id);
setSelectedDevice(id);
const connection = new IHTTPConnection(id);
// TODO: Promise never resolves
void connection.connect({
@@ -4,12 +4,13 @@ import { useCallback, useEffect, useState } from "react";
import { Button, majorScale, Pane } from "evergreen-ui";
import { FiPlusCircle } from "react-icons/fi";
import { useAppStore } from "@app/core/stores/appStore.js";
import { subscribeAll } from "@app/core/subscriptions.js";
import { useDeviceStore } from "@core/stores/deviceStore.js";
import { randId } from "@core/utils/randId.js";
import { ISerialConnection } from "@meshtastic/meshtasticjs";
import type { CloseProps } from "../SlideSheets/NewDevice.js";
import type { CloseProps } from "../../NewDevice.js";
interface USBID {
id: number;
@@ -19,6 +20,7 @@ interface USBID {
export const Serial = ({ close }: CloseProps): JSX.Element => {
const [serialPorts, setSerialPorts] = useState<SerialPort[]>([]);
const { addDevice } = useDeviceStore();
const { setSelectedDevice } = useAppStore();
const updateSerialPortList = useCallback(async () => {
setSerialPorts(await navigator.serial.getPorts());
@@ -37,6 +39,7 @@ export const Serial = ({ close }: CloseProps): JSX.Element => {
const onConnect = async (port: SerialPort) => {
const id = randId();
const device = addDevice(id);
setSelectedDevice(id);
const connection = new ISerialConnection(id);
await connection.connect({
port,
@@ -0,0 +1,18 @@
import type React from "react";
import { Pane } from "evergreen-ui";
import JSONPretty from "react-json-pretty";
import type { Node } from "@app/core/stores/deviceStore.js";
export interface LocationProps {
node?: Node;
}
export const Location = ({ node }: LocationProps): JSX.Element => {
return (
<Pane>
<JSONPretty data={node.data.position} />
</Pane>
);
};
@@ -0,0 +1,17 @@
import type React from "react";
import { Pane } from "evergreen-ui";
import JSONPretty from "react-json-pretty";
import type { Node } from "@app/core/stores/deviceStore.js";
export interface OverviewProps {
node?: Node;
}
export const Overview = ({ node }: OverviewProps): JSX.Element => {
return (
<Pane>
<JSONPretty data={node.data.user} />
</Pane>
);
};
+5 -3
View File
@@ -8,6 +8,7 @@ import { useDeviceStore } from "@core/stores/deviceStore.js";
import { NoDevice } from "../misc/NoDevice.js";
import { Progress } from "../Progress.js";
import { PeerInfo } from "../SlideSheets/PeerInfo.js";
import { Header } from "./Header.js";
import { Sidebar } from "./Sidebar/index.js";
@@ -32,12 +33,12 @@ export const AppLayout = ({ children }: AppLayoutProps): JSX.Element => {
<Header />
<Pane display="flex" flex={1} height="100%" width="100%">
{devices.length ? (
devices.map((device, index) => (
devices.map((device) => (
<Pane
key={index}
key={device.id}
width="100%"
height="100%"
display={index === selectedDevice ? "grid" : "none"}
display={device.id === selectedDevice ? "grid" : "none"}
gap={majorScale(3)}
gridTemplateColumns="16rem 1fr"
>
@@ -45,6 +46,7 @@ export const AppLayout = ({ children }: AppLayoutProps): JSX.Element => {
{device && device.ready ? (
<>
<Sidebar />
<PeerInfo />
<Pane height="100%" display="flex">
{children}
</Pane>
+9 -4
View File
@@ -5,6 +5,7 @@ import {
Button,
CrossIcon,
GlobeIcon,
HelpIcon,
IconButton,
Link,
majorScale,
@@ -65,13 +66,13 @@ export const Header = (): JSX.Element => {
</Link>
</Pane>
<Tablist display="flex" marginX={majorScale(4)}>
{getDevices().map((device, index) => (
{getDevices().map((device) => (
<Tab
key={index}
key={device.id}
gap={majorScale(1)}
isSelected={index === selectedDevice}
isSelected={device.id === selectedDevice}
onSelect={() => {
setSelectedDevice(index);
setSelectedDevice(device.id);
}}
>
<Hashicon value={device.hardware.myNodeNum.toString()} size={20} />
@@ -121,6 +122,9 @@ export const Header = (): JSX.Element => {
<Button
iconBefore={CrossIcon}
onClick={() => {
void getDevices()
.find((d) => d.id === selectedDevice)
?.connection?.disconnect();
removeDevice(selectedDevice ?? 0);
}}
>
@@ -138,6 +142,7 @@ export const Header = (): JSX.Element => {
</Button>
</Link>
</Tooltip>
<IconButton icon={HelpIcon} />
<Tooltip content="Visit Meshtastic.org">
<Link target="_blank" href="https://meshtastic.org/">
<IconButton icon={GlobeIcon} />
@@ -23,23 +23,33 @@ export interface SlideSheetTabbedContentProps {
heading: string;
description: string;
tabs: TabType[];
tabIcon?: React.ReactNode;
}
export const SlideSheetTabbedContent = ({
heading,
description,
tabs,
tabIcon,
}: SlideSheetTabbedContentProps): JSX.Element => {
const [selectedTab, setSelectedTab] = useState(0);
return (
<>
<Pane zIndex={1} flexShrink={0} elevation={1} backgroundColor="white">
<Pane padding={16} borderBottom="muted">
<Heading size={600}>{heading}</Heading>
<Paragraph size={400} color="muted">
{description}
</Paragraph>
<Pane
display="flex"
padding={16}
borderBottom="muted"
gap={majorScale(1)}
>
{tabIcon}
<Pane>
<Heading size={600}>{heading}</Heading>
<Paragraph size={400} color="muted">
{description}
</Paragraph>
</Pane>
</Pane>
<Pane display="flex" padding={8}>
<Tablist>