feat: Points for doing reviews
This commit is contained in:
parent
d08e591e27
commit
977f5df9dd
@ -130,7 +130,7 @@ function dateInNDays(n: number): number {
|
|||||||
|
|
||||||
userRouter.post("/lastReview", async (req: LRequest, res) => {
|
userRouter.post("/lastReview", async (req: LRequest, res) => {
|
||||||
// Check if we get the needed data
|
// Check if we get the needed data
|
||||||
if (!req.body || !("meta" in req.body) || !("sm2" in req.body)) {
|
if (!req.body || !("meta" in req.body) || !("sm2" in req.body) || !("delta" in req.body)) {
|
||||||
res.send({
|
res.send({
|
||||||
error: "400",
|
error: "400",
|
||||||
data: {
|
data: {
|
||||||
@ -152,6 +152,8 @@ userRouter.post("/lastReview", async (req: LRequest, res) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user.score += parseInt(req.body.delta);
|
||||||
|
|
||||||
Object.keys(req.body.sm2).forEach((id: string) => {
|
Object.keys(req.body.sm2).forEach((id: string) => {
|
||||||
const vocabId = parseInt(id);
|
const vocabId = parseInt(id);
|
||||||
const correct: boolean = req.body.sm2[id];
|
const correct: boolean = req.body.sm2[id];
|
||||||
@ -184,6 +186,7 @@ userRouter.post("/lastReview", async (req: LRequest, res) => {
|
|||||||
$set: {
|
$set: {
|
||||||
lastReview: user.lastReview,
|
lastReview: user.lastReview,
|
||||||
vocabMetadata: user.vocabMetadata,
|
vocabMetadata: user.vocabMetadata,
|
||||||
|
score: user.score,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -5,4 +5,4 @@ rm -rf dist/
|
|||||||
chmod 705 dist dist/app
|
chmod 705 dist dist/app
|
||||||
chmod 604 dist/app/*
|
chmod 604 dist/app/*
|
||||||
|
|
||||||
#sed "s/\/src/\/app\/src/" dist/app/index.html
|
sed -e "s/\/src/\/app\/src/g" --in-place dist/app/index.html
|
||||||
|
@ -120,6 +120,14 @@ export function setLastReview(metadata: IReviewMetadata) {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const SET_USER_SCORE_DELTA = "SET_USER_SCORE_DELTA";
|
||||||
|
export function setUserScoreDelta(delta: number) {
|
||||||
|
return {
|
||||||
|
type: SET_USER_SCORE_DELTA,
|
||||||
|
delta,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export const SET_REVIEW = "SET_REVIEW";
|
export const SET_REVIEW = "SET_REVIEW";
|
||||||
export function setReview(current: IReviewCard, meta: IReviewMetadata) {
|
export function setReview(current: IReviewCard, meta: IReviewMetadata) {
|
||||||
return {
|
return {
|
||||||
|
@ -31,7 +31,8 @@ interface IProps {
|
|||||||
setAuthenticated: (status: boolean) => void;
|
setAuthenticated: (status: boolean) => void;
|
||||||
setDidLogin: (status: boolean) => void;
|
setDidLogin: (status: boolean) => void;
|
||||||
setUser: (user: IUser) => void;
|
setUser: (user: IUser) => void;
|
||||||
setLastReview: (meta: IReviewMetadata) => void;
|
setLastReview: (meta: IReviewMetadata, delta: number) => void;
|
||||||
|
setUserScoreDelta: (delta: number) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Replace the sessionStorage with localStorage?
|
// TODO: Replace the sessionStorage with localStorage?
|
||||||
@ -107,9 +108,10 @@ export default class Application extends React.Component<IProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Type?
|
// TODO: Type?
|
||||||
setLastReview = (meta: IReviewMetadata, sm2: any) => {
|
setLastReview = (meta: IReviewMetadata, sm2: any, delta: number) => {
|
||||||
// Update the state
|
// Update the state
|
||||||
this.props.setLastReview(meta);
|
this.props.setLastReview(meta);
|
||||||
|
this.props.setUserScoreDelta(delta);
|
||||||
|
|
||||||
// Tell the server about the last review
|
// Tell the server about the last review
|
||||||
fetch(`${BACKEND_URL}/api/user/lastReview`, {
|
fetch(`${BACKEND_URL}/api/user/lastReview`, {
|
||||||
@ -121,6 +123,7 @@ export default class Application extends React.Component<IProps> {
|
|||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
meta,
|
meta,
|
||||||
sm2,
|
sm2,
|
||||||
|
delta,
|
||||||
}),
|
}),
|
||||||
}).then(resp => resp.json(), err => {
|
}).then(resp => resp.json(), err => {
|
||||||
console.log("Application::setLastReview: POSTing last results failed");
|
console.log("Application::setLastReview: POSTing last results failed");
|
||||||
|
@ -4,7 +4,10 @@ import { IUser } from "../models/user";
|
|||||||
|
|
||||||
import Application from "../components/app";
|
import Application from "../components/app";
|
||||||
|
|
||||||
import { setAuthenticated, setUser, setDidLogin, setLastReview } from "../actions";
|
import {
|
||||||
|
setAuthenticated, setUser, setDidLogin, setLastReview,
|
||||||
|
setUserScoreDelta
|
||||||
|
} from "../actions";
|
||||||
|
|
||||||
import { IReviewMetadata } from "../models/review";
|
import { IReviewMetadata } from "../models/review";
|
||||||
|
|
||||||
@ -20,6 +23,7 @@ const mapDispatchToProps = dispatch => {
|
|||||||
setDidLogin: (state: boolean) => dispatch(setDidLogin(state)),
|
setDidLogin: (state: boolean) => dispatch(setDidLogin(state)),
|
||||||
setUser: (user: IUser) => dispatch(setUser(user)),
|
setUser: (user: IUser) => dispatch(setUser(user)),
|
||||||
setLastReview: (meta: IReviewMetadata) => dispatch(setLastReview(meta)),
|
setLastReview: (meta: IReviewMetadata) => dispatch(setLastReview(meta)),
|
||||||
|
setUserScoreDelta: (delta: number) => dispatch(setUserScoreDelta(delta)),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ interface IProps {
|
|||||||
levelId?: number;
|
levelId?: number;
|
||||||
vocabByLevel?: (level: number) => Promise<IVocab[]>;
|
vocabByLevel?: (level: number) => Promise<IVocab[]>;
|
||||||
vocabByQueue?: () => Promise<IVocab[]>;
|
vocabByQueue?: () => Promise<IVocab[]>;
|
||||||
setLastReview: (meta: IReviewMetadata, sm2: any) => void;
|
setLastReview: (meta: IReviewMetadata, sm2: any, delta: number) => void;
|
||||||
reviewType: ReviewType;
|
reviewType: ReviewType;
|
||||||
|
|
||||||
history: any;
|
history: any;
|
||||||
@ -65,6 +65,7 @@ const ReviewPageWithRouter = withRouter(
|
|||||||
private inputRef: HTMLInputElement;
|
private inputRef: HTMLInputElement;
|
||||||
// Mapping: Vocab Id -> Correctly answered
|
// Mapping: Vocab Id -> Correctly answered
|
||||||
private sm2_metadata: any = {};
|
private sm2_metadata: any = {};
|
||||||
|
private score_delta = 0;
|
||||||
|
|
||||||
constructor(props: any) {
|
constructor(props: any) {
|
||||||
super(props);
|
super(props);
|
||||||
@ -189,13 +190,15 @@ const ReviewPageWithRouter = withRouter(
|
|||||||
// Check if the user's answer was correct
|
// Check if the user's answer was correct
|
||||||
if (minDist === 0) {
|
if (minDist === 0) {
|
||||||
this.updateGroupSM2(true);
|
this.updateGroupSM2(true);
|
||||||
|
// TODO: Is this correct?
|
||||||
|
this.score_delta += 1;
|
||||||
|
|
||||||
// TODO: Show it's correct?
|
// TODO: Show it's correct?
|
||||||
// Show the next vocab word
|
// Show the next vocab word
|
||||||
if (this.reviewQueue.size() === 0) {
|
if (this.reviewQueue.size() === 0) {
|
||||||
// Update the metadata
|
// Update the metadata
|
||||||
this.props.setReview(this.props.current, this.increaseMeta(1, 0));
|
this.props.setReview(this.props.current, this.increaseMeta(1, 0));
|
||||||
this.props.setLastReview(this.props.metadata, this.sm2_metadata);
|
this.props.setLastReview(this.props.metadata, this.sm2_metadata, this.score_delta);
|
||||||
this.props.setLoading(true);
|
this.props.setLoading(true);
|
||||||
|
|
||||||
// Show the drawer button again
|
// Show the drawer button again
|
||||||
@ -213,18 +216,9 @@ const ReviewPageWithRouter = withRouter(
|
|||||||
} else if (minDist <= LEVENSHTEIN_MAX_DISTANCE) {
|
} else if (minDist <= LEVENSHTEIN_MAX_DISTANCE) {
|
||||||
this.props.setPopover(true, "Das war fast richtig", "yellow", "black");
|
this.props.setPopover(true, "Das war fast richtig", "yellow", "black");
|
||||||
} else {
|
} else {
|
||||||
// Find the IVocab item
|
|
||||||
/* const vocab = this.vocabFromId(this.props.current.id);
|
|
||||||
* if (vocab) {
|
|
||||||
* // Re-Add the vocabulary item to the review queue
|
|
||||||
* // TODO: Only re-add when it when it's not re-queued
|
|
||||||
* // vocabToReviewCard(vocab).forEach(this.reviewQueue.enqueue);
|
|
||||||
* } else {
|
|
||||||
* console.log("[ReviewPage::checkInput] Could not find IVocab item for wrong IReviewCard");
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
// Update the metadata
|
// Update the metadata
|
||||||
this.updateGroupSM2(false);
|
this.updateGroupSM2(false);
|
||||||
|
this.score_delta -= 1;
|
||||||
this.props.setReview(this.props.current, this.increaseMeta(0, 1));
|
this.props.setReview(this.props.current, this.increaseMeta(0, 1));
|
||||||
this.props.setPopover(true, "Das war nicht richtig", "red", "white");
|
this.props.setPopover(true, "Das war nicht richtig", "red", "white");
|
||||||
}
|
}
|
||||||
|
@ -202,6 +202,12 @@ export function LateinicusApp(state: IState = initialState, action: any) {
|
|||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
lastReview: action.metadata,
|
lastReview: action.metadata,
|
||||||
});
|
});
|
||||||
|
case Actions.SET_USER_SCORE_DELTA:
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
user: Object.assign({}, state.user, {
|
||||||
|
score: state.user.score + action.delta,
|
||||||
|
}),
|
||||||
|
});
|
||||||
case Actions.REVIEW_SET_LOADING:
|
case Actions.REVIEW_SET_LOADING:
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
review: Object.assign({}, state.review, {
|
review: Object.assign({}, state.review, {
|
||||||
|
Reference in New Issue
Block a user