major challenges refactor
commented out resetEditor in main remove heatmap timoutpull/1043/head
parent
4d2b0844ae
commit
03ea412b4a
|
@ -70,6 +70,7 @@
|
|||
"node-slack": "0.0.7",
|
||||
"node-uuid": "^1.4.3",
|
||||
"nodemailer": "~1.3.0",
|
||||
"object.assign": "^3.0.0",
|
||||
"passport-facebook": "^2.0.0",
|
||||
"passport-google-oauth2": "^0.1.6",
|
||||
"passport-linkedin-oauth2": "^1.2.1",
|
||||
|
|
|
@ -331,6 +331,8 @@ $(document).ready(function() {
|
|||
|
||||
$('#story-submit').on('click', storySubmitButtonHandler);
|
||||
|
||||
// $('#reset-button').on('click', resetEditor);
|
||||
|
||||
var commentSubmitButtonHandler = function commentSubmitButtonHandler() {
|
||||
$('#comment-button').unbind('click');
|
||||
var data = $('#comment-box').val();
|
||||
|
|
|
@ -31,9 +31,15 @@
|
|||
*/
|
||||
|
||||
var R = require('ramda'),
|
||||
Rx = require('rx'),
|
||||
assign = require('object.assign'),
|
||||
debug = require('debug')('freecc:challenges'),
|
||||
utils = require('../utils'),
|
||||
|
||||
// this would be so much cleaner with destructering...
|
||||
saveUser = require('../utils/rx').saveUser,
|
||||
observableQueryFromModel = require('../utils/rx').observableQueryFromModel,
|
||||
|
||||
userMigration = require('../utils/middleware').userMigration,
|
||||
ifNoUserRedirectTo = require('../utils/middleware').ifNoUserRedirectTo;
|
||||
|
||||
|
@ -55,6 +61,16 @@ function unDasherize(name) {
|
|||
return ('' + name).replace(/\-/g, ' ');
|
||||
}
|
||||
|
||||
function updateUserProgress(user, challengeId, completedChallenge) {
|
||||
var index = user.uncompletedChallenges.indexOf(challengeId);
|
||||
if (index > -1) {
|
||||
user.progressTimestamps.push(Date.now());
|
||||
user.uncompletedChallenges.splice(index, 1);
|
||||
}
|
||||
user.completedChallenges.push(completedChallenge);
|
||||
return user;
|
||||
}
|
||||
|
||||
module.exports = function(app) {
|
||||
var router = app.loopback.Router();
|
||||
var Challenge = app.models.Challenge;
|
||||
|
@ -143,6 +159,7 @@ module.exports = function(app) {
|
|||
return elem;
|
||||
}
|
||||
});
|
||||
|
||||
if (!req.user.currentChallenge) {
|
||||
req.user.currentChallenge = {};
|
||||
req.user.currentChallenge.challengeId = challengeMapWithIds['0'][0];
|
||||
|
@ -201,11 +218,11 @@ module.exports = function(app) {
|
|||
challengeId: challenge.id,
|
||||
challengeName: challenge.name,
|
||||
dashedName: challenge.dashedName,
|
||||
challengeBlock: R.head(R.flatten(Object.keys(challengeMapWithIds).
|
||||
map(function (key) {
|
||||
challengeBlock: R.head(R.flatten(Object.keys(challengeMapWithIds)
|
||||
.map(function (key) {
|
||||
return challengeMapWithIds[key]
|
||||
.filter(function (elem) {
|
||||
return String(elem) === challenge.id;
|
||||
return elem === ('' + challenge.id);
|
||||
})
|
||||
.map(function () {
|
||||
return key;
|
||||
|
@ -261,143 +278,124 @@ module.exports = function(app) {
|
|||
}
|
||||
|
||||
function completedBonfire(req, res, next) {
|
||||
var isCompletedWith = req.body.challengeInfo.completedWith || '';
|
||||
var isCompletedDate = Math.round(+new Date());
|
||||
debug('compltedBonfire');
|
||||
var completedWith = req.body.challengeInfo.completedWith || false;
|
||||
var challengeId = req.body.challengeInfo.challengeId;
|
||||
var isSolution = req.body.challengeInfo.solution;
|
||||
var challengeName = req.body.challengeInfo.challengeName;
|
||||
|
||||
if (isCompletedWith) {
|
||||
User.find({
|
||||
where: { username: isCompletedWith.toLowerCase() },
|
||||
limit: 1
|
||||
}, function (err, pairedWith) {
|
||||
if (err) { return next(err); }
|
||||
var challengeData = {
|
||||
id: challengeId,
|
||||
name: req.body.challengeInfo.challengeName,
|
||||
completedDate: Math.round(+new Date()),
|
||||
solution: req.body.challengeInfo.solution,
|
||||
challengeType: 5
|
||||
};
|
||||
|
||||
var index = req.user.uncompletedChallenges.indexOf(challengeId);
|
||||
if (index > -1) {
|
||||
req.user.progressTimestamps.push(Date.now() || 0);
|
||||
req.user.uncompletedChallenges.splice(index, 1);
|
||||
}
|
||||
pairedWith = pairedWith.pop();
|
||||
observableQueryFromModel(
|
||||
User,
|
||||
'findOne',
|
||||
{ where: { username: ('' + completedWith).toLowerCase() } }
|
||||
)
|
||||
.doOnNext(function(pairedWith) {
|
||||
debug('paired with ', pairedWith);
|
||||
if (pairedWith) {
|
||||
|
||||
index = pairedWith.uncompletedChallenges.indexOf(challengeId);
|
||||
if (index > -1) {
|
||||
pairedWith.progressTimestamps.push(Date.now() || 0);
|
||||
pairedWith.uncompletedChallenges.splice(index, 1);
|
||||
|
||||
}
|
||||
|
||||
pairedWith.completedChallenges.push({
|
||||
id: challengeId,
|
||||
name: challengeName,
|
||||
completedWith: req.user.id,
|
||||
completedDate: isCompletedDate,
|
||||
solution: isSolution,
|
||||
challengeType: 5
|
||||
});
|
||||
|
||||
req.user.completedChallenges.push({
|
||||
id: challengeId,
|
||||
name: challengeName,
|
||||
completedWith: pairedWith.id,
|
||||
completedDate: isCompletedDate,
|
||||
solution: isSolution,
|
||||
challengeType: 5
|
||||
});
|
||||
updateUserProgress(
|
||||
pairedWith,
|
||||
challengeId,
|
||||
assign({ completedWith: req.user.id }, challengeData)
|
||||
);
|
||||
}
|
||||
// User said they paired, but pair wasn't found
|
||||
req.user.completedChallenges.push({
|
||||
id: challengeId,
|
||||
name: challengeName,
|
||||
completedWith: null,
|
||||
completedDate: isCompletedDate,
|
||||
solution: isSolution,
|
||||
challengeType: 5
|
||||
});
|
||||
|
||||
req.user.save(function (err, user) {
|
||||
if (err) { return next(err); }
|
||||
|
||||
if (pairedWith) {
|
||||
pairedWith.save(function (err, paired) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
if (user && paired) {
|
||||
return res.send(true);
|
||||
}
|
||||
});
|
||||
} else if (user) {
|
||||
res.send(true);
|
||||
})
|
||||
.withLatestFrom(
|
||||
Rx.Observable.just(req.user),
|
||||
function(pairedWith, user) {
|
||||
debug('yo');
|
||||
return {
|
||||
user: user,
|
||||
pairedWith: pairedWith
|
||||
};
|
||||
}
|
||||
)
|
||||
// side effects should always be done in do's and taps
|
||||
.doOnNext(function(dats) {
|
||||
updateUserProgress(
|
||||
dats.user,
|
||||
challengeId,
|
||||
dats.pairedWith ?
|
||||
// paired programmer found and adding to data
|
||||
assign({ completedWith: dats.pairedWith.id }, challengeData) :
|
||||
// user said they paired, but pair wasn't found
|
||||
challengeData
|
||||
);
|
||||
})
|
||||
// not iterate users
|
||||
.flatMap(function(dats) {
|
||||
debug('flatmap');
|
||||
return Rx.Observable.from([dats.user, dats.pairedWith]);
|
||||
})
|
||||
// save user
|
||||
.flatMap(function(user) {
|
||||
// save user will do nothing if user is falsey
|
||||
debug('saving user', user.username);
|
||||
return saveUser(user);
|
||||
})
|
||||
.subscribe(
|
||||
function(user) {
|
||||
debug('onNext');
|
||||
if (user) {
|
||||
debug('user %s saved', user.username);
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
req.user.completedChallenges.push({
|
||||
id: challengeId,
|
||||
name: challengeName,
|
||||
completedWith: null,
|
||||
completedDate: isCompletedDate,
|
||||
solution: isSolution,
|
||||
challengeType: 5
|
||||
});
|
||||
|
||||
var index = req.user.uncompletedChallenges.indexOf(challengeId);
|
||||
if (index > -1) {
|
||||
|
||||
req.user.progressTimestamps.push(Date.now() || 0);
|
||||
req.user.uncompletedChallenges.splice(index, 1);
|
||||
}
|
||||
|
||||
req.user.save(function (err) {
|
||||
if (err) { return next(err); }
|
||||
res.send(true);
|
||||
});
|
||||
}
|
||||
},
|
||||
next,
|
||||
function() {
|
||||
debug('completed');
|
||||
return res.status(200).send(true);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function completedChallenge(req, res, next) {
|
||||
|
||||
var isCompletedDate = Math.round(+new Date());
|
||||
var completedDate = Math.round(+new Date());
|
||||
var challengeId = req.body.challengeInfo.challengeId;
|
||||
|
||||
req.user.completedChallenges.push({
|
||||
id: challengeId,
|
||||
completedDate: isCompletedDate,
|
||||
name: req.body.challengeInfo.challengeName,
|
||||
solution: null,
|
||||
githubLink: null,
|
||||
verified: true
|
||||
});
|
||||
var index = req.user.uncompletedChallenges.indexOf(challengeId);
|
||||
|
||||
if (index > -1) {
|
||||
req.user.progressTimestamps.push(Date.now() || 0);
|
||||
req.user.uncompletedChallenges.splice(index, 1);
|
||||
}
|
||||
|
||||
req.user.save(function (err, user) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
updateUserProgress(
|
||||
req.user,
|
||||
challengeId,
|
||||
{
|
||||
id: challengeId,
|
||||
completedDate: completedDate,
|
||||
name: req.body.challengeInfo.challengeName,
|
||||
solution: null,
|
||||
githubLink: null,
|
||||
verified: true
|
||||
}
|
||||
if (user) {
|
||||
res.sendStatus(200);
|
||||
}
|
||||
});
|
||||
);
|
||||
|
||||
saveUser(req.user)
|
||||
.subscribe(
|
||||
function() { },
|
||||
next,
|
||||
function() {
|
||||
res.sendStatus(200);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function completedZiplineOrBasejump(req, res, next) {
|
||||
|
||||
var isCompletedWith = req.body.challengeInfo.completedWith || false;
|
||||
var isCompletedDate = Math.round(+new Date());
|
||||
var completedWith = req.body.challengeInfo.completedWith || false;
|
||||
var completedDate = Math.round(+new Date());
|
||||
var challengeId = req.body.challengeInfo.challengeId;
|
||||
var solutionLink = req.body.challengeInfo.publicURL;
|
||||
var githubLink = req.body.challengeInfo.challengeType === '4'
|
||||
? req.body.challengeInfo.githubURL : true;
|
||||
|
||||
var githubLink = req.body.challengeInfo.challengeType === '4' ?
|
||||
req.body.challengeInfo.githubURL :
|
||||
true;
|
||||
|
||||
var challengeType = req.body.challengeInfo.challengeType === '4' ?
|
||||
4 : 3;
|
||||
4 :
|
||||
3;
|
||||
|
||||
if (!solutionLink || !githubLink) {
|
||||
req.flash('errors', {
|
||||
msg: 'You haven\'t supplied the necessary URLs for us to inspect ' +
|
||||
|
@ -406,93 +404,64 @@ module.exports = function(app) {
|
|||
return res.sendStatus(403);
|
||||
}
|
||||
|
||||
if (isCompletedWith) {
|
||||
User.find({
|
||||
where: { username: isCompletedWith.toLowerCase() },
|
||||
limit: 1
|
||||
}, function (err, pairedWithFromMongo) {
|
||||
if (err) { return next(err); }
|
||||
var index = req.user.uncompletedChallenges.indexOf(challengeId);
|
||||
if (index > -1) {
|
||||
req.user.progressTimestamps.push(Date.now() || 0);
|
||||
req.user.uncompletedChallenges.splice(index, 1);
|
||||
var challengeData = {
|
||||
id: challengeId,
|
||||
name: req.body.challengeInfo.challengeName,
|
||||
completedDate: completedDate,
|
||||
solution: solutionLink,
|
||||
githubLink: githubLink,
|
||||
challengeType: challengeType,
|
||||
verified: false
|
||||
};
|
||||
|
||||
observableQueryFromModel(
|
||||
User,
|
||||
'findOne',
|
||||
{ where: { username: completedWith.toLowerCase() } }
|
||||
)
|
||||
.doOnNext(function(pairedWith) {
|
||||
if (pairedWith) {
|
||||
updateUserProgress(
|
||||
pairedWith,
|
||||
challengeId,
|
||||
assign({ completedWith: req.user.id }, challengeData)
|
||||
);
|
||||
}
|
||||
var pairedWith = pairedWithFromMongo.pop();
|
||||
|
||||
req.user.completedChallenges.push({
|
||||
id: challengeId,
|
||||
name: req.body.challengeInfo.challengeName,
|
||||
completedWith: pairedWith.id,
|
||||
completedDate: isCompletedDate,
|
||||
solution: solutionLink,
|
||||
githubLink: githubLink,
|
||||
challengeType: challengeType,
|
||||
verified: false
|
||||
});
|
||||
|
||||
req.user.save(function (err, user) {
|
||||
if (err) { return next(err); }
|
||||
|
||||
if (req.user.id.toString() === pairedWith.id.toString()) {
|
||||
return res.sendStatus(200);
|
||||
})
|
||||
.withLatestFrom(Rx.Observable.just(req.user), function(user, pairedWith) {
|
||||
return {
|
||||
user: user,
|
||||
pairedWith: pairedWith
|
||||
};
|
||||
})
|
||||
.doOnNext(function(dats) {
|
||||
updateUserProgress(
|
||||
dats.user,
|
||||
challengeId,
|
||||
dats.pairedWith ?
|
||||
assign({ completedWith: dats.pairedWith.id }, challengeData) :
|
||||
challengeData
|
||||
);
|
||||
})
|
||||
.flatMap(function(dats) {
|
||||
return Rx.Observable.from([dats.user, dats.pairedWith]);
|
||||
})
|
||||
// save users
|
||||
.flatMap(function(user) {
|
||||
// save user will do nothing if user is falsey
|
||||
return saveUser(user);
|
||||
})
|
||||
.subscribe(
|
||||
function(user) {
|
||||
if (user) {
|
||||
debug('user %s saved', user.username);
|
||||
}
|
||||
index = pairedWith.uncompletedChallenges.indexOf(challengeId);
|
||||
if (index > -1) {
|
||||
pairedWith.progressTimestamps.push(Date.now() || 0);
|
||||
pairedWith.uncompletedChallenges.splice(index, 1);
|
||||
|
||||
}
|
||||
|
||||
pairedWith.completedChallenges.push({
|
||||
id: challengeId,
|
||||
name: req.body.challengeInfo.coursewareName,
|
||||
completedWith: req.user.id,
|
||||
completedDate: isCompletedDate,
|
||||
solution: solutionLink,
|
||||
githubLink: githubLink,
|
||||
challengeType: challengeType,
|
||||
verified: false
|
||||
});
|
||||
pairedWith.save(function (err, paired) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
if (user && paired) {
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
|
||||
req.user.completedChallenges.push({
|
||||
id: challengeId,
|
||||
name: req.body.challengeInfo.challengeName,
|
||||
completedWith: null,
|
||||
completedDate: isCompletedDate,
|
||||
solution: solutionLink,
|
||||
githubLink: githubLink,
|
||||
challengeType: challengeType,
|
||||
verified: false
|
||||
});
|
||||
|
||||
var index = req.user.uncompletedChallenges.indexOf(challengeId);
|
||||
if (index > -1) {
|
||||
req.user.progressTimestamps.push(Date.now() || 0);
|
||||
req.user.uncompletedChallenges.splice(index, 1);
|
||||
}
|
||||
|
||||
req.user.save(function (err, user) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
},
|
||||
next,
|
||||
function() {
|
||||
return res.status(200).send(true);
|
||||
}
|
||||
// NOTE(berks): under certain conditions this will not close
|
||||
// the response.
|
||||
if (user) {
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function challengeMap(req, res, next) {
|
||||
|
|
|
@ -4,7 +4,7 @@ var _ = require('lodash'),
|
|||
crypto = require('crypto'),
|
||||
nodemailer = require('nodemailer'),
|
||||
moment = require('moment'),
|
||||
//debug = require('debug')('freecc:cntr:userController'),
|
||||
// debug = require('debug')('freecc:cntr:userController'),
|
||||
|
||||
secrets = require('../../config/secrets');
|
||||
|
||||
|
|
|
@ -47,88 +47,32 @@ block content
|
|||
.background-svg.img-center
|
||||
.points-on-top
|
||||
= "[ " + (progressTimestamps.length) + " ]"
|
||||
|
||||
|
||||
.row
|
||||
.col-xs-12
|
||||
if (website1Title && website1Link && website1Image)
|
||||
.row
|
||||
.col-xs-12.col-md-5
|
||||
img.img-center.img-responsive.portfolio-image(src=website1Image, alt="@#{username}'s #{website1Title}")
|
||||
.col-xs-12.col-md-7
|
||||
h3.text-center.wrappable.flat-top= website1Title
|
||||
a.btn.btn-lg.btn-block.btn-info(href=website1Link, target='_blank')
|
||||
i.fa.icon-beaker
|
||||
| Try it out
|
||||
br
|
||||
if (website1Title && website1Link && !website1Image)
|
||||
.col-xs-12.col-md-12
|
||||
h3.text-center.wrappable.flat-top= website1Title
|
||||
a.btn.btn-lg.btn-block.btn-info(href=website1Link, target='_blank')
|
||||
i.fa.icon-beaker
|
||||
| Try it out
|
||||
br
|
||||
if (website2Title && website2Link && website2Image)
|
||||
.row
|
||||
.col-xs-12.col-md-5
|
||||
img.img-responsive.portfolio-image.img-center(src=website2Image, alt="@#{username}'s #{website2Title}")
|
||||
.col-xs-12.col-md-7
|
||||
h3.text-center.wrappable.flat-top= website2Title
|
||||
a.btn.btn-lg.btn-block.btn-info(href=website2Link, target='_blank')
|
||||
i.fa.icon-beaker
|
||||
| Try it out
|
||||
br
|
||||
if (website2Title && website2Link && !website2Image)
|
||||
.col-xs-12.col-md-12
|
||||
h3.text-center.wrappable.flat-top= website2Title
|
||||
a.btn.btn-lg.btn-block.btn-info(href=website2Link, target='_blank')
|
||||
i.fa.icon-beaker
|
||||
| Try it out
|
||||
br
|
||||
if (website3Title && website3Link && website3Image)
|
||||
.row
|
||||
.col-xs-12.col-md-5
|
||||
img.img-responsive.portfolio-image.img-center(src=website3Image, alt="@#{username}'s #{website1Title}")
|
||||
.col-xs-12.col-md-7
|
||||
h3.text-center.wrappable.flat-top= website3Title
|
||||
a.btn.btn-lg.btn-block.btn-info(href=website3Link, target='_blank')
|
||||
i.fa.icon-beaker
|
||||
| Try it out
|
||||
if (website3Title && website3Link && !website3Image)
|
||||
.col-xs-12.col-md-12
|
||||
h3.text-center.wrappable.flat-top= website3Title
|
||||
a.btn.btn-lg.btn-block.btn-info(href=website3Link, target='_blank')
|
||||
i.fa.icon-beaker
|
||||
| Try it out
|
||||
|
||||
.spacer
|
||||
.hidden-xs.hidden-sm.col-md-12
|
||||
#cal-heatmap.d3-centered
|
||||
script.
|
||||
$(document).ready(function () {
|
||||
setTimeout(function () {
|
||||
var cal = new CalHeatMap();
|
||||
var calendar = !{JSON.stringify(calender)};
|
||||
cal.init({
|
||||
itemSelector: "#cal-heatmap",
|
||||
domain: "month",
|
||||
subDomain: "x_day",
|
||||
domainGutter: 10,
|
||||
data: calendar,
|
||||
cellSize: 15,
|
||||
align: 'center',
|
||||
cellRadius: 3,
|
||||
cellPadding: 2,
|
||||
tooltip: true,
|
||||
range: 6,
|
||||
start: new Date().setDate(new Date().getDate() - 150),
|
||||
legendColors: ["#cccccc", "#215f1e"],
|
||||
legend: [1, 2, 3],
|
||||
label: {
|
||||
position: "top"
|
||||
}
|
||||
});
|
||||
}, 300);
|
||||
var cal = new CalHeatMap();
|
||||
var calendar = !{JSON.stringify(calender)};
|
||||
cal.init({
|
||||
itemSelector: "#cal-heatmap",
|
||||
domain: "month",
|
||||
subDomain: "x_day",
|
||||
domainGutter: 10,
|
||||
data: calendar,
|
||||
cellSize: 15,
|
||||
align: 'center',
|
||||
cellRadius: 3,
|
||||
cellPadding: 2,
|
||||
tooltip: true,
|
||||
range: 6,
|
||||
start: new Date().setDate(new Date().getDate() - 150),
|
||||
legendColors: ["#cccccc", "#215f1e"],
|
||||
legend: [1, 2, 3],
|
||||
label: {
|
||||
position: "top"
|
||||
}
|
||||
});
|
||||
});
|
||||
.row
|
||||
.hidden-xs.col-sm-12.text-center
|
||||
|
|
Loading…
Reference in New Issue