mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-19 07:37:25 +01:00
challenges: sync score to challenge, lotsa bug fixes
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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`
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
| |
|
||||
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
|
||||
| |
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user