Outsource http, joystick to common/ and react-app to root

Same reason as before commit
Note: some changes to http were necessary due to global object
- untested!

Also remove unneded duplicate components folder
This commit is contained in:
jonny_jr9
2023-09-07 12:53:16 +02:00
parent 13b896accb
commit f76db1d9bc
25 changed files with 14 additions and 29995 deletions

28358
react-app/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

40
react-app/package.json Normal file
View File

@@ -0,0 +1,40 @@
{
"name": "react-new",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-joystick-component": "^4.0.1",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4",
"websocket": "^1.0.34"
},
"scripts": {
"start": "react-scripts start",
"build": "GENERATE_SOURCEMAP=false react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

View File

@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Armchair control webapp"
/>
<title>armchair ctl</title>
</head>
<body style="background-color:#001427; color:white;">
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

245
react-app/src/App.js vendored Normal file
View File

@@ -0,0 +1,245 @@
import { Joystick } from 'react-joystick-component';
import React, { useState} from 'react';
//import { w3cwebsocket as W3CWebSocket } from "websocket";
function App() {
//declare variables that can be used and updated in html
const [x_html, setX_html] = useState(0);
const [y_html, setY_html] = useState(0);
const [ip, setIp] = useState("10.0.0.66");
//===============================
//=========== config ============
//===============================
const decimalPlaces = 3;
const joystickSize = 250; //affects scaling of coordinates and size of joystick on website
const throttle = 300; //throtthe interval the joystick sends data while moving (ms)
const toleranceSnapToZeroPer = 20;//percentage of moveable range the joystick can be moved from the axix and value stays at 0
//-------------------------------------------------
//------- Scale coordinate, apply tolerance -------
//-------------------------------------------------
//function that:
// - scales the coodinate to a range of -1 to 1
// - snaps 0 zero for a given tolerance in percent
// - rounds value do given decimal places
// - TODO: add threshold it snaps to 1 / -1 (100%) toleranceEnd
const ScaleCoordinateTolerance = (input) => {
//calc tolerance threshold and available range
const tolerance = joystickSize/2 * toleranceSnapToZeroPer/100;
const range = joystickSize/2 - tolerance;
let result = 0;
//console.log("value:",input,"tolerance:",tolerance," range:",range);
//input positive and above 'snap to zero' threshold
if ( input > 0 && input > tolerance ){
result = ((input-tolerance)/range).toFixed(decimalPlaces);
}
//input negative and blow 'snap to zero' threshold
else if ( input < 0 && input < -tolerance ){
result = ((input+tolerance)/range).toFixed(decimalPlaces);
}
//inside threshold around zero
else {
result = 0;
}
//return result
//console.log("result:", result, "\n");
return result;
}
//----------------------------------------
//----------- Scale coordinate -----------
//----------------------------------------
//simply scale coordinate from joystick to a value of -1 to 1 without applying any tolerances
const ScaleCoordinate = (input) => {
return ( input / (joystickSize/2) ).toFixed(decimalPlaces);
}
//-------------------------------------------
//------- Senda data via POST request -------
//-------------------------------------------
//function that sends an object as json to the esp32 with a http post request
const httpSendObject = async (object_data) => {
//debug log
console.log("Sending:", object_data);
let json = JSON.stringify(object_data);
//console.log("json string:", json);
//remove quotes around numbers:
//so cJSON parses the values as actua[l numbers than strings
const regex2 = /"(-?[0-9]+\.{0,1}[0-9]*)"/g
json = json.replace(regex2, '$1')
//console.log("json removed quotes:", json);
//--- API url / ip ---
//await fetch("http://10.0.1.69/api/joystick", {
//await fetch("http://10.0.1.72/api/joystick", {
await fetch("api/joystick", {
method: "POST",
//apparently browser sends OPTIONS request before actual POST request, this OPTIONS request was not handled by esp32
//also the custom set Access-Control-Allow-Origin header in esp32 url header was not read because of that
//changed content type to text/plain to workaround this
//https://stackoverflow.com/questions/1256593/why-am-i-getting-an-options-request-instead-of-a-get-request
headers: {
//"Content-Type": "application/json",
"Content-Type": "text/plain",
},
body: json,
})
//.then((response) => console.log(response));
};
//---------------------------------------
//--- function when joystick is moved ---
//---------------------------------------
//function that is run for each move event
//evaluate coordinates and send to esp32
const handleMove = (e) => {
//console.log("data from joystick-element X:" + e.x + " Y:" + e.y + " distance:" + e.distance);
//--- convert coordinates ---
//Note: tolerance (snap to zero) now handled by controller -> send raw coordinates
//const x = ScaleCoordinateTolerance(e.x);
//const y = ScaleCoordinateTolerance(e.y);
const x = ScaleCoordinate(e.x);
const y = ScaleCoordinate(e.y);
//create object with necessary data
const joystick_data={
x: x,
y: y
}
//send object with joystick data as json to controller
httpSendObject(joystick_data);
//update variables for html
setX_html(joystick_data.x);
setY_html(joystick_data.y);
};
//------------------------------------------
//--- function when joystick is released ---
//------------------------------------------
const handleStop = (e) => {
//create object with all values 0
const joystick_data={
x: 0,
y: 0,
}
//update variables for html
setX_html(0);
setY_html(0);
//send object with joystick data as json to controller
httpSendObject(joystick_data);
};
//=============================
//======== return html ========
//=============================
return (
<>
<div style={{display:'flex', justifyContent:'center', alignItems:'center', height:'100vh'}}>
<div>
<div style={{position: 'absolute', top: '0', left: '0', width: '100%'}}>
<h1 style={{width:'100%', textAlign:'center'}}>Armchair ctl</h1>
</div>
<Joystick
size={joystickSize}
sticky={false}
baseColor="#8d0801"
stickColor="#708d81"
throttle={throttle}
move={handleMove}
stop={handleStop}
>
</Joystick>
<ul>
<li> x={x_html} </li>
<li> y={y_html} </li>
</ul>
</div>
</div>
{/*
buttons for changing the api IP
<div>
<a>current ip used: {ip}</a>
<button onClick={() => {setIp("10.0.0.66")}} >10.0.0.66 (BKA-network)</button>
</div>
*/}
</>
);
}
export default App;
//del, testing, unused code
//---------------------------------------------
//--------- Send data via websocket -----------
//---------------------------------------------
//moved to normal POST request since websocket connection was unreliable on esp32
// //create websocket
// const websocket = useRef(null);
// //const socketUrl = "ws://" + window.location.host + "/ws-api/servo";
// const socketUrl = "ws://10.0.1.69/ws-api/joystick";
// useEffect(() => {
// websocket.current = new W3CWebSocket(socketUrl);
// websocket.current.onmessage = (message) => {
// console.log('got reply! ', message);
// };
// websocket.current.onopen = (event) => {
// console.log('OPENED WEBSOCKET', event);
// //sendJoystickData(0, 0, 0, 0);
// websocket.current.send("");
// };
// websocket.current.onclose = (event) => {
// console.log('CLOSED WEBSOCKET', event);
// };
// return () => websocket.current.close();
// }, [])
//
//
//
// //function for sending joystick data (provided as parameters) to controller via websocket
// const sendJoystickDataWebsocket = (x, y, radius, angle) => {
// //debug log
// console.log("Sending:\n X:" + x + "\n Y:" + y + "\n radius:" + radius + "\n angle: " + angle);
//
// websocket.current.send(
// JSON.stringify({
// x: x,
// y: y,
// radius: radius,
// angle: angle
// })
// );
// }

14
react-app/src/index.js vendored Normal file
View File

@@ -0,0 +1,14 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals