Add initial dynamic challenge rendering

This commit is contained in:
Berkeley Martinez
2016-05-09 13:42:39 -07:00
parent 59dcabb588
commit a0f6ecfca2
20 changed files with 376 additions and 171 deletions

View File

@@ -1,7 +1,12 @@
import { Observable } from 'rx';
import { Schema, valuesOf, arrayOf, normalize } from 'normalizr';
import { nameify, dasherize } from '../utils';
import { nameify, dasherize, unDasherize } from '../utils';
import debug from 'debug';
const isDev = process.env.NODE_ENV !== 'production';
const isBeta = !!process.env.BETA;
const challengesRegex = /^(bonfire|waypoint|zipline|basejump|checkpoint)/i;
const log = debug('fcc:challenges');
const challenge = new Schema('challenge', { idAttribute: 'dashedName' });
const block = new Schema('block', { idAttribute: 'dashedName' });
const superBlock = new Schema('superBlock', { idAttribute: 'dashedName' });
@@ -72,12 +77,64 @@ function cachedMap(Block) {
.shareReplay();
}
function shouldNotFilterComingSoon({ isComingSoon, isBeta: challengeIsBeta }) {
return isDev ||
!isComingSoon ||
(isBeta && challengeIsBeta);
}
function getFirstChallenge(challengeMap$) {
return challengeMap$
.map(({ entities: { superBlock, block, challenge }, result }) => {
return challenge[
block[
superBlock[
result[0]
].blocks[0]
].challenges[0]
];
});
}
function getChallengeByDashedName(dashedName, challengeMap$) {
const challengeName = unDasherize(dashedName)
.replace(challengesRegex, '');
const testChallengeName = new RegExp(challengeName, 'i');
log('looking for %s', testChallengeName);
return challengeMap$
.map(({ entities }) => entities.challenge)
.flatMap(challengeMap => {
return Observable.from(Object.keys(challengeMap))
.map(key => challengeMap[key]);
})
.filter(challenge => {
return shouldNotFilterComingSoon(challenge) &&
testChallengeName.test(challenge.name);
})
.last({ defaultValue: null })
.flatMap(challengeOrNull => {
if (challengeOrNull) {
return Observable.just(challengeOrNull);
}
return getFirstChallenge(challengeMap$);
})
.map(challenge => ({
entities: { challenge: { [challenge.dashedName]: challenge } },
result: challenge.dashedName
}));
}
export default function mapService(app) {
const Block = app.models.Block;
const challengeMap$ = cachedMap(Block);
return {
name: 'map',
read: (req, resource, params, config, cb) => {
read: (req, resource, { dashedName } = {}, config, cb) => {
if (dashedName) {
return getChallengeByDashedName(dashedName, challengeMap$)
.subscribe(challenge => cb(null, challenge), cb);
}
return challengeMap$.subscribe(map => cb(null, map), cb);
}
};