diff --git a/assets/js/controllers/tasksCtrl.coffee b/assets/js/controllers/tasksCtrl.coffee new file mode 100644 index 0000000000..7fd39f9634 --- /dev/null +++ b/assets/js/controllers/tasksCtrl.coffee @@ -0,0 +1,140 @@ +"use strict" +habitrpg.controller "TasksCtrl", ($scope, $rootScope, $location, filterFilter, User, Algos, Helpers, Notification) -> + + $scope.taskLists = [ + {header: 'Habits', type: 'habit', inputValue:'_newHabit', placeHolder: 'New Habit', list: User.user.habits, main:true, editable:true} + {header: 'Dailies', type: 'daily', inputValue:'_newDaily', placeHolder: 'New Daily', list: User.user.dailys, main:true, editable:true} + {header: 'Todos', type: 'todo', inputValue:'_newTodo', placeHolder: 'New Todo', list: User.user.todos, main:true, editable:true} + {header: 'Reward', type: 'reward', inputValue:'_newReward', placeHolder: 'New Reward', list: User.user.rewards, main:true, editable:true} + ] + + $scope.score = (task, direction) -> + + #save current stats to compute the difference after scoring. + statsDiff = {} + oldStats = _.clone(User.user.stats) + Algos.score User.user, task, direction + + #compute the stats change. + _.each oldStats, (value, key) -> + newValue = User.user.stats[key] + statsDiff[key] = newValue - value if newValue isnt value + + + #notify user if there are changes in stats. + if Object.keys(statsDiff).length > 0 + Notification.push + type: "stats" + stats: statsDiff + + if task.type is "reward" and _.isEmpty(statsDiff) + Notification.push + type: "text" + text: "Not enough GP." + + User.log + op: "score" + data: task + dir: direction + + + $scope.notDue = (task) -> + if task.type is "daily" + not window.habitrpgShared.helpers.shouldDo(moment(), task.repeat) + else + false + + $scope.getClass = (value) -> + out = "" + if value < -20 + out += " color-worst" + else if value < -10 + out += " color-worse" + else if value < -1 + out += " color-bad" + else if value < 1 + out += " color-neutral" + else if value < 5 + out += " color-good" + else if value < 10 + out += " color-better" + else + out += " color-best" + out + + $scope.addTask = -> + return unless $scope.newTask.length + defaults = + text: $scope.newTask + type: $scope.taskType() + value: (if $scope.taskType() is "reward" then 20 else 0) + + extra = {} + switch $scope.taskType() + when "habit" + extra = + up: true + down: true + when "daily", "todo" + extra = completed: false + newTask = _.defaults(extra, defaults) + newTask.id = Helpers.uuid() + User.user[newTask.type + "s"].unshift newTask + $scope.showedTasks.unshift newTask + User.log + op: "addTask" + data: newTask + + $scope.newTask = "" + + + #Add the new task to the actions log + $scope.clearDoneTodos = -> + + + #We can't alter $scope.user.tasks here. We have to invoke API call. + #To be implemented + $scope.selectTask = (task) -> + $rootScope.selectedTask = task + $location.path "/tasks/" + task.id + + $scope.changeCheck = (task) -> + + # This is calculated post-change, so task.completed=true if they just checked it + if task.completed + $scope.score task, "up" + else + $scope.score task, "down" + + $(".taskWell").css "height", $(window).height() - 61 + + # TODO this should be somewhere else, but fits the html location better here + $rootScope.revive = -> + window.habitrpgShared.algos.revive User.user + User.log op: "revive" + + counter = 0 + + ### + ------------------------ + Items + ------------------------ + ### + $scope.$watch "user.items", -> + $scope.itemStore = window.habitrpgShared.items.updateStore($scope.user) + + $scope.buy = (type) -> + hasEnough = window.habitrpgShared.items.buyItem($scope.user, type) + if hasEnough + User.log + op: "buy" + type: type + + Notification.push + type: "text" + text: "Item bought!" + + else + Notification.push + type: "text" + text: "Not enough GP." diff --git a/assets/js/controllers/tasksCtrl.js b/assets/js/controllers/tasksCtrl.js deleted file mode 100644 index 3db9a77af5..0000000000 --- a/assets/js/controllers/tasksCtrl.js +++ /dev/null @@ -1,188 +0,0 @@ -'use strict'; - -habitrpg.controller('TasksCtrl', - ['$scope', '$rootScope', '$location', 'filterFilter', 'User', 'Algos', 'Helpers', 'Notification', - function($scope, $rootScope, $location, filterFilter, User, Algos, Helpers, Notification) { - - $scope.user = User.user; - - $scope.taskTypeTitleSingular = function () { -// show title according to the location, singular form - return $rootScope.taskContext.type.charAt(0).toUpperCase() + $rootScope.taskContext.type.slice(1); - }; - - $scope.taskType = function () { - return $location.path().split('/')[1] - }; - - $scope.tasks = function () { - //return task array based on our location i.e. /habit will return user.habits[] - return User.user[$scope.taskType() + 's']; - }; - - $scope.showedTasks = [] - - $scope.taskFilter = function (task) { - return ($location.path() == '/todo') ? !task.completed : - ($location.path() == '/todo/completed') ? task.completed : - true; - }; - - $scope.score = function (task, direction) { - //save current stats to compute the difference after scoring. - var statsDiff = {}; - var oldStats = _.clone(User.user.stats); - - Algos.score(User.user, task, direction); - - //compute the stats change. - _.each(oldStats, function (value, key) { - var newValue = User.user.stats[key]; - if (newValue !== value) { - statsDiff[key] = newValue - value; - } - }); - //notify user if there are changes in stats. - if (Object.keys(statsDiff).length > 0) { - Notification.push({type: 'stats', stats: statsDiff}); - } - - if (task.type == 'reward' && _.isEmpty(statsDiff)) { - Notification.push({type: 'text', text: 'Not enough GP.'}); - } - - User.log({op: 'score', data: task, dir: direction}); - }; - - $scope.notDue = function(task) { - if (task.type == 'daily') { - return !window.habitrpgShared.helpers.shouldDo(moment(), task.repeat); - } else { - return false - } - } - - $scope.getClass = function(value) { - - var out = '' - if (value < -20) - out += ' color-worst' - else if (value < -10) - out += ' color-worse' - else if (value < -1) - out += ' color-bad' - else if (value < 1) - out += ' color-neutral' - else if (value < 5) - out += ' color-good' - else if (value < 10) - out += ' color-better' - else - out += ' color-best' - return out - } - - $scope.addTask = function () { - if (!$scope.newTask.length) { - return; - } - - var defaults = { - text: $scope.newTask, - type: $scope.taskType(), - value: $scope.taskType() == 'reward' ? 20 : 0 - }, - extra = {}; - - switch ($scope.taskType()) { - case 'habit': - extra = {up: true, down: true}; - break; - case 'daily': - case 'todo': - extra = {completed: false}; - break; - } - - - var newTask = _.defaults(extra, defaults); - newTask.id = Helpers.uuid(); - User.user[newTask.type + 's'].unshift(newTask) - $scope.showedTasks.unshift(newTask) - User.log({op: 'addTask', data: newTask}); - $scope.newTask = ''; - //Add the new task to the actions log - - }; - - $scope.clearDoneTodos = function () { - //We can't alter $scope.user.tasks here. We have to invoke API call. - //To be implemented - }; - - $scope.selectTask = function (task) { - $rootScope.selectedTask = task; - $location.path('/tasks/' + task.id) - } - - $scope.changeCheck = function (task) { - // This is calculated post-change, so task.completed=true if they just checked it - if (task.completed) { - $scope.score(task, 'up') - } else { - $scope.score(task, 'down') - } - } - - $('.taskWell').css('height', $(window).height() - 61) - - // TODO this should be somewhere else, but fits the html location better here - $rootScope.revive = function() { - window.habitrpgShared.algos.revive(User.user); - User.log({op:'revive'}); - } - - var counter = 0; - - - /** - * ------------------------ - * Items - * ------------------------ - */ - - $scope.$watch('user.items', function(){ - $scope.itemStore = window.habitrpgShared.items.updateStore($scope.user); - }); - - $scope.buy = function(type) { - var hasEnough = window.habitrpgShared.items.buyItem($scope.user, type); - if (hasEnough) { - User.log({op:'buy', type:type}); - Notification.push({type:'text', text:"Item bought!"}) - } else { - Notification.push({type:'text', text:"Not enough GP."}) - } - } - - /* - $scope.loadMore = function() { - - var length = $scope.showedTasks.length - if (typeof $scope.tasks() != 'undefined') { - for (var i = length; i < length+7; i++) { - if (typeof $scope.tasks()[i] != 'undefined') { - $scope.showedTasks.push($scope.tasks()[i]); - } - } - } - - - }; - - $scope.loadMore() - - */ - - } -]); diff --git a/views/header/header.jade b/views/header/header.jade index d6846e4e03..b4f3cdd58f 100644 --- a/views/header/header.jade +++ b/views/header/header.jade @@ -6,8 +6,10 @@ header.site-header(ng-class='{hidden: user.preferences.hideHeader}', role='banner', data-partysize='{{party.members.length>1 ? truarr(party.members.length) : 0}}') // avatar .herobox-wrap.main-herobox(ng-controller='UserAvatarCtrl') + include ./avatar //app:avatar:avatar(profile='{{user}}', main='true') + // stat bars .hero-stats .meter.health(title='Health') diff --git a/views/index.jade b/views/index.jade index df43cd7fc4..ea1137539e 100644 --- a/views/index.jade +++ b/views/index.jade @@ -5,8 +5,8 @@ block content include ./modals/login include ./header/header - span(ng-class='{hidden: _gamePane}') - | app:filters:filters + span(ng-hide='_gamePane') + app:filters:filters br #notification-area @@ -14,11 +14,11 @@ block content app:alerts:flash //if they hide the header, we still need user-menu visible app:settings:menu(ng-show='_user.preferences.hideHeader') - .exp-chart(ng-class='{hidden: _page.charts.exp}') + .exp-chart(ng-show='_page.charts.exp') #main.grid - div(ng-class='{hidden: _gamePane}') - app:tasks:task-lists(habits='{{_habitList}}', dailys='{{_dailyList}}', todos='{{_todoList}}', rewards='{{_rewardList}}', main='true', editable='true') - div(ng-class='{hidden: _gamePane}') + div(ng-hide='_gamePane') + include ./tasks/task-list + div(ng-show='_gamePane') app:game-pane:main app:footer:footer diff --git a/views/modals/achievements.jade b/views/modals/achievements.jade new file mode 100644 index 0000000000..7b6d81360e --- /dev/null +++ b/views/modals/achievements.jade @@ -0,0 +1,11 @@ + +// Streak Achievement +div(modal='modals.streakAchievement', header='Achievement!') + .modal-header + h3 Achievement! + .modal-body + .achievement.achievement-thermometer + | You have stacked your "Streaker" Achievement! Every 21 days of streak, you gain 1 achievement point here. + .modal-footer + button.btn.btn-default.cancel(ng-click='modals.modals.streakAchievement = false') Cancel + diff --git a/views/tasks/task-list.html b/views/tasks/task-list.html new file mode 100644 index 0000000000..a571201970 --- /dev/null +++ b/views/tasks/task-list.html @@ -0,0 +1,86 @@ + + + + + +
+
+ + + + + + + + + + +
+ {{gold(floor(user.stats.gp))}} + +
+
+ {{silver(user.stats.gp)}} + +
+
+ +

