Skip to content

Commit

Permalink
Initalized Node
Browse files Browse the repository at this point in the history
  • Loading branch information
shuja-shah committed May 31, 2024
1 parent fb88b07 commit 5a150f2
Show file tree
Hide file tree
Showing 9 changed files with 908 additions and 63 deletions.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,15 @@
}
},
"dependencies": {
"axios": "^1.7.2",
"electron-debug": "^3.2.0",
"electron-log": "^4.4.8",
"electron-updater": "^6.1.4",
"proptypes": "^1.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.16.0"
"react-router-dom": "^6.16.0",
"reactflow": "^11.11.3"
},
"devDependencies": {
"@electron/notarize": "^2.1.0",
Expand Down
23 changes: 23 additions & 0 deletions src/nodes/DetectNode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import PropTypes from "prop-types";

Check failure on line 1 in src/nodes/DetectNode.js

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

Replace `"prop-types"` with `'prop-types'`
import { Handle, Position } from "reactflow";

Check failure on line 2 in src/nodes/DetectNode.js

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

Replace `"reactflow"` with `'reactflow'`

const DetectNode = () => {

Check failure on line 4 in src/nodes/DetectNode.js

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

Function component is not a function declaration
return (
<div>
<h3 className="bg-gradient-to-br from-blue-100 to-purple-200 p-6 text-black text-2xl font-semibold rounded-md">
Detect
</h3>
<Handle type="target" position={Position.Left} />
<Handle type="source" position={Position.Right} />
</div>
);
};

DetectNode.propTypes = {
data: PropTypes.shape({
image: PropTypes.instanceOf(File),
onDetection: PropTypes.func.isRequired,
}).isRequired,
};

export default DetectNode;
63 changes: 63 additions & 0 deletions src/nodes/ImageInputNode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { useCallback, useState } from "react";

Check failure on line 1 in src/nodes/ImageInputNode.js

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

Replace `"react"` with `'react'`
import PropTypes from "prop-types";

Check failure on line 2 in src/nodes/ImageInputNode.js

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

Replace `"prop-types"` with `'prop-types'`
import { Handle, Position } from "reactflow";

Check failure on line 3 in src/nodes/ImageInputNode.js

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

Replace `"reactflow"` with `'reactflow'`

const ImageInputNode = ({ data }) => {

Check failure on line 5 in src/nodes/ImageInputNode.js

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

Function component is not a function declaration
const [image, setImage] = useState(null);

const onImageChange = useCallback(
(event) => {
if (event.target.files && event.target.files[0]) {
const file = event.target.files[0];
data.onImageUpload(file);
const reader = new FileReader();
reader.onload = () => {
setImage(reader.result);
};
reader.readAsDataURL(file);
}
},
[data]

Check failure on line 20 in src/nodes/ImageInputNode.js

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

Insert `,`
);

return (
<div className="w-[300px] bg-gradient-to-br from-blue-100 to-purple-200 p-8 rounded-3xl shadow-md">
<label className="block text-center mb-2">

Check failure on line 25 in src/nodes/ImageInputNode.js

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

A form label must be associated with a control
<span className=" bg-gradient-to-br from-blue-400 to-purple-300 hover:from-blue-500 hover:to-purple-400 text-white font-bold py-2 px-4 rounded cursor-pointer">
Upload Image
</span>
<input
type="file"
accept="image/*"
onChange={onImageChange}
className="hidden "
/>
</label>

{image && (
<img
src={image}
alt="uploaded"
style={{
width: "250px",

Check failure on line 42 in src/nodes/ImageInputNode.js

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

Replace `"250px"` with `'250px'`
display: "block",
margin: "0 auto",
borderRadius: "4px",
height: "250px",

}}
className="mt-6"
/>
)}
<Handle type="source" position={Position.Right} />
</div>
);
};

ImageInputNode.propTypes = {
data: PropTypes.shape({
onImageUpload: PropTypes.func.isRequired,
}).isRequired,
};

export default ImageInputNode;
75 changes: 75 additions & 0 deletions src/nodes/OutputNode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { useEffect, useRef } from "react";
import PropTypes from "prop-types";
import { Handle, Position } from "reactflow";

const OutputNode = ({ data }) => {
const canvasRef = useRef(null);
const lastFrameIndexRef = useRef(0);

const hasConnectionFromVideoInput = data.edges.some(
(edge) => edge.source === "2" && edge.target === "3"
);


useEffect(() => {
if (!hasConnectionFromVideoInput) return;

const canvas = canvasRef.current;
const ctx = canvas.getContext("2d");
let animationFrameId;

const drawFrame = () => {
if (data.processedFrames.length > lastFrameIndexRef.current) {
const frameData = data.processedFrames[lastFrameIndexRef.current];
const img = new Image();
img.onload = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
lastFrameIndexRef.current++;
};
img.src = `data:image/jpeg;base64,${frameData}`;
}
animationFrameId = requestAnimationFrame(drawFrame);
};

drawFrame();

return () => {
cancelAnimationFrame(animationFrameId);
};
}, [data.processedFrames]);

return (
<div className="bg-gradient-to-br from-blue-100 to-purple-200 text-center p-4 text-black text-2xl font-semibold rounded-3xl">
<p className="mb-2">Output</p>
{data.detectedImage && (
<img
src={data.detectedImage}
alt="Detected"
width={300}
className="h-[300px] mb-2"
/>
)}
{data.processedFrames && (
<div className="">
<canvas
ref={canvasRef}
style={{ maxWidth: "100%" }}
height="300"
></canvas>
</div>
)}
<Handle type="target" position={Position.Left} />
</div>
);
};

