Add initial dynamic challenge rendering
This commit is contained in:
@@ -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);
|
||||
}
|
||||
};
|
||||
|
Reference in New Issue
Block a user