mirror of
https://github.com/sudoxnym/habitica.git
synced 2026-08-03 08:21:07 +00:00
challenge prize: award winner 1 achievement and challenge.prize
gems. then close challenge.
This commit is contained in:
parent
f6ebd9997e
commit
9d15e724e2
5 changed files with 73 additions and 15 deletions
|
|
@ -206,32 +206,71 @@ api.update = function(req, res){
|
|||
})
|
||||
}
|
||||
|
||||
// DELETE
|
||||
api['delete'] = function(req, res){
|
||||
/**
|
||||
* Called by either delete() or selectWinner(). Will delete the challenge and set the "broken" property on all users' subscribed tasks
|
||||
* @param {cid} the challenge id
|
||||
* @param {broken} the object representing the broken status of the challenge. Eg:
|
||||
* {broken: 'CHALLENGE_DELETED', id: CHALLENGE_ID}
|
||||
* {broken: 'CHALLENGE_CLOSED', id: CHALLENGE_ID, winner: USER_NAME}
|
||||
*/
|
||||
function closeChal(cid, broken, cb) {
|
||||
var removed;
|
||||
async.waterfall([
|
||||
function(cb){
|
||||
Challenge.findOneAndRemove({_id:req.params.cid}, cb)
|
||||
function(cb2){
|
||||
Challenge.findOneAndRemove({_id:cid}, cb2)
|
||||
},
|
||||
function(_removed, cb) {
|
||||
function(_removed, cb2) {
|
||||
removed = _removed;
|
||||
User.find({_id:{$in: removed.members}}, cb);
|
||||
User.find({_id:{$in: removed.members}}, cb2);
|
||||
},
|
||||
function(users, cb) {
|
||||
function(users, cb2) {
|
||||
var parallel = [];
|
||||
_.each(users, function(user){
|
||||
_.each(user.tasks, function(task){
|
||||
if (task.challenge && task.challenge.id == removed._id) {
|
||||
task.challenge.broken = 'CHALLENGE_DELETED';
|
||||
_.mege(task.challenge, broken);
|
||||
}
|
||||
})
|
||||
parallel.push(function(cb2){
|
||||
user.save(cb2);
|
||||
parallel.push(function(cb3){
|
||||
user.save(cb3);
|
||||
})
|
||||
})
|
||||
async.parallel(parallel, cb);
|
||||
async.parallel(parallel, cb2);
|
||||
}
|
||||
], function(err){
|
||||
], cb);
|
||||
}
|
||||
|
||||
// DELETE
|
||||
api['delete'] = function(req, res){
|
||||
closeChal(req.params.cid, {broken: 'CHALLENGE_DELETED'}, function(err){
|
||||
if (err) return res.json(500, {err: err});
|
||||
res.send(200);
|
||||
})
|
||||
}
|
||||
|
||||
api.selectWinner = function(req, res) {
|
||||
if (!req.query.uid) return res.json(401, {err: 'Must select a winner'});
|
||||
var chal;
|
||||
async.waterfall([
|
||||
function(cb){
|
||||
Challenge.findById(req.params.cid, cb);
|
||||
},
|
||||
function(_chal, cb){
|
||||
if (!_chal) return cb('Challenge ' + req.params.cid + ' not found.');
|
||||
chal = _chal;
|
||||
User.findById(req.query.uid, cb)
|
||||
},
|
||||
function(winner, cb){
|
||||
if (!winner) return cb('Winner ' + req.query.uid + ' not found.');
|
||||
_.defaults(winner.achievements, {challenges: []});
|
||||
winner.achievements.challenges.push(chal.name);
|
||||
winner.balance += chal.prize/4;
|
||||
winner.save(cb);
|
||||
},
|
||||
function(saved, num, cb) {
|
||||
closeChal(req.params.cid, {broken: 'CHALLENGE_CLOSED', winner: saved.profile.name}, cb);
|
||||
}
|
||||
], function(){
|
||||
if (err) return res.json(500, {err: err});
|
||||
res.send(200);
|
||||
})
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ var TaskSchema = new Schema({
|
|||
streak: {type: Number, 'default': 0},
|
||||
challenge: {
|
||||
id: {type: 'String', ref:'Challenge'},
|
||||
broken: String // CHALLENGE_DELETED, TASK_DELETED, UNSUBSCRIBED, etc
|
||||
broken: String, // CHALLENGE_DELETED, TASK_DELETED, UNSUBSCRIBED, CHALLENGE_CLOSED
|
||||
winner: String // user.profile.name
|
||||
// group: {type: 'Strign', ref: 'Group'} // if we restore this, rename `id` above to `challenge`
|
||||
}
|
||||
}, {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,9 @@ var UserSchema = new Schema({
|
|||
helpedHabit: Boolean,
|
||||
ultimateGear: Boolean,
|
||||
beastMaster: Boolean,
|
||||
streak: Number
|
||||
veteran: Boolean,
|
||||
streak: Number,
|
||||
challenges: Array
|
||||
},
|
||||
auth: {
|
||||
facebook: Schema.Types.Mixed,
|
||||
|
|
|
|||
|
|
@ -74,4 +74,14 @@
|
|||
h5 Original User!
|
||||
small
|
||||
| One of the <em>very</em> original early adopters, Talk about alpha tester!
|
||||
hr
|
||||
hr
|
||||
|
||||
div(ng-if='profile.achievements.challenges || user._id == profile._id')
|
||||
// This is a very strange icon to use. revisit
|
||||
.achievement.achievement-karaoke(ng-show='profile.achievements.challenges')
|
||||
div(ng-class='{muted: !profile.achievements.challenges}')
|
||||
h5 Was the winner in the following challenges
|
||||
ul
|
||||
li(ng-repeat='chal in profile.achievements.challenges') {{chal}}
|
||||
hr
|
||||
|
||||
|
|
|
|||
|
|
@ -75,6 +75,12 @@ li(ng-repeat='task in obj[list.type+"s"]', class='task {{taskClasses(task, user.
|
|||
a(ng-click='unlink(task, "keep-all")') Keep Them
|
||||
| |
|
||||
a(ng-click='unlink(task, "remove-all")') Remove Them
|
||||
div(ng-if='task.challenge.broken=="CHALLENGE_CLOSED"')
|
||||
p. This challenge has been completed, and the winner was <span class='badge'>{{task.challenge.winner}}</span>!. What to do with the orphan tasks?
|
||||
p
|
||||
a(ng-click='unlink(task, "keep-all")') Keep Them
|
||||
| |
|
||||
a(ng-click='unlink(task, "remove-all")') Remove Them
|
||||
//-div(ng-if='task.challenge.broken=="UNSUBSCRIBED"')
|
||||
p Broken Challenge Link: this task was part of a challenge, but you have unsubscribed from the challenge. What to do with the orphan tasks?
|
||||
p
|
||||
|
|
|
|||
Loading…
Reference in a new issue