mirror of
https://github.com/sudoxnym/habitica.git
synced 2026-08-01 23:40:25 +00:00
rewrite2 save task
This commit is contained in:
parent
9aa4a5a08a
commit
ee8fdc80fa
9 changed files with 134 additions and 251 deletions
42
assets/js/controllers/taskDetailsCtrl.coffee
Normal file
42
assets/js/controllers/taskDetailsCtrl.coffee
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
"use strict"
|
||||
habitrpg.controller "TaskDetailsCtrl", ($scope, $rootScope, $location, User) ->
|
||||
|
||||
$scope.save = (task) ->
|
||||
setVal = (k, v) ->
|
||||
if typeof v isnt "undefined"
|
||||
op = {op: "set", data: {}}
|
||||
op.data["tasks." + task.id + "." + k] = v
|
||||
log.push op
|
||||
log = []
|
||||
setVal "text", task.text
|
||||
setVal "notes", task.notes
|
||||
setVal "priority", task.priority
|
||||
if task.type is "habit"
|
||||
setVal "up", task.up
|
||||
setVal "down", task.down
|
||||
else if task.type is "daily"
|
||||
setVal "repeat", task.repeat
|
||||
|
||||
# _.each(task.repeat, function(v, k) {
|
||||
# setVal("repeat." + k, v);
|
||||
# })
|
||||
else if task.type is "todo"
|
||||
setVal "date", task.date
|
||||
else setVal "value", task.value if task.type is "reward"
|
||||
User.log log
|
||||
task._editing = false
|
||||
|
||||
$scope.cancel = ->
|
||||
# reset $scope.task to $scope.originalTask
|
||||
for key of $scope.task
|
||||
$scope.task[key] = $scope.originalTask[key]
|
||||
$scope.originalTask = null
|
||||
$scope.editedTask = null
|
||||
$scope.editing = false
|
||||
|
||||
$scope.remove = (task) ->
|
||||
confirmed = window.confirm("Delete this task?")
|
||||
return if confirmed isnt true
|
||||
tasks = User.user[task.type + "s"]
|
||||
User.log {op: "delTask", data: task}
|
||||
delete tasks.splice(tasks.indexOf(task), 1)
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
habitrpg.controller('TaskDetailsCtrl',
|
||||
['$scope', '$rootScope', '$location', 'User',
|
||||
function($scope, $rootScope, $location, User) {
|
||||
|
||||
$scope.task = $rootScope.selectedTask;
|
||||
$scope.editing = false;
|
||||
$scope.editedTask = null;
|
||||
|
||||
$scope.goBack = function () {
|
||||
$rootScope.selectedTask = null;
|
||||
$location.path('/' + $scope.task.type);
|
||||
};
|
||||
|
||||
$scope.edit = function () {
|
||||
$scope.originalTask = _.clone($scope.task); // TODO deep clone?;
|
||||
$scope.editedTask = $scope.task;
|
||||
$scope.editing = true;
|
||||
};
|
||||
|
||||
$scope.save = function () {
|
||||
var task = $scope.task,
|
||||
log = [];
|
||||
|
||||
function setVal(k,v){
|
||||
if (typeof v !== "undefined") {
|
||||
var op = {op: 'set', data:{}};
|
||||
op.data["tasks." + task.id + "." + k] = v;
|
||||
log.push(op);
|
||||
}
|
||||
}
|
||||
|
||||
setVal("text", task.text);
|
||||
setVal("notes", task.notes);
|
||||
setVal("priority", task.priority);
|
||||
if (task.type == 'habit') {
|
||||
setVal("up", task.up);
|
||||
setVal("down", task.down);
|
||||
} else if (task.type == 'daily') {
|
||||
setVal("repeat", task.repeat);
|
||||
// _.each(task.repeat, function(v, k) {
|
||||
// setVal("repeat." + k, v);
|
||||
// })
|
||||
} else if (task.type == 'todo') {
|
||||
setVal("date", task.date);
|
||||
} else if (task.type == 'reward') {
|
||||
setVal("value", task.value);
|
||||
}
|
||||
|
||||
|
||||
User.log(log);
|
||||
$rootScope.selectedTask = null;
|
||||
$location.path('/' + $scope.task.type);
|
||||
$scope.editing = false;
|
||||
};
|
||||
|
||||
$scope.cancel = function () {
|
||||
// reset $scope.task to $scope.originalTask
|
||||
for (var key in $scope.task) {
|
||||
$scope.task[key] = $scope.originalTask[key];
|
||||
}
|
||||
$scope.originalTask = null;
|
||||
$scope.editedTask = null;
|
||||
$scope.editing = false;
|
||||
};
|
||||
|
||||
$scope.delete = function () {
|
||||
var confirmed = window.confirm("Delete this task?");
|
||||
if (confirmed !== true) return;
|
||||
var task = $scope.task;
|
||||
var tasks = User.user[task.type+'s'];
|
||||
User.log({op: 'delTask', data: task});
|
||||
$scope.goBack();
|
||||
delete tasks.splice(tasks.indexOf(task),1);
|
||||
};
|
||||
}
|
||||
]);
|
||||
|
|
@ -1,11 +1,12 @@
|
|||
"use strict"
|
||||
habitrpg.controller "TasksCtrl", ($scope, $rootScope, $location, filterFilter, User, Algos, Helpers, Notification) ->
|
||||
|
||||
#FIXME
|
||||
$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}
|
||||
{header: 'Habits', type: 'habit', placeHolder: 'New Habit', main:true, editable:true}
|
||||
{header: 'Dailies', type: 'daily', placeHolder: 'New Daily', main:true, editable:true}
|
||||
{header: 'Todos', type: 'todo', placeHolder: 'New Todo', main:true, editable:true}
|
||||
{header: 'Reward', type: 'reward', placeHolder: 'New Reward', main:true, editable:true}
|
||||
]
|
||||
|
||||
$scope.score = (task, direction) ->
|
||||
|
|
@ -37,61 +38,25 @@ habitrpg.controller "TasksCtrl", ($scope, $rootScope, $location, filterFilter, U
|
|||
data: task
|
||||
dir: direction
|
||||
|
||||
$scope.saveTask = (task) ->
|
||||
sets = {}
|
||||
sets["user."]
|
||||
User.log [
|
||||
op: 'set', {}
|
||||
]
|
||||
|
||||
$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()
|
||||
$scope.addTask = (text) ->
|
||||
newTask = window.habitrpgShared.helpers.taskDefaults({text})
|
||||
User.user[newTask.type + "s"].unshift newTask
|
||||
$scope.showedTasks.unshift newTask
|
||||
# $scope.showedTasks.unshift newTask # FIXME what's thiss?
|
||||
User.log
|
||||
op: "addTask"
|
||||
data: newTask
|
||||
|
||||
$scope.newTask = ""
|
||||
|
||||
delete $scope.list.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) ->
|
||||
|
|
|
|||
59
assets/js/services/notificationServices.coffee
Normal file
59
assets/js/services/notificationServices.coffee
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
angular.module("notificationServices", []).factory "Notification", ->
|
||||
#FIXME
|
||||
|
||||
fixMe =
|
||||
push: ->
|
||||
get: ->
|
||||
animate: ->
|
||||
clearTimer: ->
|
||||
init: ->
|
||||
return fixMe
|
||||
|
||||
data = message: ""
|
||||
active = false
|
||||
timer = null
|
||||
hide: ->
|
||||
$("#notification").fadeOut ->
|
||||
$("#notification").css "webkit-transform", "none"
|
||||
$("#notification").css "top", "-63px"
|
||||
$("#notification").css "left", "0px"
|
||||
setTimeout (->
|
||||
$("#notification").show()
|
||||
), 190
|
||||
|
||||
active = false
|
||||
timer = null
|
||||
|
||||
animate: ->
|
||||
if timer
|
||||
clearTimeout timer
|
||||
timer = setTimeout(@hide, 2000)
|
||||
if active is false
|
||||
active = true
|
||||
$("#notification").transition
|
||||
y: 63
|
||||
x: 0
|
||||
|
||||
timer = setTimeout(@hide, 2000)
|
||||
|
||||
push: (message) ->
|
||||
data.message = ""
|
||||
switch message.type
|
||||
when "stats"
|
||||
data.message = "Experience: " + message.stats.exp + "<br />GP: " + message.stats.gp.toFixed(2) if message.stats.exp? and message.stats.gp?
|
||||
data.message = "HP: " + message.stats.hp.toFixed(2) if message.stats.hp
|
||||
data.message = "<br />GP: " + message.stats.gp.toFixed(2) if message.stats.gp and not message.stats.exp?
|
||||
when "text"
|
||||
data.message = message.text
|
||||
@animate()
|
||||
|
||||
get: ->
|
||||
data
|
||||
|
||||
clearTimer: ->
|
||||
clearTimeout timer
|
||||
timer = null
|
||||
active = false
|
||||
|
||||
init: ->
|
||||
timer = setTimeout(@hide, 2000)
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
angular.module('notificationServices', []).
|
||||
factory('Notification', function () {
|
||||
var data = {message:''};
|
||||
var active = false;
|
||||
var timer = null;
|
||||
|
||||
return {
|
||||
|
||||
hide: function () {
|
||||
$('#notification').fadeOut(function () {
|
||||
$('#notification').css('webkit-transform', 'none')
|
||||
$('#notification').css('top', '-63px')
|
||||
$('#notification').css('left', '0px');
|
||||
|
||||
setTimeout(function() {
|
||||
$('#notification').show()
|
||||
}, 190)
|
||||
});
|
||||
|
||||
active = false;
|
||||
timer = null;
|
||||
},
|
||||
|
||||
animate: function () {
|
||||
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(this.hide, 2000)
|
||||
}
|
||||
|
||||
if (active == false) {
|
||||
active = true;
|
||||
|
||||
$('#notification').transition({ y: 63, x: 0 });
|
||||
timer = setTimeout(this.hide, 2000);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
push: function (message) {
|
||||
data.message = ''
|
||||
switch(message.type) {
|
||||
case 'stats':
|
||||
if (message.stats.exp != null && message.stats.gp != null)
|
||||
data.message = 'Experience: ' + message.stats.exp + '<br />GP: ' + message.stats.gp.toFixed(2)
|
||||
if (message.stats.hp)
|
||||
data.message = 'HP: ' + message.stats.hp.toFixed(2)
|
||||
if (message.stats.gp && message.stats.exp == null)
|
||||
data.message = '<br />GP: ' + message.stats.gp.toFixed(2)
|
||||
break;
|
||||
case 'text':
|
||||
data.message = message.text
|
||||
break;
|
||||
}
|
||||
|
||||
this.animate()
|
||||
},
|
||||
|
||||
get: function () {
|
||||
return data;
|
||||
},
|
||||
|
||||
clearTimer: function () {
|
||||
clearTimeout(timer);
|
||||
timer = null;
|
||||
active = false;
|
||||
},
|
||||
|
||||
init: function () {
|
||||
timer = setTimeout(this.hide, 2000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
|
@ -5,34 +5,6 @@ moment = require 'moment'
|
|||
misc = require './misc'
|
||||
|
||||
|
||||
###
|
||||
Make scoring functionality available to the app
|
||||
###
|
||||
module.exports.app = (appExports, model) ->
|
||||
user = model.at('_user')
|
||||
|
||||
appExports.addTask = (e, el) ->
|
||||
type = $(el).attr('data-task-type')
|
||||
newModel = model.at('_new' + type.charAt(0).toUpperCase() + type.slice(1))
|
||||
text = newModel.get()
|
||||
# Don't add a blank task; 20/02/13 Added a check for undefined value, more at issue #463 -lancemanfv
|
||||
return if /^(\s)*$/.test(text) || text == undefined
|
||||
|
||||
newTask = {id: model.id(), type, text, notes: '', value: 0}
|
||||
newTask.tags = _.reduce user.get('filters'), ((memo,v,k) -> memo[k]=v if v; memo), {}
|
||||
|
||||
switch type
|
||||
when 'habit'
|
||||
newTask = _.defaults {up: true, down: true}, newTask
|
||||
when 'reward'
|
||||
newTask = _.defaults {value: 20}, newTask
|
||||
when 'daily'
|
||||
newTask = _.defaults {repeat:{su:true,m:true,t:true,w:true,th:true,f:true,s:true}, completed: false }, newTask
|
||||
when 'todo'
|
||||
newTask = _.defaults {completed: false }, newTask
|
||||
e.at().unshift newTask # e.at() in this case is the list, which was scoped here using {#with @list}...{/}
|
||||
newModel.set ''
|
||||
|
||||
appExports.del = (e) ->
|
||||
return unless confirm("Are you sure you want to delete this task?") is true
|
||||
$('[rel=tooltip]').tooltip('hide')
|
||||
|
|
@ -122,9 +94,6 @@ module.exports.app = (appExports, model) ->
|
|||
user.set "#{taskPath}.#{key}", val
|
||||
true
|
||||
|
||||
appExports.tasksToggleAdvanced = (e, el) ->
|
||||
$(el).next('.advanced-option').toggleClass('visuallyhidden')
|
||||
|
||||
appExports.tasksSaveAndClose = ->
|
||||
# When they update their notes, re-establish tooltip & popover
|
||||
$('[rel=tooltip]').tooltip()
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ html
|
|||
!= js('controllers/settingsCtrl')
|
||||
!= js('controllers/statsCtrl')
|
||||
!= js('controllers/tasksCtrl')
|
||||
!= js('controllers/taskDetailsCtrl')
|
||||
!= js('controllers/userAvatarCtrl')
|
||||
|
||||
//webfonts
|
||||
|
|
|
|||
|
|
@ -26,14 +26,14 @@ div(ng-controller='TasksCtrl')
|
|||
.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')
|
||||
form.addtask-form.form-inline.new-task-form(name='new{{list.type}}form', ng-show='list.editable', ng-hide='_showCompleted && list.type=="todo"', data-task-type='{{list.type}}', ng-submit='addTask(list.newTask)')
|
||||
span.addtask-field
|
||||
input(type='text', value='{{list.inputValue}}', placeholder='{{list.placeHolder}}')
|
||||
input.addtask-btn(type='submit', value='+')
|
||||
input(type='text', ng-model='list.newTask', placeholder='{{list.placeHolder}}', required)
|
||||
input.addtask-btn(type='submit', value='+', ng-disabled='new{{list.type}}form.$invalid')
|
||||
hr
|
||||
|
||||
// Actual List
|
||||
ul(class='{{list.type}}s', ng-show='list.list')
|
||||
ul(class='{{list.type}}s', ng-show='user[list.type + "s"]')
|
||||
include ./task
|
||||
|
||||
// Static Rewards
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
li(ng-repeat='task in list.list', class='task {{taskClasses(task,user.filters,user.preferences.dayStart,user.lastCron,_showCompleted,list.main)}}', data-id='{{task.id}}')
|
||||
li(ng-repeat='task in user[list.type + "s"]', class='task {{taskClasses(task,user.filters,user.preferences.dayStart,user.lastCron,_showCompleted,list.main)}}', data-id='{{task.id}}')
|
||||
// right-hand side control buttons
|
||||
.task-meta-controls
|
||||
// Streak
|
||||
|
|
@ -76,7 +76,7 @@ li(ng-repeat='task in list.list', class='task {{taskClasses(task,user.filters,us
|
|||
// <p><a>Keep</a> | <a>Keep all from challenge</a> | <a>Delete</a> | <a>Delete all from challenge</a></p>
|
||||
// </div>
|
||||
// {{/}}
|
||||
form(x-bind='submit:toggleTaskEdit')
|
||||
form(ng-controller="TaskDetailsCtrl", ng-submit='save(task)')
|
||||
// text & notes
|
||||
fieldset.option-group
|
||||
// {{#unless taskInChallenge(task)}}
|
||||
|
|
@ -105,13 +105,13 @@ li(ng-repeat='task in list.list', class='task {{taskClasses(task,user.filters,us
|
|||
legend.option-title Repeat
|
||||
.task-controls.tile-group.repeat-days
|
||||
// note, does not use data-toggle="buttons-checkbox" - it would interfere with our own click binding
|
||||
button.task-action-btn.tile(ng-class='{active: task.repeat.su}', type='button', data-day='su', x-bind='click:toggleDay') Su
|
||||
button.task-action-btn.tile(ng-class='{active: task.repeat.m}', type='button', data-day='m', x-bind='click:toggleDay') M
|
||||
button.task-action-btn.tile(ng-class='{active: task.repeat.t}', type='button', data-day='t', x-bind='click:toggleDay') T
|
||||
button.task-action-btn.tile(ng-class='{active: task.repeat.w}', type='button', data-day='w', x-bind='click:toggleDay') W
|
||||
button.task-action-btn.tile(ng-class='{active: task.repeat.th}', type='button', data-day='th', x-bind='click:toggleDay') Th
|
||||
button.task-action-btn.tile(ng-class='{active: task.repeat.f}', type='button', data-day='f', x-bind='click:toggleDay') F
|
||||
button.task-action-btn.tile(ng-class='{active: task.repeat.s}', type='button', data-day='s', x-bind='click:toggleDay') S
|
||||
button.task-action-btn.tile(ng-class='{active: task.repeat.su}', type='button', data-day='su', ng-click='task.repeat.su = !task.repeat.su') Su
|
||||
button.task-action-btn.tile(ng-class='{active: task.repeat.m}', type='button', data-day='m', ng-click='task.repeat.m = !task.repeat.m') M
|
||||
button.task-action-btn.tile(ng-class='{active: task.repeat.t}', type='button', data-day='t', ng-click='task.repeat.t = !task.repeat.t') T
|
||||
button.task-action-btn.tile(ng-class='{active: task.repeat.w}', type='button', data-day='w', ng-click='task.repeat.w = !task.repeat.w') W
|
||||
button.task-action-btn.tile(ng-class='{active: task.repeat.th}', type='button', data-day='th', ng-click='task.repeat.th = !task.repeat.th') Th
|
||||
button.task-action-btn.tile(ng-class='{active: task.repeat.f}', type='button', data-day='f', ng-click='task.repeat.f = !task.repeat.f') F
|
||||
button.task-action-btn.tile(ng-class='{active: task.repeat.s}', type='button', data-day='s', ng-click='task.repeat.s = !task.repeat.s') S
|
||||
// if Reward, pricing
|
||||
fieldset.option-group.option-short(ng-if='task.type=="reward"')
|
||||
legend.option-title Price
|
||||
|
|
@ -124,9 +124,9 @@ li(ng-repeat='task in list.list', class='task {{taskClasses(task,user.filters,us
|
|||
input.option-content.datepicker(type='text', value='{{task.date}}', data-date-format='mm/dd/yyyy')
|
||||
app:filters:filter-fieldgroup(ng-if='list.main')
|
||||
// Advanced Options
|
||||
span(ng-if='task.type=="reward"')
|
||||
p.option-title.mega(x-bind='clicktasksToggleAdvanced') Advanced Options
|
||||
fieldset.option-group.advanced-option.visuallyhidden
|
||||
span(ng-if='task.type!="reward"')
|
||||
p.option-title.mega(ng-click='task._advanced = !task._advanced') Advanced Options
|
||||
fieldset.option-group.advanced-option(ng-class="{visuallyhidden: !task._advanced}")
|
||||
legend.option-title
|
||||
a.priority-multiplier-help(href='https://trello.com/card/priority-multiplier/50e5d3684fe3a7266b0036d6/17', target='_blank')
|
||||
i.icon-question-sign
|
||||
|
|
@ -144,6 +144,6 @@ li(ng-repeat='task in list.list', class='task {{taskClasses(task,user.filters,us
|
|||
span(ng-if='task.type=="daily"')
|
||||
legend.option-title Restore Streak
|
||||
input.option-content(type='number', ng-model='task.streak')
|
||||
button.task-action-btn.tile.spacious(type='submit', x-bind='clicktasksSaveAndClose') Save & Close
|
||||
button.task-action-btn.tile.spacious(type='submit') Save & Close
|
||||
|
||||
div(class='{{task.id}}-chart', ng-show='_page.charts[task.id]')
|
||||
|
|
|
|||
Loading…
Reference in a new issue