{{header}}

+ +
+ +
+ + +
+
+ + + + + +
+ +
+ + +
+ +
+ + The Power of Habit: Why We Do What We Do in Life and Business + Getting Things Done: The Art of Stress-Free Productivity + The Checklist Manifesto: How to Get Things Right + Drive: The Surprising Truth About What Motivates Us +
+ + +
+ + + + +
+ +
+
\ No newline at end of file diff --git a/views/tasks/task-list.jade b/views/tasks/task-list.jade new file mode 100644 index 0000000000..9505d6d0a9 --- /dev/null +++ b/views/tasks/task-list.jade @@ -0,0 +1,75 @@ +div(ng-controller='TasksCtrl') + .module(ng-controller='TasksCtrl', ng-repeat='list in taskLists', ng-class='{"rewards-module": list.type==="reward"}') + .task-column(class='{{list.type}}s', ng-class='{"tabbable tabs-below": list.type=="todo"}') + + // Todos export/graph options + span.option-box.pull-right(ng-if='list.main && list.type=="todo"') + a.option-action(ng-show='user.history.todos', x-bind='click:toggleChart', data-id='todos', rel='tooltip', title='Progress') + i.icon-signal + a.option-action(ng-href='/v1/users/{{user.id}}/calendar.ics?apiToken={{user.apiToken}}', rel='tooltip', title='iCal') + i.icon-calendar + // + + // Gold & Gems + span.option-box.pull-right.wallet(ng-if='list.main && list.type=="reward"') + .money + | {{gold(floor(user.stats.gp))}} + span.shop_gold(rel='tooltip', title='Gold') + .money + | {{silver(user.stats.gp)}} + span.shop_silver(rel='tooltip', title='Silver') + + // Header + h2.task-column_title {{list.header}} + + // Todo Chart + .todos-chart(ng-if='list.type == "todo"', ng-show='_page.charts.todos') + + // Add New + form.addtask-form.form-inline.new-task-form(ng-show='editable', ng-hide='_showCompleted && list.type=="todo"', data-task-type='{{list.type}}', x-bind='submit:addTask') + span.addtask-field + input(type='text', value='{{list.inputValue}}', placeholder='{{list.placeHolder}}') + input.addtask-btn(type='submit', value='+') + hr + + // Actual List + ul(class='{{list.type}}s', ng-show='list.list') + app:tasks:task(ng-repeat='task in list.list') + + // Static Rewards + ul.items(ng-show='list.main && list.type=="reward"', ng-show='user.flags.itemsEnabled') + app:reward:item(item='{{_items.next.weapon}}') + app:reward:item(item='{{_items.next.armor}}') + app:reward:item(item='{{_items.next.head}}') + app:reward:item(item='{{_items.next.shield}}') + app:reward:item(item='{{_items.potion}}') + app:reward:item(item='{{_items.reroll}}') + + br + + // Ads + div(ng-if='authenticated() && user.flags.ads != "hide" && list.main') + span.pull-right + a(x-bind='click:showStripe', rel='tooltip', title='Remove Ads') + i.icon-remove + br + a(href='#', data-target='#why-ads-modal', data-toggle='modal', rel='tooltip', title='Why Ads?') + i.icon-question-sign + a(ng-if='list.type=="habit"', href='http://www.amazon.com/gp/product/1400069289/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1400069289&linkCode=as2&tag=ha0d2-20') The Power of Habit: Why We Do What We Do in Life and Business + img(src='//www.assoc-amazon.com/e/ir?t=ha0d2-20&l=as2&o=1&a=1400069289', width='1', height='1', border='0', alt='', style='border:none !important; margin:0px !important;') + a(ng-if='list.type=="daily"', href='http://www.amazon.com/gp/product/0142000280/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0142000280&linkCode=as2&tag=ha0d2-20') Getting Things Done: The Art of Stress-Free Productivity + img(src='//www.assoc-amazon.com/e/ir?t=ha0d2-20&l=as2&o=1&a=0142000280', width='1', height='1', border='0', alt='', style='border:none !important; margin:0px !important;') + a(ng-if='list.type=="todo"', href='http://www.amazon.com/gp/product/0312430000/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0312430000&linkCode=as2&tag=ha0d2-20') The Checklist Manifesto: How to Get Things Right + img(src='//www.assoc-amazon.com/e/ir?t=ha0d2-20&l=as2&o=1&a=0312430000', width='1', height='1', border='0', alt='', style='border:none !important; margin:0px !important;') + a(ng-if='list.type=="reward"', href='http://www.amazon.com/gp/product/1594484805/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1594484805&linkCode=as2&tag=ha0d2-20') Drive: The Surprising Truth About What Motivates Us + img(src='//www.assoc-amazon.com/e/ir?t=ha0d2-20&l=as2&o=1&a=1594484805', width='1', height='1', border='0', alt='', style='border:none !important; margin:0px !important;') + + // Todo Tabs + div(ng-if='list.type=="todo"') + button.task-action-btn.tile.spacious.bright(ng-show='_showCompleted', x-bind='click:clearCompleted') Clear Completed + // remaining/completed tabs + ul.nav.nav-tabs + li(ng-class='{active: !_showCompleted}') + a(x-bind='click: todosShowRemaining') Remaining + li(ng-class='{active: _showCompleted}') + a(x-bind='click: todosShowCompleted') Complete diff --git a/views/tasks/tasks.html b/views/tasks/tasks.html index 8468064a61..f1dbf12fc9 100644 --- a/views/tasks/tasks.html +++ b/views/tasks/tasks.html @@ -1,165 +1,92 @@ - - -

