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 = new google.visualization.LineChart $(".challenge-#{chal.id}-member-#{member.id}-history-#{task.id}")[0]
|
||||||
// chart.draw(data, options)
|
// 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) {
|
$scope.unsubscribe = function(keep) {
|
||||||
if (keep == 'cancel') {
|
if (keep == 'cancel') {
|
||||||
$scope.selectedChal = undefined;
|
$scope.selectedChal = undefined;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
habitrpg.controller("TasksCtrl", ['$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) {
|
function($scope, $rootScope, $location, User, Algos, Helpers, Notification, $http, API_URL) {
|
||||||
$scope.score = function(task, direction) {
|
$scope.score = function(task, direction) {
|
||||||
if (task.type === "reward" && User.user.stats.gp < task.value){
|
if (task.type === "reward" && User.user.stats.gp < task.value){
|
||||||
return Notification.text('Not enough GP.');
|
return Notification.text('Not enough GP.');
|
||||||
@@ -94,6 +94,14 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User', '
|
|||||||
$scope.editing = false;
|
$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
|
Items
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ var syncChalToUser = function(chal, user) {
|
|||||||
_.each(chal.tasks, function(task){
|
_.each(chal.tasks, function(task){
|
||||||
var type = task.type;
|
var type = task.type;
|
||||||
_.defaults(task, {tags: tags, challenge:{}});
|
_.defaults(task, {tags: tags, challenge:{}});
|
||||||
_.defaults(task.challenge, {id:chal._id, broken:false});
|
_.defaults(task.challenge, {id:chal._id});
|
||||||
if (user.tasks[task.id]) {
|
if (user.tasks[task.id]) {
|
||||||
_.merge(user.tasks[task.id], keepAttrs(task));
|
_.merge(user.tasks[task.id], keepAttrs(task));
|
||||||
} else {
|
} else {
|
||||||
@@ -213,8 +213,6 @@ api.leave = function(req, res){
|
|||||||
Challenge.findByIdAndUpdate(cid, {$pull:{members:user._id}}, cb);
|
Challenge.findByIdAndUpdate(cid, {$pull:{members:user._id}}, cb);
|
||||||
},
|
},
|
||||||
function(chal, cb){
|
function(chal, cb){
|
||||||
// Remove challenge from user
|
|
||||||
//User.findByIdAndUpdate(user._id, {$pull:{challenges:cid}}, cb);
|
|
||||||
var i = user.challenges.indexOf(cid)
|
var i = user.challenges.indexOf(cid)
|
||||||
if (~i) user.challenges.splice(i,1);
|
if (~i) user.challenges.splice(i,1);
|
||||||
unlink(user, chal._id, keep)
|
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 user = res.locals.user;
|
||||||
var tid = req.params.id;
|
var tid = req.params.id;
|
||||||
var cid = user.tasks[tid].challenge.id;
|
var cid = user.tasks[tid].challenge.id;
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
/* @see ./routes.coffee for routing*/
|
/* @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 url = require('url');
|
||||||
var ipn = require('paypal-ipn');
|
var ipn = require('paypal-ipn');
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
@@ -16,6 +13,7 @@ var check = validator.check;
|
|||||||
var sanitize = validator.sanitize;
|
var sanitize = validator.sanitize;
|
||||||
var User = require('./../models/user').model;
|
var User = require('./../models/user').model;
|
||||||
var Group = require('./../models/group').model;
|
var Group = require('./../models/group').model;
|
||||||
|
var Challenge = require('./../models/challenge').model;
|
||||||
var api = module.exports;
|
var api = module.exports;
|
||||||
|
|
||||||
// FIXME put this in a proper location
|
// 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
|
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
|
// Send error responses for improper API call
|
||||||
if (!id) return res.json(500, {err: ':id required'});
|
if (!id) return res.json(500, {err: ':id required'});
|
||||||
if (direction !== 'up' && direction !== 'down') {
|
if (direction !== 'up' && direction !== 'down') {
|
||||||
|
if (direction == 'unlink') return next();
|
||||||
return res.json(500, {err: ":direction must be 'up' or 'down'"});
|
return res.json(500, {err: ":direction must be 'up' or 'down'"});
|
||||||
}
|
}
|
||||||
// If exists already, score it
|
// If exists already, score it
|
||||||
@@ -131,6 +140,9 @@ api.scoreTask = function(req, res, next) {
|
|||||||
delta: delta
|
delta: delta
|
||||||
}, saved.toJSON().stats));
|
}, 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},
|
streak: {type: Number, 'default': 0},
|
||||||
challenge: {
|
challenge: {
|
||||||
id: {type: 'String', ref:'Challenge'},
|
id: {type: 'String', ref:'Challenge'},
|
||||||
broken: {type: Boolean, 'default': false}
|
broken: String // CHALLENGE_DELETED, TASK_DELETED, UNSUBSCRIBED, etc
|
||||||
// group: {type: 'Strign', redf: 'Group'} // if we restore this, rename `id` above to `challenge`
|
// group: {type: 'Strign', ref: 'Group'} // if we restore this, rename `id` above to `challenge`
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -2,22 +2,15 @@
|
|||||||
.span2.well
|
.span2.well
|
||||||
h4 Filters
|
h4 Filters
|
||||||
ul
|
ul
|
||||||
|
li(ng-repeat='group in groups')
|
||||||
|
input(type='checkbox', ng-model='search.group')
|
||||||
|
| {{group.name}}
|
||||||
li
|
li
|
||||||
input(type='checkbox', checked='checked')
|
input(type='checkbox', ng-model='search.members')
|
||||||
.label.label-warning todo
|
| Subscribed (TODO)
|
||||||
| Party
|
|
||||||
li
|
li
|
||||||
input(type='checkbox', checked='checked')
|
input(type='checkbox', ng-model='search.members')
|
||||||
.label.label-warning todo
|
| Available (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
|
|
||||||
.span10
|
.span10
|
||||||
// Creation form
|
// Creation form
|
||||||
a.btn.btn-success(ng-click='create()') Create Challenge
|
a.btn.btn-success(ng-click='create()') Create Challenge
|
||||||
@@ -33,7 +26,7 @@
|
|||||||
habitrpg-tasks(main=false, obj='newChallenge')
|
habitrpg-tasks(main=false, obj='newChallenge')
|
||||||
|
|
||||||
// Challenges list
|
// 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
|
.accordion-heading
|
||||||
ul.pull-right.challenge-accordion-header-specs
|
ul.pull-right.challenge-accordion-header-specs
|
||||||
li {{challenge.members.length}} Subscribers
|
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"')
|
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 Broken Challenge Link: this task was part of a challenge, but has been removed from it. What would you like to do?
|
||||||
p
|
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
|
a(ng-click="remove(list, $index)") Remove It
|
||||||
div(ng-if='task.challenge.broken=="CHALLENGE_DELETED"')
|
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 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
|
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"')
|
//-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 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
|
p
|
||||||
|
|||||||
Reference in New Issue
Block a user