Files
Signlanguage_Datacollector/frontend/src/components/RandomVideoUpload.tsx
2023-03-14 14:25:46 +01:00

202 lines
7.8 KiB
TypeScript
Executable File

import React, { useState, useRef, useEffect, ChangeEvent } from 'react';
import { Sign, SignVideo, SimpleSign } from '../types/sign';
import { useParams } from 'react-router-dom';
import { getRandomSign, getSign } from '../services/signs';
import ReactModal from 'react-modal';
import { acceptVideo, deleteVideo, uploadSignVideo } from '../services/signvideos';
import { LoadingButton } from './loading-button/loading-button';
import VideoRecorder from 'react-video-recorder';
import SignVideoGrid from './SignVideoGrid';
import SignVideoPlayer from './SignVideoPlayer';
const RandomSignUpload: React.FC = () => {
const [sign, setSign] = useState<SimpleSign | null>(null);
const [signVideo, setSignVideo] = useState<string | null>(null);
const [recordedBlob, setRecordedBlob] = useState<Blob | null>(null);
const signVideoRef = useRef<HTMLVideoElement>(null);
const popupVideoRef = useRef<HTMLVideoElement>(null);
const [popUpShown, setPopUpShown] = useState(false);
const [recorderKey, setRecorderKey] = useState(1);
const [uploadProgress, setUploadProgress] = useState<number | null>(null);
const [videoUrl, setVideoUrl] = useState<string | null>(null);
useEffect(() => {
if (recordedBlob) {
setVideoUrl(URL.createObjectURL(recordedBlob));
setPopUpShown(true);
} else {
setVideoUrl(null);
}
}, [recordedBlob]);
const handleUploadProgress = (progess: number) => {
if (progess) {
setUploadProgress(progess);
}
}
const handleUpload = async () => {
setUploadProgress(0);
uploadSignVideo(sign!.id, recordedBlob!, handleUploadProgress).then((response) => {
console.log("upload complete");
setPopUpShown(false);
// get new random sign
get_random_sign();
// add the new sign video to the sign
const newSign = { ...sign! };
setSign(newSign);
setUploadProgress(100);
}).catch((error) => {
setUploadProgress(null);
}
);
}
useEffect(() => {
if (signVideoRef.current) {
signVideoRef.current.play();
}
}, []);
const get_random_sign = () => {
getRandomSign().then((response) => {
// check if the sign is different from the current one
if (sign === null || sign.id !== response.id) {
setSign(response);
setUploadProgress(null);
// set the video url
setSignVideo(response.video_url);
} else {
// get a new sign
get_random_sign();
}
}
);
}
useEffect(() => {
// get random sign
get_random_sign();
}, []);
const dismissPopup = () => {
setPopUpShown(false);
// remove the recorded blob
setRecordedBlob(null);
};
return (
<div>
{
sign ? <div>
<div className="flex items-center justify-between">
<h1 className="text-8xl font-bold mx-auto text-center">{sign.name}</h1>
</div>
<div className="flex">
<button className="ml-auto p-2 rounded-full text-red-600 hover:bg-red-600 hover:text-white" onClick={get_random_sign}>
Skip
</button>
</div>
<div className="flex">
{
signVideo &&
<div className="w-1/2">
<video key={signVideo} loop controls width='100%' height='100%'>
<source src={signVideo} type='video/mp4' />
</video>
</div>
}
<div id="recorder-wrapper" className="w-1/2">
<VideoRecorder
key={recorderKey}
countdownTime={3000}
onRecordingComplete={(blob) => {
setRecordedBlob(blob)
// reset the VideoRecorder
setRecorderKey(prevKey => prevKey + 1);
}}
showReplayControls={false}
replayVideoAutoplayAndLoopOff={true}
isOnInitially
timeLimit={4000}
/>
</div>
</div>
</div > : <div>Loading...</div>
}
<ReactModal
isOpen={popUpShown}
shouldCloseOnOverlayClick={false}
className="modal bg-white rounded-3xl bg-gray-300 p-7"
ariaHideApp={false}
style={{
content: {
position: "absolute",
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
},
}}
>
{videoUrl &&
<div>
<video key="vid" ref={popupVideoRef} src={videoUrl!} controls loop className="pb-4" />
<LoadingButton title="Upload" onClick={handleUpload} progress={uploadProgress} />
</div>
}
{(uploadProgress === null || uploadProgress === 0) &&
<button onClick={dismissPopup} className="bg-white p-2 rounded-full text-red-600 hover:bg-red-600 hover:text-white absolute top-1 right-1">
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
}
</ReactModal>
<div>
<p className="ml-4 text-lg font-bold my-4">Hoe werkt het?</p>
<div className="ml-4 flex flex-col my-4">
<div className="flex items-center">
<span className="text-xl font-bold mr-2">Stap 1:</span>
<span className="text-lg">Bekijk de video aan de linkerkant en doe het teken zelf na (bovenlichaam moet zichtbaar zijn).</span>
</div>
<div className="flex items-center mt-2">
<span className="text-xl font-bold mr-2">Stap 2:</span>
<span className="text-lg">Klik op de rode opnameknop om uw eigen video op te nemen.</span>
</div>
<div className="flex items-center mt-2">
<span className="text-xl font-bold mr-2">Stap 3:</span>
<span className="text-lg">Voer het teken uit en spreek het woord uit.</span>
</div>
<div className="flex items-center mt-2">
<span className="text-xl font-bold mr-2">Stap 4:</span>
<span className="text-lg">Zodra u uw video hebt opgenomen, kunt u ervoor kiezen om deze te uploaden door op de knop 'Uploaden' te klikken of het pop-upvenster te sluiten.</span>
</div>
<div className="flex items-center mt-2">
<span className="text-xl font-bold mr-2">Stap 5:</span>
<span className="text-lg">Uw video wordt beoordeeld door ons team.</span>
</div>
</div>
</div>
</div>
);
};
export default RandomSignUpload;