mirror of
https://github.com/sudoxnym/habitica.git
synced 2026-08-01 07:21:15 +00:00
refactor much of the hodge-podge code into their own files
This commit is contained in:
parent
4dd7bad81a
commit
230d672fc7
8 changed files with 284 additions and 266 deletions
|
|
@ -1,10 +1,78 @@
|
|||
character = require './character'
|
||||
browser = require './browser'
|
||||
items = require './items'
|
||||
|
||||
moment = require 'moment'
|
||||
_ = require 'underscore'
|
||||
lodash = require 'lodash'
|
||||
derby = require 'derby'
|
||||
|
||||
module.exports.view = (view) ->
|
||||
view.fn "username", (auth) ->
|
||||
if auth?.facebook?.displayName?
|
||||
auth.facebook.displayName
|
||||
else if auth?.facebook?
|
||||
fb = auth.facebook
|
||||
if fb._raw then "#{fb.name.givenName} #{fb.name.familyName}" else fb.name
|
||||
else if auth?.local?
|
||||
auth.local.username
|
||||
else
|
||||
'Anonymous'
|
||||
|
||||
module.exports.app = (appExports, model) ->
|
||||
user = model.at '_user'
|
||||
|
||||
revive = (batch) ->
|
||||
# Reset stats
|
||||
batch.set 'stats.hp', 50
|
||||
batch.set 'stats.lvl', 1
|
||||
batch.set 'stats.gp', 0
|
||||
batch.set 'stats.exp', 0
|
||||
|
||||
# Reset items
|
||||
batch.set 'items.armor', 0
|
||||
batch.set 'items.weapon', 0
|
||||
batch.set 'items.head', 0
|
||||
batch.set 'items.shield', 0
|
||||
|
||||
# Reset item store
|
||||
items.updateStore(model)
|
||||
|
||||
appExports.revive = (e, el) ->
|
||||
batch = new character.BatchUpdate(model)
|
||||
batch.startTransaction()
|
||||
revive(batch)
|
||||
batch.commit()
|
||||
|
||||
appExports.reset = (e, el) ->
|
||||
batch = new character.BatchUpdate(model)
|
||||
batch.startTransaction()
|
||||
taskTypes = ['habit', 'daily', 'todo', 'reward']
|
||||
batch.set 'tasks', {}
|
||||
_.each taskTypes, (type) -> batch.set "idLists.#{type}", []
|
||||
batch.set 'balance', 2 if user.get('balance') < 2 #only if they haven't manually bought tokens
|
||||
revive(batch)
|
||||
batch.commit()
|
||||
browser.resetDom(model)
|
||||
|
||||
appExports.closeKickstarterNofitication = (e, el) ->
|
||||
user.set('flags.kickstarter', 'hide')
|
||||
|
||||
appExports.customizeGender = (e, el) ->
|
||||
user.set 'preferences.gender', $(el).attr('data-value')
|
||||
|
||||
appExports.customizeHair = (e, el) ->
|
||||
user.set 'preferences.hair', $(el).attr('data-value')
|
||||
|
||||
appExports.customizeSkin = (e, el) ->
|
||||
user.set 'preferences.skin', $(el).attr('data-value')
|
||||
|
||||
appExports.customizeArmorSet = (e, el) ->
|
||||
user.set 'preferences.armorSet', $(el).attr('data-value')
|
||||
|
||||
|
||||
userSchema =
|
||||
# _id
|
||||
# _id
|
||||
stats: { gp: 0, exp: 0, lvl: 1, hp: 50 }
|
||||
party: { current: null, invitation: null }
|
||||
items: { weapon: 0, armor: 0, head: 0, shield: 0 }
|
||||
|
|
@ -22,7 +90,7 @@ userSchema =
|
|||
partyEnabled: false
|
||||
itemsEnabled: false
|
||||
kickstarter: 'show'
|
||||
# ads: 'show' # added on registration
|
||||
# ads: 'show' # added on registration
|
||||
|
||||
module.exports.newUserObject = ->
|
||||
# deep clone, else further new users get duplicate objects
|
||||
|
|
@ -79,41 +147,41 @@ module.exports.BatchUpdate = BatchUpdate = (model) ->
|
|||
updates = {}
|
||||
|
||||
{
|
||||
user: user
|
||||
user: user
|
||||
|
||||
obj: ->
|
||||
obj ?= user.get()
|
||||
return obj
|
||||
obj: ->
|
||||
obj ?= user.get()
|
||||
return obj
|
||||
|
||||
startTransaction: ->
|
||||
# start a batch transaction - nothing between now and @commit() will be set immediately
|
||||
transactionInProgress = true
|
||||
model._dontPersist = true
|
||||
startTransaction: ->
|
||||
# start a batch transaction - nothing between now and @commit() will be set immediately
|
||||
transactionInProgress = true
|
||||
model._dontPersist = true
|
||||
|
||||
# Really strange, user.get() seems to only return attributes which have previously been accessed. So in
|
||||
# many cases, userObj.tasks.{taskId}.value is undefined - so we manually .get() each attribute here.
|
||||
# Additionally, for some reason after getting the user object, changing properies manually (userObj.stats.hp = 50)
|
||||
# seems to actually run user.set('stats.hp',50) which we don't want to do - so we deepClone here
|
||||
#_.each Object.keys(userSchema), (key) -> obj[key] = lodash.cloneDeep user.get(key)
|
||||
obj = model.get('users.'+user.get('id'), true)
|
||||
# Really strange, user.get() seems to only return attributes which have previously been accessed. So in
|
||||
# many cases, userObj.tasks.{taskId}.value is undefined - so we manually .get() each attribute here.
|
||||
# Additionally, for some reason after getting the user object, changing properies manually (userObj.stats.hp = 50)
|
||||
# seems to actually run user.set('stats.hp',50) which we don't want to do - so we deepClone here
|
||||
#_.each Object.keys(userSchema), (key) -> obj[key] = lodash.cloneDeep user.get(key)
|
||||
obj = model.get('users.'+user.get('id'), true)
|
||||
|
||||
###
|
||||
Handles updating the user model. If this is an en-mass operation (eg, server cron), changes are queued
|
||||
but not actually set to the model. It also modifies userObj in case you need to access properties manually later.
|
||||
If transaction not in progress, it just runs standard model.set()
|
||||
###
|
||||
set: (path, val) ->
|
||||
updates[path] = val if transactionInProgress
|
||||
user.set(path, val)
|
||||
###
|
||||
Handles updating the user model. If this is an en-mass operation (eg, server cron), changes are queued
|
||||
but not actually set to the model. It also modifies userObj in case you need to access properties manually later.
|
||||
If transaction not in progress, it just runs standard model.set()
|
||||
###
|
||||
set: (path, val) ->
|
||||
updates[path] = val if transactionInProgress
|
||||
user.set(path, val)
|
||||
|
||||
###
|
||||
Hack to get around dom bindings being lost if parent objects are replaced whole-sale
|
||||
eg, user.set('stats', {hp:50, exp:10...}) will break dom bindings, but user.set('stats.hp',50) is ok
|
||||
###
|
||||
setStats: (stats) ->
|
||||
stats ?= obj.stats
|
||||
that = @
|
||||
_.each Object.keys(stats), (key) -> that.set "stats.#{key}", stats[key]
|
||||
###
|
||||
Hack to get around dom bindings being lost if parent objects are replaced whole-sale
|
||||
eg, user.set('stats', {hp:50, exp:10...}) will break dom bindings, but user.set('stats.hp',50) is ok
|
||||
###
|
||||
setStats: (stats) ->
|
||||
stats ?= obj.stats
|
||||
that = @
|
||||
_.each Object.keys(stats), (key) -> that.set "stats.#{key}", stats[key]
|
||||
|
||||
# queue: (path, val) ->
|
||||
# # Special function for setting object properties by string dot-notation. See http://stackoverflow.com/a/6394168/362790
|
||||
|
|
@ -124,10 +192,10 @@ module.exports.BatchUpdate = BatchUpdate = (model) ->
|
|||
# curr[next]
|
||||
# , obj
|
||||
|
||||
commit: ->
|
||||
model._dontPersist = false
|
||||
# some hackery in our own branched racer-db-mongo, see findAndModify of lefnire/racer-db-mongo#habitrpg index.js
|
||||
user.set "update__", updates
|
||||
transactionInProgress = false
|
||||
updates = {}
|
||||
commit: ->
|
||||
model._dontPersist = false
|
||||
# some hackery in our own branched racer-db-mongo, see findAndModify of lefnire/racer-db-mongo#habitrpg index.js
|
||||
user.set "update__", updates
|
||||
transactionInProgress = false
|
||||
updates = {}
|
||||
}
|
||||
|
|
@ -7,24 +7,7 @@ module.exports.daysBetween = (a, b) ->
|
|||
module.exports.dayMapping = dayMapping = {0:'su',1:'m',2:'t',3:'w',4:'th',5:'f',6:'s',7:'su'}
|
||||
|
||||
module.exports.viewHelpers = (view) ->
|
||||
view.fn 'taskClasses', (type, completed, value, repeat) ->
|
||||
#TODO figure out how to just pass in the task model, so i can access all these properties from one object
|
||||
classes = type
|
||||
|
||||
# show as completed if completed (naturally) or not required for today
|
||||
if completed or (repeat and repeat[dayMapping[moment().day()]]==false)
|
||||
classes += " completed"
|
||||
|
||||
switch
|
||||
when value<-8 then classes += ' color-worst'
|
||||
when value>=-8 and value<-5 then classes += ' color-worse'
|
||||
when value>=-5 and value<-1 then classes += ' color-bad'
|
||||
when value>=-1 and value<1 then classes += ' color-neutral'
|
||||
when value>=1 and value<5 then classes += ' color-good'
|
||||
when value>=5 and value<10 then classes += ' color-better'
|
||||
when value>=10 then classes += ' color-best'
|
||||
return classes
|
||||
|
||||
|
||||
view.fn "percent", (x, y) ->
|
||||
x=1 if x==0
|
||||
Math.round(x/y*100)
|
||||
|
|
@ -40,13 +23,3 @@ module.exports.viewHelpers = (view) ->
|
|||
return gp/0.25
|
||||
|
||||
|
||||
view.fn "username", (auth) ->
|
||||
if auth?.facebook?.displayName?
|
||||
auth.facebook.displayName
|
||||
else if auth?.facebook?
|
||||
fb = auth.facebook
|
||||
if fb._raw then "#{fb.name.givenName} #{fb.name.familyName}" else fb.name
|
||||
else if auth?.local?
|
||||
auth.local.username
|
||||
else
|
||||
'Anonymous'
|
||||
|
|
@ -5,24 +5,21 @@ derby.use require('../../ui')
|
|||
derby.use require('derby-auth/components');
|
||||
|
||||
# Custom requires
|
||||
character = require './character'
|
||||
tasks = require './tasks'
|
||||
scoring = require './scoring'
|
||||
schema = require './schema'
|
||||
helpers = require './helpers'
|
||||
browser = require './browser'
|
||||
party = require './party'
|
||||
items = require './items'
|
||||
|
||||
helpers.viewHelpers view
|
||||
character.view view
|
||||
tasks.view view
|
||||
items.view view
|
||||
|
||||
moment = require('moment')
|
||||
_ = require('underscore')
|
||||
|
||||
setupListReferences = (model) ->
|
||||
taskTypes = ['habit', 'daily', 'todo', 'reward']
|
||||
_.each taskTypes, (type) -> model.refList "_#{type}List", "_user.tasks", "_user.idLists.#{type}"
|
||||
|
||||
|
||||
# ========== ROUTES ==========
|
||||
|
||||
get '/', (page, model, next) ->
|
||||
|
|
@ -43,7 +40,7 @@ get '/', (page, model, next) ->
|
|||
user = users.at(0)
|
||||
model.ref '_user', user
|
||||
|
||||
batch = new schema.BatchUpdate(model)
|
||||
batch = new character.BatchUpdate(model)
|
||||
batch.startTransaction()
|
||||
obj = batch.obj()
|
||||
obj = user.get() unless obj.items? #why is this happening?
|
||||
|
|
@ -52,10 +49,14 @@ get '/', (page, model, next) ->
|
|||
|
||||
items.server(model)
|
||||
|
||||
schema.updateUser(batch)
|
||||
character.updateUser(batch)
|
||||
batch.commit()
|
||||
|
||||
setupListReferences(model)
|
||||
# refLists
|
||||
_.each ['habit', 'daily', 'todo', 'reward'], (type) ->
|
||||
model.refList "_#{type}List", "_user.tasks", "_user.idLists.#{type}"
|
||||
|
||||
# tnl function
|
||||
model.fn '_tnl', '_user.stats.lvl', (lvl) ->
|
||||
# see https://github.com/lefnire/habitrpg/issues/4
|
||||
# also update in scoring.coffee. TODO create a function accessible in both locations
|
||||
|
|
@ -73,191 +74,13 @@ ready (model) ->
|
|||
lastCron = user.get('lastCron')
|
||||
user.set('lastCron', +new Date) if (!lastCron? or lastCron == 'new')
|
||||
|
||||
# Setup model in scoring functions
|
||||
scoring.cron()
|
||||
|
||||
browser.app(exports, model)
|
||||
party.app(exports, model)
|
||||
character.app(exports, model)
|
||||
tasks.app(exports, model)
|
||||
items.app(exports, model)
|
||||
party.app(exports, model)
|
||||
require('../server/private').app(exports, model)
|
||||
require('./debug').app(exports, model) if model.get('_view.nodeEnv') != 'production'
|
||||
|
||||
user.on 'set', 'tasks.*.completed', (i, completed, previous, isLocal, passed) ->
|
||||
return if passed? && passed.cron # Don't do this stuff on cron
|
||||
direction = () ->
|
||||
return 'up' if completed==true and previous == false
|
||||
return 'down' if completed==false and previous == true
|
||||
throw new Error("Direction neither 'up' nor 'down' on checkbox set.")
|
||||
|
||||
# Score the user based on todo task
|
||||
task = user.at("tasks.#{i}")
|
||||
scoring.score(i, direction())
|
||||
|
||||
exports.addTask = (e, el, next) ->
|
||||
type = $(el).attr('data-task-type')
|
||||
list = model.at "_#{type}List"
|
||||
newModel = model.at('_new' + type.charAt(0).toUpperCase() + type.slice(1))
|
||||
text = newModel.get()
|
||||
# Don't add a blank todo
|
||||
return if /^(\s)*$/.test(text)
|
||||
|
||||
newModel.set ''
|
||||
switch type
|
||||
|
||||
when 'habit'
|
||||
list.push {type: type, text: text, notes: '', value: 0, up: true, down: true}
|
||||
|
||||
when 'reward'
|
||||
list.push {type: type, text: text, notes: '', value: 20 }
|
||||
|
||||
when 'daily'
|
||||
list.push {type: type, text: text, notes: '', value: 0, repeat:{su:true,m:true,t:true,w:true,th:true,f:true,s:true}, completed: false }
|
||||
|
||||
when 'todo'
|
||||
list.push {type: type, text: text, notes: '', value: 0, completed: false }
|
||||
|
||||
# list.on 'set', '*.completed', (i, completed, previous, isLocal) ->
|
||||
# # Move the item to the bottom if it was checked off
|
||||
# list.move i, -1 if completed && isLocal
|
||||
|
||||
exports.del = (e, el) ->
|
||||
# Derby extends model.at to support creation from DOM nodes
|
||||
#task = model.at(e.target)
|
||||
# FIXME normally that would work, and we'd later simply call `user.del task` (instead of that 4-liner down there)
|
||||
# however, see https://github.com/lefnire/habitrpg/pull/226#discussion_r2810391
|
||||
|
||||
id = $(e.target).parents('li.task').attr('data-id')
|
||||
return unless id?
|
||||
|
||||
task = user.at "tasks.#{id}"
|
||||
type = task.get('type')
|
||||
|
||||
history = task.get('history')
|
||||
if history and history.length>2
|
||||
# prevent delete-and-recreate hack on red tasks
|
||||
if task.get('value') < 0
|
||||
result = confirm("Are you sure? Deleting this task will hurt you (to prevent deleting, then re-creating red tasks).")
|
||||
if result != true
|
||||
return # Cancel. Don't delete, don't hurt user
|
||||
else
|
||||
task.set('type','habit') # hack to make sure it hits HP, instead of performing "undo checkbox"
|
||||
scoring.score(id, direction:'down')
|
||||
|
||||
# prevent accidently deleting long-standing tasks
|
||||
else
|
||||
result = confirm("Are you sure you want to delete this task?")
|
||||
return if result != true
|
||||
|
||||
#TODO bug where I have to delete from _users.tasks AND _{type}List,
|
||||
# fix when query subscriptions implemented properly
|
||||
$('[rel=tooltip]').tooltip('hide')
|
||||
|
||||
ids = user.get("idLists.#{type}")
|
||||
ids.splice(ids.indexOf(id),1)
|
||||
user.del('tasks.'+id)
|
||||
user.set("idLists.#{type}", ids)
|
||||
|
||||
|
||||
exports.clearCompleted = (e, el) ->
|
||||
todoIds = user.get('idLists.todo')
|
||||
removed = false
|
||||
_.each model.get('_todoList'), (task) ->
|
||||
if task.completed
|
||||
removed = true
|
||||
user.del('tasks.'+task.id)
|
||||
todoIds.splice(todoIds.indexOf(task.id), 1)
|
||||
if removed
|
||||
user.set('idLists.todo', todoIds)
|
||||
|
||||
exports.toggleDay = (e, el) ->
|
||||
task = model.at(e.target)
|
||||
if /active/.test($(el).attr('class')) # previous state, not current
|
||||
task.set('repeat.' + $(el).attr('data-day'), false)
|
||||
else
|
||||
task.set('repeat.' + $(el).attr('data-day'), true)
|
||||
|
||||
exports.toggleTaskEdit = (e, el) ->
|
||||
hideId = $(el).attr('data-hide-id')
|
||||
toggleId = $(el).attr('data-toggle-id')
|
||||
$(document.getElementById(hideId)).hide()
|
||||
$(document.getElementById(toggleId)).toggle()
|
||||
|
||||
exports.toggleChart = (e, el) ->
|
||||
hideSelector = $(el).attr('data-hide-id')
|
||||
chartSelector = $(el).attr('data-toggle-id')
|
||||
historyPath = $(el).attr('data-history-path')
|
||||
$(document.getElementById(hideSelector)).hide()
|
||||
$(document.getElementById(chartSelector)).toggle()
|
||||
|
||||
matrix = [['Date', 'Score']]
|
||||
for obj in model.get(historyPath)
|
||||
date = +new Date(obj.date)
|
||||
readableDate = moment(date).format('MM/DD')
|
||||
matrix.push [ readableDate, obj.value ]
|
||||
data = google.visualization.arrayToDataTable matrix
|
||||
|
||||
options = {
|
||||
title: 'History'
|
||||
#TODO use current background color: $(el).css('background-color), but convert to hex (see http://goo.gl/ql5pR)
|
||||
backgroundColor: 'whiteSmoke'
|
||||
}
|
||||
|
||||
chart = new google.visualization.LineChart(document.getElementById( chartSelector ))
|
||||
chart.draw(data, options)
|
||||
|
||||
exports.score = (e, el, next) ->
|
||||
direction = $(el).attr('data-direction')
|
||||
direction = 'up' if direction == 'true/'
|
||||
direction = 'down' if direction == 'false/'
|
||||
task = model.at $(el).parents('li')[0]
|
||||
scoring.score(task.get('id'), direction)
|
||||
|
||||
revive = (batch) ->
|
||||
# Reset stats
|
||||
batch.set 'stats.hp', 50
|
||||
batch.set 'stats.lvl', 1
|
||||
batch.set 'stats.gp', 0
|
||||
batch.set 'stats.exp', 0
|
||||
|
||||
# Reset items
|
||||
batch.set 'items.armor', 0
|
||||
batch.set 'items.weapon', 0
|
||||
batch.set 'items.head', 0
|
||||
batch.set 'items.shield', 0
|
||||
|
||||
# Reset item store
|
||||
items.updateStore(model)
|
||||
|
||||
exports.revive = (e, el) ->
|
||||
batch = new schema.BatchUpdate(model)
|
||||
batch.startTransaction()
|
||||
revive(batch)
|
||||
batch.commit()
|
||||
|
||||
exports.reset = (e, el) ->
|
||||
batch = new schema.BatchUpdate(model)
|
||||
batch.startTransaction()
|
||||
taskTypes = ['habit', 'daily', 'todo', 'reward']
|
||||
batch.set 'tasks', {}
|
||||
_.each taskTypes, (type) -> batch.set "idLists.#{type}", []
|
||||
batch.set 'balance', 2 if user.get('balance') < 2 #only if they haven't manually bought tokens
|
||||
revive(batch)
|
||||
batch.commit()
|
||||
browser.resetDom(model)
|
||||
|
||||
exports.closeKickstarterNofitication = (e, el) ->
|
||||
user.set('flags.kickstarter', 'hide')
|
||||
|
||||
exports.customizeGender = (e, el) ->
|
||||
user.set 'preferences.gender', $(el).attr('data-value')
|
||||
|
||||
exports.customizeHair = (e, el) ->
|
||||
user.set 'preferences.hair', $(el).attr('data-value')
|
||||
|
||||
exports.customizeSkin = (e, el) ->
|
||||
user.set 'preferences.skin', $(el).attr('data-value')
|
||||
|
||||
exports.customizeArmorSet = (e, el) ->
|
||||
user.set 'preferences.armorSet', $(el).attr('data-value')
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
_ = require('underscore')
|
||||
schema = require './schema'
|
||||
character = require './character'
|
||||
browser = require './browser'
|
||||
|
||||
partyQ = null
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ moment = require 'moment'
|
|||
_ = require 'underscore'
|
||||
helpers = require './helpers'
|
||||
browser = require './browser'
|
||||
schema = require './schema'
|
||||
character = require './character'
|
||||
items = require './items'
|
||||
MODIFIER = .02 # each new level, armor, weapon add 2% modifier (this number may change)
|
||||
user = undefined
|
||||
|
|
@ -25,7 +25,6 @@ expModifier = (value, modifiers = {}) ->
|
|||
dmg = items.items.weapon[weapon].modifier # each new weapon increases exp gain
|
||||
dmg += (lvl-1) * MODIFIER # same for lvls
|
||||
modified = value + (value * dmg)
|
||||
debugger
|
||||
return modified
|
||||
|
||||
###
|
||||
|
|
@ -40,7 +39,6 @@ hpModifier = (value, modifiers = {}) ->
|
|||
lvl = modifiers.lvl || user.get('stats.lvl')
|
||||
ac = items.items.armor[armor].modifier + items.items.head[head].modifier + items.items.shield[shield].modifier # each new armor decreases HP loss
|
||||
ac += (lvl-1) * MODIFIER # same for lvls
|
||||
debugger
|
||||
modified = value - (value * ac)
|
||||
return modified
|
||||
|
||||
|
|
@ -106,7 +104,7 @@ score = (taskId, direction, times, batch, cron) ->
|
|||
commit = false
|
||||
unless batch?
|
||||
commit = true
|
||||
batch = new schema.BatchUpdate(model)
|
||||
batch = new character.BatchUpdate(model)
|
||||
batch.startTransaction()
|
||||
obj = batch.obj()
|
||||
|
||||
|
|
@ -194,7 +192,7 @@ cron = () ->
|
|||
today = +new Date
|
||||
daysPassed = helpers.daysBetween(today, user.get('lastCron'))
|
||||
if daysPassed > 0
|
||||
batch = new schema.BatchUpdate(model)
|
||||
batch = new character.BatchUpdate(model)
|
||||
batch.startTransaction()
|
||||
batch.set 'lastCron', today
|
||||
obj = batch.obj()
|
||||
|
|
|
|||
156
src/app/tasks.coffee
Normal file
156
src/app/tasks.coffee
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
scoring = require './scoring'
|
||||
helpers = require './helpers'
|
||||
_ = require 'underscore'
|
||||
moment = require 'moment'
|
||||
|
||||
module.exports.view = (view) ->
|
||||
view.fn 'taskClasses', (type, completed, value, repeat) ->
|
||||
#TODO figure out how to just pass in the task model, so i can access all these properties from one object
|
||||
classes = type
|
||||
|
||||
# show as completed if completed (naturally) or not required for today
|
||||
if completed or (repeat and repeat[helpers.dayMapping[moment().day()]]==false)
|
||||
classes += " completed"
|
||||
|
||||
switch
|
||||
when value<-8 then classes += ' color-worst'
|
||||
when value>=-8 and value<-5 then classes += ' color-worse'
|
||||
when value>=-5 and value<-1 then classes += ' color-bad'
|
||||
when value>=-1 and value<1 then classes += ' color-neutral'
|
||||
when value>=1 and value<5 then classes += ' color-good'
|
||||
when value>=5 and value<10 then classes += ' color-better'
|
||||
when value>=10 then classes += ' color-best'
|
||||
return classes
|
||||
|
||||
module.exports.app = (appExports, model) ->
|
||||
user = model.at('_user')
|
||||
|
||||
user.on 'set', 'tasks.*.completed', (i, completed, previous, isLocal, passed) ->
|
||||
return if passed? && passed.cron # Don't do this stuff on cron
|
||||
direction = () ->
|
||||
return 'up' if completed==true and previous == false
|
||||
return 'down' if completed==false and previous == true
|
||||
throw new Error("Direction neither 'up' nor 'down' on checkbox set.")
|
||||
|
||||
# Score the user based on todo task
|
||||
task = user.at("tasks.#{i}")
|
||||
scoring.score(i, direction())
|
||||
|
||||
appExports.addTask = (e, el, next) ->
|
||||
type = $(el).attr('data-task-type')
|
||||
list = model.at "_#{type}List"
|
||||
newModel = model.at('_new' + type.charAt(0).toUpperCase() + type.slice(1))
|
||||
text = newModel.get()
|
||||
# Don't add a blank todo
|
||||
return if /^(\s)*$/.test(text)
|
||||
|
||||
newModel.set ''
|
||||
switch type
|
||||
|
||||
when 'habit'
|
||||
list.push {type: type, text: text, notes: '', value: 0, up: true, down: true}
|
||||
|
||||
when 'reward'
|
||||
list.push {type: type, text: text, notes: '', value: 20 }
|
||||
|
||||
when 'daily'
|
||||
list.push {type: type, text: text, notes: '', value: 0, repeat:{su:true,m:true,t:true,w:true,th:true,f:true,s:true}, completed: false }
|
||||
|
||||
when 'todo'
|
||||
list.push {type: type, text: text, notes: '', value: 0, completed: false }
|
||||
|
||||
# list.on 'set', '*.completed', (i, completed, previous, isLocal) ->
|
||||
# # Move the item to the bottom if it was checked off
|
||||
# list.move i, -1 if completed && isLocal
|
||||
|
||||
appExports.del = (e, el) ->
|
||||
# Derby extends model.at to support creation from DOM nodes
|
||||
#task = model.at(e.target)
|
||||
# FIXME normally that would work, and we'd later simply call `user.del task` (instead of that 4-liner down there)
|
||||
# however, see https://github.com/lefnire/habitrpg/pull/226#discussion_r2810391
|
||||
|
||||
id = $(e.target).parents('li.task').attr('data-id')
|
||||
return unless id?
|
||||
|
||||
task = user.at "tasks.#{id}"
|
||||
type = task.get('type')
|
||||
|
||||
history = task.get('history')
|
||||
if history and history.length>2
|
||||
# prevent delete-and-recreate hack on red tasks
|
||||
if task.get('value') < 0
|
||||
result = confirm("Are you sure? Deleting this task will hurt you (to prevent deleting, then re-creating red tasks).")
|
||||
if result != true
|
||||
return # Cancel. Don't delete, don't hurt user
|
||||
else
|
||||
task.set('type','habit') # hack to make sure it hits HP, instead of performing "undo checkbox"
|
||||
scoring.score(id, direction:'down')
|
||||
|
||||
# prevent accidently deleting long-standing tasks
|
||||
else
|
||||
result = confirm("Are you sure you want to delete this task?")
|
||||
return if result != true
|
||||
|
||||
#TODO bug where I have to delete from _users.tasks AND _{type}List,
|
||||
# fix when query subscriptions implemented properly
|
||||
$('[rel=tooltip]').tooltip('hide')
|
||||
|
||||
ids = user.get("idLists.#{type}")
|
||||
ids.splice(ids.indexOf(id),1)
|
||||
user.del('tasks.'+id)
|
||||
user.set("idLists.#{type}", ids)
|
||||
|
||||
|
||||
appExports.clearCompleted = (e, el) ->
|
||||
todoIds = user.get('idLists.todo')
|
||||
removed = false
|
||||
_.each model.get('_todoList'), (task) ->
|
||||
if task.completed
|
||||
removed = true
|
||||
user.del('tasks.'+task.id)
|
||||
todoIds.splice(todoIds.indexOf(task.id), 1)
|
||||
if removed
|
||||
user.set('idLists.todo', todoIds)
|
||||
|
||||
appExports.toggleDay = (e, el) ->
|
||||
task = model.at(e.target)
|
||||
if /active/.test($(el).attr('class')) # previous state, not current
|
||||
task.set('repeat.' + $(el).attr('data-day'), false)
|
||||
else
|
||||
task.set('repeat.' + $(el).attr('data-day'), true)
|
||||
|
||||
appExports.toggleTaskEdit = (e, el) ->
|
||||
hideId = $(el).attr('data-hide-id')
|
||||
toggleId = $(el).attr('data-toggle-id')
|
||||
$(document.getElementById(hideId)).hide()
|
||||
$(document.getElementById(toggleId)).toggle()
|
||||
|
||||
appExports.toggleChart = (e, el) ->
|
||||
hideSelector = $(el).attr('data-hide-id')
|
||||
chartSelector = $(el).attr('data-toggle-id')
|
||||
historyPath = $(el).attr('data-history-path')
|
||||
$(document.getElementById(hideSelector)).hide()
|
||||
$(document.getElementById(chartSelector)).toggle()
|
||||
|
||||
matrix = [['Date', 'Score']]
|
||||
for obj in model.get(historyPath)
|
||||
date = +new Date(obj.date)
|
||||
readableDate = moment(date).format('MM/DD')
|
||||
matrix.push [ readableDate, obj.value ]
|
||||
data = google.visualization.arrayToDataTable matrix
|
||||
|
||||
options = {
|
||||
title: 'History'
|
||||
#TODO use current background color: $(el).css('background-color), but convert to hex (see http://goo.gl/ql5pR)
|
||||
backgroundColor: 'whiteSmoke'
|
||||
}
|
||||
|
||||
chart = new google.visualization.LineChart(document.getElementById( chartSelector ))
|
||||
chart.draw(data, options)
|
||||
|
||||
appExports.score = (e, el, next) ->
|
||||
direction = $(el).attr('data-direction')
|
||||
direction = 'up' if direction == 'true/'
|
||||
direction = 'down' if direction == 'false/'
|
||||
task = model.at $(el).parents('li')[0]
|
||||
scoring.score(task.get('id'), direction)
|
||||
|
|
@ -47,7 +47,7 @@ strategies =
|
|||
options =
|
||||
domain: process.env.BASE_URL || 'http://localhost:3000'
|
||||
allowPurl: true
|
||||
schema: require('../app/schema').newUserObject()
|
||||
schema: require('../app/character').newUserObject()
|
||||
customAccessControl: habitrpgStore.customAccessControl
|
||||
|
||||
mongo_store = new MongoStore {url: process.env.NODE_DB_URI}, ->
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
_ = require 'underscore'
|
||||
schema = require "../app/schema"
|
||||
character = require "../app/character"
|
||||
|
||||
module.exports.middleware = (req, res, next) ->
|
||||
model = req.getModel()
|
||||
|
|
@ -33,7 +33,7 @@ module.exports.app = (appExports, model) ->
|
|||
Buy Reroll Button
|
||||
###
|
||||
appExports.buyReroll = (e, el, next) ->
|
||||
batch = new schema.BatchUpdate(model)
|
||||
batch = new character.BatchUpdate(model)
|
||||
obj = model.get('_user')
|
||||
batch.set 'balance', obj.balance-1
|
||||
_.each obj.tasks, (task) -> batch.set("tasks.#{task.id}.value", 0) unless task.type == 'reward'
|
||||
|
|
|
|||
Loading…
Reference in a new issue