feat(challenge): Add pre-fetching logic

This commit is contained in:
Stuart Taylor
2018-02-23 18:34:46 +00:00
committed by Stuart Taylor
parent 2143063084
commit fec1abfb46
3 changed files with 71 additions and 4 deletions

View File

@ -10,12 +10,24 @@ import {
fetchChallengeCompleted,
fetchChallengesCompleted,
challengeSelector
fetchNewBlock,
challengeSelector,
superBlocksSelector,
currentChallengeSelector
} from './';
import { isChallengeLoaded, fullBlocksSelector } from '../entities/index.js';
import {
isChallengeLoaded,
fullBlocksSelector,
entitiesSelector
} from '../entities';
import { shapeChallenges } from './utils';
import { types as challenge } from '../routes/Challenges/redux';
import {
getFirstChallengeOfNextBlock,
getFirstChallengeOfNextSuperBlock,
getNextChallenge
} from '../routes/Challenges/utils';
import { langSelector } from '../Router/redux';
const isDev = debug.enabled('fcc:*');
@ -86,4 +98,48 @@ export function fetchChallengesForBlockEpic(
});
}
export default combineEpics(fetchChallengeEpic, fetchChallengesForBlockEpic);
function fetchChallengesForNextBlockEpic(action$, { getState }) {
return action$::ofType(challenge.checkForNextBlock)
.map(() => {
let nextChallenge = {};
let isNewBlock = false;
let isNewSuperBlock = false;
const state = getState();
const challenge = currentChallengeSelector(state);
const superBlocks = superBlocksSelector(state);
const entities = entitiesSelector(state);
nextChallenge = getNextChallenge(challenge, entities, { isDev });
// block completed.
if (!nextChallenge) {
isNewBlock = true;
nextChallenge = getFirstChallengeOfNextBlock(
challenge,
entities,
{ isDev }
);
}
// superBlock completed
if (!nextChallenge) {
isNewSuperBlock = true;
nextChallenge = getFirstChallengeOfNextSuperBlock(
challenge,
entities,
superBlocks,
{ isDev }
);
}
const isNewBlockRequired = (
(isNewBlock || isNewSuperBlock) &&
!nextChallenge.description
);
return isNewBlockRequired ?
fetchNewBlock(nextChallenge.block) :
{ type: 'NULL' };
});
}
export default combineEpics(
fetchChallengeEpic,
fetchChallengesForBlockEpic,
fetchChallengesForNextBlockEpic
);

View File

@ -11,6 +11,8 @@ import {
closeChallengeModal,
submitChallenge,
checkForNextBlock,
challengeModalSelector,
successMessageSelector
} from './redux';
@ -34,12 +36,14 @@ const mapDispatchToProps = function(dispatch) {
},
submitChallenge: () => {
dispatch(submitChallenge());
}
},
checkForNextBlock: () => dispatch(checkForNextBlock())
};
return () => dispatchers;
};
const propTypes = {
checkForNextBlock: PropTypes.func.isRequired,
close: PropTypes.func.isRequired,
handleKeypress: PropTypes.func.isRequired,
isOpen: PropTypes.bool,
@ -48,6 +52,11 @@ const propTypes = {
};
export class CompletionModal extends PureComponent {
componentDidUpdate() {
if (this.props.isOpen) {
this.props.checkForNextBlock();
}
}
render() {
const {
close,

View File

@ -77,6 +77,7 @@ export const types = createTypes([
'checkChallenge',
createAsyncTypes('submitChallenge'),
'moveToNextChallenge',
'checkForNextBlock',
// help
'openHelpModal',
@ -150,6 +151,7 @@ export const submitChallengeComplete = createAction(
);
export const moveToNextChallenge = createAction(types.moveToNextChallenge);
export const checkForNextBlock = createAction(types.checkForNextBlock);
// help
export const openHelpModal = createAction(types.openHelpModal);