diff --git a/frontend/src/config.ts b/frontend/src/config.ts index de3389e..4bb76bd 100644 --- a/frontend/src/config.ts +++ b/frontend/src/config.ts @@ -3,3 +3,6 @@ export const LEVENSHTEIN_MAX_DISTANCE = 2; // export const BACKEND_URL = "http://127.0.0.1"; export const BACKEND_URL = "https://192.168.178.100"; + +// How often a wrongly answered group will be readded to the review queue +export const MAX_ERROR_THRESHOLD = 2; diff --git a/frontend/src/pages/review.tsx b/frontend/src/pages/review.tsx index d21d5a2..4e1f282 100644 --- a/frontend/src/pages/review.tsx +++ b/frontend/src/pages/review.tsx @@ -25,7 +25,7 @@ import { IVocab, IReviewCard, vocabToReviewCard, reviewQTypeToStr } from "../mod import { ReviewType, IReviewMetadata } from "../models/review"; import { levW } from "../algorithms/levenshtein"; -import { LEVENSHTEIN_MAX_DISTANCE } from "../config"; +import { LEVENSHTEIN_MAX_DISTANCE, MAX_ERROR_THRESHOLD } from "../config"; import { Queue } from "../utils/queue"; @@ -63,6 +63,9 @@ const ReviewPageWithRouter = withRouter( // Used for positioning the popover private buttonRef: HTMLButtonElement; private inputRef: HTMLInputElement; + // How often a group has been wrongly answered + // (Mapping: Vocab Id -> amount of times it was wrongly answered) + private error_data = {}; // Mapping: Vocab Id -> Correctly answered private sm2_metadata: any = {}; private score_delta = 0; @@ -97,6 +100,9 @@ const ReviewPageWithRouter = withRouter( // Convert the vocab items into review queue cards res.forEach(vocab => { + // Set the error data for the group + this.error_data[vocab.id] = 0; + vocabToReviewCard(vocab).forEach(this.reviewQueue.enqueue); }); @@ -182,8 +188,10 @@ const ReviewPageWithRouter = withRouter( // Check if the given answer is somewhere in the german words const input = this.inputRef.value || ""; + const { current } = this.props; + // Map all possible answers to lowercase ( => ignore casing) - const answers = this.props.current.answers.map((el) => el.toLowerCase()); + const answers = current.answers.map((el) => el.toLowerCase()); // Calculate the distances to all possible answers const dists = answers.map((el) => levW(input.toLowerCase(), el)); // Find the lowest distance @@ -203,7 +211,7 @@ const ReviewPageWithRouter = withRouter( if (this.reviewQueue.size() === 0) { // Update the metadata const newMeta = this.increaseMeta(1, 0); - this.props.setReview(this.props.current, newMeta); + this.props.setReview(current, newMeta); this.props.setLastReview(newMeta, this.sm2_metadata, this.score_delta); this.props.setLoading(true); @@ -221,6 +229,22 @@ const ReviewPageWithRouter = withRouter( } else { // Update the metadata this.updateGroupSM2(false); + + // Update the error data + this.error_data[current.id] += 1; + if (this.error_data[current.id] <= MAX_ERROR_THRESHOLD) { + // Read the vocabulary group to the queue + // Find the vocabulary item + // TODO: if(!vocab) + const vocab = this.vocab.find(el => el.id === current.id); + + // Re-add the vocabulary group + // NOTE: We don't need to force a re-render, as the state + // will be updated since we need to show the popover. + vocabToReviewCard(vocab).forEach(this.reviewQueue.enqueue); + } + + // TODO: Is this the correct amount this.score_delta -= 1; this.props.setReview(this.props.current, this.increaseMeta(0, 1)); this.props.setPopover(true, "Das war nicht richtig", "red", "white");