Skip to content

Commit

Permalink
Merge pull request #5 from TrentonBowserFanClub/v1-controls
Browse files Browse the repository at this point in the history
V1 controls
  • Loading branch information
jwmke authored Mar 31, 2024
2 parents 311938b + c24c4c6 commit 889e961
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 24 deletions.
2 changes: 1 addition & 1 deletion MODULE.bazel.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions src/api/v1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ python3.11 -m venv venv
```

From here, you can source your venv with the following commands.
Windows, probably:

Windows:

```
./venv/bin/Activate.ps1
.\venv\Scripts\Activate.ps1
```

Linux:
Expand Down
28 changes: 19 additions & 9 deletions src/api/v1/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,25 @@
from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect
from websockets.exceptions import ConnectionClosed
from fastapi.templating import Jinja2Templates
from fastapi.middleware.cors import CORSMiddleware
import asyncio
import cv2

app = FastAPI()
camera = cv2.VideoCapture(0, cv2.CAP_DSHOW)
camera = cv2.VideoCapture(1, cv2.CAP_DSHOW)
templates = Jinja2Templates(directory="templates")

origins = [
"http://localhost:3000",
]

@app.get("/")
def read_root():
return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"], # Allow all HTTP methods
allow_headers=["*"], # Allow all headers
)


# https://stackoverflow.com/a/70626324
Expand All @@ -35,3 +38,10 @@ async def get_stream(websocket: WebSocket):
await asyncio.sleep(0.03)
except (WebSocketDisconnect, ConnectionClosed):
print("Client disconnected")


@app.post("/command")
async def command(request: Request):
data = await request.json()
print(data)
return {"status": "success"}
2 changes: 1 addition & 1 deletion src/api/v1/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ sniffio==1.3.1
starlette==0.36.3
typing_extensions==4.10.0
uvicorn==0.29.0
uvloop==0.19.0
# uvloop==0.19.0
watchfiles==0.21.0
websockets==12.0
11 changes: 10 additions & 1 deletion src/ui/v1/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions src/ui/v1/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,20 @@
"lint": "next lint"
},
"dependencies": {
"next": "14.1.4",
"react": "^18",
"react-dom": "^18",
"next": "14.1.4"
"react-icons": "^5.0.1"
},
"devDependencies": {
"typescript": "^5",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"autoprefixer": "^10.0.1",
"eslint": "^8",
"eslint-config-next": "14.1.4",
"postcss": "^8",
"tailwindcss": "^3.3.0",
"eslint": "^8",
"eslint-config-next": "14.1.4"
"typescript": "^5"
}
}
6 changes: 5 additions & 1 deletion src/ui/v1/src/app/globals.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@tailwind utilities;

.text-transparent {
color: transparent !important;
}
118 changes: 113 additions & 5 deletions src/ui/v1/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
"use client"
import { useRef, useEffect, useInsertionEffect } from "react";
import { useRef, useEffect, useInsertionEffect, useState } from "react";
import { FaArrowDown, FaArrowLeft, FaArrowRight, FaArrowUp } from "react-icons/fa";

export default function Home() {
const ws = new WebSocket('ws://localhost:8000/ws');
const canvasRef = useRef<HTMLCanvasElement>(null);

const [left, setLeft] = useState(0);
const [up, setUp] = useState(0);
const [right, setRight] = useState(0);
const [down, setDown] = useState(0);

useInsertionEffect(() => {

ws.onmessage = (event) => {
if (event.data instanceof Blob) {
const reader = new FileReader();
Expand All @@ -27,7 +32,6 @@ export default function Home() {
}
};

// Clean up WebSocket connection on component unmount
return () => {
ws.close();
};
Expand All @@ -37,11 +41,115 @@ export default function Home() {
const canvas = canvasRef.current;
const context = canvas?.getContext('2d');
}, []);


useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
switch (event.key) {
case "ArrowUp":
setUp(1);
break;
case "ArrowDown":
setDown(1);
break;
case "ArrowLeft":
setLeft(1);
break;
case "ArrowRight":
setRight(1);
break;
default:
break;
}
};

document.addEventListener("keydown", handleKeyDown);

return () => {
document.removeEventListener("keydown", handleKeyDown);
};
}, []);

useEffect(() => {
const handleKeyUp = (event: KeyboardEvent) => {
switch (event.key) {
case "ArrowUp":
setUp(0);
break;
case "ArrowDown":
setDown(0);
break;
case "ArrowLeft":
setLeft(0);
break;
case "ArrowRight":
setRight(0);
break;
default:
break;
}
}

document.addEventListener("keyup", handleKeyUp);

return () => {
document.removeEventListener("keyup", handleKeyUp);
}
}, [])

useEffect(() => {
fetch('http://localhost:8000/command', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
left,
up,
right,
down
}),
});
}, [down, left, right, up])

return (
<main className="min-h-screen w-full">
<div className="flex flex-col items-center justify-center min-h-screen max-h-screen overflow-hidden w-full">
<canvas ref={canvasRef} className="h-3/5 w-3/5" />
<div className="grid grid-cols-6 w-full">
<div className="col-span-4">
<canvas ref={canvasRef} className="w-full" />
</div>
<div className="col-span-2 bg-gradient-to-br from-red to-yellow">
<div className="flex flex-col items-center justify-center h-full">
<div className="grid grid-cols-3 w-1/3">
<div className="aspect-square"/>
<div className={up ? "border-green text-green" : "border-blue text-blue"}>
<div className="border-4 rounded-[50%] aspect-square flex justify-center items-center">
<FaArrowUp size={32}/>
</div>
</div>
<div className="aspect-square"/>
<div className={left ? "border-green text-green" : "border-blue text-blue"}>
<div className="border-4 rounded-[50%] aspect-square flex justify-center items-center">
<FaArrowLeft size={32}/>
</div>
</div>
<div className="aspect-square"/>
<div className={right ? "border-green text-green" : "border-blue text-blue"}>
<div className="border-4 rounded-[50%] aspect-square flex justify-center items-center">
<FaArrowRight size={32}/>
</div>
</div>
<div className="aspect-square"/>
<div className={down ? "border-green text-green" : "border-blue text-blue"}>
<div className="border-4 rounded-[50%] aspect-square flex justify-center items-center">
<FaArrowDown size={32}/>
</div>
</div>
<div className="aspect-square"/>
</div>
</div>
</div>
</div>
</div>
</main>
);
Expand Down
10 changes: 10 additions & 0 deletions src/ui/v1/tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ const config: Config = {
"conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
},
},
colors: {
red: "#ee6352",
green: "#59cd90",
blue: "#3fa7d6",
yellow: "#fac05e",
purple: "#b678e0",
black: "#1e1e1e",
white: "#f9f9f9",
orange: "#f79d84"
}
},
plugins: [],
};
Expand Down

0 comments on commit 889e961

Please sign in to comment.