Commit d9272568 authored by supundileepa00's avatar supundileepa00

feat: Initial UI development with main functionalities

parent 5b04c61f
...@@ -16,6 +16,7 @@ import { ...@@ -16,6 +16,7 @@ import {
InputAdornment, InputAdornment,
Stack, Stack,
Tooltip, Tooltip,
Container,
} from '@mui/material'; } from '@mui/material';
// layouts // layouts
import MainLayout from '../layouts/main'; import MainLayout from '../layouts/main';
...@@ -99,142 +100,156 @@ export default function AboutPage() { ...@@ -99,142 +100,156 @@ export default function AboutPage() {
<Head> <Head>
<title>Translate SSL to Text</title> <title>Translate SSL to Text</title>
</Head> </Head>
<ButtonGroup disableElevation variant="contained" aria-label="Disabled elevation buttons">
<Button <Container maxWidth="l">
variant={checkTranalationTypeForUpload()} <ButtonGroup disableElevation variant="contained" aria-label="Disabled elevation buttons">
startIcon={<UploadIcon />} <Button
onClick={() => { variant={checkTranalationTypeForUpload()}
setIsUploadFile(true); startIcon={<UploadIcon />}
}} onClick={() => {
> setIsUploadFile(true);
Upload }}
</Button> >
<Button Upload
variant={checkTranalationTypeForRecord()} </Button>
endIcon={<EmergencyRecordingIcon />} <Button
onClick={() => { variant={checkTranalationTypeForRecord()}
setIsUploadFile(false); startIcon={<EmergencyRecordingIcon />}
}} onClick={() => {
> setIsUploadFile(false);
Record }}
</Button> >
</ButtonGroup> Record
{isUploadFile ? ( </Button>
<Box sx={{ flexGrow: 1 }}> </ButtonGroup>
<Card> {isUploadFile ? (
<CardHeader title="Upload a video containing Sign Language" /> <Box sx={{ flexGrow: 1 }}>
<Grid container spacing={2}> <Card>
<Grid item xs={12} md={6}> <CardHeader title="Upload a video containing Sign Language" />
<Card> <Grid container spacing={2}>
<CardContent> <Grid item xs={12} md={6}>
<Upload <Card>
file={file} <CardContent>
onDrop={handleDropSingleFile} <Upload
onDelete={() => setFile(null)} file={file}
/> onDrop={handleDropSingleFile}
</CardContent> onDelete={() => setFile(null)}
</Card>
</Grid>
<Grid item xs={12} md={6}>
<Card sx={{ p: 5 }}>
<Box
display="grid"
gridTemplateColumns={{ xs: 'repeat(1, 1fr)', md: 'repeat(2, 1fr)' }}
gap={5}
>
<Stack spacing={2}>
<Typography variant="overline" sx={{ color: 'text.secondary' }}>
on Change
</Typography>
<TextField
fullWidth
value={value}
onChange={handleChange}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<Tooltip title="Copy">
<IconButton onClick={() => onCopy(value)}>
<Iconify icon="eva:copy-fill" width={24} />
</IconButton>
</Tooltip>
</InputAdornment>
),
}}
/> />
</Stack> </CardContent>
</Box> </Card>
</Card> </Grid>
<Grid item xs={12} md={6}>
<Card sx={{ p: 5 }}>
<Box
display="grid"
gridTemplateColumns={{ xs: 'repeat(1, 1fr)', md: 'repeat(2, 1fr)' }}
gap={5}
>
<Stack spacing={2}>
<Typography variant="overline" sx={{ color: 'text.secondary' }}>
on Change
</Typography>
<TextField
fullWidth
value={value}
onChange={handleChange}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<Tooltip title="Copy">
<IconButton onClick={() => onCopy(value)}>
<Iconify icon="eva:copy-fill" width={24} />
</IconButton>
</Tooltip>
</InputAdornment>
),
}}
/>
</Stack>
</Box>
</Card>
</Grid>
<Grid item xs={12} md={12}>
<center>
<Button
variant="contained"
style={{ width: '200px', height: '60px', fontSize: '20px' }}
sx={{
mb: 3,
}}
>
Translate
</Button>
</center>
</Grid>
</Grid> </Grid>
</Grid> </Card>
</Card> </Box>
</Box> ) : (
) : ( // Video Capture
// Video Capture
<Box sx={{ flexGrow: 1 }}>
<Box sx={{ flexGrow: 1 }}> <Card>
<Card> <CardHeader title="Upload a video containing Sign Language" />
<CardHeader title="Upload a video containing Sign Language" /> <Grid container spacing={2}>
<Grid container spacing={2}> <Grid item xs={12} md={6}>
<Grid item xs={12} md={6}> <Card>
<Card> <CardContent>
<CardContent> <WebcamStreamCapture />
<WebcamStreamCapture /> </CardContent>
</CardContent> </Card>
</Card> </Grid>
</Grid> <Grid item xs={12} md={6}>
<Grid item xs={12} md={6}> <Card sx={{ p: 5 }}>
<Card sx={{ p: 5 }}> <Box
<Box display="grid"
display="grid" gridTemplateColumns={{ xs: 'repeat(1, 1fr)', md: 'repeat(2, 1fr)' }}
gridTemplateColumns={{ xs: 'repeat(1, 1fr)', md: 'repeat(2, 1fr)' }} gap={5}
gap={5} >
> <Stack spacing={2}>
<Stack spacing={2}> <Typography variant="overline" sx={{ color: 'text.secondary' }}>
<Typography variant="overline" sx={{ color: 'text.secondary' }}> on Change
on Change </Typography>
</Typography>
<TextField
<TextField fullWidth
fullWidth value={value}
value={value} onChange={handleChange}
onChange={handleChange} InputProps={{
InputProps={{ endAdornment: (
endAdornment: ( <InputAdornment position="end">
<InputAdornment position="end"> <Tooltip title="Copy">
<Tooltip title="Copy"> <IconButton onClick={() => onCopy(value)}>
<IconButton onClick={() => onCopy(value)}> <Iconify icon="eva:copy-fill" width={24} />
<Iconify icon="eva:copy-fill" width={24} /> </IconButton>
</IconButton> </Tooltip>
</Tooltip> </InputAdornment>
</InputAdornment> ),
), }}
}} />
/> </Stack>
</Stack> </Box>
</Box> </Card>
</Card> </Grid>
<Grid item xs={12} md={12}>
<center>
<Button
variant="contained"
style={{ width: '200px', height: '60px', fontSize: '20px' }}
sx={{
mb: 3,
}}
>
Translate
</Button>
</center>
</Grid>
</Grid> </Grid>
</Grid> </Card>
</Card> </Box>
</Box> )}
// <RecordView /> </Container>
)}
</> </>
); );
} }
const RecordView = () => {
const { status, startRecording, stopRecording, mediaBlobUrl } = useReactMediaRecorder({
video: true,
});
return (
<div>
<p>{status}</p>
<button onClick={startRecording}>Start Recording</button>
<button onClick={stopRecording}>Stop Recording</button>
<video src={mediaBlobUrl} controls autoPlay loop />
</div>
);
};
.videoContainer {
position: relative;
width: 50%;
padding-top: 56.25%; /* 16:9 aspect ratio */
}
.futuristicVideo {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
outline: none;
background-color: black;
opacity: 0.8;
filter: blur(4px);
transition: opacity 0.5s, filter 0.5s;
}
.futuristicVideo:hover {
opacity: 1;
filter: blur(0);
}
import React from 'react'; import React, { useEffect, useState } from 'react';
import Webcam from 'react-webcam'; import Webcam from 'react-webcam';
import { Box, Button } from '@mui/material'; import { Box, Button, Container, Grid, Stack } from '@mui/material';
import StopIcon from '@mui/icons-material/Stop';
import RadioButtonCheckedIcon from '@mui/icons-material/RadioButtonChecked';
import styles from './WebcamStreamCapture.module.css';
const WebcamStreamCapture = () => { const WebcamStreamCapture = () => {
const webcamRef = React.useRef(null); const webcamRef = React.useRef(null);
const mediaRecorderRef = React.useRef(null); const mediaRecorderRef = React.useRef(null);
...@@ -10,7 +12,10 @@ const WebcamStreamCapture = () => { ...@@ -10,7 +12,10 @@ const WebcamStreamCapture = () => {
const [mediaBlobUrl, setMediaBlobUrl] = React.useState([]); const [mediaBlobUrl, setMediaBlobUrl] = React.useState([]);
const handleStartCaptureClick = React.useCallback(() => { const handleStartCaptureClick = React.useCallback(() => {
setRecordedChunks([]);
setMediaBlobUrl([]);
setCapturing(true); setCapturing(true);
mediaRecorderRef.current = new MediaRecorder(webcamRef.current.stream, { mediaRecorderRef.current = new MediaRecorder(webcamRef.current.stream, {
mimeType: 'video/webm', mimeType: 'video/webm',
}); });
...@@ -27,8 +32,18 @@ const WebcamStreamCapture = () => { ...@@ -27,8 +32,18 @@ const WebcamStreamCapture = () => {
[setRecordedChunks] [setRecordedChunks]
); );
const handleStopCaptureClick = React.useCallback(() => { const handleStopCaptureClick = React.useCallback(async () => {
mediaRecorderRef.current.stop(); mediaRecorderRef.current.stop();
const blob = new Blob(recordedChunks, {
type: 'video/mp4',
});
const url = await URL.createObjectURL(blob);
console.log(url);
await setMediaBlobUrl(url);
setCapturing(false); setCapturing(false);
}, [mediaRecorderRef, webcamRef, setCapturing]); }, [mediaRecorderRef, webcamRef, setCapturing]);
...@@ -49,20 +64,71 @@ const WebcamStreamCapture = () => { ...@@ -49,20 +64,71 @@ const WebcamStreamCapture = () => {
} }
}, [recordedChunks]); }, [recordedChunks]);
// Styles for camera
const [width, setWidth] = useState(window.innerWidth);
const handleResize = () => {
setWidth(window.innerWidth);
};
useEffect(() => {
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return ( return (
<> <>
<Webcam audio={false} ref={webcamRef} /> <Grid container spacing={2}>
{capturing ? ( <Grid item xs={12}>
<Button onClick={handleStopCaptureClick}>Stop Capture</Button> <center>
) : ( <Webcam audio={false} ref={webcamRef} style={{ width: '100%', maxWidth: '500px' }} />
<Button onClick={handleStartCaptureClick}>Start Capture</Button> </center>
)} </Grid>
{recordedChunks.length > 0 && <Button onClick={handleDownload}>Download</Button>} <Grid item xs={12}>
<video src={mediaBlobUrl} controls autoPlay loop /> <center>
{capturing ? (
<Button
onClick={handleStopCaptureClick}
startIcon={<StopIcon />}
color="error"
variant="contained"
>
Stop Capture
</Button>
) : (
<Button
onClick={handleStartCaptureClick}
startIcon={<RadioButtonCheckedIcon />}
color="error"
variant="contained"
>
Start Capture
</Button>
)}
{recordedChunks.length > 0 && (
<Button
onClick={handleDownload}
variant="contained"
sx={{
ml: 1,
}}
>
Download
</Button>
)}
</center>
</Grid>
<Grid item xs={12}>
<center>
<video src={mediaBlobUrl} controls autoPlay />
</center>
{/* <div className={styles.videoContainer}>
<video className={styles.futuristicVideo} src={mediaBlobUrl} controls autoPlay />
</div> */}
</Grid>
</Grid>
</> </>
); );
}; };
export default WebcamStreamCapture; export default WebcamStreamCapture;
// https://www.npmjs.com/package/react-webcam
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment