feat: Implement SM2
This commit is contained in:
@@ -4,3 +4,5 @@ rm -rf dist/
|
||||
./node_modules/.bin/parcel build --out-dir dist/app src/index.html
|
||||
chmod 705 dist dist/app
|
||||
chmod 604 dist/app/*
|
||||
|
||||
#sed "s/\/src/\/app\/src/" dist/app/index.html
|
||||
|
||||
@@ -106,7 +106,8 @@ export default class Application extends React.Component<IProps> {
|
||||
});
|
||||
}
|
||||
|
||||
setLastReview = (meta: IReviewMetadata) => {
|
||||
// TODO: Type?
|
||||
setLastReview = (meta: IReviewMetadata, sm2: any) => {
|
||||
// Update the state
|
||||
this.props.setLastReview(meta);
|
||||
|
||||
@@ -119,6 +120,7 @@ export default class Application extends React.Component<IProps> {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
meta,
|
||||
sm2,
|
||||
}),
|
||||
}).then(resp => resp.json(), err => {
|
||||
console.log("Application::setLastReview: POSTing last results failed");
|
||||
|
||||
@@ -33,6 +33,7 @@ interface IProps {
|
||||
levelId?: number;
|
||||
vocabByLevel?: (level: number) => Promise<IVocab[]>;
|
||||
vocabByQueue?: () => Promise<IVocab[]>;
|
||||
setLastReview: (meta: IReviewMetadata, sm2: any) => void;
|
||||
reviewType: ReviewType;
|
||||
|
||||
history: any;
|
||||
@@ -51,7 +52,6 @@ interface IProps {
|
||||
setSummary: (state: boolean) => void;
|
||||
setPopover: (state: boolean, text: string, color: string, textColor: string) => void;
|
||||
drawerButtonState: (state: boolean) => void;
|
||||
setLastReview: (meta: IReviewMetadata) => void;
|
||||
setReview: (curent: IReviewCard, meta: IReviewMetadata) => void;
|
||||
setLoading: (state: boolean) => void;
|
||||
}
|
||||
@@ -63,6 +63,7 @@ const ReviewPageWithRouter = withRouter(
|
||||
// Used for positioning the popover
|
||||
private buttonRef: HTMLButtonElement;
|
||||
private inputRef: HTMLInputElement;
|
||||
// Mapping: Vocab Id -> Correctly answered
|
||||
private sm2_metadata: any = {};
|
||||
|
||||
constructor(props: any) {
|
||||
@@ -133,6 +134,46 @@ const ReviewPageWithRouter = withRouter(
|
||||
return this.vocab.find((el) => el.id === this.props.current.id);
|
||||
}
|
||||
|
||||
// When a vocabulary item has been answered, we need to update
|
||||
// the group's SuperMemo2-data.
|
||||
// We update based on the following State-Machine: (C = Correct; W = Wrong)
|
||||
// Answer | Group | New group
|
||||
// | | state
|
||||
// -------+-------+----------
|
||||
// C | C | C
|
||||
// C | W | W
|
||||
// W | C | W
|
||||
// W | W | W
|
||||
// (1)C | - | C
|
||||
// (2)W | - | W
|
||||
// @correct: Was the answer given correct?
|
||||
updateGroupSM2 = (correct: boolean) => {
|
||||
const { id } = this.props.current;
|
||||
switch (correct) {
|
||||
case true:
|
||||
// Case (1)
|
||||
if (!(id in this.sm2_metadata)) {
|
||||
this.sm2_metadata[id] = true;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (this.sm2_metadata[id]) {
|
||||
case true:
|
||||
this.sm2_metadata[id] = true;
|
||||
break;
|
||||
case false:
|
||||
this.sm2_metadata[id] = false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case false:
|
||||
// We don't need to explicitly catch case (2), as we set
|
||||
// anything, that was incorrectly answered to false.
|
||||
this.sm2_metadata[id] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
checkInput = () => {
|
||||
// Check if the given answer is somewhere in the german words
|
||||
const input = this.inputRef.value || "";
|
||||
@@ -146,12 +187,14 @@ const ReviewPageWithRouter = withRouter(
|
||||
|
||||
// Check if the user's answer was correct
|
||||
if (minDist === 0) {
|
||||
this.updateGroupSM2(true);
|
||||
|
||||
// TODO: Show it's correct?
|
||||
// Show the next vocab word
|
||||
if (this.reviewQueue.size() === 0) {
|
||||
// Update the metadata
|
||||
this.props.setReview(this.props.current, this.increaseMeta(1, 0));
|
||||
this.props.setLastReview(this.props.metadata);
|
||||
this.props.setLastReview(this.props.metadata, this.sm2_metadata);
|
||||
this.props.setLoading(true);
|
||||
|
||||
// Show the drawer button again
|
||||
@@ -163,6 +206,8 @@ const ReviewPageWithRouter = withRouter(
|
||||
// Increase the vocab
|
||||
this.props.setReview(this.reviewQueue.dequeue(), this.increaseMeta(1, 0));
|
||||
this.inputRef.value = "";
|
||||
|
||||
// TODO(?): Show a snackbar for showing the updated score
|
||||
}
|
||||
} else if (minDist <= LEVENSHTEIN_MAX_DISTANCE) {
|
||||
this.props.setPopover(true, "Das war fast richtig", "yellow", "black");
|
||||
@@ -178,11 +223,10 @@ const ReviewPageWithRouter = withRouter(
|
||||
* }
|
||||
*/
|
||||
// Update the metadata
|
||||
this.updateGroupSM2(false);
|
||||
this.props.setReview(this.props.current, this.increaseMeta(0, 1));
|
||||
this.props.setPopover(true, "Das war nicht richtig", "red", "white");
|
||||
}
|
||||
|
||||
// TODO(?): Show a snackbar for showing the updated score
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
Reference in New Issue
Block a user