diff --git a/common/script/ops/addTask.js b/common/script/ops/addTask.js index 81f642ab02..592f877248 100644 --- a/common/script/ops/addTask.js +++ b/common/script/ops/addTask.js @@ -5,6 +5,7 @@ import taskDefaults from '../libs/taskDefaults'; module.exports = function addTask (user, req = {body: {}}) { let task = taskDefaults(req.body); user.tasksOrder[`${task.type}s`].unshift(task._id); + user[`${task.type}s`].unshift(task); if (user.preferences.newTaskEdit) { task._editing = true; diff --git a/common/script/ops/deleteTask.js b/common/script/ops/deleteTask.js index b818cf7ed4..42d37f7efa 100644 --- a/common/script/ops/deleteTask.js +++ b/common/script/ops/deleteTask.js @@ -6,16 +6,15 @@ import _ from 'lodash'; module.exports = function deleteTask (user, req = {}) { let tid = _.get(req, 'params.id'); - let task = user.tasks[tid]; + let taskType = _.get(req, 'params.taskType'); - if (!task) { + let index = _.findIndex(user[`${taskType}s`], function(task) {return task._id === tid;}); + + if (index === -1) { throw new NotFound(i18n.t('messageTaskNotFound', req.language)); } - let index = user[`${task.type}s`].indexOf(task); - if (index !== -1) { - user[`${task.type}s`].splice(index, 1); - } + user[`${taskType}s`].splice(index, 1); return {}; }; diff --git a/common/script/ops/sortTask.js b/common/script/ops/sortTask.js index ca79b03e24..77e7a167a3 100644 --- a/common/script/ops/sortTask.js +++ b/common/script/ops/sortTask.js @@ -8,23 +8,24 @@ import _ from 'lodash'; // TODO used only in client, move there? -module.exports = function sortTag (user, req = {}) { +module.exports = function sortTask (user, req = {}) { let id = _.get(req, 'params.id'); let to = _.get(req, 'query.to'); let fromParam = _.get(req, 'query.from'); + let taskType = _.get(req, 'params.taskType'); - let task = user.tasks[id]; + let index = _.findIndex(user[`${taskType}s`], function(task) {return task._id === id;}); - if (!task) { + if (index === -1) { throw new NotFound(i18n.t('messageTaskNotFound', req.language)); } if (!to && !fromParam) { throw new BadRequest('?to=__&from=__ are required'); } - let tasks = user[`${task.type}s`]; + let tasks = user[`${taskType}s`]; - if (task.type === 'todo' && tasks[fromParam] !== task) { + if (taskType === 'todo') { let preenedTasks = preenTodos(tasks); if (to !== -1) { @@ -34,10 +35,6 @@ module.exports = function sortTag (user, req = {}) { fromParam = tasks.indexOf(preenedTasks[fromParam]); } - if (tasks[fromParam] !== task) { - throw new NotFound(i18n.t('messageTaskNotFound', req.language)); - } - let movedTask = tasks.splice(fromParam, 1)[0]; if (to === -1) { diff --git a/website/public/js/app.js b/website/public/js/app.js index 147b2a7465..5d685de42a 100644 --- a/website/public/js/app.js +++ b/website/public/js/app.js @@ -310,6 +310,7 @@ window.habitrpg = angular.module('habitrpg', }); var settings = JSON.parse(localStorage.getItem(STORAGE_SETTINGS_ID)); + if (settings && settings.auth) { $httpProvider.defaults.headers.common['Content-Type'] = 'application/json;charset=utf-8'; $httpProvider.defaults.headers.common['x-api-user'] = settings.auth.apiId; diff --git a/website/public/js/controllers/authCtrl.js b/website/public/js/controllers/authCtrl.js index 5b486677f5..94451276ab 100644 --- a/website/public/js/controllers/authCtrl.js +++ b/website/public/js/controllers/authCtrl.js @@ -64,7 +64,7 @@ angular.module('habitrpg') }).error(errorAlert); }; - $scope.playButtonClick = function(){ + $scope.playButtonClick = function() { Analytics.track({'hitType':'event','eventCategory':'button','eventAction':'click','eventLabel':'Play'}) if (User.authenticated()) { window.location.href = ('/' + window.location.hash); diff --git a/website/public/js/controllers/filtersCtrl.js b/website/public/js/controllers/filtersCtrl.js index e2597af241..2ba1a4da2c 100644 --- a/website/public/js/controllers/filtersCtrl.js +++ b/website/public/js/controllers/filtersCtrl.js @@ -14,7 +14,7 @@ habitrpg.controller("FiltersCtrl", ['$scope', '$rootScope', 'User', 'Shared', _.each(User.user.tags, function(tag){ // Send an update op for each changed tag (excluding new tags & deleted tags, this if() packs a punch) if (tagsSnap[tag.id] && tagsSnap[tag.id].name != tag.name) - User.updateTag({params:{id:tag.id},body:{name:tag.name}}); + User.updateTag({params:{id:tag.id}, body:{name:tag.name}}); }) $scope._editing = false; } else { @@ -37,7 +37,7 @@ habitrpg.controller("FiltersCtrl", ['$scope', '$rootScope', 'User', 'Shared', $scope.updateTaskFilter(); $scope.createTag = function() { - User.addTag({body:{name:$scope._newTag.name, id:Shared.uuid()}}); + User.addTag({body:{name: $scope._newTag.name, id: Shared.uuid()}}); $scope._newTag.name = ''; }; }]); diff --git a/website/public/js/controllers/tasksCtrl.js b/website/public/js/controllers/tasksCtrl.js index 857f1e2393..fa88ecd271 100644 --- a/website/public/js/controllers/tasksCtrl.js +++ b/website/public/js/controllers/tasksCtrl.js @@ -24,7 +24,7 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User','N if (direction === 'down') $rootScope.playSound('Minus_Habit'); else if (direction === 'up') $rootScope.playSound('Plus_Habit'); } - User.score({params:{id: task.id, direction:direction}}); + User.score({params:{task: task, direction:direction}}); Analytics.updateUser(); Analytics.track({'hitType':'event','eventCategory':'behavior','eventAction':'score task','taskType':task.type,'direction':direction}); }; @@ -33,12 +33,12 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User','N var newTask = { text: task, type: listDef.type, - tags: _.transform(User.user.filters, function(m, v, k) { - if (v) m.push(v); - }), + // tags: _.transform(User.user.filters, function(m, v, k) { + // if (v) m.push(v); + // }), }; - User.addTask({body:newTask}); + User.addTask({body: newTask}); } $scope.addTask = function(addTo, listDef) { @@ -80,7 +80,7 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User','N */ $scope.pushTask = function(task, index, location) { var to = (location === 'bottom' || $scope.ctrlPressed) ? -1 : 0; - User.sortTask({params:{id:task.id},query:{from:index, to:to}}) + User.sortTask({params:{id: task._id, taskType: task.type}, query:{from:index, to:to}}) }; /** @@ -96,17 +96,17 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User','N $scope.removeTask = function(task) { if (!confirm(window.env.t('sureDelete', {taskType: window.env.t(task.type), taskText: task.text}))) return; - User.deleteTask({params:{id:task.id}}) + User.deleteTask({params:{id: task._id, taskType: task.type}}) }; $scope.saveTask = function(task, stayOpen, isSaveAndClose) { if (task.checklist) task.checklist = _.filter(task.checklist,function(i){return !!i.text}); - User.updateTask({params:{id:task.id},body:task}); + User.updateTask(task, {body: task}); if (!stayOpen) task._editing = false; if (isSaveAndClose) { - $("#task-" + task.id).parent().children('.popover').removeClass('in'); + $("#task-" + task._id).parent().children('.popover').removeClass('in'); } if (task.type == 'habit') Guide.goto('intro', 3); @@ -126,7 +126,7 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User','N }; $scope.unlink = function(task, keep) { - Tasks.unlinkTask(task.id, keep) + Tasks.unlinkTask(task._id, keep) .success(function () { User.log({}); }); @@ -159,7 +159,7 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User','N */ function focusChecklist(task,index) { window.setTimeout(function(){ - $('#task-'+task.id+' .checklist-form input[type="text"]')[index].focus(); + $('#task-'+task._id+' .checklist-form input[type="text"]')[index].focus(); }); } @@ -173,7 +173,7 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User','N // Don't allow creation of an empty checklist item // TODO Provide UI feedback that this item is still blank } else if ($index == task.checklist.length-1){ - User.updateTask({params:{id:task.id},body:task}); // don't preen the new empty item + User.updateTask({params:{id:task._id},body:task}); // don't preen the new empty item task.checklist.push({completed:false,text:''}); focusChecklist(task,task.checklist.length-1); } else { @@ -185,12 +185,12 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User','N $scope.removeChecklistItem = function(task, $event, $index, force){ // Remove item if clicked on trash icon if (force) { - Tasks.removeChecklistItem(task.id, task.checklist[$index]._id); + Tasks.removeChecklistItem(task._id, task.checklist[$index]._id); task.checklist.splice($index, 1); } else if (!task.checklist[$index].text) { // User deleted all the text and is now wishing to delete the item // saveTask will prune the empty item - Tasks.removeChecklistItem(task.id, task.checklist[$index]._id); + Tasks.removeChecklistItem(task._id, task.checklist[$index]._id); // Move focus if the list is still non-empty if ($index > 0) focusChecklist(task, $index-1); diff --git a/website/public/js/directives/hrpg-sort-tags.directive.js b/website/public/js/directives/hrpg-sort-tags.directive.js index 5b42bc778f..93fb115116 100644 --- a/website/public/js/directives/hrpg-sort-tags.directive.js +++ b/website/public/js/directives/hrpg-sort-tags.directive.js @@ -16,7 +16,7 @@ ui.item.data('startIndex', ui.item.index()); }, stop: function (event, ui) { - User.user.ops.sortTag({ + User.sortTag({ query: { from: ui.item.data('startIndex'), to:ui.item.index() diff --git a/website/public/js/directives/hrpg-sort-tasks.directive.js b/website/public/js/directives/hrpg-sort-tasks.directive.js index 820fccfbe8..0ce42d82eb 100644 --- a/website/public/js/directives/hrpg-sort-tasks.directive.js +++ b/website/public/js/directives/hrpg-sort-tasks.directive.js @@ -20,8 +20,8 @@ stop: function (event, ui) { var task = angular.element(ui.item[0]).scope().task; var startIndex = ui.item.data('startIndex'); - User.user.ops.sortTask({ - params: { id: task.id }, + User.sortTask({ + params: { id: task._id, taskType: task.type }, query: { from: startIndex, to: ui.item.index() diff --git a/website/public/js/services/taskServices.js b/website/public/js/services/taskServices.js index a8acbe527c..5eaad3ff74 100644 --- a/website/public/js/services/taskServices.js +++ b/website/public/js/services/taskServices.js @@ -3,20 +3,20 @@ var TASK_KEYS_TO_REMOVE = ['_id', 'completed', 'date', 'dateCompleted', 'history', 'id', 'streak', 'createdAt']; angular.module('habitrpg') -.factory('Tasks', ['$rootScope', 'Shared', 'User', '$http', - function tasksFactory($rootScope, Shared, User, $http) { +.factory('Tasks', ['$rootScope', 'Shared', '$http', + function tasksFactory($rootScope, Shared, $http) { function getUserTasks () { return $http({ method: 'GET', - url: 'api/v3/tasks/user', + url: '/api/v3/tasks/user', }); }; function createUserTasks (taskDetails) { return $http({ method: 'POST', - url: 'api/v3/tasks/user', + url: '/api/v3/tasks/user', data: taskDetails, }); }; @@ -24,14 +24,14 @@ angular.module('habitrpg') function getChallengeTasks (challengeId) { return $http({ method: 'GET', - url: 'api/v3/tasks/challenge/' + challengeId, + url: '/api/v3/tasks/challenge/' + challengeId, }); }; function createChallengeTasks (challengeId, taskDetails) { return $http({ method: 'POST', - url: 'api/v3/tasks/challenge/' + challengeId, + url: '/api/v3/tasks/challenge/' + challengeId, data: taskDetails, }); }; @@ -39,14 +39,14 @@ angular.module('habitrpg') function getTask (taskId) { return $http({ method: 'GET', - url: 'api/v3/tasks/' + taskId, + url: '/api/v3/tasks/' + taskId, }); }; function updateTask (taskId, taskDetails) { return $http({ method: 'PUT', - url: 'api/v3/tasks/' + taskId, + url: '/api/v3/tasks/' + taskId, data: taskDetails, }); }; @@ -54,28 +54,28 @@ angular.module('habitrpg') function deleteTask (taskId) { return $http({ method: 'DELETE', - url: 'api/v3/tasks/' + taskId, + url: '/api/v3/tasks/' + taskId, }); }; function scoreTask (taskId, direction) { return $http({ method: 'POST', - url: 'api/v3/tasks/' + taskId + '/score/' + direction, + url: '/api/v3/tasks/' + taskId + '/score/' + direction, }); }; function moveTask (taskId, position) { return $http({ method: 'POST', - url: 'api/v3/tasks/' + taskId + '/move/to/' + position, + url: '/api/v3/tasks/' + taskId + '/move/to/' + position, }); }; function addChecklistItem (taskId, checkListItem) { return $http({ method: 'POST', - url: 'api/v3/tasks/' + taskId + '/checklist', + url: '/api/v3/tasks/' + taskId + '/checklist', data: checkListItem, }); }; @@ -83,14 +83,14 @@ angular.module('habitrpg') function scoreCheckListItem (taskId, itemId) { return $http({ method: 'POST', - url: 'api/v3/tasks/' + taskId + '/checklist/' + itemId + '/score', + url: '/api/v3/tasks/' + taskId + '/checklist/' + itemId + '/score', }); }; function updateChecklistItem (taskId, itemId, itemDetails) { return $http({ method: 'PUT', - url: 'api/v3/tasks/' + taskId + '/checklist/' + itemId, + url: '/api/v3/tasks/' + taskId + '/checklist/' + itemId, data: itemDetails, }); }; @@ -98,21 +98,21 @@ angular.module('habitrpg') function removeChecklistItem (taskId, itemId) { return $http({ method: 'DELETE', - url: 'api/v3/tasks/' + taskId + '/checklist/' + itemId, + url: '/api/v3/tasks/' + taskId + '/checklist/' + itemId, }); }; function addTagToTask (taskId, tagId) { return $http({ method: 'POST', - url: 'api/v3/tasks/' + taskId + '/tags/' + tagId, + url: '/api/v3/tasks/' + taskId + '/tags/' + tagId, }); }; function removeTagFromTask (taskId, tagId) { return $http({ method: 'DELETE', - url: 'api/v3/tasks/' + taskId + '/tags/' + tagId, + url: '/api/v3/tasks/' + taskId + '/tags/' + tagId, }); }; @@ -123,21 +123,21 @@ angular.module('habitrpg') return $http({ method: 'POST', - url: 'api/v3/tasks/unlink/' + taskId + '?keep=' + keep, + url: '/api/v3/tasks/unlink/' + taskId + '?keep=' + keep, }); }; function clearCompletedTodos () { return $http({ method: 'POST', - url: 'api/v3/tasks/clearCompletedTodos', + url: '/api/v3/tasks/clearCompletedTodos', }); }; function editTask(task) { task._editing = !task._editing; - task._tags = !User.user.preferences.tagsCollapsed; - task._advanced = !User.user.preferences.advancedCollapsed; + // task._tags = !User.user.preferences.tagsCollapsed; + // task._advanced = !User.user.preferences.advancedCollapsed; if($rootScope.charts[task.id]) $rootScope.charts[task.id] = false; } diff --git a/website/public/js/services/userServices.js b/website/public/js/services/userServices.js index 627c287786..d7fc93c46a 100644 --- a/website/public/js/services/userServices.js +++ b/website/public/js/services/userServices.js @@ -14,8 +14,8 @@ angular.module('habitrpg') /** * Services that persists and retrieves user from localStorage. */ - .factory('User', ['$rootScope', '$http', '$location', '$window', 'STORAGE_USER_ID', 'STORAGE_SETTINGS_ID', 'Notification', 'ApiUrl', - function($rootScope, $http, $location, $window, STORAGE_USER_ID, STORAGE_SETTINGS_ID, Notification, ApiUrl) { + .factory('User', ['$rootScope', '$http', '$location', '$window', 'STORAGE_USER_ID', 'STORAGE_SETTINGS_ID', 'Notification', 'ApiUrl', 'Tasks', + function($rootScope, $http, $location, $window, STORAGE_USER_ID, STORAGE_SETTINGS_ID, Notification, ApiUrl, Tasks) { var authenticated = false; var defaultSettings = { auth: { apiId: '', apiToken: ''}, @@ -48,7 +48,7 @@ angular.module('habitrpg') function sync() { $http({ method: "GET", - url: 'api/v3/user/', + url: '/api/v3/user/', }) .then(function (response) { if (response.data.message) Notification.text(response.data.message); @@ -82,7 +82,19 @@ angular.module('habitrpg') save(); $rootScope.$emit('userSynced'); + + return Tasks.getUserTasks(); }) + .then(function (response) { + var tasks = response.data.data; + user.habits = []; + user.todos = []; + user.dailys = []; + user.rewards = []; + tasks.forEach(function (element, index, array) { + user[element.type + 's'].push(element) + }) + }); } sync(); @@ -95,7 +107,7 @@ angular.module('habitrpg') if (!opData) opData = {}; $window.habitrpgShared.ops[opName](user, opData); - var url = 'api/v3/user/' + endPoint; + var url = '/api/v3/user/' + endPoint; if (paramString) { url += '/' + paramString } @@ -119,7 +131,7 @@ angular.module('habitrpg') function setUser(updates) { for (var key in updates) { - user[key] = updates[key]; + _.set(user, key, updates[key]); } } @@ -135,46 +147,53 @@ angular.module('habitrpg') }, addTask: function (data) { - //@TODO: Should this been on habitrpgShared? user.ops.addTask(data); save(); - //@TODO: Call task service when PR is merged + Tasks.createUserTasks(data.body); }, score: function (data) { - user.ops.scoreTask(data); + $window.habitrpgShared.ops.scoreTask({user: user, task: data.params.task, direction: data.params.direction}, data.params); save(); - //@TODO: Call task service when PR is merged + Tasks.scoreTask(data.params.task._id, data.params.direction); }, sortTask: function (data) { user.ops.sortTask(data); save(); - //@TODO: Call task service when PR is merged + Tasks.moveTask(data.params.id, data.query.to); }, - updateTask: function (data) { - user.ops.updateTask(data); + updateTask: function (task, data) { + $window.habitrpgShared.ops.updateTask(task, data); save(); - //@TODO: Call task service when PR is merged + Tasks.updateTask(task._id, data.body); }, deleteTask: function (data) { user.ops.deleteTask(data); save(); - //@TODO: Call task service when PR is merged + Tasks.deleteTask(data.params.id); }, addTag: function(data) { user.ops.addTag(data); save(); - //@TODO: Call task service when PR is merged + $http({ + method: "PUT", + url: '/api/v3/user', + data: {filters: user.filters}, + }); }, updateTag: function(data) { user.ops.updateTag(data); save(); - //@TODO: Call task service when PR is merged + $http({ + method: "PUT", + url: '/api/v3/user', + data: {filters: user.filters}, + }); }, addTenGems: function () { @@ -222,7 +241,7 @@ angular.module('habitrpg') $http({ method: "POST", - url: 'api/v3/user/' + 'buy-special-spell/' + key, + url: '/api/v3/user/' + 'buy-special-spell/' + key, }) .then(function (response) { Notification.text(response.data.message); @@ -267,12 +286,9 @@ angular.module('habitrpg') setUser(updates); $http({ method: "PUT", - url: 'api/v3/user', + url: '/api/v3/user', data: updates, - }) - .then(function (response) { - sync(); - }) + }); }, reroll: function () { @@ -334,13 +350,18 @@ angular.module('habitrpg') settings.auth.apiId = uuid; settings.auth.apiToken = token; settings.online = true; - if (user && user._v) user._v--; // shortcut to always fetch new updates on page reload - userServices.log({}, function(){ - // If they don't have timezone, set it - if (user.preferences.timezoneOffset !== offset) - userServices.set({'preferences.timezoneOffset': offset}); - cb && cb(); - }); + save(); + sync(); + if (cb) { + cb(); + } + //@TODO: Do we need the timezone set? + // userServices.log({}, function(){ + // // If they don't have timezone, set it + // if (user.preferences.timezoneOffset !== offset) + // userServices.set({'preferences.timezoneOffset': offset}); + // cb && cb(); + // }); } else { alert('Please enter your ID and Token in settings.') } diff --git a/website/public/manifest.json b/website/public/manifest.json index cb3db7a968..c6c87ffb4b 100644 --- a/website/public/manifest.json +++ b/website/public/manifest.json @@ -132,6 +132,7 @@ "js/services/sharedServices.js", "js/services/socialServices.js", "js/services/statServices.js", + "js/services/taskServices.js", "js/services/userServices.js", "js/controllers/authCtrl.js", "js/controllers/footerCtrl.js" @@ -166,6 +167,7 @@ "js/services/sharedServices.js", "js/services/socialServices.js", "js/services/statServices.js", + "js/services/taskServices.js", "js/services/userServices.js", "js/controllers/authCtrl.js", "js/controllers/footerCtrl.js" diff --git a/website/views/shared/tasks/edit/index.jade b/website/views/shared/tasks/edit/index.jade index 952fbdbb17..d5032f94ce 100644 --- a/website/views/shared/tasks/edit/index.jade +++ b/website/views/shared/tasks/edit/index.jade @@ -8,7 +8,7 @@ div(ng-if='task._editing') p a(ng-click='unlink(task, "keep")')=env.t('keepIt') |    - a(ng-click="removeTask(task, obj")=env.t('removeIt') + a(ng-click="removeTask(task, obj)")=env.t('removeIt') div(ng-if='task.challenge.broken=="CHALLENGE_DELETED"') p |