OutputNode.propTypes = {
data: PropTypes.shape({
processedFrames: PropTypes.arrayOf(PropTypes.string).isRequired,
detectedImage: PropTypes.string,
edges: PropTypes.array.isRequired,
}).isRequired,
};

export default OutputNode;
72 changes: 72 additions & 0 deletions src/nodes/WebcamNode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { useRef, useEffect, useState } from "react";
import PropTypes from "prop-types";
import { Handle, Position } from "reactflow";

const WebcamInputNode = ({ data }) => {
const videoRef = useRef(null);
const [showVideo, setShowVideo] = useState(false);

useEffect(() => {
let stream;

const initializeWebcam = async () => {
try {
stream = await navigator.mediaDevices.getUserMedia({
video: true,
});
if (videoRef.current) {
videoRef.current.srcObject = stream;
data.onVideoUpload(stream);
}
} catch (error) {
console.error("Error accessing webcam:", error);

Check warning on line 22 in src/nodes/WebcamNode.js

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

Unexpected console statement
}
};

if (showVideo) {
initializeWebcam();
}

return () => {
if (stream) {
stream.getTracks().forEach((track) => track.stop());
}
};
}, [data, showVideo]);

const handleStartClick = () => {
setShowVideo(true);
};

const handleVideoClick = () => {
setShowVideo((prevShowVideo) => !prevShowVideo);
};

return (
<div className="w-[400px] bg-gradient-to-br from-blue-100 to-purple-200 p-6 rounded-3xl">
<h3 className="mb-2 text-black text-2xl font-semibold text-center">
Webcam
</h3>
<div className="flex justify-center" onClick={handleStartClick}>
<button className=" bg-gradient-to-br from-blue-400 to-purple-300 text-white font-bold py-2 px-4 rounded mb-2">
Start
</button>
</div>

{showVideo && (
<div onClick={handleVideoClick}>
<video ref={videoRef} autoPlay playsInline />
</div>
)}
<Handle type="source" position={Position.Right} />
</div>
);
};

WebcamInputNode.propTypes = {
data: PropTypes.shape({
onVideoUpload: PropTypes.func.isRequired,
}).isRequired,
};

export default WebcamInputNode;
65 changes: 4 additions & 61 deletions src/renderer/App.css
Original file line number Diff line number Diff line change
@@ -1,62 +1,5 @@
/*
* @NOTE: Prepend a `~` to css file paths that are in your node_modules
* See https://github.com/webpack-contrib/sass-loader#imports
*/
body {
position: relative;
color: white;
height: 100vh;
background: linear-gradient(
200.96deg,
#fedc2a -29.09%,
#dd5789 51.77%,
#7a2c9e 129.35%
);
font-family: sans-serif;
overflow-y: hidden;
display: flex;
justify-content: center;
align-items: center;
}

button {
background-color: white;
padding: 10px 20px;
border-radius: 10px;
border: none;
appearance: none;
font-size: 1.3rem;
box-shadow: 0px 8px 28px -6px rgba(24, 39, 75, 0.12),
0px 18px 88px -4px rgba(24, 39, 75, 0.14);
transition: all ease-in 0.1s;
cursor: pointer;
opacity: 0.9;
}

button:hover {
transform: scale(1.05);
opacity: 1;
}

li {
list-style: none;
}

a {
text-decoration: none;
height: fit-content;
width: fit-content;
margin: 10px;
}

a:hover {
opacity: 1;
text-decoration: none;
}

.Hello {
display: flex;
justify-content: center;
align-items: center;
margin: 20px 0;
body{
background-color:aliceblue;
margin: 0 0;
padding: 0 0;
}
3 changes: 2 additions & 1 deletion src/renderer/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { MemoryRouter as Router, Routes, Route } from 'react-router-dom';
import './App.css';
import Flow from './Flow';

function Hello() {
return (
Expand All @@ -21,7 +22,7 @@ export default function App() {
return (
<Router>
<Routes>
<Route path="/" element={<Hello />} />
<Route path="/" element={<Flow />} />
</Routes>
</Router>
);
Expand Down
Loading

0 comments on commit 5a150f2

Please sign in to comment.