-

You have stacked your "Streaker" Achievement! Every 21 days of streak, you gain 1 achievement point here. -

- <@footer> - - -
+ + - +
+
- - - - -
-
- - {{#if @main}} - - - {#if _user.history.todos} - - {/} - + + + + - {{/}} - - - <@ads>The Checklist Manifesto: How to Get Things Right - - - - - - -
-
- - -
-
- - {{#if @main}} - +
- {gold(floor(_user.stats.gp))} + {{gold(floor(user.stats.gp))}}
- {silver(_user.stats.gp)} + {{silver(user.stats.gp)}}
- {{/}} - - <@extra> - {{#if @main}} - -
- - -

{{t(@header)}}

- - {{#if equal(@type,'todo')}}
{{/}} - - {#if @editable} - - - - {{#with @list}} -
- - -
- {{/}} -
- {/} -
    - {#each @list as :task}{/} -
- {{@extra}} -
- - {{#if and( _loggedIn, notEqual(_user.flags.ads,'hide'), @main )}} - -
- -
- - {{@ads}} - {{/}} diff --git a/views/tasks/tasks.jade b/views/tasks/tasks.jade new file mode 100644 index 0000000000..b957bab465 --- /dev/null +++ b/views/tasks/tasks.jade @@ -0,0 +1,3 @@ +// + Created by lefnire on 8/25/13. +