refactor challenges
now only queries challenges on start up use default scheduler for array manipulation
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { Observable } from 'rx';
|
import { Observable, Scheduler } from 'rx';
|
||||||
import assign from 'object.assign';
|
import assign from 'object.assign';
|
||||||
import debugFactory from 'debug';
|
import debugFactory from 'debug';
|
||||||
import utils from '../utils';
|
import utils from '../utils';
|
||||||
@@ -18,11 +18,16 @@ import {
|
|||||||
} from '../utils/middleware';
|
} from '../utils/middleware';
|
||||||
|
|
||||||
const debug = debugFactory('freecc:challenges');
|
const debug = debugFactory('freecc:challenges');
|
||||||
const challengeMapWithNames = utils.getChallengeMapWithNames();
|
|
||||||
const challengeMapWithIds = utils.getChallengeMapWithIds();
|
|
||||||
const challengeMapWithDashedNames = utils.getChallengeMapWithDashedNames();
|
|
||||||
const challengesRegex = /^(bonfire|waypoint|zipline|basejump)/i;
|
const challengesRegex = /^(bonfire|waypoint|zipline|basejump)/i;
|
||||||
const firstChallenge = 'waypoint-say-hello-to-html-elements';
|
const firstChallenge = 'waypoint-say-hello-to-html-elements';
|
||||||
|
const challengeView = {
|
||||||
|
0: 'coursewares/showHTML',
|
||||||
|
1: 'coursewares/showJS',
|
||||||
|
2: 'coursewares/showVideo',
|
||||||
|
3: 'coursewares/showZiplineOrBasejump',
|
||||||
|
4: 'coursewares/showZiplineOrBasejump',
|
||||||
|
5: 'coursewares/showBonfire'
|
||||||
|
};
|
||||||
|
|
||||||
const dasherize = utils.dasherize;
|
const dasherize = utils.dasherize;
|
||||||
const unDasherize = utils.unDasherize;
|
const unDasherize = utils.unDasherize;
|
||||||
@@ -64,7 +69,12 @@ module.exports = function(app) {
|
|||||||
// create a stream of all the challenges
|
// create a stream of all the challenges
|
||||||
const challenge$ = findChallenge$(challengesQuery)
|
const challenge$ = findChallenge$(challengesQuery)
|
||||||
.doOnNext(() => debug('query challenges'))
|
.doOnNext(() => debug('query challenges'))
|
||||||
.flatMap(challenges => Observable.from(challenges))
|
.flatMap(challenges => Observable.from(
|
||||||
|
challenges,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
Scheduler.default
|
||||||
|
))
|
||||||
.shareReplay();
|
.shareReplay();
|
||||||
|
|
||||||
// create a stream of challenge blocks
|
// create a stream of challenge blocks
|
||||||
@@ -162,7 +172,12 @@ module.exports = function(app) {
|
|||||||
.elementAt(blockIndex)
|
.elementAt(blockIndex)
|
||||||
.flatMap(block => {
|
.flatMap(block => {
|
||||||
// find where our challenge lies in the block
|
// find where our challenge lies in the block
|
||||||
const challengeIndex$ = Observable.from(block.challenges)
|
const challengeIndex$ = Observable.from(
|
||||||
|
block.challenges,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
Scheduler.default
|
||||||
|
)
|
||||||
.findIndex(({ id }) => id === challengeId);
|
.findIndex(({ id }) => id === challengeId);
|
||||||
|
|
||||||
// grab next challenge in this block
|
// grab next challenge in this block
|
||||||
@@ -201,44 +216,53 @@ module.exports = function(app) {
|
|||||||
res.redirect('/challenges/' + nextChallengeName);
|
res.redirect('/challenges/' + nextChallengeName);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function returnCurrentChallenge(req, res, next) {
|
function returnCurrentChallenge(req, res, next) {
|
||||||
|
Observable.just(req.user)
|
||||||
|
.flatMap(user => {
|
||||||
if (!req.user.currentChallenge) {
|
if (!req.user.currentChallenge) {
|
||||||
req.user.currentChallenge = {};
|
return challenge$
|
||||||
req.user.currentChallenge.challengeId = challengeMapWithIds['0'][0];
|
.first()
|
||||||
req.user.currentChallenge.challengeName = challengeMapWithNames['0'][0];
|
.flatMap(challenge => {
|
||||||
req.user.currentChallenge.dashedName =
|
user.currentChallenge = {
|
||||||
challengeMapWithDashedNames['0'][0];
|
challengeId: challenge.id,
|
||||||
|
challengeName: challenge.name,
|
||||||
|
dashedName: challenge.dashedName
|
||||||
|
};
|
||||||
|
return saveUser(user);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
return Observable.just(user);
|
||||||
var nameString = req.user.currentChallenge.dashedName;
|
})
|
||||||
|
.map(user => user.currentChallenge.dashedName)
|
||||||
saveUser(req.user)
|
|
||||||
.subscribe(
|
.subscribe(
|
||||||
function() {},
|
function(challengeName) {
|
||||||
|
res.redirect('/challenges/' + challengeName);
|
||||||
|
},
|
||||||
next,
|
next,
|
||||||
function() {
|
function() {
|
||||||
res.redirect('/challenges/' + nameString);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function returnIndividualChallenge(req, res, next) {
|
function returnIndividualChallenge(req, res, next) {
|
||||||
var origChallengeName = req.params.challengeName;
|
const origChallengeName = req.params.challengeName;
|
||||||
var unDashedName = unDasherize(origChallengeName);
|
const unDashedName = unDasherize(origChallengeName);
|
||||||
|
|
||||||
var challengeName = challengesRegex.test(unDashedName) ?
|
const challengeName = challengesRegex.test(unDashedName) ?
|
||||||
// remove first word if matches
|
// remove first word if matches
|
||||||
unDashedName.split(' ').slice(1).join(' ') :
|
unDashedName.split(' ').slice(1).join(' ') :
|
||||||
unDashedName;
|
unDashedName;
|
||||||
|
|
||||||
debug('looking for ', challengeName);
|
const testChallengeName = new RegExp(challengeName, 'i');
|
||||||
Challenge.findOne(
|
debug('looking for %s', testChallengeName);
|
||||||
{ where: { name: { like: challengeName, options: 'i' } } },
|
challenge$
|
||||||
function(err, challenge) {
|
.filter((challenge) => {
|
||||||
if (err) { return next(err); }
|
return testChallengeName.test(challenge.name);
|
||||||
|
})
|
||||||
|
.lastOrDefault(null)
|
||||||
|
.flatMap(challenge => {
|
||||||
|
|
||||||
// Handle not found
|
// Handle not found
|
||||||
if (!challenge) {
|
if (!challenge) {
|
||||||
@@ -249,14 +273,14 @@ module.exports = function(app) {
|
|||||||
origChallengeName +
|
origChallengeName +
|
||||||
'` Please double check the name.'
|
'` Please double check the name.'
|
||||||
});
|
});
|
||||||
return res.redirect('/challenges');
|
return Observable.just('/challenges');
|
||||||
}
|
|
||||||
// Redirect to full name if the user only entered a partial
|
|
||||||
if (dasherize(challenge.name) !== origChallengeName) {
|
|
||||||
debug('redirecting to fullname');
|
|
||||||
return res.redirect('/challenges/' + dasherize(challenge.name));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dasherize(challenge.name) !== origChallengeName) {
|
||||||
|
return Observable.just('/challenges/' + dasherize(challenge.name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (challenge) {
|
||||||
if (req.user) {
|
if (req.user) {
|
||||||
req.user.currentChallenge = {
|
req.user.currentChallenge = {
|
||||||
challengeId: challenge.id,
|
challengeId: challenge.id,
|
||||||
@@ -265,7 +289,9 @@ module.exports = function(app) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var commonLocals = {
|
// save user does nothing if user does not exist
|
||||||
|
return saveUser(req.user)
|
||||||
|
.map(() => ({
|
||||||
title: challenge.name,
|
title: challenge.name,
|
||||||
dashedName: origChallengeName,
|
dashedName: origChallengeName,
|
||||||
name: challenge.name,
|
name: challenge.name,
|
||||||
@@ -286,28 +312,21 @@ module.exports = function(app) {
|
|||||||
MDNlinks: getMDNLinks(challenge.MDNlinks),
|
MDNlinks: getMDNLinks(challenge.MDNlinks),
|
||||||
// htmls specific
|
// htmls specific
|
||||||
environment: utils.whichEnvironment()
|
environment: utils.whichEnvironment()
|
||||||
};
|
}));
|
||||||
|
|
||||||
// TODO Berkeley
|
|
||||||
var challengeView = {
|
|
||||||
0: 'coursewares/showHTML',
|
|
||||||
1: 'coursewares/showJS',
|
|
||||||
2: 'coursewares/showVideo',
|
|
||||||
3: 'coursewares/showZiplineOrBasejump',
|
|
||||||
4: 'coursewares/showZiplineOrBasejump',
|
|
||||||
5: 'coursewares/showBonfire'
|
|
||||||
};
|
|
||||||
|
|
||||||
saveUser(req.user)
|
|
||||||
.subscribe(
|
|
||||||
function() {},
|
|
||||||
next,
|
|
||||||
function() {
|
|
||||||
var view = challengeView[challenge.challengeType];
|
|
||||||
res.render(view, commonLocals);
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.subscribe(
|
||||||
|
function(data) {
|
||||||
|
if (typeof data === 'string') {
|
||||||
|
debug('redirecting to %s', data);
|
||||||
|
return res.redirect(data);
|
||||||
|
}
|
||||||
|
var view = challengeView[data.challengeType];
|
||||||
|
res.render(view, data);
|
||||||
|
},
|
||||||
|
next,
|
||||||
|
function() {}
|
||||||
);
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function completedBonfire(req, res, next) {
|
function completedBonfire(req, res, next) {
|
||||||
@@ -359,7 +378,7 @@ module.exports = function(app) {
|
|||||||
challengeData
|
challengeData
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
// not iterate users
|
// iterate users
|
||||||
.flatMap(function(dats) {
|
.flatMap(function(dats) {
|
||||||
debug('flatmap');
|
debug('flatmap');
|
||||||
return Observable.from([dats.user, dats.pairedWith]);
|
return Observable.from([dats.user, dats.pairedWith]);
|
||||||
|
Reference in New Issue
Block a user