Fix(challenge): update user challenge map on challenge complete
This commit is contained in:
@ -94,6 +94,16 @@ export const updateUserLang = createAction(
|
|||||||
types.updateUserLang,
|
types.updateUserLang,
|
||||||
(username, lang) => ({ username, lang })
|
(username, lang) => ({ username, lang })
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// updateUserChallenge(
|
||||||
|
// username: String,
|
||||||
|
// challengeInfo: Object
|
||||||
|
// ) => Action
|
||||||
|
export const updateUserChallenge = createAction(
|
||||||
|
types.updateUserChallenge,
|
||||||
|
(username, challengeInfo) => ({ username, challengeInfo })
|
||||||
|
);
|
||||||
|
|
||||||
export const updateAppLang = createAction(types.updateAppLang);
|
export const updateAppLang = createAction(types.updateAppLang);
|
||||||
|
|
||||||
// used when server needs client to redirect
|
// used when server needs client to redirect
|
||||||
|
@ -82,5 +82,22 @@ export default function entities(state = initialState, action) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (action.type === types.updateUserChallenge) {
|
||||||
|
const { challengeInfo } = action.payload;
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
user: {
|
||||||
|
...state.user,
|
||||||
|
[username]: {
|
||||||
|
...state.user[username],
|
||||||
|
challengeMap: {
|
||||||
|
...state.user[username].challengeMap,
|
||||||
|
[challengeInfo.id]: challengeInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ export default createTypes([
|
|||||||
'updateUserFlag',
|
'updateUserFlag',
|
||||||
'updateUserEmail',
|
'updateUserEmail',
|
||||||
'updateUserLang',
|
'updateUserLang',
|
||||||
|
'updateUserChallenge',
|
||||||
'showSignIn',
|
'showSignIn',
|
||||||
'loadCurrentChallenge',
|
'loadCurrentChallenge',
|
||||||
'updateMyCurrentChallenge',
|
'updateMyCurrentChallenge',
|
||||||
|
@ -59,7 +59,10 @@ export const updateFile = createAction(
|
|||||||
export const updateFiles = createAction(types.updateFiles);
|
export const updateFiles = createAction(types.updateFiles);
|
||||||
|
|
||||||
// rechallenge
|
// rechallenge
|
||||||
export const executeChallenge = createAction(types.executeChallenge);
|
export const executeChallenge = createAction(
|
||||||
|
types.executeChallenge,
|
||||||
|
() => null
|
||||||
|
);
|
||||||
|
|
||||||
export const updateMain = createAction(types.updateMain);
|
export const updateMain = createAction(types.updateMain);
|
||||||
export const frameMain = createAction(types.frameMain);
|
export const frameMain = createAction(types.frameMain);
|
||||||
|
@ -2,22 +2,30 @@ import { Observable } from 'rx';
|
|||||||
|
|
||||||
import types from './types';
|
import types from './types';
|
||||||
import { moveToNextChallenge } from './actions';
|
import { moveToNextChallenge } from './actions';
|
||||||
import {
|
|
||||||
createErrorObservable,
|
|
||||||
updateUserPoints
|
|
||||||
} from '../../../redux/actions';
|
|
||||||
import { makeToast } from '../../../toasts/redux/actions';
|
|
||||||
|
|
||||||
import { challengeSelector } from './selectors';
|
import { challengeSelector } from './selectors';
|
||||||
import { randomCompliment } from '../../../utils/get-words';
|
import { randomCompliment } from '../../../utils/get-words';
|
||||||
|
import {
|
||||||
|
createErrorObservable,
|
||||||
|
updateUserPoints,
|
||||||
|
updateUserChallenge
|
||||||
|
} from '../../../redux/actions';
|
||||||
import { backEndProject } from '../../../utils/challengeTypes';
|
import { backEndProject } from '../../../utils/challengeTypes';
|
||||||
|
import { makeToast } from '../../../toasts/redux/actions';
|
||||||
import { postJSON$ } from '../../../../utils/ajax-stream';
|
import { postJSON$ } from '../../../../utils/ajax-stream';
|
||||||
|
|
||||||
function postChallenge(url, body, username) {
|
function postChallenge(url, username, _csrf, challengeInfo) {
|
||||||
|
const body = { ...challengeInfo, _csrf };
|
||||||
const saveChallenge$ = postJSON$(url, body)
|
const saveChallenge$ = postJSON$(url, body)
|
||||||
.retry(3)
|
.retry(3)
|
||||||
.map(({ points }) => {
|
.flatMap(({ points, lastUpdated, completedDate }) => {
|
||||||
return updateUserPoints(username, points);
|
return Observable.of(
|
||||||
|
updateUserPoints(username, points),
|
||||||
|
updateUserChallenge(
|
||||||
|
username,
|
||||||
|
{ ...challengeInfo, lastUpdated, completedDate }
|
||||||
|
)
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.catch(createErrorObservable);
|
.catch(createErrorObservable);
|
||||||
const challengeCompleted$ = Observable.of(moveToNextChallenge());
|
const challengeCompleted$ = Observable.of(moveToNextChallenge());
|
||||||
@ -44,12 +52,13 @@ function submitModern(type, state) {
|
|||||||
app: { user, csrfToken },
|
app: { user, csrfToken },
|
||||||
challengesApp: { files }
|
challengesApp: { files }
|
||||||
} = state;
|
} = state;
|
||||||
const body = {
|
const challengeInfo = { id, files };
|
||||||
id,
|
return postChallenge(
|
||||||
_csrf: csrfToken,
|
'/modern-challenge-completed',
|
||||||
files
|
user,
|
||||||
};
|
csrfToken,
|
||||||
return postChallenge('/modern-challenge-completed', body, user);
|
challengeInfo
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Observable.just(makeToast({ message: 'Not quite there, yet.' }));
|
return Observable.just(makeToast({ message: 'Not quite there, yet.' }));
|
||||||
@ -62,16 +71,16 @@ function submitProject(type, state, { solution, githubLink }) {
|
|||||||
const {
|
const {
|
||||||
app: { user, csrfToken }
|
app: { user, csrfToken }
|
||||||
} = state;
|
} = state;
|
||||||
const body = {
|
const challengeInfo = { id, challengeType, solution };
|
||||||
id,
|
|
||||||
challengeType,
|
|
||||||
solution,
|
|
||||||
_csrf: csrfToken
|
|
||||||
};
|
|
||||||
if (challengeType === backEndProject) {
|
if (challengeType === backEndProject) {
|
||||||
body.githubLink = githubLink;
|
challengeInfo.githubLink = githubLink;
|
||||||
}
|
}
|
||||||
return postChallenge('/project-completed', body, user);
|
return postChallenge(
|
||||||
|
'/project-completed',
|
||||||
|
user,
|
||||||
|
csrfToken,
|
||||||
|
challengeInfo
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function submitSimpleChallenge(type, state) {
|
function submitSimpleChallenge(type, state) {
|
||||||
@ -81,11 +90,13 @@ function submitSimpleChallenge(type, state) {
|
|||||||
const {
|
const {
|
||||||
app: { user, csrfToken }
|
app: { user, csrfToken }
|
||||||
} = state;
|
} = state;
|
||||||
const body = {
|
const challengeInfo = { id };
|
||||||
id,
|
return postChallenge(
|
||||||
_csrf: csrfToken
|
'/challenge-completed',
|
||||||
};
|
user,
|
||||||
return postChallenge('/challenge-completed', body, user);
|
csrfToken,
|
||||||
|
challengeInfo
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const submitTypes = {
|
const submitTypes = {
|
||||||
|
@ -61,7 +61,12 @@ function buildUserUpdate(
|
|||||||
|
|
||||||
log('user update data', updateData);
|
log('user update data', updateData);
|
||||||
|
|
||||||
return { alreadyCompleted, updateData };
|
return {
|
||||||
|
alreadyCompleted,
|
||||||
|
updateData,
|
||||||
|
completedDate: finalChallenge.completedDate,
|
||||||
|
lastUpdated: finalChallenge.lastUpdated
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function(app) {
|
export default function(app) {
|
||||||
@ -138,14 +143,14 @@ export default function(app) {
|
|||||||
files
|
files
|
||||||
} = req.body;
|
} = req.body;
|
||||||
|
|
||||||
const { alreadyCompleted, updateData } = buildUserUpdate(
|
const {
|
||||||
|
alreadyCompleted,
|
||||||
|
updateData,
|
||||||
|
lastUpdated
|
||||||
|
} = buildUserUpdate(
|
||||||
user,
|
user,
|
||||||
id,
|
id,
|
||||||
{
|
{ id, files, completedDate }
|
||||||
id,
|
|
||||||
files,
|
|
||||||
completedDate
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const points = alreadyCompleted ? user.points : user.points + 1;
|
const points = alreadyCompleted ? user.points : user.points + 1;
|
||||||
@ -156,7 +161,9 @@ export default function(app) {
|
|||||||
if (type === 'json') {
|
if (type === 'json') {
|
||||||
return res.json({
|
return res.json({
|
||||||
points,
|
points,
|
||||||
alreadyCompleted
|
alreadyCompleted,
|
||||||
|
completedDate,
|
||||||
|
lastUpdated
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return res.sendStatus(200);
|
return res.sendStatus(200);
|
||||||
@ -184,7 +191,11 @@ export default function(app) {
|
|||||||
const completedDate = Date.now();
|
const completedDate = Date.now();
|
||||||
const { id, solution, timezone } = req.body;
|
const { id, solution, timezone } = req.body;
|
||||||
|
|
||||||
const { alreadyCompleted, updateData } = buildUserUpdate(
|
const {
|
||||||
|
alreadyCompleted,
|
||||||
|
updateData,
|
||||||
|
lastUpdated
|
||||||
|
} = buildUserUpdate(
|
||||||
req.user,
|
req.user,
|
||||||
id,
|
id,
|
||||||
{ id, solution, completedDate },
|
{ id, solution, completedDate },
|
||||||
@ -200,7 +211,9 @@ export default function(app) {
|
|||||||
if (type === 'json') {
|
if (type === 'json') {
|
||||||
return res.json({
|
return res.json({
|
||||||
points,
|
points,
|
||||||
alreadyCompleted
|
alreadyCompleted,
|
||||||
|
completedDate,
|
||||||
|
lastUpdated
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return res.sendStatus(200);
|
return res.sendStatus(200);
|
||||||
@ -253,7 +266,8 @@ export default function(app) {
|
|||||||
.flatMap(() => {
|
.flatMap(() => {
|
||||||
const {
|
const {
|
||||||
alreadyCompleted,
|
alreadyCompleted,
|
||||||
updateData
|
updateData,
|
||||||
|
lastUpdated
|
||||||
} = buildUserUpdate(user, completedChallenge.id, completedChallenge);
|
} = buildUserUpdate(user, completedChallenge.id, completedChallenge);
|
||||||
|
|
||||||
return user.update$(updateData)
|
return user.update$(updateData)
|
||||||
@ -262,7 +276,9 @@ export default function(app) {
|
|||||||
if (type === 'json') {
|
if (type === 'json') {
|
||||||
return res.send({
|
return res.send({
|
||||||
alreadyCompleted,
|
alreadyCompleted,
|
||||||
points: alreadyCompleted ? user.points : user.points + 1
|
points: alreadyCompleted ? user.points : user.points + 1,
|
||||||
|
completedDate: completedChallenge.completedDate,
|
||||||
|
lastUpdated
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return res.status(200).send(true);
|
return res.status(200).send(true);
|
||||||
|
Reference in New Issue
Block a user