Files
freeCodeCamp/common/app/routes/challenges/redux/completion-saga.js

107 lines
2.8 KiB
JavaScript
Raw Normal View History

2016-06-01 15:52:08 -07:00
import { Observable } from 'rx';
import { push } from 'react-router-redux';
import types from './types';
import {
showChallengeComplete,
moveToNextChallenge,
updateCurrentChallenge
} from './actions';
import {
createErrorObservable,
makeToast,
updatePoints
} from '../../../redux/actions';
import { getNextChallenge } from '../utils';
import { challengeSelector } from './selectors';
import { postJSON$ } from '../../../../utils/ajax-stream';
function completedChallenge(state) {
let body;
let isSignedIn = false;
try {
const {
challenge: { id }
} = challengeSelector(state);
const {
app: { isSignedIn: _isSignedId, csrfToken },
challengesApp: { files }
} = state;
isSignedIn = _isSignedId;
body = {
id,
_csrf: csrfToken,
files
};
} catch (err) {
return createErrorObservable(err);
}
const saveChallenge$ = postJSON$('/modern-challenge-completed', body)
.retry(3)
.flatMap(({ alreadyCompleted, points }) => {
return Observable.of(
makeToast({
message:
'Challenge saved.' +
(alreadyCompleted ? '' : ' First time Completed!'),
title: 'Saved',
type: 'info'
}),
updatePoints(points)
);
})
.catch(createErrorObservable);
const challengeCompleted$ = Observable.of(
moveToNextChallenge(),
makeToast({
title: 'Congratulations!',
2016-06-04 18:12:14 -07:00
message: isSignedIn ? ' Saving...' : 'Moving on to next challenge.',
2016-06-01 15:52:08 -07:00
type: 'success'
})
);
return Observable.merge(saveChallenge$, challengeCompleted$);
}
export default function completionSaga(actions$, getState) {
return actions$
.filter(({ type }) => (
type === types.checkChallenge ||
type === types.submitChallenge ||
type === types.moveToNextChallenge
))
.flatMap(({ type }) => {
const state = getState();
const { tests } = state.challengesApp;
2016-06-04 18:12:14 -07:00
if (tests.length > 0 && tests.every(test => test.pass && !test.err)) {
2016-06-01 15:52:08 -07:00
if (type === types.checkChallenge) {
return Observable.of(
showChallengeComplete()
);
}
if (type === types.submitChallenge) {
return completedChallenge(state);
}
if (type === types.moveToNextChallenge) {
const nextChallenge = getNextChallenge(
state.challengesApp.challenge,
state.entities,
state.challengesApp.superBlocks
);
return Observable.of(
updateCurrentChallenge(nextChallenge),
push(`/challenges/${nextChallenge.dashedName}`)
);
}
}
return Observable.just(makeToast({
2016-06-04 18:12:14 -07:00
message: 'Not all tests are passing, yet.',
title: 'Almost There!',
2016-06-01 15:52:08 -07:00
type: 'info'
}));
});
}