Finalized the Speaking module exercise

This commit is contained in:
Tiago Ribeiro
2023-07-14 12:08:25 +01:00
parent 6a2fab4f88
commit 2c10a203a5
8 changed files with 128 additions and 24 deletions

View File

@@ -5,7 +5,17 @@ import {Module} from "@/interfaces";
import Selection from "@/exams/Selection";
import Reading from "@/exams/Reading";
import {Exam, ListeningExam, ReadingExam, SpeakingExam, UserSolution, WritingEvaluation, WritingExam, WritingExercise} from "@/interfaces/exam";
import {
Exam,
ListeningExam,
ReadingExam,
SpeakingExam,
UserSolution,
Evaluation,
WritingExam,
WritingExercise,
SpeakingExercise,
} from "@/interfaces/exam";
import Listening from "@/exams/Listening";
import Writing from "@/exams/Writing";
import {ToastContainer, toast} from "react-toastify";
@@ -19,7 +29,7 @@ import {v4 as uuidv4} from "uuid";
import useUser from "@/hooks/useUser";
import useExamStore from "@/stores/examStore";
import Layout from "@/components/High/Layout";
import {writingReverseMarking} from "@/utils/score";
import {speakingReverseMarking, writingReverseMarking} from "@/utils/score";
export const getServerSideProps = withIronSessionSsr(({req, res}) => {
const user = req.session.user;
@@ -119,11 +129,47 @@ export default function Page() {
}
};
const evaluateSpeakingAnswer = async (examId: string, exerciseId: string, solution: UserSolution) => {
const speakingExam = exams.find((x) => x.id === examId)!;
const exercise = speakingExam.exercises.find((x) => x.id === exerciseId)! as SpeakingExercise;
const blobResponse = await axios.get(exercise.userSolutions[0].solution.trim());
const audioBlob = Buffer.from(blobResponse.data, "binary");
const audioFile = new File([audioBlob], "audio.wav", {type: "audio/wav"});
const formData = new FormData();
formData.append("audio", audioFile, "audio.wav");
formData.append("question", `${exercise.text.replaceAll("\n", "")} You should talk about: ${exercise.prompts.join(", ")}`);
const config = {
headers: {
"Content-Type": "audio/mp3",
},
};
const response = await axios.post("/api/evaluate/speaking", formData, config);
if (response.status === 200) {
setUserSolutions([
...userSolutions.filter((x) => x.exercise !== exerciseId),
{
...solution,
score: {
correct: speakingReverseMarking[response.data.overall],
missing: 0,
total: 100,
},
solutions: [{id: exerciseId, solution: response.data.fullPath, evaluation: response.data}],
},
]);
}
};
const evaluateWritingAnswer = async (examId: string, exerciseId: string, solution: UserSolution) => {
const writingExam = exams.find((x) => x.id === examId)!;
const exercise = writingExam.exercises.find((x) => x.id === exerciseId)! as WritingExercise;
const response = await axios.post<WritingEvaluation>("/api/evaluate/writing", {
const response = await axios.post<Evaluation>("/api/evaluate/writing", {
question: `${exercise.prompt} ${exercise.attachment ? exercise.attachment.description : ""}`.replaceAll("\n", ""),
answer: solution.solutions[0].solution.trim().replaceAll("\n", " "),
});
@@ -155,11 +201,17 @@ export default function Page() {
const onFinish = (solutions: UserSolution[]) => {
const solutionIds = solutions.map((x) => x.exercise);
if (exam && exam.module === "writing" && solutions.length > 0 && !showSolutions) {
if (exam && (exam.module === "writing" || exam.module === "speaking") && solutions.length > 0 && !showSolutions) {
setHasBeenUploaded(true);
setIsEvaluationLoading(true);
Promise.all(
exam.exercises.map((exercise) => evaluateWritingAnswer(exam.id, exercise.id, solutions.find((x) => x.exercise === exercise.id)!)),
exam.exercises.map((exercise) =>
(exam.module === "writing" ? evaluateWritingAnswer : evaluateSpeakingAnswer)(
exam.id,
exercise.id,
solutions.find((x) => x.exercise === exercise.id)!,
),
),
).finally(() => {
setIsEvaluationLoading(false);
setHasBeenUploaded(false);