Created a simple test page where I'll implement the recorder for the speaking module

This commit is contained in:
Tiago Ribeiro
2023-06-14 14:37:12 +01:00
parent 31e2e56833
commit 31f2eb510e
4 changed files with 146 additions and 574 deletions

View File

@@ -1,13 +1,19 @@
/* eslint-disable @next/next/no-img-element */
import Head from "next/head";
import Navbar from "@/components/Navbar";
import {ToastContainer} from "react-toastify";
import {withIronSessionSsr} from "iron-session/next";
import {sessionOptions} from "@/lib/session";
import useUser from "@/hooks/useUser";
import Sidebar from "@/components/Sidebar";
import {ReactMediaRecorder} from "react-media-recorder";
import dynamic from "next/dynamic";
import {BsCheckCircleFill, BsMicFill, BsPauseCircle, BsPlayCircle, BsPlayFill, BsTrashFill} from "react-icons/bs";
import {useEffect, useState} from "react";
const ReactMediaRecorder = dynamic(() => import("react-media-recorder").then((mod) => mod.ReactMediaRecorder), {
ssr: false,
});
export const getServerSideProps = withIronSessionSsr(({req, res}) => {
const user = req.session.user;
@@ -30,6 +36,21 @@ export const getServerSideProps = withIronSessionSsr(({req, res}) => {
export default function Page() {
const {user} = useUser({redirectTo: "/login"});
const [recordingDuration, setRecordingDuration] = useState(0);
const [isRecording, setIsRecording] = useState(false);
useEffect(() => {
let recordingInterval: NodeJS.Timer | undefined = undefined;
if (isRecording) {
recordingInterval = setInterval(() => setRecordingDuration((prev) => prev + 1), 1000);
} else if (recordingInterval) {
clearInterval(recordingInterval);
}
return () => {
if (recordingInterval) clearInterval(recordingInterval);
};
}, [isRecording]);
return (
<>
@@ -51,13 +72,115 @@ export default function Page() {
<div className="w-5/6 h-full mr-8 bg-white shadow-md rounded-2xl p-12 flex flex-col gap-12">
<ReactMediaRecorder
audio
askPermissionOnMount
render={({status, startRecording, stopRecording, mediaBlobUrl}) => (
<div>
<p>{status}</p>
<button onClick={startRecording}>Start Recording</button>
<button onClick={stopRecording}>Stop Recording</button>
<audio src={mediaBlobUrl} controls autoPlay loop />
render={({status, startRecording, stopRecording, pauseRecording, resumeRecording, clearBlobUrl, mediaBlobUrl}) => (
<div className="w-full p-4 px-8 bg-transparent border-2 border-mti-gray-platinum rounded-2xl flex-col gap-8 items-center">
<p className="text-base font-normal">Record your answer:</p>
<div className="flex gap-8 items-center justify-center py-8">
{status === "idle" && (
<>
{!mediaBlobUrl && <div className="w-full h-2 max-w-4xl bg-mti-gray-smoke rounded-full" />}
{status === "idle" && (
<BsMicFill
onClick={() => {
setRecordingDuration(0);
startRecording();
setIsRecording(true);
}}
className="h-5 w-5 text-mti-gray-cool cursor-pointer"
/>
)}
</>
)}
{status === "recording" && (
<>
<div className="flex gap-4 items-center">
<span className="text-xs w-9">
{Math.round(recordingDuration / 60)
.toString(10)
.padStart(2, "0")}
:
{Math.round(recordingDuration % 60)
.toString(10)
.padStart(2, "0")}
</span>
</div>
<div className="w-full h-2 max-w-4xl bg-mti-gray-smoke rounded-full" />
<div className="flex gap-4 items-center">
<BsPauseCircle
onClick={() => {
setIsRecording(false);
pauseRecording();
}}
className="text-red-500 w-8 h-8 cursor-pointer"
/>
<BsCheckCircleFill
onClick={() => {
setIsRecording(false);
stopRecording();
}}
className="text-mti-green-light w-8 h-8 cursor-pointer"
/>
</div>
</>
)}
{status === "paused" && (
<>
<div className="flex gap-4 items-center">
<span className="text-xs w-9">
{Math.round(recordingDuration / 60)
.toString(10)
.padStart(2, "0")}
:
{Math.round(recordingDuration % 60)
.toString(10)
.padStart(2, "0")}
</span>
</div>
<div className="w-full h-2 max-w-4xl bg-mti-gray-smoke rounded-full" />
<div className="flex gap-4 items-center">
<BsPlayCircle
onClick={() => {
setIsRecording(true);
resumeRecording();
}}
className="text-mti-green-light w-8 h-8 cursor-pointer"
/>
<BsCheckCircleFill
onClick={() => {
setIsRecording(false);
stopRecording();
}}
className="text-mti-green-light w-8 h-8 cursor-pointer"
/>
</div>
</>
)}
{status === "stopped" && (
<>
<BsPlayFill className="text-mti-gray-cool cursor-pointer w-5 h-5" />
<div className="w-full h-2 max-w-4xl bg-mti-gray-smoke rounded-full" />
<div className="flex gap-4 items-center">
<BsTrashFill
className="text-mti-gray-cool cursor-pointer w-5 h-5"
onClick={() => {
setRecordingDuration(0);
clearBlobUrl();
}}
/>
<BsMicFill
onClick={() => {
clearBlobUrl();
setRecordingDuration(0);
startRecording();
setIsRecording(true);
}}
className="h-5 w-5 text-mti-gray-cool cursor-pointer"
/>
</div>
</>
)}
</div>
</div>
)}
/>