Permalink
Cannot retrieve contributors at this time
Fetching contributors…
| import { Observable } from 'rx'; | |
| // import { routeActions } from 'react-simple-router'; | |
| import types from './types'; | |
| import { getMouse } from './utils'; | |
| import { makeToast, updatePoints } from '../../../redux/actions'; | |
| import { hikeCompleted, goToNextHike } from './actions'; | |
| import { postJSON$ } from '../../../../utils/ajax-stream'; | |
| export default () => ({ getState, dispatch }) => next => { | |
| return function answerSaga(action) { | |
| if (types.answer !== action.type) { | |
| return next(action); | |
| } | |
| const { | |
| e, | |
| answer, | |
| userAnswer, | |
| info, | |
| threshold | |
| } = action.payload; | |
| const { | |
| app: { isSignedIn }, | |
| hikesApp: { | |
| currentQuestion, | |
| currentHike: { id, name, challengeType }, | |
| tests = [], | |
| delta = [ 0, 0 ] | |
| } | |
| } = getState(); | |
| let finalAnswer; | |
| // drag answer, compute response | |
| if (typeof userAnswer === 'undefined') { | |
| const [positionX] = getMouse(e, delta); | |
| // question released under threshold | |
| if (Math.abs(positionX) < threshold) { | |
| return next(action); | |
| } | |
| if (positionX >= threshold) { | |
| finalAnswer = true; | |
| } | |
| if (positionX <= -threshold) { | |
| finalAnswer = false; | |
| } | |
| } else { | |
| finalAnswer = userAnswer; | |
| } | |
| // incorrect question | |
| if (answer !== finalAnswer) { | |
| if (info) { | |
| dispatch({ | |
| type: 'makeToast', | |
| payload: { | |
| title: 'Hint', | |
| message: info, | |
| type: 'info' | |
| } | |
| }); | |
| } | |
| return Observable | |
| .just({ type: types.removeShake }) | |
| .delay(500) | |
| .startWith({ type: types.startShake }) | |
| .doOnNext(dispatch); | |
| } | |
| if (tests[currentQuestion]) { | |
| return Observable | |
| .just({ type: types.goToNextQuestion }) | |
| .delay(300) | |
| .startWith({ type: types.primeNextQuestion }); | |
| } | |
| let updateUser$; | |
| if (isSignedIn) { | |
| const body = { id, name, challengeType }; | |
| updateUser$ = postJSON$('/completed-challenge', body) | |
| // if post fails, will retry once | |
| .retry(3) | |
| .flatMap(({ alreadyCompleted, points }) => { | |
| return Observable.of( | |
| makeToast({ | |
| message: | |
| 'Challenge saved.' + | |
| (alreadyCompleted ? '' : ' First time Completed!'), | |
| title: 'Saved', | |
| type: 'info' | |
| }), | |
| updatePoints(points), | |
| ); | |
| }) | |
| .catch(error => { | |
| return Observable.just({ | |
| type: 'error', | |
| error | |
| }); | |
| }); | |
| } else { | |
| updateUser$ = Observable.empty(); | |
| } | |
| const challengeCompleted$ = Observable.of( | |
| goToNextHike(), | |
| makeToast({ | |
| title: 'Congratulations!', | |
| message: 'Hike completed.' + (isSignedIn ? ' Saving...' : ''), | |
| type: 'success' | |
| }) | |
| ); | |
| return Observable.merge(challengeCompleted$, updateUser$) | |
| .delay(300) | |
| .startWith(hikeCompleted(finalAnswer)) | |
| .catch(error => Observable.just({ | |
| type: 'error', | |
| error | |
| })); | |
| }; | |
| }; |