Compare commits
10 Commits
08c92a7900
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4466dc4331 | ||
|
|
b17c62ae09 | ||
|
|
5a59f87f13 | ||
|
|
f9e5916081 | ||
|
|
8a4795296e | ||
|
|
8f703dd1c7 | ||
|
|
46f041d58e | ||
|
|
3e95bc2633 | ||
|
|
f926604c7f | ||
|
|
c7140e0653 |
14
webapp/jsconfig.json
Normal file
14
webapp/jsconfig.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Node",
|
||||
"target": "ES2020",
|
||||
"jsx": "react",
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"**/node_modules/*"
|
||||
]
|
||||
}
|
||||
1146
webapp/package-lock.json
generated
1146
webapp/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -7,17 +7,20 @@
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"bootstrap": "^5.3.2",
|
||||
"leaflet": "^1.9.4",
|
||||
"leaflet-contextmenu": "^1.4.0",
|
||||
"milsymbol": "^2.2.0",
|
||||
"react": "^18.2.0",
|
||||
"react-bootstrap": "^2.9.0",
|
||||
"react-container-dimensions": "^1.4.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-hook-form": "^7.46.2",
|
||||
"react-leaflet": "^4.2.1",
|
||||
"react-router-dom": "^6.18.0",
|
||||
"react-scripts": "^5.0.1",
|
||||
"react-use-websocket": "^4.3.1",
|
||||
"sass": "^1.66.1",
|
||||
"typescript": "^5.2.2",
|
||||
"usehooks-ts": "^2.9.1",
|
||||
"web-vitals": "^2.1.4",
|
||||
"websocket": "^1.0.34"
|
||||
},
|
||||
|
||||
72
webapp/public/Own_Ship.svg
Normal file
72
webapp/public/Own_Ship.svg
Normal file
@@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
id="svg2"
|
||||
height="592.92773"
|
||||
width="592.92773"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="NATO Map Symbol - Friendly Sea - Own Ship.svg">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1536"
|
||||
inkscape:window-height="801"
|
||||
id="namedview65"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="68.45469"
|
||||
inkscape:cy="233.21213"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2"
|
||||
inkscape:object-nodes="true" />
|
||||
<defs
|
||||
id="defs4" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#00c8ff;stroke-width:8;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path2988"
|
||||
d="m 514.47312,296.57436 a 218.00928,218.00928 0 0 1 -436.018504,0 218.00928,218.00928 0 1 1 436.018504,0 z"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#00c8ff;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 296.46387,78.454681 0,436.018369"
|
||||
id="path4136"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#00c8ff;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 514.47305,296.46387 -436.018363,0"
|
||||
id="path4136-5"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -1,205 +1,39 @@
|
||||
// App.js
|
||||
import React, { Component } from "react";
|
||||
import "./App.css";
|
||||
// import { connect, sendMsg } from "./components/api/index";
|
||||
import Header from './components/Header';
|
||||
import Controls from "./components/control/controls";
|
||||
// import ChatHistory from "./components/ChatHistory/ChatHistory.jsx";
|
||||
|
||||
import OpenSeaMap from "./components/OpenSeaMap/OpenSeaMap";
|
||||
import Header from "./components/Header/index"
|
||||
import SimControl from './components/SimControl'
|
||||
import {w3cwebsocket as W3CWebSocket} from "websocket"
|
||||
|
||||
import { BrowserRouter, Routes, Route } from "react-router-dom";
|
||||
import Gateway from "./components/Gateway";
|
||||
import Database from "./components/Database";
|
||||
import Scenarios from "./components/Scenarios";
|
||||
import Settings from "./components/Settings";
|
||||
import Debug from "./components/Debug";
|
||||
|
||||
|
||||
export const defaultLocale = "en-US";
|
||||
|
||||
const config = {
|
||||
// apiUrl: process.env.REACT_APP_WEBAPP_WS_URL,
|
||||
apiUrl: "192.168.3.13",
|
||||
apiProt: 30747
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<><Header />
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route path="/" element={<SimControl />} />
|
||||
<Route path="/debug" element={<Debug />} />
|
||||
|
||||
<Route path="/scenarios" element={<Scenarios />} />
|
||||
<Route path="/database" element={<Database />} />
|
||||
<Route path="/gateway" element={<Gateway />} />
|
||||
<Route path="/settings" element={<Settings />} />
|
||||
|
||||
</Routes>
|
||||
</BrowserRouter></>
|
||||
);
|
||||
}
|
||||
|
||||
// const config = {
|
||||
// // apiUrl: process.env.REACT_APP_WEBAPP_WS_URL,
|
||||
// apiUrl: "localhost",
|
||||
// apiProt: 9999
|
||||
// }
|
||||
|
||||
|
||||
const client = new W3CWebSocket("ws://"+config.apiUrl+":"+config.apiProt+"/");
|
||||
|
||||
|
||||
class App extends Component {
|
||||
state = {
|
||||
Entities: [],
|
||||
EntityOnFocus: undefined,
|
||||
PositionClicked: undefined
|
||||
}
|
||||
|
||||
|
||||
|
||||
componentDidMount() {
|
||||
console.log(config.apiUrl);
|
||||
|
||||
client.onopen = () => {
|
||||
console.log("Websocket Client for Map Connected");
|
||||
};
|
||||
|
||||
client.onmessage = (message) => {
|
||||
const dataFromServer = JSON.parse(message.data);
|
||||
// console.log('reply: ', dataFromServer);
|
||||
|
||||
if(dataFromServer.Data === "COP")
|
||||
{
|
||||
|
||||
// console.log(this.state.EntityOnFocus);
|
||||
var tmp = []
|
||||
if(this.state.Entities.length !== 0){
|
||||
|
||||
|
||||
dataFromServer.Entities.forEach((elementFromWS, indexWS) => {
|
||||
|
||||
this.state.Entities.forEach((elementStored, indexStore) => {
|
||||
if(elementFromWS.id === elementStored.id)
|
||||
{
|
||||
|
||||
if(elementStored.onFocus !==true | elementStored.onFocus === undefined)
|
||||
{
|
||||
tmp.push(elementFromWS);
|
||||
}else
|
||||
{
|
||||
tmp.push(elementStored);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}else{
|
||||
tmp = dataFromServer.Entities;
|
||||
}
|
||||
// console.log(tmp);
|
||||
this.setState((state) => ({
|
||||
// Entities: structuredClone(dataFromServer.Entities)
|
||||
Entities: structuredClone(tmp)
|
||||
|
||||
})
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// interval for updates
|
||||
setInterval(() => {
|
||||
this.updateEntities();
|
||||
}, 2000);
|
||||
|
||||
|
||||
}
|
||||
|
||||
updateEntities()
|
||||
{
|
||||
var msg =
|
||||
{
|
||||
Type: "Request",
|
||||
Data: "COP"
|
||||
|
||||
}
|
||||
client.send(JSON.stringify(msg));
|
||||
}
|
||||
|
||||
getEntityFromID(Entities, SelectedEntity)
|
||||
{
|
||||
// console.log(Entities);
|
||||
}
|
||||
|
||||
setEntityOnFocus(Entity)
|
||||
{
|
||||
if(Entity == undefined)
|
||||
{
|
||||
this.resetEntityOnFocus();
|
||||
return;
|
||||
}
|
||||
|
||||
this.getEntityFromID(this.state.Entities,Entity)
|
||||
console.log(Entity);
|
||||
this.setState({
|
||||
EntityOnFocus: Entity
|
||||
});
|
||||
this.state.Entities.forEach((element, index) => {
|
||||
// console.log(element);
|
||||
|
||||
if(element.id === Entity.EntityID)
|
||||
{
|
||||
var tmpList = structuredClone(this.state.Entities);
|
||||
tmpList[index].onFocus = true;
|
||||
if(Entity.NewPos !== undefined)
|
||||
{
|
||||
tmpList[index].Position = Entity.NewPos
|
||||
}
|
||||
this.setState({
|
||||
Entities: structuredClone(tmpList)
|
||||
});
|
||||
if(Entity.dragged !== undefined)
|
||||
{
|
||||
if(Entity.dragged === true)
|
||||
{
|
||||
tmpList[index].dragged = true;
|
||||
}
|
||||
}
|
||||
console.log(tmpList[index]);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
resetEntityOnFocus()
|
||||
{
|
||||
if(this.state.EntityOnFocus !== undefined)
|
||||
{
|
||||
this.state.Entities.map((element ,index) => {
|
||||
if(element.id === this.state.EntityOnFocus.EntityID)
|
||||
{
|
||||
this.state.Entities[index].onFocus = false;
|
||||
}
|
||||
})
|
||||
console.log(this.state.Entities)
|
||||
this.setState({
|
||||
EntityOnFocus: undefined
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setFocusPosition(props)
|
||||
{
|
||||
|
||||
// console.log(Entity);
|
||||
this.setState({
|
||||
PositionClicked: props
|
||||
});
|
||||
}
|
||||
|
||||
Functions = {
|
||||
updateEntities: this.updateEntities.bind(this),
|
||||
resetEntityOnFocus: this.resetEntityOnFocus.bind(this)
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const {name} = this.state;
|
||||
return (
|
||||
<div className="App">
|
||||
<Header />
|
||||
<div className="Content">
|
||||
|
||||
<Controls Functions= {this.Functions} Client= {client} Entities= {this.state.Entities} updateEntities = {this.updateEntities} EntityOnFocus = {this.state.EntityOnFocus} PositionClicked = {this.state.PositionClicked} />
|
||||
|
||||
<OpenSeaMap Entities= {this.state.Entities} updateEntities = {this.updateEntities} setEntityOnFocus = {this.setEntityOnFocus.bind(this)} setFocusPosition = {this.setFocusPosition.bind(this)}/>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
||||
12
webapp/src/components/Database/Database.jsx
Normal file
12
webapp/src/components/Database/Database.jsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import React from "react";
|
||||
|
||||
|
||||
function Database()
|
||||
{
|
||||
return(
|
||||
<p>Database</p>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
export default Database;
|
||||
3
webapp/src/components/Database/index.js
Normal file
3
webapp/src/components/Database/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import Database from "./Database.jsx";
|
||||
|
||||
export default Database;
|
||||
135
webapp/src/components/Debug/Debug.jsx
Normal file
135
webapp/src/components/Debug/Debug.jsx
Normal file
@@ -0,0 +1,135 @@
|
||||
import React from "react";
|
||||
import {w3cwebsocket as W3CWebSocket} from "websocket"
|
||||
import PerceivedTruth from "./components/perceivedTruth/perceivedTruth.jsx";
|
||||
import "./Debug.scss"
|
||||
import { useEffect, useState } from 'react'
|
||||
import { getCOP,loadAutoraster } from "../api/APICalls";
|
||||
|
||||
import TrackListClass from "../SimControl/Tracklist.tsx";
|
||||
|
||||
|
||||
const config = {
|
||||
// apiUrl: process.env.REACT_APP_WEBAPP_WS_URL,
|
||||
apiUrl: "192.168.3.13",
|
||||
apiProt: 30747
|
||||
}
|
||||
let client = null;
|
||||
// let client = new W3CWebSocket("ws://"+config.apiUrl+":"+config.apiProt+"/");
|
||||
|
||||
function Scenarios()
|
||||
{
|
||||
const [trackList, settrackList] = useState([]);
|
||||
const [entityTracklist, setEntityTracklist] = useState([]);
|
||||
|
||||
const [clientConnected, setclientConnected] = useState(false);
|
||||
// const [client, setclient] = useState(W3CWebSocket);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
React.useEffect(() => {
|
||||
client = new W3CWebSocket("ws://"+config.apiUrl+":"+config.apiProt+"/");
|
||||
|
||||
client.onopen = () => {
|
||||
console.log("Websocket Client for Debug Component");
|
||||
setclientConnected(true)
|
||||
};
|
||||
console.log(`initializing interval`);
|
||||
const interval = setInterval(() => {
|
||||
updateEntities();
|
||||
}, 1000);
|
||||
|
||||
return () => {
|
||||
console.log(`clearing interval`);
|
||||
clearInterval(interval);
|
||||
client.close();
|
||||
client = null;
|
||||
};
|
||||
|
||||
|
||||
}, []); // has no dependency - this will be called on-component-mount
|
||||
|
||||
useEffect(() => {
|
||||
client.onmessage = (message) => {
|
||||
if(message.data !== "null")
|
||||
{
|
||||
|
||||
// console.log(message.data);
|
||||
const dataFromServer = JSON.parse(message.data);
|
||||
|
||||
if(dataFromServer.Data === "COP")
|
||||
{
|
||||
settrackList(dataFromServer.Entities);
|
||||
}else
|
||||
{
|
||||
// console.log(dataFromServer);
|
||||
setEntityTracklist(dataFromServer)
|
||||
}
|
||||
|
||||
}
|
||||
else{
|
||||
console.log(message);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function updateEntities()
|
||||
{
|
||||
// var msg =
|
||||
// {
|
||||
// Type: "Request",
|
||||
// Data: "COP"
|
||||
|
||||
// }
|
||||
|
||||
client.send(getCOP());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
const sendSampleMessage = () =>
|
||||
{
|
||||
var msg =
|
||||
{
|
||||
Data: "TEST",
|
||||
Type: "Save",
|
||||
}
|
||||
console.log(msg);
|
||||
client.send(JSON.stringify(msg));
|
||||
|
||||
}
|
||||
|
||||
const startSampleScenario = () =>
|
||||
{
|
||||
|
||||
client.send(loadAutoraster());
|
||||
|
||||
}
|
||||
|
||||
|
||||
return(
|
||||
<>
|
||||
{/* <div><button onClick={sendSampleMessage}> Save Scenario</button></div>
|
||||
<div><button onClick={startSampleScenario}> Sample Scenario</button></div> */}
|
||||
<div className="Container">
|
||||
|
||||
<div className="InfoPane" >
|
||||
<p>Debug</p>
|
||||
<PerceivedTruth Client={client} EntityTracklist={entityTracklist} Tracklist= {trackList} />
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</>
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
export default Scenarios;
|
||||
9
webapp/src/components/Debug/Debug.scss
Normal file
9
webapp/src/components/Debug/Debug.scss
Normal file
@@ -0,0 +1,9 @@
|
||||
.Container
|
||||
{
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.InfoPane{
|
||||
width: 100%;
|
||||
padding-left: 1rem
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
import { useLeafletContext } from '@react-leaflet/core'
|
||||
import { MapContainer, TileLayer, Marker,Tooltip} from 'react-leaflet'
|
||||
|
||||
import L, { Icon, icon } from 'leaflet'
|
||||
import { useEffect, useState,useRef, useCallback,useMemo } from 'react'
|
||||
|
||||
import "./map.scss"
|
||||
|
||||
import { OwnShipIcon, createIcon } from '../../../../SimControl/components/OpenSeaMap/icon'
|
||||
|
||||
|
||||
|
||||
|
||||
const zoom = 9
|
||||
|
||||
function DisplayPosition({ map,center }) {
|
||||
const [position, setPosition] = useState(() => map.getCenter())
|
||||
|
||||
// const onClick = useCallback(() => {
|
||||
// map.setView(center, zoom)
|
||||
// }, [map])
|
||||
|
||||
const onMove = useCallback(() => {
|
||||
|
||||
setPosition(map.getCenter())
|
||||
}, [map])
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
map.setView(center, zoom)
|
||||
|
||||
|
||||
}, [center, map])
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
map.on('move', onMove)
|
||||
return () => {
|
||||
map.off('move', onMove)
|
||||
}
|
||||
}, [map, onMove])
|
||||
|
||||
return (
|
||||
<p>
|
||||
latitude: {position.lat.toFixed(4)}, longitude: {position.lng.toFixed(4)}{' '}
|
||||
{/* <button onClick={onClick}>reset</button> */}
|
||||
</p>
|
||||
)
|
||||
}
|
||||
|
||||
function MyMap({center,Tracklist}) {
|
||||
const [map, setMap] = useState(null)
|
||||
const [mapcenter, setMapcenter] = useState([51.505, -0.09])
|
||||
const [isFocused, setIsFocused] = useState(false)
|
||||
const [trackList,setTracklist] = useState([])
|
||||
|
||||
// const OwnShipIcon = L.icon({
|
||||
// iconUrl: 'Own_Ship.svg',
|
||||
|
||||
// iconSize: [50, 50], // size of the icon
|
||||
|
||||
// });
|
||||
|
||||
useEffect(() => {
|
||||
// console.log(center);
|
||||
if(center.length !== 0)
|
||||
{
|
||||
setMapcenter(center);
|
||||
setIsFocused(true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}, [center]);
|
||||
|
||||
useEffect(() => {
|
||||
// console.log(Tracklist);
|
||||
// makeList(Tracklist.Tracks)
|
||||
var tracks = Tracklist.Tracks
|
||||
|
||||
var list = [];
|
||||
// var Symbol = {
|
||||
// ID: "1234",
|
||||
// Name:"Own Ship",
|
||||
// Position: mapcenter ,
|
||||
// IconData: OwnShipIcon,
|
||||
// }
|
||||
// list.push(Symbol);
|
||||
// setTracklist(list);
|
||||
|
||||
if(tracks === undefined)
|
||||
{
|
||||
return;
|
||||
}
|
||||
tracks.forEach(element => {
|
||||
console.log(element)
|
||||
|
||||
var Symbol = {
|
||||
ID: element.ID,
|
||||
Name:element.Name,
|
||||
Position: [element.Position[0], element.Position[1]] ,
|
||||
IconData: createIcon(element.Type, element.Side),
|
||||
}
|
||||
|
||||
list.push(Symbol);
|
||||
|
||||
|
||||
});
|
||||
// console.log(list);
|
||||
setTracklist(list);
|
||||
|
||||
|
||||
|
||||
}, [Tracklist, mapcenter]);
|
||||
|
||||
|
||||
|
||||
// function makeList(tracks)
|
||||
// {
|
||||
|
||||
|
||||
// }
|
||||
|
||||
|
||||
function makeIcons()
|
||||
{
|
||||
if(trackList === undefined)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var list =[];
|
||||
trackList.forEach(element => {
|
||||
list.push(
|
||||
<Marker name={element.Name} key={element.ID} icon={element.IconData} position={element.Position} >
|
||||
<Tooltip direction='bottom' offset={[0,10]} opacity={1} permanent>
|
||||
<span>{element.Name}</span>
|
||||
</Tooltip>
|
||||
</Marker>)
|
||||
|
||||
})
|
||||
|
||||
return(
|
||||
list
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
const displayMap = useMemo(
|
||||
() => (
|
||||
<MapContainer
|
||||
center={mapcenter}
|
||||
zoom={zoom}
|
||||
attributionControl={false}
|
||||
// scrollWheelZoom={false}
|
||||
ref={setMap}>
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||
/>
|
||||
|
||||
{isFocused ? <Marker icon={OwnShipIcon} position={mapcenter} >
|
||||
<Tooltip direction='bottom' offset={[0,13]} opacity={1} permanent>
|
||||
<span>{"Own Ship"}</span>
|
||||
</Tooltip>
|
||||
</Marker> :null }
|
||||
{ makeIcons()}
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
</MapContainer>
|
||||
),
|
||||
[isFocused, mapcenter, trackList],
|
||||
)
|
||||
|
||||
return (
|
||||
<div className='Smallapmap'>
|
||||
{map ? <DisplayPosition map={map} center={mapcenter} /> : null}
|
||||
{displayMap }
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default MyMap;
|
||||
@@ -0,0 +1,9 @@
|
||||
.Smallapmap {
|
||||
// display: flex;
|
||||
// padding-top: 10px;
|
||||
height: 500px;
|
||||
width: 100%;
|
||||
// padding-left: 20%;
|
||||
display: inline-flex;
|
||||
// height: 80%;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
.App {
|
||||
display: flex;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
height: 40vmin;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.App-logo {
|
||||
animation: App-logo-spin infinite 20s linear;
|
||||
}
|
||||
}
|
||||
|
||||
.App-header {
|
||||
background-color: #282c34;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: calc(10px + 2vmin);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.App-link {
|
||||
color: #61dafb;
|
||||
}
|
||||
|
||||
@keyframes App-logo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.leaflet-container {
|
||||
width: 70vw;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
box-sizing: border-box;
|
||||
padding: 2em;
|
||||
width: 30vw;
|
||||
}
|
||||
|
||||
.sidebar h2,
|
||||
.sidebar p,
|
||||
.sidebar ul {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.sidebar h2 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.sidebar button {
|
||||
width: 100%;
|
||||
font-weight: bold;
|
||||
padding: .8em 1em;
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { getWSTestMessage ,getTracklist } from '../../../api/APICalls';
|
||||
import MyMap from "./map/map.jsx"
|
||||
|
||||
import "./perceivedTruth.scss"
|
||||
import TrackList from './tracklist/tracklist.jsx';
|
||||
|
||||
|
||||
function PerceivedTruth(props)
|
||||
{
|
||||
|
||||
const [selectedOption, setSelectedOption] = useState('option1')
|
||||
const [selectedOptionFull, setSelectedOptionFull] = useState({
|
||||
ID : null,
|
||||
Label:"",
|
||||
Position: []
|
||||
})
|
||||
|
||||
|
||||
const [selectOptions, setSelectOptions] = useState([])
|
||||
|
||||
const [trackList, settrackList] = useState([]);
|
||||
const [client, setclient] = useState()
|
||||
|
||||
const handleSubmit = (event) => {
|
||||
if(selectedOption !== "option1" && selectedOption !== "" )
|
||||
{
|
||||
|
||||
let updatedValue = getAttributesForID(selectedOption);
|
||||
|
||||
setSelectedOptionFull(selectedOptionFull => ({
|
||||
...selectedOptionFull,
|
||||
...updatedValue
|
||||
}));
|
||||
|
||||
client.send(getTracklist(selectedOption));
|
||||
event.preventDefault()
|
||||
console.log(`Submitted selected option: ${selectedOption}`)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function getAttributesForID(ID)
|
||||
{
|
||||
let attributes = {
|
||||
ID: undefined,
|
||||
Name: "",
|
||||
Position : []
|
||||
|
||||
};
|
||||
|
||||
selectOptions.forEach(element => {
|
||||
// console.log(element);
|
||||
|
||||
if(element.value === ID)
|
||||
{
|
||||
attributes.ID = ID;
|
||||
attributes.Name = element.label;
|
||||
attributes.Position = element.position;
|
||||
}
|
||||
})
|
||||
return attributes;
|
||||
}
|
||||
|
||||
function prepareTracklistForSelect(Tracklist)
|
||||
{
|
||||
if(Tracklist!== undefined)
|
||||
{
|
||||
var options = [];
|
||||
Tracklist.forEach(element => {
|
||||
|
||||
var item =
|
||||
{
|
||||
value : element.id,
|
||||
label : element.Name,
|
||||
position: element.Position
|
||||
|
||||
};
|
||||
|
||||
options.push(item);
|
||||
});
|
||||
|
||||
setSelectOptions(options);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
//Runs on the first render
|
||||
//And any time any dependency value changes
|
||||
console.log(props.EntityTracklist);
|
||||
setclient(props.Client);
|
||||
settrackList(props.Tracklist);
|
||||
prepareTracklistForSelect(trackList);
|
||||
|
||||
|
||||
}, [props, trackList]);
|
||||
|
||||
|
||||
|
||||
return(
|
||||
<div className='box'>
|
||||
<div className='EntityTracklist'>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<label htmlFor="my-select">Select Track:</label>
|
||||
<select
|
||||
id="my-select"
|
||||
value={selectedOption}
|
||||
onChange={(event) => setSelectedOption(event.target.value)}
|
||||
>
|
||||
<option> </option>
|
||||
{selectOptions.map((option, index) => (
|
||||
<option key={index} value={option.value} label={option.label} />
|
||||
))}
|
||||
</select>
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
|
||||
<p>{ selectedOptionFull.Label}</p>
|
||||
|
||||
<TrackList Tracklist ={props.EntityTracklist} />
|
||||
|
||||
</div>
|
||||
<div className='SideMap'>
|
||||
<MyMap center={selectedOptionFull.Position} Tracklist ={props.EntityTracklist} />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
)}
|
||||
export default PerceivedTruth;
|
||||
@@ -0,0 +1,14 @@
|
||||
.box{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
.EntityTracklist
|
||||
{
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.SideMap{
|
||||
width: 40%;
|
||||
justify-content: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import "./tracklist.scss"
|
||||
|
||||
import round from "../../../../Utils.jsx"
|
||||
|
||||
function TrackList(props)
|
||||
{
|
||||
const [tracklist, setTracklist] = useState(Array)
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
setTracklist(Array);
|
||||
// console.log(props)
|
||||
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
|
||||
if(props.Tracklist.Tracks !== undefined)
|
||||
{
|
||||
setTracklist(props.Tracklist.Tracks);
|
||||
|
||||
}
|
||||
// console.log(props)
|
||||
|
||||
}, [props]);
|
||||
|
||||
function MakeSensorList(props)
|
||||
{
|
||||
if(props === undefined)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var list = [];
|
||||
props.Sensors.forEach(element => {
|
||||
list.push(<span> {element.Name} Range: {element.Range} NM </span>)
|
||||
|
||||
});
|
||||
|
||||
return(list);
|
||||
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div class="divTable">
|
||||
<div class="divTableBody">
|
||||
<div class="divTableRow">
|
||||
<div class="divTableCell">NR</div>
|
||||
<div class="divTableCell">ID</div>
|
||||
<div class="divTableCell">Name</div>
|
||||
<div class="divTableCell">Position</div>
|
||||
<div class="divTableCell">Bearing</div>
|
||||
<div class="divTableCell">Range</div>
|
||||
<div class="divTableCell">Threat</div>
|
||||
<div class="divTableCell">Sensors</div>
|
||||
<div class="divTableCell">Status</div>
|
||||
</div>
|
||||
{/* {<MakeRow />} */}
|
||||
|
||||
{
|
||||
tracklist.map( (elem,index) => {
|
||||
if(elem.Position !== undefined)
|
||||
{
|
||||
// console.log(elem)
|
||||
|
||||
return(
|
||||
<div class="divTableRow">
|
||||
|
||||
<div class="divTableCell">{index}</div>
|
||||
<div class="divTableCell">{elem.ID}</div>
|
||||
<div class="divTableCell">{elem.Name}</div>
|
||||
<div class="divTableCell">{round(elem.Position[0],4)}, {round(elem.Position[1],4)}</div>
|
||||
<div class="divTableCell">{round(elem.Bearing,2)}</div>
|
||||
<div class="divTableCell">{round(elem.Distance,2)}</div>
|
||||
<div class="divTableCell">{elem.Threat}</div>
|
||||
<div class="divTableCell">{}</div>
|
||||
<div class="divTableCell">{elem.Status}</div>
|
||||
|
||||
{/* <div class="divTableCell">{MakeSensorList(elem) }</div> */}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
)}
|
||||
|
||||
export default TrackList;
|
||||
@@ -0,0 +1,30 @@
|
||||
/* DivTable.com */
|
||||
.divTable{
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
.divTableRow {
|
||||
display: table-row;
|
||||
}
|
||||
.divTableHeading {
|
||||
background-color: #EEE;
|
||||
display: table-header-group;
|
||||
}
|
||||
.divTableCell, .divTableHead {
|
||||
border: 1px solid #999999;
|
||||
display: table-cell;
|
||||
padding: 3px 10px;
|
||||
}
|
||||
.divTableHeading {
|
||||
background-color: #EEE;
|
||||
display: table-header-group;
|
||||
font-weight: bold;
|
||||
}
|
||||
.divTableFoot {
|
||||
background-color: #EEE;
|
||||
display: table-footer-group;
|
||||
font-weight: bold;
|
||||
}
|
||||
.divTableBody {
|
||||
display: table-row-group;
|
||||
}
|
||||
3
webapp/src/components/Debug/index.js
Normal file
3
webapp/src/components/Debug/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import Debug from "./Debug.jsx";
|
||||
|
||||
export default Debug;
|
||||
12
webapp/src/components/Gateway/Gateway.jsx
Normal file
12
webapp/src/components/Gateway/Gateway.jsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import React from "react";
|
||||
|
||||
|
||||
function Gateway()
|
||||
{
|
||||
return(
|
||||
<p>Gateway</p>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
export default Gateway;
|
||||
3
webapp/src/components/Gateway/index.js
Normal file
3
webapp/src/components/Gateway/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import Gateway from "./Gateway.jsx";
|
||||
|
||||
export default Gateway;
|
||||
@@ -1,10 +1,40 @@
|
||||
import React from "react";
|
||||
import Container from 'react-bootstrap/Container';
|
||||
import Nav from 'react-bootstrap/Nav';
|
||||
import Navbar from 'react-bootstrap/Navbar';
|
||||
import "./header.scss";
|
||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||
|
||||
function Header() {
|
||||
return(
|
||||
<Navbar expand="lg" bg="secondary">
|
||||
|
||||
<Container fluid >
|
||||
<Navbar.Brand href="/"><h2>Cloud Simulator</h2></Navbar.Brand>
|
||||
<Navbar.Toggle aria-controls="navbarScroll" />
|
||||
<Navbar.Collapse id="navbarScroll">
|
||||
<Nav
|
||||
className="me-auto my-2 my-lg-0"
|
||||
style={{ maxHeight: '100px' }}
|
||||
navbarScroll
|
||||
>
|
||||
<Nav.Link href="debug">Debug</Nav.Link>
|
||||
|
||||
<Nav.Link href="scenarios">Scenarios</Nav.Link>
|
||||
<Nav.Link href="database">Database</Nav.Link>
|
||||
<Nav.Link href="gateway">Gateway</Nav.Link>
|
||||
<Nav.Link href="settings">Settings</Nav.Link>
|
||||
|
||||
|
||||
|
||||
</Nav>
|
||||
</Navbar.Collapse>
|
||||
</Container>
|
||||
</Navbar>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const Header = () => (
|
||||
<div className="header">
|
||||
<font className="caption">Cloud Simulator</font>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default Header;
|
||||
|
||||
@@ -1,211 +0,0 @@
|
||||
|
||||
// import { useMapEvents } from 'react-leaflet/hooks'
|
||||
import React, { Component } from "react";
|
||||
import { MapContainer, TileLayer,Marker, Popup, Tooltip,useMapEvents,contextmenu } from 'react-leaflet'
|
||||
import { friend,Hostile, iconShip,createIcon } from "./icon";
|
||||
import "./OpenSeaMap.scss";
|
||||
import {w3cwebsocket as W3CWebSocket} from "websocket";
|
||||
import ContainerDimensions from 'react-container-dimensions';
|
||||
import {} from "leaflet-contextmenu";
|
||||
|
||||
|
||||
class OpenSeaMap extends Component {
|
||||
|
||||
state = {
|
||||
EntityOnFocus: undefined,
|
||||
}
|
||||
updateDimensions() {
|
||||
const height = window.innerWidth >= 950 ? window.innerHeight : 400
|
||||
this.setState({ height: height })
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.updateDimensions()
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener("resize", this.updateDimensions.bind(this))
|
||||
console.log(this.state.EntityOnFocus);
|
||||
|
||||
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener("resize", this.updateDimensions.bind(this))
|
||||
}
|
||||
|
||||
|
||||
handleClick(e)
|
||||
{
|
||||
// console.log(e.target)
|
||||
// this.setState({ currentPos: e.latlng });
|
||||
// console.log(e.latlng);
|
||||
|
||||
// console.log("hello world");
|
||||
}
|
||||
|
||||
|
||||
|
||||
makeIcon(index, entity,props,state)
|
||||
{
|
||||
var isOnFocus = false;
|
||||
if(this.state.EntityOnFocus !== undefined){
|
||||
// console.log(entity.id+ " " , this.state.EntityOnFocus);
|
||||
|
||||
if(entity.id === this.state.EntityOnFocus.EntityID)
|
||||
{
|
||||
isOnFocus = true
|
||||
// if(this.state.EntityOnFocus.NewPos !== undefined)
|
||||
// {
|
||||
// entity.pos = this.state.EntityOnFocus.NewPos;
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
var icon;
|
||||
icon = createIcon(entity.Type,entity.Side)
|
||||
return (
|
||||
<Marker name={entity.Name} key={index} icon={icon} position={entity.Position} data={entity.id}
|
||||
draggable={isOnFocus? true : false}
|
||||
contextmenu={true}
|
||||
contextmenuWidth={140}
|
||||
|
||||
contextmenuItems={[{
|
||||
text:"Edit",
|
||||
index:0,
|
||||
callback: function() {
|
||||
// this.setState({
|
||||
// EntityOnFocus:entity.id
|
||||
// })
|
||||
var Ent = {
|
||||
EntityID : entity.id,
|
||||
NewPos : undefined
|
||||
}
|
||||
state.EntityOnFocus = Ent;
|
||||
props.setEntityOnFocus(Ent)
|
||||
// console.log(state.EntityOnFocus);
|
||||
}
|
||||
}, {
|
||||
text:"Delete",
|
||||
// separator: true,
|
||||
index: 1
|
||||
}, {
|
||||
text:"Exit",
|
||||
callback: function()
|
||||
{
|
||||
state.EntityOnFocus = undefined;
|
||||
props.setEntityOnFocus(undefined);
|
||||
},
|
||||
// separator: true,
|
||||
index: 2
|
||||
}]}
|
||||
// contextmenuItems: [{
|
||||
// text: 'Circle 1',
|
||||
// callback: function() {
|
||||
// circleContextClick(circle1);
|
||||
// }
|
||||
// }]
|
||||
eventHandlers={{
|
||||
click: (e) => {
|
||||
// console.log(e.target);
|
||||
// var Ent = {
|
||||
// EntityID : e.target.options.data,
|
||||
// NewPos : undefined
|
||||
|
||||
// }
|
||||
// this.setState((state) =>({
|
||||
// EntityOnFocus: Ent
|
||||
// }))
|
||||
// this.props.setEntityOnFocus(Ent);
|
||||
|
||||
// this.props.setEntityOnFocus(e.target.options.data);
|
||||
},
|
||||
dragend: (e) =>
|
||||
{
|
||||
var Ent = {
|
||||
EntityID : e.target.options.data,
|
||||
NewPos : [e.target._latlng.lat,e.target._latlng.lng],
|
||||
dragged: true
|
||||
|
||||
}
|
||||
this.setState((state) =>({
|
||||
EntityOnFocus: Ent
|
||||
}))
|
||||
|
||||
this.props.setEntityOnFocus(Ent);
|
||||
// console.log(e.target);
|
||||
|
||||
// console.log(e.target._latlng);
|
||||
|
||||
},
|
||||
// contextmenu: (e) =>
|
||||
// {
|
||||
// console.log("right click");
|
||||
// }
|
||||
}}
|
||||
// eventHandlers={this.MarkerEventHandler}
|
||||
>
|
||||
|
||||
{/* <Popup>
|
||||
Omu-Aran the Head Post of Igbomina land,
|
||||
is a town in the Nigerian state of Kwara.
|
||||
It originated from Ife and currently the local
|
||||
government headquarters of Irepodun local government.
|
||||
</Popup> */}
|
||||
<Tooltip direction='bottom' offset={[0,13]} opacity={1} permanent>
|
||||
<span>{entity.Name}</span>
|
||||
</Tooltip>
|
||||
</Marker>
|
||||
);
|
||||
}
|
||||
|
||||
setPos(props)
|
||||
{
|
||||
console.log(props);
|
||||
|
||||
this.props.setFocusPosition([1,2])
|
||||
}
|
||||
|
||||
render() {
|
||||
const LocationFinderDummy = (props) => {
|
||||
const map = useMapEvents({
|
||||
click(e) {
|
||||
|
||||
props.props.setFocusPosition(e.latlng)
|
||||
// console.log(e.latlng);
|
||||
},
|
||||
});
|
||||
return null;
|
||||
};
|
||||
// const positions = this.props.Positions.map((pos, index) => (
|
||||
// <Marker name={"test"} key={index} position={pos.position} icon= {ship} />
|
||||
// ));
|
||||
|
||||
return (
|
||||
|
||||
<div className='map' style={{ height: this.state.height }} >
|
||||
<MapContainer center={[54, 11]} zoom={6} scrollWheelZoom={true} contextmenu={false}
|
||||
|
||||
>
|
||||
<LocationFinderDummy props ={this.props} />
|
||||
|
||||
<TileLayer
|
||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
|
||||
<TileLayer
|
||||
url="https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png" />
|
||||
{/* {positions} */}
|
||||
{this.props.Entities.map((pos, index) => (
|
||||
this.makeIcon(index,pos,this.props,this.state)
|
||||
))}
|
||||
</MapContainer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export default OpenSeaMap;
|
||||
57
webapp/src/components/Scenarios/Scenarios.jsx
Normal file
57
webapp/src/components/Scenarios/Scenarios.jsx
Normal file
@@ -0,0 +1,57 @@
|
||||
import React from "react";
|
||||
import {w3cwebsocket as W3CWebSocket} from "websocket"
|
||||
|
||||
|
||||
function Scenarios()
|
||||
{
|
||||
const config = {
|
||||
// apiUrl: process.env.REACT_APP_WEBAPP_WS_URL,
|
||||
apiUrl: "192.168.3.13",
|
||||
apiProt: 30747
|
||||
}
|
||||
const client = new W3CWebSocket("ws://"+config.apiUrl+":"+config.apiProt+"/");
|
||||
|
||||
client.onmessage = (message) => {
|
||||
console.log(message);
|
||||
|
||||
}
|
||||
|
||||
|
||||
const sendSampleMessage = () =>
|
||||
{
|
||||
var msg =
|
||||
{
|
||||
Data: "TEST",
|
||||
Type: "Save",
|
||||
}
|
||||
console.log(msg);
|
||||
client.send(JSON.stringify(msg));
|
||||
|
||||
}
|
||||
|
||||
const startSampleScenario = () =>
|
||||
{
|
||||
var msg =
|
||||
{
|
||||
Data: "Scenario",
|
||||
Type: "AutoRaster",
|
||||
}
|
||||
console.log(msg);
|
||||
client.send(JSON.stringify(msg));
|
||||
|
||||
}
|
||||
|
||||
|
||||
return(
|
||||
<>
|
||||
<p>Scenarios</p>
|
||||
<div><button onClick={sendSampleMessage}> Save Scenario</button></div>
|
||||
<div><button onClick={startSampleScenario}> Sample Scenario</button></div>
|
||||
|
||||
</>
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
export default Scenarios;
|
||||
3
webapp/src/components/Scenarios/index.js
Normal file
3
webapp/src/components/Scenarios/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import Scenarios from "./Scenarios.jsx";
|
||||
|
||||
export default Scenarios;
|
||||
12
webapp/src/components/Settings/Settings.jsx
Normal file
12
webapp/src/components/Settings/Settings.jsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import React from "react";
|
||||
|
||||
|
||||
function Settings()
|
||||
{
|
||||
return(
|
||||
<p>Settings</p>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
export default Settings;
|
||||
3
webapp/src/components/Settings/index.js
Normal file
3
webapp/src/components/Settings/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import Settings from "./Settings.jsx";
|
||||
|
||||
export default Settings;
|
||||
224
webapp/src/components/SimControl/SimControl.jsx
Normal file
224
webapp/src/components/SimControl/SimControl.jsx
Normal file
@@ -0,0 +1,224 @@
|
||||
import React, { Component } from "react";
|
||||
import {w3cwebsocket as W3CWebSocket} from "websocket"
|
||||
// import Header from './components/Header';
|
||||
import OpenSeaMap from "./components/OpenSeaMap/OpenSeaMap";
|
||||
import EntityControl from './components/EntityControl/EntityControl';
|
||||
import Tracklist from './components/Tracklist'
|
||||
import Equipment from './components/EntityControl/components/Equipment'
|
||||
|
||||
import Tab from 'react-bootstrap/Tab';
|
||||
import Tabs from 'react-bootstrap/Tabs';
|
||||
|
||||
import TrackListClass from "./Tracklist.tsx";
|
||||
import Track from "./Track.tsx";
|
||||
|
||||
import './SimControl.scss'
|
||||
import EntityTrackList from "./components/EntityTrackList";
|
||||
import { getCOP, getWSTestMessage } from "../api/APICalls";
|
||||
|
||||
|
||||
|
||||
|
||||
const config = {
|
||||
// apiUrl: process.env.REACT_APP_WEBAPP_WS_URL,
|
||||
apiUrl: "192.168.3.13",
|
||||
apiProt: 30747
|
||||
}
|
||||
const client = new W3CWebSocket("ws://"+config.apiUrl+":"+config.apiProt+"/");
|
||||
|
||||
|
||||
|
||||
class SimControl extends Component {
|
||||
state = {
|
||||
Entities: [],
|
||||
EntityOnFocus: undefined,
|
||||
PositionClicked: undefined,
|
||||
TrackList_: new TrackListClass()
|
||||
}
|
||||
|
||||
|
||||
componentWillUnmount()
|
||||
{
|
||||
// client.close();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
console.log(config.apiUrl);
|
||||
|
||||
client.onopen = () => {
|
||||
console.log("Websocket Client for Map Connected");
|
||||
};
|
||||
|
||||
client.onmessage = (message) => {
|
||||
const dataFromServer = JSON.parse(message.data);
|
||||
// console.log('reply: ', dataFromServer);
|
||||
|
||||
|
||||
if(dataFromServer.Data === "COP" && dataFromServer.Entities !== undefined )
|
||||
{
|
||||
var idsFromWs = [];
|
||||
dataFromServer.Entities.forEach((elementFromWS, indexWS) => {
|
||||
idsFromWs.push(elementFromWS.id);
|
||||
});
|
||||
this.state.TrackList_.checkifTrackIsStillSended(idsFromWs);
|
||||
// this.state.TrackList_.deleteAll();
|
||||
|
||||
var allTracks = this.state.TrackList_.getArrayOfKeys();
|
||||
dataFromServer.Entities.forEach((elementFromWS, indexWS) => {
|
||||
|
||||
// console.log(elementFromWS);
|
||||
if(this.state.TrackList_.isInList(elementFromWS.id))
|
||||
{
|
||||
this.state.TrackList_.updateTrack(elementFromWS);
|
||||
|
||||
}else{
|
||||
|
||||
this.state.TrackList_.addTrack(structuredClone(new Track(elementFromWS)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
// console.log(this.state.TrackList_.getSize());
|
||||
this.setState((state) => ({
|
||||
// // Entities: structuredClone(dataFromServer.Entities)
|
||||
// Entities: structuredClone(tmp)
|
||||
|
||||
}))
|
||||
}else if(dataFromServer.Entities === undefined)
|
||||
{
|
||||
this.state.TrackList_.deleteAll();
|
||||
console.log("delting all");
|
||||
console.log(this.state.TrackList_.getSize());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// interval for updates
|
||||
setInterval(() => {
|
||||
this.updateEntities();
|
||||
}, 2000);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
isStored(id) {
|
||||
var found = false;
|
||||
this.state.Entities.forEach((elementStored, indexStore) => {
|
||||
if (id === elementStored.id)
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
});
|
||||
|
||||
return found;
|
||||
|
||||
}
|
||||
|
||||
|
||||
updateEntities()
|
||||
{
|
||||
// var msg =
|
||||
// {
|
||||
// Type: "Request",
|
||||
// Data: "COP"
|
||||
|
||||
// }
|
||||
client.send(getCOP());
|
||||
}
|
||||
|
||||
getEntityFromID(Entities, SelectedEntity)
|
||||
{
|
||||
// console.log(Entities);
|
||||
}
|
||||
|
||||
setEntityOnFocus(Entity)
|
||||
{
|
||||
console.log(Entity);
|
||||
this.setState({
|
||||
EntityOnFocus: structuredClone(this.state.TrackList_.getTrack(Entity))
|
||||
})
|
||||
|
||||
}
|
||||
resetEntityOnFocus()
|
||||
{
|
||||
if(this.state.EntityOnFocus !== undefined)
|
||||
{
|
||||
this.state.Entities.map((element ,index) => {
|
||||
if(element.id === this.state.EntityOnFocus.EntityID)
|
||||
{
|
||||
this.state.Entities[index].onFocus = false;
|
||||
}
|
||||
})
|
||||
console.log(this.state.Entities)
|
||||
this.setState({
|
||||
EntityOnFocus: undefined
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setFocusPosition(props)
|
||||
{
|
||||
|
||||
// console.log(props);
|
||||
this.setState({
|
||||
PositionClicked: props
|
||||
});
|
||||
}
|
||||
|
||||
Functions = {
|
||||
updateEntities: this.updateEntities.bind(this),
|
||||
resetEntityOnFocus: this.resetEntityOnFocus.bind(this),
|
||||
PositionClicked: this.setFocusPosition.bind(this)
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
|
||||
<div className="Content">
|
||||
|
||||
{/* <Controls TrackList = {this.state.TrackList_} Functions= {this.Functions} Client= {client} Entities= {this.state.Entities} updateEntities = {this.updateEntities} EntityOnFocus = {this.state.EntityOnFocus} PositionClicked = {this.state.PositionClicked} /> */}
|
||||
<div className="controls">
|
||||
<Tracklist entities= {this.state.TrackList_} />
|
||||
<Tabs
|
||||
defaultActiveKey="home"
|
||||
transition={false}
|
||||
id="noanim-tab-example"
|
||||
className="mb-3"
|
||||
>
|
||||
<Tab eventKey="home" title="Home">
|
||||
<EntityControl
|
||||
Functions = {this.props.Functions}
|
||||
Client = { client }
|
||||
Entity = { this.state.EntityOnFocus}
|
||||
PositionClicked = {this.state.PositionClicked}
|
||||
/>
|
||||
</Tab>
|
||||
<Tab eventKey="Equipment" title="Equipment">
|
||||
<Equipment Entity ={this.state.EntityOnFocus} />
|
||||
</Tab>
|
||||
<Tab eventKey="internalTrack" title="internal Tracks">
|
||||
Internaltracklist
|
||||
</Tab>
|
||||
<Tab eventKey="orders" title="Orders">
|
||||
Orders
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
<OpenSeaMap Client = {client} TrackListMap = {this.state.TrackList_.getTracks()} TrackList = {this.state.TrackList_} setFocusPosition = {this.setFocusPosition.bind(this)} setEntityOnFocus = {this.setEntityOnFocus.bind(this)} />
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default SimControl;
|
||||
6
webapp/src/components/SimControl/SimControl.scss
Normal file
6
webapp/src/components/SimControl/SimControl.scss
Normal file
@@ -0,0 +1,6 @@
|
||||
.controls{
|
||||
/* display: flex; */
|
||||
width: 24%;
|
||||
float: left;
|
||||
min-width: 400px;
|
||||
}
|
||||
38
webapp/src/components/SimControl/Track.tsx
Normal file
38
webapp/src/components/SimControl/Track.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
class Track{
|
||||
Id : string;
|
||||
Name = String();
|
||||
Type = String();
|
||||
Side = String();
|
||||
Course = Number();
|
||||
Speed = Number();
|
||||
External = Boolean();
|
||||
Height = Number();
|
||||
Position = [Number(), Number()]
|
||||
isOnFucus = Boolean();
|
||||
isOnEdit = Boolean();
|
||||
|
||||
constructor(input)
|
||||
{
|
||||
if(input.id !== undefined)
|
||||
{
|
||||
this.Id = input.id;
|
||||
}else{
|
||||
return;
|
||||
}
|
||||
|
||||
this.Name = input.Name;
|
||||
this.Course = input.Course;
|
||||
this.Speed = input.Speed;
|
||||
this.External = input.External;
|
||||
this.Height = input.Height;
|
||||
this.Position = input.Position;
|
||||
this.Type = input.Type;
|
||||
this.Side = input.Side;
|
||||
this.isOnFucus = false;
|
||||
this.isOnEdit = false;
|
||||
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
export default Track
|
||||
118
webapp/src/components/SimControl/Tracklist.tsx
Normal file
118
webapp/src/components/SimControl/Tracklist.tsx
Normal file
@@ -0,0 +1,118 @@
|
||||
|
||||
import { ObjectType } from 'typescript';
|
||||
import Track from './Track'
|
||||
|
||||
|
||||
class TrackListCLass
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
this.trackMap = new Map<string, Track>();
|
||||
}
|
||||
|
||||
|
||||
trackMap: Map<string, Track> ;
|
||||
|
||||
|
||||
getTrack(id :string)
|
||||
{
|
||||
return this.trackMap.get(id);
|
||||
}
|
||||
|
||||
isInList(id :string)
|
||||
{
|
||||
return this.trackMap.has(id);
|
||||
}
|
||||
|
||||
addTrack(track :Track)
|
||||
{
|
||||
this.trackMap.set(track.Id,track);
|
||||
}
|
||||
|
||||
updateTrack(input: { id: string; Name: string; Course: number; Speed: number; External: boolean; Height: number; Position: number[]; Type: string; Side: string; })
|
||||
{
|
||||
|
||||
var Track = this.trackMap.get(input.id);
|
||||
if(Track === undefined)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(Track.isOnEdit === false)
|
||||
{
|
||||
Track.Name = input.Name;
|
||||
Track.Course = input.Course;
|
||||
Track.Speed = input.Speed;
|
||||
Track.External = input.External;
|
||||
Track.Height = input.Height;
|
||||
Track.Position = input.Position;
|
||||
Track.Type = input.Type;
|
||||
Track.Side = input.Side;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
getKeys()
|
||||
{
|
||||
return this.trackMap.keys;
|
||||
}
|
||||
getSize()
|
||||
{
|
||||
return this.trackMap.size;
|
||||
}
|
||||
|
||||
getArrayOfKeys()
|
||||
{
|
||||
var Tracks = new Array<string>();
|
||||
this.trackMap.forEach((val,index) =>
|
||||
Tracks.push(val.Id)
|
||||
)
|
||||
|
||||
|
||||
return Tracks;
|
||||
}
|
||||
|
||||
getTracks()
|
||||
{
|
||||
var Tracks = new Array<Track>();
|
||||
this.trackMap.forEach((val,index) =>
|
||||
Tracks.push(val)
|
||||
)
|
||||
|
||||
|
||||
return Tracks;
|
||||
}
|
||||
|
||||
|
||||
getTrackMap()
|
||||
{
|
||||
return this.trackMap;
|
||||
}
|
||||
|
||||
deteleTrack(id :string)
|
||||
{
|
||||
this.trackMap.delete(id);
|
||||
}
|
||||
|
||||
deleteAll()
|
||||
{
|
||||
this.trackMap.clear();
|
||||
}
|
||||
|
||||
checkifTrackIsStillSended(tracksFromWS: Array<string>)
|
||||
{
|
||||
this.trackMap.forEach((val,index) => {
|
||||
if(!tracksFromWS.includes(val.Id))
|
||||
{
|
||||
this.deteleTrack(val.Id);
|
||||
console.log("deleted: " + val.Id);
|
||||
};
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default TrackListCLass
|
||||
@@ -4,6 +4,7 @@ import { useForm, SubmitHandler } from "react-hook-form"
|
||||
import Form from 'react-bootstrap/Form';
|
||||
import FloatingLabel from 'react-bootstrap/FloatingLabel';
|
||||
import InputGroup from 'react-bootstrap/InputGroup';
|
||||
import round from "../../../Utils";
|
||||
|
||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||
|
||||
@@ -14,7 +15,8 @@ import './controls.css'
|
||||
|
||||
function EntityControl(props)
|
||||
{
|
||||
|
||||
const RoundPrecision = 2;
|
||||
const RoundPrecisionPosition = 5;
|
||||
|
||||
|
||||
const [Entity, setEntity] = useState(undefined);
|
||||
@@ -23,55 +25,98 @@ function EntityControl(props)
|
||||
const [PositionDragged, setPositionDragged] = useState(false);
|
||||
// const [Speed, setSpeed] = useState();
|
||||
|
||||
const [formData, setFormData] = useState({name: "",course: "" ,speed: 0,position: [0,0],height:0});
|
||||
const [formData, setFormData] = useState({name: "",course: 0 ,speed: 0,position: [0,0],height:0});
|
||||
|
||||
|
||||
|
||||
useEffect(() => { // Update the document title using the browser API document.title = `You clicked ${count} times`;
|
||||
// useEffect(() => { // Update the document title using the browser API document.title = `You clicked ${count} times`;
|
||||
|
||||
// console.log(props.Entity);
|
||||
// console.log(props.Entity);
|
||||
|
||||
if(props.Entity !== undefined)
|
||||
{
|
||||
console.log(props.Entity)
|
||||
if(Entity === undefined)
|
||||
{
|
||||
setEntity(props.Entity);
|
||||
setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position,height:props.Entity.Height })
|
||||
|
||||
}else if(Entity.id !== props.Entity.id)
|
||||
{
|
||||
setEntity(props.Entity);
|
||||
setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position,height:props.Entity.Height})
|
||||
|
||||
} else if(Entity.id === props.Entity.id && Entity.Position !== props.Entity.Position)
|
||||
{
|
||||
setFormData({...formData,position:props.Entity.Position,height:props.Entity.Height})
|
||||
setPositionDragged(true);
|
||||
// if(props.Entity !== undefined)
|
||||
// {
|
||||
// setEntity(Entity);
|
||||
// setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position,height:round(props.Entity.Height,RoundPrecision)})
|
||||
|
||||
|
||||
}
|
||||
// setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position})
|
||||
|
||||
}
|
||||
// // // console.log(props.Entity)
|
||||
// // if(Entity === undefined)
|
||||
// // {
|
||||
// // setEntity(props.Entity);
|
||||
// // setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position,height:round(props.Entity.Height,RoundPrecision) })
|
||||
|
||||
// // }else if(Entity.id !== props.Entity.id)
|
||||
// // {
|
||||
// // setEntity(props.Entity);
|
||||
// // setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position,height:round(props.Entity.Height,RoundPrecision)})
|
||||
// // console.log("new entity")
|
||||
// // } else if(Entity.id === props.Entity.id && Entity.Position !== props.Entity.Position)
|
||||
// // {
|
||||
// // setFormData({...formData,position:props.Entity.Position,height:round(props.Entity.Height,RoundPrecision)})
|
||||
// // setPositionDragged(true);
|
||||
// // console.log("dragged");
|
||||
|
||||
// // }
|
||||
// // setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position})
|
||||
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
},[props.Entity,props]);
|
||||
// },[Entity, props.Entity]);
|
||||
|
||||
useEffect(() => {
|
||||
if(props.PositionCliecked !== undefined)
|
||||
// console.log(props.Entity);
|
||||
|
||||
// console.log(Entity);
|
||||
if(props.Entity !== undefined)
|
||||
{
|
||||
console.log(props.PositionCliecked)
|
||||
var pos = [0,0];
|
||||
pos[0] = props.PositionCliecked.lat;
|
||||
pos[1] = props.PositionCliecked.lng
|
||||
setFormData({...formData,position:pos});
|
||||
setEntity(structuredClone(props.Entity));
|
||||
if(Entity === undefined)
|
||||
{
|
||||
setEntity(props.Entity);
|
||||
setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position,height:round(props.Entity.Height,RoundPrecision) })
|
||||
|
||||
}else if(Entity.Id !== props.Entity.Id)
|
||||
{
|
||||
setEntity(props.Entity);
|
||||
setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position,height:round(props.Entity.Height,RoundPrecision)})
|
||||
console.log("new entity")
|
||||
} else if(Entity.Id === props.Entity.Id && Entity.Position !== props.Entity.Position)
|
||||
{
|
||||
// setFormData({...formData,position:props.Entity.Position,height:round(props.Entity.Height,RoundPrecision)})
|
||||
setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position,height:round(props.Entity.Height,RoundPrecision)})
|
||||
|
||||
setPositionDragged(true);
|
||||
console.log("dragged");
|
||||
|
||||
}
|
||||
}else{
|
||||
console.log("reset");
|
||||
setFormData({name:"",course:"",speed:"",position:["",""],height:"" })
|
||||
setEntity(undefined);
|
||||
}
|
||||
|
||||
},[props.PositionCliecked])
|
||||
|
||||
},[props.Entity])
|
||||
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if(props.PositionClicked !== undefined)
|
||||
{
|
||||
// setEntity(undefined);
|
||||
// console.log(props.PositionClicked)
|
||||
var pos = [0,0];
|
||||
pos[0] = props.PositionClicked.lat;
|
||||
pos[1] = props.PositionClicked.lng
|
||||
setFormData({...formData,name:"",course:0,speed:0,position:pos});
|
||||
}
|
||||
|
||||
},[props.PositionClicked])
|
||||
|
||||
|
||||
|
||||
@@ -195,9 +240,9 @@ const handleClick = (e) => {
|
||||
{
|
||||
props.Entity.onFocus = undefined;
|
||||
}
|
||||
setFormData({name:'',course:'',speed:'',position:['','']})
|
||||
setFormData({name:'',course:0,speed:0,position:[0,0],height:0})
|
||||
setEntity(undefined)
|
||||
props.Functions.resetEntityOnFocus();
|
||||
// props.Functions.resetEntityOnFocus();
|
||||
|
||||
}
|
||||
|
||||
@@ -216,16 +261,15 @@ const handleClick = (e) => {
|
||||
}
|
||||
}
|
||||
|
||||
// const handleChange = (event) => {
|
||||
// const { name, value } = event.target;
|
||||
// setFormData((prevFormData) => ({ ...prevFormData, [name]: value }));
|
||||
// };
|
||||
|
||||
|
||||
|
||||
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
// console.log(e.target.data);
|
||||
// console.log(formData)
|
||||
console.log(Entity)
|
||||
// console.log(Entity)
|
||||
if(Entity === undefined)
|
||||
{
|
||||
var msg =
|
||||
@@ -235,8 +279,8 @@ const handleClick = (e) => {
|
||||
Name: formData.name,
|
||||
Speed: formData.speed.toString(),
|
||||
Course: formData.course.toString(),
|
||||
Position: formData.position,
|
||||
Height: formData.height,
|
||||
Position: [formData.position[0].toString(),formData.position[1].toString()],
|
||||
Height: formData.height.toString(),
|
||||
SetPosition: true
|
||||
|
||||
}
|
||||
@@ -254,11 +298,11 @@ const handleClick = (e) => {
|
||||
{
|
||||
Data: "Entity",
|
||||
Type: "Update",
|
||||
ID: Entity.id,
|
||||
ID: Entity.Id,
|
||||
Speed: formData.speed.toString(),
|
||||
Course: formData.course.toString(),
|
||||
Position: formData.position,
|
||||
Height: formData.height,
|
||||
Position: [formData.position[0].toString(),formData.position[1].toString()],
|
||||
Height: formData.height.toString(),
|
||||
SetPosition: setPos
|
||||
|
||||
}
|
||||
@@ -274,7 +318,7 @@ const handleClick = (e) => {
|
||||
return (
|
||||
|
||||
<div>
|
||||
<div><button onClick={ emptyForm}> New</button> </div>
|
||||
|
||||
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="ControlsComponent">
|
||||
@@ -320,6 +364,7 @@ const handleClick = (e) => {
|
||||
<InputGroup className="mb-3">
|
||||
<InputGroup.Text id="basic-addon1">Name</InputGroup.Text>
|
||||
<Form.Control
|
||||
required
|
||||
name="Name"
|
||||
placeholder="Name"
|
||||
aria-label="Name"
|
||||
@@ -353,14 +398,14 @@ const handleClick = (e) => {
|
||||
<div class="div7">
|
||||
<div class="input-group mb-3 NumberInputsGroup">
|
||||
<span class="input-group-text">Lat</span>
|
||||
<input className="ControlInput NumberInputs" name="Lat" type="text" onChange={handleInput} value={formData.position[0]} />
|
||||
<input className="ControlInput NumberInputs" name="Lat" type="text" onChange={handleInput} value={round(formData.position[0],RoundPrecisionPosition)} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="div8">
|
||||
<div class="input-group mb-3 NumberInputsGroup" >
|
||||
<span class="input-group-text">Lon</span>
|
||||
{/* <input className="ControlInput" name="Lat" readOnly={true} type="text" onClick={handleClick} value={formData.position[0]} /> */}
|
||||
<input className="ControlInput NumberInputs" name="Lon" readOnly={true} type="text" onClick={handleClick} onChange={handleInput} value={formData.position[1]}/>
|
||||
<input className="ControlInput NumberInputs" name="Lon" readOnly={true} type="text" onClick={handleClick} onChange={handleInput} value={round(formData.position[1],RoundPrecisionPosition)}/>
|
||||
</div>
|
||||
{/* <div className="flex">
|
||||
<div className="ControlHeader">Lon:</div>
|
||||
@@ -378,11 +423,17 @@ const handleClick = (e) => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div> <button type='submit'>Save</button> </div>
|
||||
<div className="TopButtons">
|
||||
<div><button onClick={ emptyForm}> New</button></div>
|
||||
<div><button type="button" onClick={resetForm}> Reset</button></div>
|
||||
<div><button type='submit'>Save</button> </div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</form>
|
||||
<button onClick={resetForm}> RESET</button>
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import React from "react"
|
||||
import {useState,useEffect, useRef} from 'react';
|
||||
|
||||
|
||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||
|
||||
|
||||
import './Equipment.css'
|
||||
|
||||
|
||||
|
||||
function Equipment(props)
|
||||
{
|
||||
|
||||
|
||||
|
||||
const [Entity, setEntity] = useState(undefined);
|
||||
const [EntitySelected, setEntitySelected] = useState(false)
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if(props.Entity !== undefined)
|
||||
{
|
||||
setEntity(props.Entity);
|
||||
setEntitySelected(true);
|
||||
}else
|
||||
{
|
||||
setEntitySelected(false);
|
||||
}
|
||||
|
||||
console.log(props)
|
||||
|
||||
|
||||
},[props.Entity])
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
|
||||
<div>
|
||||
<b>{EntitySelected ? '' : 'no Entity Selected'}</b>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Equipment;
|
||||
@@ -0,0 +1,3 @@
|
||||
import Equipment from "./Equipment";
|
||||
|
||||
export default Equipment;
|
||||
@@ -1,8 +1,3 @@
|
||||
.controls{
|
||||
/* display: flex; */
|
||||
width: 24%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.ControlsComponent{
|
||||
display: grid;
|
||||
@@ -56,20 +51,12 @@ float: left;
|
||||
display: contents;
|
||||
}
|
||||
|
||||
/* .parent {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-template-rows: repeat(3 2em);
|
||||
grid-column-gap: 0px;
|
||||
grid-row-gap: 0px;
|
||||
}
|
||||
|
||||
.div1 { grid-area: 1 / 1 / 2 / 3; }
|
||||
.div2 { grid-area: 2 / 1 / 3 / 2; }
|
||||
.div3 { grid-area: 2 / 2 / 3 / 3; }
|
||||
.div4 { grid-area: 3 / 2 / 4 / 3; }
|
||||
.div5 { grid-area: 3 / 1 / 4 / 2; } */
|
||||
|
||||
.TopButtons
|
||||
{
|
||||
width: 100%;
|
||||
justify-content: space-evenly;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.parent {
|
||||
display: grid;
|
||||
@@ -0,0 +1,100 @@
|
||||
import React from 'react';
|
||||
import './controls.css'
|
||||
// import { sendMsg } from '../api';
|
||||
import Tracklist from './Tracklist'
|
||||
import EntityControl from './EntityControl';
|
||||
import round from '../../../Utils';
|
||||
// import {w3cwebsocket as W3CWebSocket} from "websocket"
|
||||
import Tab from 'react-bootstrap/Tab';
|
||||
import Tabs from 'react-bootstrap/Tabs';
|
||||
import Track from '../../Track';
|
||||
|
||||
|
||||
class Controls extends React.Component
|
||||
{
|
||||
|
||||
state = {
|
||||
EntityOnFocus: undefined,
|
||||
}
|
||||
|
||||
|
||||
getEntityOnEdit(Entities)
|
||||
{
|
||||
// console.log(Entities.getTracks());
|
||||
// Entities.getTracks().map()
|
||||
var val = undefined;
|
||||
var array = Entities.getTracks();
|
||||
for (let index = 0; index < array.length; index++)
|
||||
{
|
||||
if(array[index].isOnEdit === true)
|
||||
{
|
||||
val = array[index];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
saveScenario(e)
|
||||
{
|
||||
var msg =
|
||||
{
|
||||
Data: "Scenario",
|
||||
Type: "Save",
|
||||
}
|
||||
|
||||
this.props.Client.send(JSON.stringify(msg))
|
||||
console.log("save scenario")
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
render() {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// console.log(getEntityFromID(this.props.Entities,this.props.EntityOnFocus));
|
||||
return (
|
||||
<div className="controls">
|
||||
<Tracklist entities= {this.props.TrackList} />
|
||||
<br />
|
||||
<div><button onClick={ this.saveScenario}> Save Scenario</button></div>
|
||||
|
||||
{/* <Tabs
|
||||
defaultActiveKey="home"
|
||||
transition={false}
|
||||
id="noanim-tab-example"
|
||||
className="mb-3"
|
||||
>
|
||||
<Tab eventKey="home" title="Home">
|
||||
<EntityControl
|
||||
Functions = {this.props.Functions}
|
||||
Client = { this.props.Client }
|
||||
TrackList = { this.props.TrackList}
|
||||
PositionCliecked = {this.props.PositionClicked}
|
||||
/>
|
||||
</Tab>
|
||||
<Tab eventKey="internalTrack" title="Internaltrack">
|
||||
Internaltracklist
|
||||
</Tab>
|
||||
<Tab eventKey="orders" title="Orders">
|
||||
Orders
|
||||
</Tab>
|
||||
</Tabs> */}
|
||||
<div className="controls">
|
||||
{/* <button onClick={this.props.updateEntities}>update</button> */}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Controls;
|
||||
@@ -0,0 +1,3 @@
|
||||
import EntityControl from "../EntityControl/EntityControl";
|
||||
|
||||
export default EntityControl;
|
||||
@@ -0,0 +1,136 @@
|
||||
import { useEffect } from "react";
|
||||
import { useState } from "react";
|
||||
|
||||
import { useInterval } from 'usehooks-ts'
|
||||
|
||||
const config = {
|
||||
// apiUrl: process.env.REACT_APP_WEBAPP_WS_URL,
|
||||
apiUrl: "192.168.3.13",
|
||||
apiProt: 30747
|
||||
}
|
||||
const client = new WebSocket("ws://"+config.apiUrl+":"+config.apiProt+"/");
|
||||
|
||||
|
||||
|
||||
function EntityTrackList( props)
|
||||
{
|
||||
|
||||
const [Entity, setEntity] = useState(undefined);
|
||||
// const [client, setclient] = useState(new WebSocket("ws://"+config.apiUrl+":"+config.apiProt+"/"));
|
||||
|
||||
// const client = new WebSocket("ws://"+config.apiUrl+":"+config.apiProt+"/");
|
||||
const [TrackList, setTrackList] = useState([]);
|
||||
client.onopen =() =>{
|
||||
console.log("ws client for tracklist is connected");
|
||||
// var msg =
|
||||
// {
|
||||
// Data: "COP",
|
||||
// Type: "EntityTrackList"
|
||||
|
||||
// }
|
||||
// client.send(JSON.stringify(msg));
|
||||
}
|
||||
|
||||
client.onmessage = (message) => {
|
||||
console.log(message);
|
||||
if(Array.isArray(message)=== true)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
useInterval(
|
||||
() => {
|
||||
// Your custom logic here
|
||||
// setCount(count + 1)
|
||||
console.log("updating")
|
||||
updateTracklist();
|
||||
},
|
||||
// Delay in milliseconds or null to stop it
|
||||
5000
|
||||
// isPlaying ? delay : null,
|
||||
)
|
||||
|
||||
const updateTracklist = () =>
|
||||
{
|
||||
if(Entity !== undefined)
|
||||
{
|
||||
var msg =
|
||||
{
|
||||
Data: "COP",
|
||||
Type: "EntityTrackList",
|
||||
ID: props.Entity.Id
|
||||
|
||||
}
|
||||
client.send(JSON.stringify(msg));
|
||||
}
|
||||
|
||||
}
|
||||
useEffect(() => {
|
||||
console.log("wird neu gerendert")
|
||||
},[])
|
||||
|
||||
useEffect(() => {
|
||||
if(props.Entity !== undefined)
|
||||
{
|
||||
if(Entity === undefined)
|
||||
{
|
||||
setEntity(props.Entity);
|
||||
}else
|
||||
{
|
||||
if(props.Entity.Id !== Entity.Id)
|
||||
{
|
||||
setEntity(props.Entity);
|
||||
}
|
||||
}
|
||||
updateTracklist();
|
||||
|
||||
}
|
||||
console.log(props.Entity);
|
||||
|
||||
},[props.Entity])
|
||||
|
||||
// useEffect(() =>
|
||||
// {
|
||||
|
||||
// },[Entity])
|
||||
|
||||
return(
|
||||
<div className="tracklist">
|
||||
<table>
|
||||
<thead>
|
||||
<tr className='TracklistHeader'>
|
||||
<th className='TracklistHeaderCell'>Name</th>
|
||||
<th className='TracklistHeaderCell'>Course</th>
|
||||
<th className='TracklistHeaderCell'>Speed</th>
|
||||
<th className='TracklistHeaderCell'>Distance</th>
|
||||
<th className='TracklistHeaderCell'>Bearing</th>
|
||||
<th className='TracklistHeaderCell'>Kind</th>
|
||||
<th className='TracklistHeaderCell'>Side</th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{ TrackList.map((val,index) => {
|
||||
return (
|
||||
<tr key={index}>
|
||||
<td >{val.Name}</td>
|
||||
<td className='TracklistCell'>{val.Course}</td>
|
||||
<td className='TracklistCell'>{val.Speed}</td>
|
||||
<td className='TracklistCell'>{}</td>
|
||||
<td className='TracklistCell'>{}</td>
|
||||
<td className='TracklistCell'>{val.Type}</td>
|
||||
<td className='TracklistCell'>{val.Side}</td>
|
||||
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
)}
|
||||
|
||||
export default EntityTrackList;
|
||||
@@ -0,0 +1,3 @@
|
||||
import EntityTrackList from "./EntityTrackList";
|
||||
|
||||
export default EntityTrackList;
|
||||
@@ -0,0 +1,249 @@
|
||||
|
||||
// import { useMapEvents } from 'react-leaflet/hooks'
|
||||
import React, { Component } from "react";
|
||||
import { MapContainer, TileLayer,Marker, Popup, Tooltip,useMapEvents } from 'react-leaflet'
|
||||
import { createIcon } from "./icon";
|
||||
import "./OpenSeaMap.scss";
|
||||
// import {w3cwebsocket as W3CWebSocket} from "websocket";
|
||||
// import ContainerDimensions from 'react-container-dimensions';
|
||||
import {} from "leaflet-contextmenu";
|
||||
import Track from "../../Track.tsx";
|
||||
|
||||
|
||||
class OpenSeaMap extends Component {
|
||||
|
||||
|
||||
state = {
|
||||
EntityOnFocus: Track,
|
||||
}
|
||||
updateDimensions() {
|
||||
const height = window.innerWidth >= 950 ? window.innerHeight : 400
|
||||
this.setState({ height: height })
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.updateDimensions()
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener("resize", this.updateDimensions.bind(this))
|
||||
// console.log(this.state.EntityOnFocus);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener("resize", this.updateDimensions.bind(this))
|
||||
}
|
||||
|
||||
|
||||
handleClick(e)
|
||||
{
|
||||
// console.log(e.target)
|
||||
// this.setState({ currentPos: e.latlng });
|
||||
// console.log(e.latlng);
|
||||
|
||||
// console.log("hello world");
|
||||
}
|
||||
|
||||
markerOnClick(e) {
|
||||
// console.log(e);
|
||||
|
||||
}
|
||||
|
||||
|
||||
setOnEdit(e)
|
||||
{
|
||||
var Track = this.props.TrackList.getTrack(e.relatedTarget.options.data);
|
||||
Track.isOnEdit = true;
|
||||
// console.log(Track);
|
||||
|
||||
|
||||
this.setState((state) =>({
|
||||
EntityOnFocus: Track
|
||||
}))
|
||||
this.props.setEntityOnFocus(Track.Id);
|
||||
|
||||
}
|
||||
|
||||
deleteEntity(id)
|
||||
{
|
||||
// console.log(id);
|
||||
try {
|
||||
var msg =
|
||||
{
|
||||
Data: "Entity",
|
||||
Type: "Delete",
|
||||
ID: id,
|
||||
}
|
||||
|
||||
|
||||
this.props.TrackList.deteleTrack(id);
|
||||
this.props.Client.send(JSON.stringify(msg))
|
||||
this.forceUpdate();
|
||||
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
resetFocus(e)
|
||||
{
|
||||
if(e !== undefined)
|
||||
{
|
||||
var Track = this.props.TrackList.getTrack(e.relatedTarget.options.data);
|
||||
if(Track !== undefined)
|
||||
{
|
||||
Track.isOnEdit = false;
|
||||
}
|
||||
|
||||
console.log(Track);
|
||||
}
|
||||
this.props.setEntityOnFocus(undefined);
|
||||
|
||||
}
|
||||
|
||||
|
||||
setNewEntityPosition(e)
|
||||
{
|
||||
// console.log(e.target.options);
|
||||
var Track = this.props.TrackList.getTrack(e.target.options.data);
|
||||
Track.isOnEdit = true;
|
||||
Track.Position = [e.target._latlng.lat,e.target._latlng.lng];
|
||||
// console.log(Track);
|
||||
this.props.setEntityOnFocus(e.target.options.data);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
makeIcon(index, entity,props,state)
|
||||
{
|
||||
|
||||
// console.log(entity);
|
||||
var isOnFocus = false;
|
||||
|
||||
if(entity.isOnEdit === true)
|
||||
{
|
||||
isOnFocus = true
|
||||
|
||||
}
|
||||
|
||||
var icon = createIcon(entity.Type,entity.Side)
|
||||
return (
|
||||
<Marker name={entity.Name} key={entity.Id} icon={icon} position={entity.Position} data={entity.Id}
|
||||
draggable={isOnFocus? true : false}
|
||||
contextmenu={true}
|
||||
contextmenuWidth={140}
|
||||
|
||||
contextmenuItems={[{
|
||||
text:"Edit",
|
||||
index:0,
|
||||
callback: this.setOnEdit.bind(this),
|
||||
},{
|
||||
text:"Delete",
|
||||
index: 1,
|
||||
callback: this.deleteEntity.bind(this,entity.Id),
|
||||
}, {
|
||||
text:"Test",
|
||||
callback: this.markerOnClick.bind(this),
|
||||
// separator: true,
|
||||
index: 2
|
||||
}, {
|
||||
text:"Exit",
|
||||
callback: this.resetFocus.bind(this),
|
||||
|
||||
index: 3
|
||||
}]}
|
||||
|
||||
eventHandlers={{
|
||||
click: (e) => {
|
||||
console.log(entity.Name);
|
||||
console.log(entity.id);
|
||||
|
||||
this.props.setEntityOnFocus(e.target.options.data)
|
||||
|
||||
},
|
||||
dragend: this.setNewEntityPosition.bind(this),
|
||||
|
||||
}}
|
||||
// eventHandlers={this.MarkerEventHandler}
|
||||
>
|
||||
|
||||
|
||||
<Tooltip direction='bottom' offset={[0,13]} opacity={1} permanent>
|
||||
<span>{entity.Name}</span>
|
||||
</Tooltip>
|
||||
|
||||
</Marker>
|
||||
);
|
||||
}
|
||||
|
||||
setPos(props)
|
||||
{
|
||||
console.log(props);
|
||||
|
||||
this.props.setFocusPosition([1,2])
|
||||
}
|
||||
|
||||
render() {
|
||||
const LocationFinderDummy = (props) => {
|
||||
const map = useMapEvents({
|
||||
|
||||
click(e) {
|
||||
|
||||
// console.log(props)
|
||||
props.props.resetFocus();
|
||||
// props.props.state.EntityOnFocus =undefined
|
||||
|
||||
// props.props.props.setEntityOnFocus(undefined);
|
||||
|
||||
|
||||
props.props.props.setFocusPosition(e.latlng)
|
||||
|
||||
|
||||
// console.log(e.latlng);
|
||||
},
|
||||
});
|
||||
|
||||
// this.state.EntityOnFocus = undefined;
|
||||
return null;
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
<div className='map' style={{ height: this.state.height }} >
|
||||
<MapContainer center={[54, 11]} zoom={6} scrollWheelZoom={true} contextmenu={false} attributionControl={false}
|
||||
|
||||
>
|
||||
<LocationFinderDummy props ={{props:this.props, resetFocus:this.resetFocus.bind(this)}} />
|
||||
|
||||
<TileLayer
|
||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
|
||||
<TileLayer
|
||||
url="https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png" />
|
||||
|
||||
{
|
||||
this.props.TrackListMap.map((element,index) => (
|
||||
this.makeIcon(index,element)
|
||||
))}
|
||||
|
||||
</MapContainer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export default OpenSeaMap;
|
||||
@@ -93,4 +93,11 @@ const Hostile = new Icon({
|
||||
iconAnchor: [hostile.getAnchor().x, hostile.getAnchor().y],
|
||||
});
|
||||
|
||||
export { iconShip, friend,Hostile,createIcon };
|
||||
|
||||
|
||||
var OwnShipIcon = new Icon({
|
||||
iconUrl: 'Own_Ship.svg',
|
||||
iconSize: [50, 50], // size of the icon
|
||||
});
|
||||
|
||||
export {OwnShipIcon, iconShip, friend,Hostile,createIcon };
|
||||
@@ -1,15 +1,25 @@
|
||||
import React from 'react';
|
||||
import './tracklist.scss'
|
||||
import round from '../../Utils';
|
||||
import round from '../../../Utils';
|
||||
import {useState,useEffect, useRef} from 'react';
|
||||
|
||||
|
||||
|
||||
class Tracklist extends React.Component
|
||||
{
|
||||
render()
|
||||
{
|
||||
// class Tracklist extends React.Component
|
||||
|
||||
return(
|
||||
|
||||
function Tracklist(props) {
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
console.log("tracklist")
|
||||
|
||||
|
||||
},[])
|
||||
|
||||
|
||||
|
||||
return(
|
||||
<div className="tracklist">
|
||||
<table>
|
||||
<thead>
|
||||
@@ -25,14 +35,14 @@ class Tracklist extends React.Component
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{ this.props.entities.map((val,index) => {
|
||||
{ props.entities.getTracks().map((val,index) => {
|
||||
return (
|
||||
<tr key={index}>
|
||||
<td >{val.Name}</td>
|
||||
<td className='TracklistCell'>{val.Course}</td>
|
||||
<td className='TracklistCell'>{val.Speed}</td>
|
||||
<td className='TracklistCell'>{round(val.Position[0],3)}</td>
|
||||
<td className='TracklistCell'>{round(val.Position[1],3)}</td>
|
||||
<td className='TracklistCell'>{round(val.Position[0],4)}</td>
|
||||
<td className='TracklistCell'>{round(val.Position[1],4)}</td>
|
||||
<td className='TracklistCell'>{val.Type}</td>
|
||||
<td className='TracklistCell'>{val.Side}</td>
|
||||
|
||||
@@ -43,7 +53,7 @@ class Tracklist extends React.Component
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
{
|
||||
display: flex;
|
||||
max-height: 40%;
|
||||
height: 300px;
|
||||
height: 400px;
|
||||
display: block;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
td
|
||||
3
webapp/src/components/SimControl/index.js
Normal file
3
webapp/src/components/SimControl/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import SimControl from "./SimControl.jsx";
|
||||
|
||||
export default SimControl;
|
||||
133
webapp/src/components/api/APICalls.jsx
Normal file
133
webapp/src/components/api/APICalls.jsx
Normal file
@@ -0,0 +1,133 @@
|
||||
export function getCOP()
|
||||
{
|
||||
var msg =
|
||||
{
|
||||
Type: "Request",
|
||||
Data: "COP"
|
||||
|
||||
}
|
||||
|
||||
return JSON.stringify(msg);
|
||||
}
|
||||
|
||||
|
||||
export function deleteEntity(id)
|
||||
{
|
||||
var msg =
|
||||
{
|
||||
Data: "Entity",
|
||||
Type: "Delete",
|
||||
ID: id,
|
||||
}
|
||||
|
||||
return JSON.stringify(msg);
|
||||
}
|
||||
|
||||
export function createEntity(Name,Speed,Course, Position, Height)
|
||||
{
|
||||
var msg =
|
||||
{
|
||||
Data: "Entity",
|
||||
Type: "New",
|
||||
Name: Name,
|
||||
Speed: Speed.toString(),
|
||||
Course: Course.toString(),
|
||||
Position: [Position[0].toString(),Position[1].toString()],
|
||||
Height: Height.toString(),
|
||||
SetPosition: true
|
||||
|
||||
}
|
||||
return JSON.stringify(msg);
|
||||
|
||||
}
|
||||
|
||||
export function updateEntity(id,Speed,Course, Position, Height, setPos)
|
||||
{
|
||||
var msg =
|
||||
{
|
||||
Data: "Entity",
|
||||
Type: "Update",
|
||||
ID: id,
|
||||
Speed: Speed.toString(),
|
||||
Course: Course.toString(),
|
||||
Position: [Position[0].toString(),Position[1].toString()],
|
||||
Height: Height.toString(),
|
||||
SetPosition: setPos
|
||||
|
||||
}
|
||||
return JSON.stringify(msg);
|
||||
}
|
||||
|
||||
|
||||
export function getTracklist(id)
|
||||
{
|
||||
var msg =
|
||||
{
|
||||
Data: "COP",
|
||||
Type: "EntityTrackList",
|
||||
ID: id,
|
||||
}
|
||||
return JSON.stringify(msg);
|
||||
|
||||
}
|
||||
|
||||
|
||||
export function saveScenario()
|
||||
{
|
||||
var msg =
|
||||
{
|
||||
Data: "Scenario",
|
||||
Type: "Save",
|
||||
}
|
||||
return JSON.stringify(msg);
|
||||
|
||||
}
|
||||
|
||||
export function deleteScenario()
|
||||
{
|
||||
var msg =
|
||||
{
|
||||
Data: "Scenario",
|
||||
Type: "Delete",
|
||||
}
|
||||
return JSON.stringify(msg);
|
||||
|
||||
}
|
||||
|
||||
export function loadScenario(id)
|
||||
{
|
||||
var msg =
|
||||
{
|
||||
Data: "Scenario",
|
||||
Type: "Load",
|
||||
ID: id,
|
||||
}
|
||||
return JSON.stringify(msg);
|
||||
|
||||
}
|
||||
|
||||
export function loadAutoraster()
|
||||
{
|
||||
var msg =
|
||||
{
|
||||
Data: "Scenario",
|
||||
Type: "AutoRaster",
|
||||
}
|
||||
return JSON.stringify(msg);
|
||||
|
||||
}
|
||||
|
||||
|
||||
export function getWSTestMessage()
|
||||
{
|
||||
var msg =
|
||||
{
|
||||
Data: "TEST",
|
||||
}
|
||||
return JSON.stringify(msg);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
// // api/index.js
|
||||
// var socket = new WebSocket("ws://localhost:8008/");
|
||||
|
||||
// let connect = cb => {
|
||||
// console.log("connecting");
|
||||
|
||||
// socket.onopen = () => {
|
||||
// console.log("Successfully Connected");
|
||||
// };
|
||||
|
||||
// socket.onmessage = msg => {
|
||||
// cb(msg);
|
||||
// };
|
||||
|
||||
// socket.onclose = event => {
|
||||
// console.log("Socket Closed Connection: ", event);
|
||||
// };
|
||||
|
||||
// socket.onerror = error => {
|
||||
// console.log("Socket Error: ", error);
|
||||
// };
|
||||
// };
|
||||
|
||||
|
||||
// let sendMsg = msg => {
|
||||
// console.log("sending msg: ", msg);
|
||||
// socket.send(msg);
|
||||
// };
|
||||
|
||||
// export { connect, sendMsg };
|
||||
@@ -1,111 +0,0 @@
|
||||
import React from 'react';
|
||||
import './controls.css'
|
||||
// import { sendMsg } from '../api';
|
||||
import Tracklist from './Tracklist'
|
||||
import EntityControl from './EntityControl';
|
||||
import round from '../Utils';
|
||||
// import {w3cwebsocket as W3CWebSocket} from "websocket"
|
||||
|
||||
|
||||
// const config = {
|
||||
// // apiUrl: process.env.REACT_APP_WEBAPP_WS_URL,
|
||||
// apiUrl: "192.168.3.13",
|
||||
// apiProt: 30747
|
||||
// }
|
||||
|
||||
|
||||
// const client = new W3CWebSocket("ws://"+config.apiUrl+":"+config.apiProt+"/");
|
||||
|
||||
// const round = (n, dp) => {
|
||||
// const h = +('1'.padEnd(dp + 1, '0')) // 10 or 100 or 1000 or etc
|
||||
// return Math.round(n * h) / h
|
||||
// }
|
||||
|
||||
class Controls extends React.Component
|
||||
{
|
||||
|
||||
state = {
|
||||
EntityOnFocus: undefined,
|
||||
}
|
||||
|
||||
componentDidMount()
|
||||
{
|
||||
// client.onopen = () => {
|
||||
// console.log(" Control Websocket Client Connected");
|
||||
// };
|
||||
|
||||
// client.onmessage = (message) => {
|
||||
// const dataFromServer = JSON.parse(message.data);
|
||||
// console.log('reply', dataFromServer);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
render() {
|
||||
function getEntityFromID(Entities, SelectedEntity)
|
||||
{
|
||||
if(SelectedEntity !== undefined)
|
||||
{
|
||||
var tmp = {};
|
||||
// tmp.NewPos= new Array(0,0);
|
||||
// console.log(tmp);
|
||||
|
||||
Entities.map((val) => {
|
||||
if(val.id === SelectedEntity.EntityID)
|
||||
{
|
||||
tmp = val
|
||||
// tmp = JSON.parse(JSON.stringify(val));
|
||||
// console.log(tmp);
|
||||
val.dragged = SelectedEntity.dragged;
|
||||
if(SelectedEntity.dragged === undefined)
|
||||
{
|
||||
val.dragged = false;
|
||||
}
|
||||
|
||||
// console.log(SelectedEntity);
|
||||
|
||||
// if(SelectedEntity.NewPos !== undefined)
|
||||
// {
|
||||
// // Object.assign(tmp, {NewPos: [{},{}]});
|
||||
// Object.assign(val, {NewPos: [{},{}]});
|
||||
|
||||
// // tmp.OldPos = val.Position;
|
||||
// // Object.assign(tmp, {NewPos: [round(SelectedEntity.NewPos[0],3),0]});
|
||||
// // val.NewPos = SelectedEntity.NewPos;
|
||||
// val.NewPos[0] = round(SelectedEntity.NewPos[0],3);
|
||||
// val.NewPos[1] = round(SelectedEntity.NewPos[1],3);
|
||||
|
||||
// // tmp.NewPos[0] = round(SelectedEntity.NewPos[0],3);
|
||||
// // tmp.NewPos[1] = round(SelectedEntity.NewPos[1],3);
|
||||
|
||||
// }
|
||||
|
||||
// tmp.NewPos = SelectedEntity.NewPos;
|
||||
}
|
||||
return tmp;
|
||||
})
|
||||
// console.log(tmp);
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// console.log(getEntityFromID(this.props.Entities,this.props.EntityOnFocus));
|
||||
return (
|
||||
<div className="controls">
|
||||
<Tracklist entities= {this.props.Entities} />
|
||||
<br />
|
||||
<div>
|
||||
{/* <button onClick={this.props.updateEntities}>update</button> */}
|
||||
<EntityControl Functions = {this.props.Functions} Client = { this.props.Client } Entity = { getEntityFromID(this.props.Entities,this.props.EntityOnFocus)} EntityOnFocus= {this.props.EntityOnFocus} PositionCliecked = {this.props.PositionClicked}/>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Controls;
|
||||
@@ -1,3 +0,0 @@
|
||||
import Controls from "./controls.jsx";
|
||||
|
||||
export default Controls;
|
||||
Reference in New Issue
Block a user