Initial 1.3.x rework

This commit is contained in:
Sacha Weatherstone
2022-07-26 08:52:23 +10:00
parent ff6019098b
commit a2280ab96e
163 changed files with 6383 additions and 14397 deletions
+128 -76
View File
@@ -1,85 +1,137 @@
import type React from 'react';
import { useState } from 'react';
import type React from "react";
import { useEffect, useMemo, useRef } from "react";
import mapboxgl from 'mapbox-gl';
import { FiMapPin } from 'react-icons/fi';
import { RiRoadMapLine } from 'react-icons/ri';
import { Pane } from "evergreen-ui";
import { Layout } from '@components/layout';
import { MapboxProvider } from '@components/MapBox/MapboxProvider';
import { useAppSelector } from '@hooks/useAppSelector';
import type { Protobuf } from '@meshtastic/meshtasticjs';
import { MapContainer } from '@pages/Map/MapContainer';
import { Marker } from '@pages/Map/Marker';
import { NodeCard } from '@pages/Nodes/NodeCard';
import { useDevice } from "@app/core/stores/deviceStore.js";
import Point from "@arcgis/core/geometry/Point";
import Graphic from "@arcgis/core/Graphic";
import FeatureLayer from "@arcgis/core/layers/FeatureLayer";
import LabelClass from "@arcgis/core/layers/support/LabelClass";
import Map from "@arcgis/core/Map";
import LineCallout3D from "@arcgis/core/symbols/callouts/LineCallout3D";
import LabelSymbol3D from "@arcgis/core/symbols/LabelSymbol3D";
import TextSymbol3DLayer from "@arcgis/core/symbols/TextSymbol3DLayer";
import SceneView from "@arcgis/core/views/SceneView";
export const Map = (): JSX.Element => {
const [selectedNode, setSelectedNode] = useState<Protobuf.NodeInfo>();
export const MapPage = (): JSX.Element => {
const { nodes } = useDevice();
const nodes = useAppSelector((state) => state.meshtastic.nodes);
const myNodeNum = useAppSelector(
(state) => state.meshtastic.radio.hardware.myNodeNum,
const nodesWithPosition = nodes.filter((node) => node.data.position);
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
console.log(nodesWithPosition);
}, [nodesWithPosition]);
const labelClass = useMemo(
() =>
new LabelClass({
labelExpressionInfo: {
expression: "$feature.name",
},
symbol: new LabelSymbol3D({
symbolLayers: [
new TextSymbol3DLayer({
text: "{name}",
material: {
color: "black",
},
halo: {
color: [255, 255, 255, 0.7],
size: 2,
},
font: {
size: 12,
weight: "bold",
},
size: 10,
}),
],
verticalOffset: {
screenLength: 150,
maxWorldLength: 2000,
minWorldLength: 30,
},
callout: new LineCallout3D({
size: 0.5,
color: [0, 0, 0],
border: {
color: [255, 255, 255],
},
}),
}),
}),
[]
);
return (
<MapboxProvider>
{nodes.map((node) => {
return (
node.data.position && (
<Marker
key={node.data.num}
center={
new mapboxgl.LngLat(
node.data.position.longitudeI / 1e7,
node.data.position.latitudeI / 1e7,
)
const points: Graphic[] = nodesWithPosition.map(
(node, index) =>
node.data.position
? new Graphic({
geometry: new Point({
latitude: node.data.position.latitudeI / 1e7,
longitude: node.data.position.longitudeI / 1e7,
}),
attributes: {
ObjectID: index,
name: node.data.user?.longName,
},
})
: new Graphic() //should be undefined/removed from array
);
useEffect(() => {
if (ref.current) {
const layer = new FeatureLayer({
labelsVisible: true,
labelingInfo: [labelClass],
source: points,
fields: [
{
name: "ObjectID",
alias: "ObjectID",
type: "oid",
},
{
name: "name",
alias: "Name",
type: "string",
},
],
});
const map = new Map({
basemap: "satellite",
ground: "world-elevation",
layers: [layer],
});
const scene = new SceneView({
container: ref.current,
map: map,
camera: {
position: nodesWithPosition[0]
? {
x: nodesWithPosition[0].data.position?.longitudeI ?? 0 / 1e7,
y: nodesWithPosition[0].data.position?.latitudeI ?? 0 / 1e7,
z: nodesWithPosition[0].data.position?.altitude ?? 0 / 1e7,
}
>
<div
onClick={(): void => {
setSelectedNode(node.data);
}}
className={`z-50 rounded-full border-2 bg-opacity-30 ${
node.data.num === selectedNode?.num
? 'border-green-500 bg-green-500'
: 'border-blue-500 bg-blue-500'
}`}
>
<div className="m-4 ">
<FiMapPin className="h-5 w-5" />
</div>
</div>
</Marker>
)
);
})}
<Layout
title="Nodes"
icon={<RiRoadMapLine />}
sidebarContents={
<div className="flex flex-col gap-2">
{!nodes.length && (
<span className="p-4 text-sm text-gray-400 dark:text-gray-600">
No nodes found.
</span>
)}
: {
y: -35.59, //Longitude
x: 148, //Latitude
z: 200, //Meters
},
tilt: 75,
},
});
scene.on("click", (event) => {
void scene.hitTest(event).then((point) => {
console.log(point);
});
});
}
}, [labelClass, points]);
{nodes.map((node) => (
<NodeCard
key={node.data.num}
node={node.data}
isMyNode={node.data.num === myNodeNum}
selected={selectedNode?.num === node.data.num}
setSelected={(): void => {
setSelectedNode(node.data);
}}
/>
))}
</div>
}
>
<MapContainer />
</Layout>
</MapboxProvider>
);
return <Pane width="100%" height="100%" ref={ref} />;
};