From d5fc4305d5dcda2488c0f89d5ccd54eec49ebbea Mon Sep 17 00:00:00 2001 From: Matthew Grove Date: Fri, 26 Nov 2021 14:46:51 +0000 Subject: [PATCH] Remove front-end check for duplicate answer Prep for refactoring of processAnswer Cloud Function, which currently doesn't work if vocab item has same cleansed answer twice --- src/Progress.js | 304 +++++++++++++++++++++++------------------------- 1 file changed, 147 insertions(+), 157 deletions(-) diff --git a/src/Progress.js b/src/Progress.js index 2809f9a..235fa19 100644 --- a/src/Progress.js +++ b/src/Progress.js @@ -320,171 +320,161 @@ export default withRouter(class Progress extends React.Component { this.startLoading(); - if (!cleansedCurrentCorrect.includes(this.cleanseVocabString(this.state.answerInput))) { - this.state.functions.processAnswer({ - answer: this.state.answerInput, - progressId: this.props.match.params.progressId, - }).then(async (result) => { - if (result.data.typo) { - this.setState({ - typo: true, - loading: false, - canProceed: true, - }); - return true; - } - - const data = result.data; - let newState = { - currentAnswerStatus: data.correct ? null : false, - currentCorrect: data.correctAnswers, - moreAnswers: data.moreAnswers, - nextPrompt: data.nextPrompt ? data.nextPrompt.item : null, - nextSound: data.nextPrompt ? data.nextPrompt.sound : null, - nextSetOwner: data.nextPrompt ? data.nextPrompt.set_owner : null, - progress: data.progress, - totalQuestions: data.totalQuestions, - correct: data.totalCorrect, - incorrect: data.totalIncorrect, - currentVocabId: data.currentVocabId, - loading: false, - canProceed: true, - typo: false, - canStartTest: true, - }; - - if (data.correct) { - this.props.logEvent("correct_answer", { - progress_id: this.props.match.params.progressId, - }); - } else { - this.props.logEvent("incorrect_answer", { - progress_id: this.props.match.params.progressId, - }); - } - - if (this.state.mode === "lives") newState.lives = data.lives; - - if (data.correct) { - // correct answer given - newState.answerInput = ""; - // show next question if there are no more answers - if (!data.moreAnswers) newState = this.showNextQuestion(newState, newState); - } else { - // incorrect answer given - // store prompt and count=0 - // store answer if in lives mode and no lives left - newState.incorrectAnswers = this.state.incorrectAnswers; - newState.incorrectAnswers[data.currentVocabId] = { - prompt: this.state.currentPrompt, - answer: data.lives === 0 ? data.correctAnswers : "", - count: 0, - }; - } - - if ((data.correct || data.lives === 0) && !data.moreAnswers && this.state.incorrectAnswers[data.currentVocabId]) { - // all answers to question given correctly - // answer was previously wrong - // store correct answer - newState.incorrectAnswers = this.state.incorrectAnswers; - newState.incorrectAnswers[data.currentVocabId].answer = data.correctAnswers; - } - - let promises = []; - - if (data.duration) { - // test done - newState.duration = data.duration; - newState.averagePercentage = data.averagePercentage; - - this.props.logEvent("test_complete", { - progress_id: this.props.match.params.progressId, - }); - - promises.push(this.state.db.collection("progress") - .where("uid", "==", this.state.user.uid) - .where("setIds", "==", this.state.setIds) - .orderBy("start_time") - .get() - .then((querySnapshot) => { - newState.attemptNumber = querySnapshot.docs.map((doc) => doc.id).indexOf(this.props.match.params.progressId) + 1; - if (querySnapshot.docs.length > 1) - newState.attemptHistory = querySnapshot.docs.filter((doc) => doc.data().duration !== null) - .map((doc) => { - if (doc.id === this.props.match.params.progressId) newState.startTime = doc.data().start_time; - return { - x: new Date(doc.data().start_time), - y: (doc.data().correct.length / doc.data().questions.length * 100), - } - }); - })); - } - - if (data.incorrectAnswers) { - let unsavedAnswers = {}; - - if (!newState.incorrectAnswers) { - newState.incorrectAnswers = {}; - } - - data.incorrectAnswers.map((vocabId) => { - if (newState.incorrectAnswers[vocabId] && newState.incorrectAnswers[vocabId].answer !== "") { - // already been logged including prompt and correct answer - newState.incorrectAnswers[vocabId].count++; - } else { - // not been saved yet - // update count in unsaved answers - unsavedAnswers[vocabId] ? unsavedAnswers[vocabId]++ : unsavedAnswers[vocabId] = 1; - } - return true; - }); - - promises.push(Promise.all(Object.keys(unsavedAnswers).map((vocabId) => { - // get and store vocab docs that haven't already been stored (due to refresh) - const progressDocRef = this.state.db - .collection("progress") - .doc(this.props.match.params.progressId); - - newState.incorrectAnswers[vocabId] = { - count: unsavedAnswers[vocabId], - }; - - return Promise.all([ - progressDocRef.collection("terms") - .doc(vocabId) - .get().then((termDoc) => { - this.state.switchLanguage ? newState.incorrectAnswers[vocabId].answer = termDoc.data().item.split("/") : newState.incorrectAnswers[vocabId].prompt = termDoc.data().item; - }), - progressDocRef.collection("definitions") - .doc(vocabId) - .get().then((definitionDoc) => { - this.state.switchLanguage ? newState.incorrectAnswers[vocabId].prompt = definitionDoc.data().item : newState.incorrectAnswers[vocabId].answer = definitionDoc.data().item.split("/"); - }) - ]); - }))); - } - - await Promise.all(promises); - - this.setState(newState, () => { - if (!newState.duration) this.answerInput.focus() - }); - }).catch((error) => { - console.log(`Couldn't process answer: ${error}`); + this.state.functions.processAnswer({ + answer: this.state.answerInput, + progressId: this.props.match.params.progressId, + }).then(async (result) => { + if (result.data.typo) { this.setState({ + typo: true, loading: false, canProceed: true, }); - }); - } else { - this.setState({ - currentAnswerStatus: null, - answerInput: "", + return true; + } + + const data = result.data; + let newState = { + currentAnswerStatus: data.correct ? null : false, + currentCorrect: data.correctAnswers, + moreAnswers: data.moreAnswers, + nextPrompt: data.nextPrompt ? data.nextPrompt.item : null, + nextSound: data.nextPrompt ? data.nextPrompt.sound : null, + nextSetOwner: data.nextPrompt ? data.nextPrompt.set_owner : null, + progress: data.progress, + totalQuestions: data.totalQuestions, + correct: data.totalCorrect, + incorrect: data.totalIncorrect, + currentVocabId: data.currentVocabId, loading: false, canProceed: true, typo: false, + canStartTest: true, + }; + + if (data.correct) { + this.props.logEvent("correct_answer", { + progress_id: this.props.match.params.progressId, + }); + } else { + this.props.logEvent("incorrect_answer", { + progress_id: this.props.match.params.progressId, + }); + } + + if (this.state.mode === "lives") newState.lives = data.lives; + + if (data.correct) { + // correct answer given + newState.answerInput = ""; + // show next question if there are no more answers + if (!data.moreAnswers) newState = this.showNextQuestion(newState, newState); + } else { + // incorrect answer given + // store prompt and count=0 + // store answer if in lives mode and no lives left + newState.incorrectAnswers = this.state.incorrectAnswers; + newState.incorrectAnswers[data.currentVocabId] = { + prompt: this.state.currentPrompt, + answer: data.lives === 0 ? data.correctAnswers : "", + count: 0, + }; + } + + if ((data.correct || data.lives === 0) && !data.moreAnswers && this.state.incorrectAnswers[data.currentVocabId]) { + // all answers to question given correctly + // answer was previously wrong + // store correct answer + newState.incorrectAnswers = this.state.incorrectAnswers; + newState.incorrectAnswers[data.currentVocabId].answer = data.correctAnswers; + } + + let promises = []; + + if (data.duration) { + // test done + newState.duration = data.duration; + newState.averagePercentage = data.averagePercentage; + + this.props.logEvent("test_complete", { + progress_id: this.props.match.params.progressId, + }); + + promises.push(this.state.db.collection("progress") + .where("uid", "==", this.state.user.uid) + .where("setIds", "==", this.state.setIds) + .orderBy("start_time") + .get() + .then((querySnapshot) => { + newState.attemptNumber = querySnapshot.docs.map((doc) => doc.id).indexOf(this.props.match.params.progressId) + 1; + if (querySnapshot.docs.length > 1) + newState.attemptHistory = querySnapshot.docs.filter((doc) => doc.data().duration !== null) + .map((doc) => { + if (doc.id === this.props.match.params.progressId) newState.startTime = doc.data().start_time; + return { + x: new Date(doc.data().start_time), + y: (doc.data().correct.length / doc.data().questions.length * 100), + } + }); + })); + } + + if (data.incorrectAnswers) { + let unsavedAnswers = {}; + + if (!newState.incorrectAnswers) { + newState.incorrectAnswers = {}; + } + + data.incorrectAnswers.map((vocabId) => { + if (newState.incorrectAnswers[vocabId] && newState.incorrectAnswers[vocabId].answer !== "") { + // already been logged including prompt and correct answer + newState.incorrectAnswers[vocabId].count++; + } else { + // not been saved yet + // update count in unsaved answers + unsavedAnswers[vocabId] ? unsavedAnswers[vocabId]++ : unsavedAnswers[vocabId] = 1; + } + return true; + }); + + promises.push(Promise.all(Object.keys(unsavedAnswers).map((vocabId) => { + // get and store vocab docs that haven't already been stored (due to refresh) + const progressDocRef = this.state.db + .collection("progress") + .doc(this.props.match.params.progressId); + + newState.incorrectAnswers[vocabId] = { + count: unsavedAnswers[vocabId], + }; + + return Promise.all([ + progressDocRef.collection("terms") + .doc(vocabId) + .get().then((termDoc) => { + this.state.switchLanguage ? newState.incorrectAnswers[vocabId].answer = termDoc.data().item.split("/") : newState.incorrectAnswers[vocabId].prompt = termDoc.data().item; + }), + progressDocRef.collection("definitions") + .doc(vocabId) + .get().then((definitionDoc) => { + this.state.switchLanguage ? newState.incorrectAnswers[vocabId].prompt = definitionDoc.data().item : newState.incorrectAnswers[vocabId].answer = definitionDoc.data().item.split("/"); + }) + ]); + }))); + } + + await Promise.all(promises); + + this.setState(newState, () => { + if (!newState.duration) this.answerInput.focus() }); - } + }).catch((error) => { + console.log(`Couldn't process answer: ${error}`); + this.setState({ + loading: false, + canProceed: true, + }); + }); } }