challenges: sync score to challenge, lotsa bug fixes

This commit is contained in:
Tyler Renelle
2013-10-27 15:27:01 -07:00
parent e52d0a156a
commit a078889d58
7 changed files with 45 additions and 83 deletions

View File

@@ -119,50 +119,6 @@ habitrpg.controller("ChallengesCtrl", ['$scope', '$rootScope', 'User', 'Challeng
// chart = new google.visualization.LineChart $(".challenge-#{chal.id}-member-#{member.id}-history-#{task.id}")[0]
// chart.draw(data, options)
/**
* Sync user to challenge (when they score, add to statistics)
*/
// TODO this needs to be moved to the server. Either:
// 1. Calculate on load (simplest, but bad performance)
// 2. Updated from user score API
// app.model.on("change", "_page.user.priv.tasks.*.value", function(id, value, previous, passed) {
// /* Sync to challenge, but do it later*/
//
// var _this = this;
// return async.nextTick(function() {
// var chal, chalTask, chalUser, ctx, cu, model, pub, task, tobj;
// model = app.model;
// ctx = {
// model: model
// };
// task = model.at("_page.user.priv.tasks." + id);
// tobj = task.get();
// pub = model.get("_page.user.pub");
// if (((chalTask = helpers.taskInChallenge.call(ctx, tobj)) != null) && chalTask.get()) {
// chalTask.increment("value", value - previous);
// chal = model.at("groups." + tobj.group.id + ".challenges." + tobj.challenge);
// chalUser = function() {
// return helpers.indexedAt.call(ctx, chal.path(), 'members', {
// id: pub.id
// });
// };
// cu = chalUser();
// if (!(cu != null ? cu.get() : void 0)) {
// chal.push("members", {
// id: pub.id,
// name: model.get(pub.profile.name)
// });
// cu = model.at(chalUser());
// } else {
// cu.set('name', pub.profile.name);
// }
// return cu.set("" + tobj.type + "s." + tobj.id, {
// value: tobj.value,
// history: tobj.history
// });
// }
// });
// });
/*
--------------------------
@@ -170,15 +126,6 @@ habitrpg.controller("ChallengesCtrl", ['$scope', '$rootScope', 'User', 'Challeng
--------------------------
*/
$scope.unlink = function(task, keep) {
// TODO move this to userServices, turn userSerivces.user into ng-resource
$http.post(API_URL + '/api/v1/user/task/' + task.id + '/unlink', {keep:keep})
.success(function(){
debugger
User.log({});
});
};
$scope.unsubscribe = function(keep) {
if (keep == 'cancel') {
$scope.selectedChal = undefined;

View File

@@ -1,7 +1,7 @@
"use strict";
habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User', 'Algos', 'Helpers', 'Notification',
function($scope, $rootScope, $location, User, Algos, Helpers, Notification) {
habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User', 'Algos', 'Helpers', 'Notification', '$http', 'API_URL',
function($scope, $rootScope, $location, User, Algos, Helpers, Notification, $http, API_URL) {
$scope.score = function(task, direction) {
if (task.type === "reward" && User.user.stats.gp < task.value){
return Notification.text('Not enough GP.');
@@ -94,6 +94,14 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User', '
$scope.editing = false;
};
$scope.unlink = function(task, keep) {
// TODO move this to userServices, turn userSerivces.user into ng-resource
$http.post(API_URL + '/api/v1/user/task/' + task.id + '/unlink?keep=' + keep)
.success(function(){
User.log({});
});
};
/*
------------------------
Items

View File

@@ -139,7 +139,7 @@ var syncChalToUser = function(chal, user) {
_.each(chal.tasks, function(task){
var type = task.type;
_.defaults(task, {tags: tags, challenge:{}});
_.defaults(task.challenge, {id:chal._id, broken:false});
_.defaults(task.challenge, {id:chal._id});
if (user.tasks[task.id]) {
_.merge(user.tasks[task.id], keepAttrs(task));
} else {
@@ -213,8 +213,6 @@ api.leave = function(req, res){
Challenge.findByIdAndUpdate(cid, {$pull:{members:user._id}}, cb);
},
function(chal, cb){
// Remove challenge from user
//User.findByIdAndUpdate(user._id, {$pull:{challenges:cid}}, cb);
var i = user.challenges.indexOf(cid)
if (~i) user.challenges.splice(i,1);
unlink(user, chal._id, keep)
@@ -229,7 +227,11 @@ api.leave = function(req, res){
});
}
api.unlink = function(req, res) {
api.unlink = function(req, res, next) {
// they're scoring the task - commented out, we probably don't need it due to route ordering in api.js
//var urlParts = req.originalUrl.split('/');
//if (_.contains(['up','down'], urlParts[urlParts.length -1])) return next();
var user = res.locals.user;
var tid = req.params.id;
var cid = user.tasks[tid].challenge.id;

View File

@@ -1,8 +1,5 @@
/* @see ./routes.coffee for routing*/
// fixme remove this junk, was coffeescript compiled (probably for IE8 compat)
var __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
var url = require('url');
var ipn = require('paypal-ipn');
var _ = require('lodash');
@@ -16,6 +13,7 @@ var check = validator.check;
var sanitize = validator.sanitize;
var User = require('./../models/user').model;
var Group = require('./../models/group').model;
var Challenge = require('./../models/challenge').model;
var api = module.exports;
// FIXME put this in a proper location
@@ -82,6 +80,16 @@ function addTask(user, task) {
---------------
*/
var syncScoreToChallenge = function(task, delta){
if (!task.challenge || !task.challenge.id) return;
Challenge.findById(task.challenge.id, function(err, chal){
if (err) throw err;
var t = chal.tasks[task.id]
t.value += delta;
t.history.push({value: t.value, date: +new Date});
chal.save();
});
}
/**
This is called form deprecated.coffee's score function, and the req.headers are setup properly to handle the login
@@ -96,6 +104,7 @@ api.scoreTask = function(req, res, next) {
// Send error responses for improper API call
if (!id) return res.json(500, {err: ':id required'});
if (direction !== 'up' && direction !== 'down') {
if (direction == 'unlink') return next();
return res.json(500, {err: ":direction must be 'up' or 'down'"});
}
// If exists already, score it
@@ -124,13 +133,16 @@ api.scoreTask = function(req, res, next) {
}
task = user.tasks[id];
var delta = algos.score(user, task, direction);
//user.markModified('flags');
//user.markModified('flags');
user.save(function(err, saved) {
if (err) return res.json(500, {err: err});
res.json(200, _.extend({
delta: delta
}, saved.toJSON().stats));
});
// if it's a challenge task, sync the score
syncScoreToChallenge(task, delta);
};
/**

View File

@@ -28,8 +28,8 @@ var TaskSchema = new Schema({
streak: {type: Number, 'default': 0},
challenge: {
id: {type: 'String', ref:'Challenge'},
broken: {type: Boolean, 'default': false}
// group: {type: 'Strign', redf: 'Group'} // if we restore this, rename `id` above to `challenge`
broken: String // CHALLENGE_DELETED, TASK_DELETED, UNSUBSCRIBED, etc
// group: {type: 'Strign', ref: 'Group'} // if we restore this, rename `id` above to `challenge`
}
});

View File

@@ -2,22 +2,15 @@
.span2.well
h4 Filters
ul
li(ng-repeat='group in groups')
input(type='checkbox', ng-model='search.group')
| {{group.name}}
li
input(type='checkbox', checked='checked')
.label.label-warning todo
| Party
input(type='checkbox', ng-model='search.members')
| Subscribed (TODO)
li
input(type='checkbox', checked='checked')
.label.label-warning todo
| (list groups)
li
input(type='checkbox', checked='checked')
.label.label-warning todo
| Subscribed
li
input(type='checkbox', checked='checked')
.label.label-warning todo
| Available
input(type='checkbox', ng-model='search.members')
| Available (TODO)
.span10
// Creation form
a.btn.btn-success(ng-click='create()') Create Challenge
@@ -33,7 +26,7 @@
habitrpg-tasks(main=false, obj='newChallenge')
// Challenges list
.accordion-group(ng-repeat='challenge in challenges', ng-init='locked=true')
.accordion-group(ng-repeat='challenge in challenges | filter:search', ng-init='locked=true')
.accordion-heading
ul.pull-right.challenge-accordion-header-specs
li {{challenge.members.length}} Subscribers

View File

@@ -64,15 +64,15 @@ li(ng-repeat='task in list.tasks', class='task {{taskClasses(task, user.filters,
div(ng-if='task.challenge.broken=="TASK_DELETED"')
p Broken Challenge Link: this task was part of a challenge, but has been removed from it. What would you like to do?
p
a(ng-click="unlink(task, 'keep')") Keep It
a(ng-click='unlink(task, "keep")') Keep It
| &nbsp;|&nbsp;
a(ng-click="remove(list, $index)") Remove It
div(ng-if='task.challenge.broken=="CHALLENGE_DELETED"')
p Broken Challenge Link: this task was part of a challenge, but the challenge (or group) has been deleted. What to do with the orphan tasks?
p
a(ng-click="unlink(task 'keep-all')") Keep Them
a(ng-click='unlink(task, "keep-all")') Keep Them
| &nbsp;|&nbsp;
a(ng-click="unlink(task, 'remove-all')") Remove 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