Added the audio player to the level exam
This commit is contained in:
@@ -18,6 +18,7 @@ import { Tab } from "@headlessui/react";
|
|||||||
import Modal from "@/components/Modal";
|
import Modal from "@/components/Modal";
|
||||||
import { typeCheckWordsMC } from "@/utils/type.check";
|
import { typeCheckWordsMC } from "@/utils/type.check";
|
||||||
import SectionNavbar from "../Navigation/SectionNavbar";
|
import SectionNavbar from "../Navigation/SectionNavbar";
|
||||||
|
import AudioPlayer from "@/components/Low/AudioPlayer";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
exam: LevelExam;
|
exam: LevelExam;
|
||||||
@@ -54,6 +55,7 @@ export default function Level({ exam, showSolutions = false, onFinish, preview =
|
|||||||
// In case client want to switch back
|
// In case client want to switch back
|
||||||
const textRenderDisabled = true;
|
const textRenderDisabled = true;
|
||||||
|
|
||||||
|
const [timesListened, setTimesListened] = useState(0);
|
||||||
const [showSubmissionModal, setShowSubmissionModal] = useState(false);
|
const [showSubmissionModal, setShowSubmissionModal] = useState(false);
|
||||||
const [showQuestionsModal, setShowQuestionsModal] = useState(false);
|
const [showQuestionsModal, setShowQuestionsModal] = useState(false);
|
||||||
const [continueAnyways, setContinueAnyways] = useState(false);
|
const [continueAnyways, setContinueAnyways] = useState(false);
|
||||||
@@ -167,6 +169,8 @@ export default function Level({ exam, showSolutions = false, onFinish, preview =
|
|||||||
if (partIndex < exam.parts.length - 1 && exam.parts[partIndex + 1].context && !textRenderDisabled) {
|
if (partIndex < exam.parts.length - 1 && exam.parts[partIndex + 1].context && !textRenderDisabled) {
|
||||||
setTextRender(true);
|
setTextRender(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setTimesListened(0);
|
||||||
setPartIndex(partIndex + 1);
|
setPartIndex(partIndex + 1);
|
||||||
setExerciseIndex(0);
|
setExerciseIndex(0);
|
||||||
setQuestionIndex(0);
|
setQuestionIndex(0);
|
||||||
@@ -247,6 +251,40 @@ export default function Level({ exam, showSolutions = false, onFinish, preview =
|
|||||||
}, 0) + (questionIndex + 1);
|
}, 0) + (questionIndex + 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const renderAudioPlayer = () => (
|
||||||
|
<div className="flex flex-col gap-8 w-full bg-mti-gray-seasalt rounded-xl py-8 px-16">
|
||||||
|
{exam?.parts[partIndex]?.audio?.source ? (
|
||||||
|
<>
|
||||||
|
<div className="flex flex-col w-full gap-2">
|
||||||
|
<h4 className="text-xl font-semibold">Please listen to the following audio attentively.</h4>
|
||||||
|
<span className="text-base">
|
||||||
|
{(() => {
|
||||||
|
const audioRepeatTimes = exam?.parts[partIndex]?.audio?.repeatableTimes;
|
||||||
|
return audioRepeatTimes && audioRepeatTimes > 0
|
||||||
|
? `You will only be allowed to listen to the audio ${audioRepeatTimes - timesListened} time(s).`
|
||||||
|
: "You may listen to the audio as many times as you would like.";
|
||||||
|
})()}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="rounded-xl flex flex-col gap-4 items-center w-full h-fit">
|
||||||
|
<AudioPlayer
|
||||||
|
key={partIndex}
|
||||||
|
src={exam?.parts[partIndex]?.audio?.source ?? ''}
|
||||||
|
color="listening"
|
||||||
|
onEnd={() => setTimesListened((prev) => prev + 1)}
|
||||||
|
disabled={exam?.parts[partIndex]?.audio?.repeatableTimes != null &&
|
||||||
|
timesListened === exam.parts[partIndex]?.audio?.repeatableTimes}
|
||||||
|
disablePause
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<span>This section will be displayed the audio once it has been generated.</span>
|
||||||
|
)}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
const renderText = () => (
|
const renderText = () => (
|
||||||
<>
|
<>
|
||||||
<div className={clsx("flex flex-col gap-6 w-full bg-mti-gray-seasalt rounded-xl mt-4 relative py-8 px-16")}>
|
<div className={clsx("flex flex-col gap-6 w-full bg-mti-gray-seasalt rounded-xl mt-4 relative py-8 px-16")}>
|
||||||
@@ -265,7 +303,7 @@ export default function Level({ exam, showSolutions = false, onFinish, preview =
|
|||||||
</h4>
|
</h4>
|
||||||
)}
|
)}
|
||||||
<div className="border border-mti-gray-dim w-full rounded-full opacity-10" />
|
<div className="border border-mti-gray-dim w-full rounded-full opacity-10" />
|
||||||
{exam.parts[partIndex].context &&
|
{(exam.parts[partIndex].context || exam.parts[partIndex].text) &&
|
||||||
<TextComponent
|
<TextComponent
|
||||||
part={exam.parts[partIndex]}
|
part={exam.parts[partIndex]}
|
||||||
contextWords={contextWords}
|
contextWords={contextWords}
|
||||||
@@ -427,13 +465,15 @@ export default function Level({ exam, showSolutions = false, onFinish, preview =
|
|||||||
renderText() :
|
renderText() :
|
||||||
<>
|
<>
|
||||||
{exam.parts[partIndex]?.context && renderText()}
|
{exam.parts[partIndex]?.context && renderText()}
|
||||||
|
{exam.parts[partIndex]?.audio && renderAudioPlayer()}
|
||||||
{(showSolutions) ?
|
{(showSolutions) ?
|
||||||
currentExercise && renderSolution(currentExercise, nextExercise, previousExercise) :
|
currentExercise && renderSolution(currentExercise, nextExercise, previousExercise) :
|
||||||
currentExercise && renderExercise(currentExercise, exam.id, next, previousExercise)
|
currentExercise && renderExercise(currentExercise, exam.id, next, previousExercise)
|
||||||
}
|
}
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
</>)
|
</>
|
||||||
|
)
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [textRender, currentExercise, changedPrompt]);
|
}, [textRender, currentExercise, changedPrompt]);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user