2012-04-27 02:19:31 +00:00
|
|
|
{get, view, ready} = require('derby').createApp module
|
|
|
|
|
|
|
|
|
|
## ROUTES ##
|
|
|
|
|
|
2012-05-02 19:50:43 +00:00
|
|
|
get '/', (page, model) ->
|
|
|
|
|
|
|
|
|
|
# Render page if a userId is already stored in session data
|
|
|
|
|
if userId = model.get '_session.userId'
|
|
|
|
|
return getRoom page, model, userId
|
|
|
|
|
|
|
|
|
|
# Otherwise, select a new userId and initialize user
|
|
|
|
|
model.async.incr 'configs.1.nextUserId', (err, userId) ->
|
|
|
|
|
model.set '_session.userId', userId
|
|
|
|
|
model.set "users.#{userId}",
|
|
|
|
|
name: 'User ' + userId
|
|
|
|
|
money: 0
|
|
|
|
|
exp: 0
|
|
|
|
|
lvl: 1
|
2012-05-03 00:32:29 +00:00
|
|
|
|
|
|
|
|
habits:
|
2012-05-03 01:15:29 +00:00
|
|
|
0: {id: 0, text: 'Take the stairs', notes: '', score: 0, up: true, down: true}
|
2012-05-03 00:32:29 +00:00
|
|
|
habitIds: [0]
|
|
|
|
|
|
2012-05-03 01:07:36 +00:00
|
|
|
dailys: # I know it's bad pluralization, but codes easier later
|
2012-05-03 01:15:29 +00:00
|
|
|
0: {id: 0, text: 'Go to the gym', notes: '', score: 0, completed: false }
|
2012-05-03 00:32:29 +00:00
|
|
|
dailyIds: [0]
|
|
|
|
|
|
2012-05-03 00:16:40 +00:00
|
|
|
todos:
|
2012-05-03 01:15:29 +00:00
|
|
|
0: {id: 0, text: 'Make a doctor appointment', notes: '', score: 0, completed: false }
|
2012-05-03 00:16:40 +00:00
|
|
|
todoIds: [0]
|
2012-05-03 00:32:29 +00:00
|
|
|
|
|
|
|
|
rewards:
|
2012-05-03 01:15:29 +00:00
|
|
|
0: {id: 0, text: '1 TV episode', notes: '', price: 20 }
|
2012-05-03 00:32:29 +00:00
|
|
|
rewardIds: [0]
|
|
|
|
|
|
2012-05-02 19:50:43 +00:00
|
|
|
getRoom page, model, userId
|
|
|
|
|
|
|
|
|
|
getRoom = (page, model, userId) ->
|
|
|
|
|
model.subscribe "users.#{userId}", (err, user) ->
|
|
|
|
|
model.ref '_user', user
|
2012-05-09 16:26:43 +00:00
|
|
|
|
2012-05-03 01:07:36 +00:00
|
|
|
# Setup "_todoList" for all the habit types
|
|
|
|
|
lists = [ 'habit', 'daily', 'todo', 'reward']
|
2012-05-09 16:26:43 +00:00
|
|
|
for type in lists
|
|
|
|
|
ids = user.at "#{type}Ids"
|
|
|
|
|
model.refList "_#{type}List", "_user.#{type}s", "_user.#{type}Ids"
|
2012-04-27 17:04:44 +00:00
|
|
|
|
|
|
|
|
page.render()
|
|
|
|
|
|
2012-04-27 02:19:31 +00:00
|
|
|
|
|
|
|
|
## CONTROLLER FUNCTIONS ##
|
|
|
|
|
|
|
|
|
|
ready (model) ->
|
|
|
|
|
|
2012-05-03 01:07:36 +00:00
|
|
|
lists = [ 'habit', 'daily', 'todo', 'reward']
|
|
|
|
|
|
2012-05-09 16:26:43 +00:00
|
|
|
for type in lists
|
|
|
|
|
list = model.at "_#{type}List"
|
2012-05-04 01:03:09 +00:00
|
|
|
|
2012-05-03 01:07:36 +00:00
|
|
|
# Make the list draggable using jQuery UI
|
2012-05-09 16:26:43 +00:00
|
|
|
ul = $("\##{type}s")
|
2012-05-03 01:07:36 +00:00
|
|
|
ul.sortable
|
|
|
|
|
handle: '.handle'
|
|
|
|
|
axis: 'y'
|
2012-05-09 16:26:43 +00:00
|
|
|
containment: "\#dragbox-#{type}"
|
2012-05-03 01:07:36 +00:00
|
|
|
update: (e, ui) ->
|
|
|
|
|
item = ui.item[0]
|
|
|
|
|
domId = item.id
|
|
|
|
|
id = item.getAttribute 'data-id'
|
|
|
|
|
to = ul.children().index(item)
|
|
|
|
|
# Use the Derby ignore option to suppress the normal move event
|
|
|
|
|
# binding, since jQuery UI will move the element in the DOM.
|
|
|
|
|
# Also, note that refList index arguments can either be an index
|
|
|
|
|
# or the item's id property
|
|
|
|
|
list.pass(ignore: domId).move {id}, to
|
|
|
|
|
|
|
|
|
|
exports.addHabit = ->
|
2012-05-03 01:15:29 +00:00
|
|
|
newHabit = model.at "_newHabit"
|
2012-05-03 01:07:36 +00:00
|
|
|
list = model.at "_habitList"
|
|
|
|
|
# Don't add a blank todo
|
|
|
|
|
return unless text = view.escapeHtml newHabit.get()
|
|
|
|
|
newHabit.set ''
|
2012-05-04 00:03:08 +00:00
|
|
|
list.push {text, notes: '', score: 0, up: true, down: true}
|
2012-05-03 01:07:36 +00:00
|
|
|
|
|
|
|
|
exports.addDaily = ->
|
2012-05-03 01:15:29 +00:00
|
|
|
newDaily = model.at "_newDaily"
|
2012-05-03 01:07:36 +00:00
|
|
|
list = model.at "_dailyList"
|
|
|
|
|
# Don't add a blank todo
|
|
|
|
|
return unless text = view.escapeHtml newDaily.get()
|
|
|
|
|
newDaily.set ''
|
|
|
|
|
# Insert the new todo before the first completed item in the list
|
|
|
|
|
# or append to the end if none are completed
|
|
|
|
|
for todo, i in list.get()
|
|
|
|
|
break if todo.completed
|
2012-05-04 00:03:08 +00:00
|
|
|
list.insert i, {text, notes: '', score: 0, completed: false }
|
2012-05-03 01:07:36 +00:00
|
|
|
|
2012-05-03 13:35:48 +00:00
|
|
|
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
|
|
|
|
|
|
2012-05-03 01:07:36 +00:00
|
|
|
exports.addTodo = ->
|
2012-05-03 01:15:29 +00:00
|
|
|
newTodo = model.at "_newTodo"
|
2012-05-03 01:07:36 +00:00
|
|
|
list = model.at "_todoList"
|
2012-04-27 17:04:44 +00:00
|
|
|
# Don't add a blank todo
|
|
|
|
|
return unless text = view.escapeHtml newTodo.get()
|
|
|
|
|
newTodo.set ''
|
|
|
|
|
# Insert the new todo before the first completed item in the list
|
|
|
|
|
# or append to the end if none are completed
|
|
|
|
|
for todo, i in list.get()
|
|
|
|
|
break if todo.completed
|
2012-05-04 00:03:08 +00:00
|
|
|
list.insert i, {text, notes: '', score: 0, completed: false }
|
2012-05-03 01:07:36 +00:00
|
|
|
|
2012-05-03 13:35:48 +00:00
|
|
|
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
|
|
|
|
|
|
2012-05-03 01:07:36 +00:00
|
|
|
exports.addReward = ->
|
2012-05-03 01:15:29 +00:00
|
|
|
newReward = model.at "_newReward"
|
2012-05-03 01:07:36 +00:00
|
|
|
list = model.at "_rewardList"
|
|
|
|
|
# Don't add a blank todo
|
|
|
|
|
return unless text = view.escapeHtml newReward.get()
|
|
|
|
|
newReward.set ''
|
2012-05-04 00:03:08 +00:00
|
|
|
list.push {text, notes: '', price: 20 }
|
2012-04-27 17:04:44 +00:00
|
|
|
|
|
|
|
|
exports.del = (e) ->
|
|
|
|
|
# Derby extends model.at to support creation from DOM nodes
|
|
|
|
|
model.at(e.target).remove()
|
2012-05-03 01:15:29 +00:00
|
|
|
|
2012-05-04 01:03:09 +00:00
|
|
|
exports.voteUp = (e) ->
|
|
|
|
|
todo = model.at(e.target)
|
|
|
|
|
exp = model.get '_user.exp'
|
|
|
|
|
model.set '_user.exp', exp +1
|
|
|
|
|
console.log todo
|
|
|
|
|
|
2012-05-03 01:15:29 +00:00
|
|
|
## RECONNECT & SHORTCUTS ##
|
2012-04-27 17:04:44 +00:00
|
|
|
|
|
|
|
|
showReconnect = model.at '_showReconnect'
|
|
|
|
|
showReconnect.set true
|
2012-04-27 02:19:31 +00:00
|
|
|
exports.connect = ->
|
2012-04-27 17:04:44 +00:00
|
|
|
showReconnect.set false
|
|
|
|
|
setTimeout (-> showReconnect.set true), 1000
|
2012-04-27 02:19:31 +00:00
|
|
|
model.socket.socket.connect()
|
|
|
|
|
|
|
|
|
|
exports.reload = -> window.location.reload()
|
2012-04-27 17:04:44 +00:00
|
|
|
|
|
|
|
|
exports.shortcuts = (e) ->
|
|
|
|
|
return unless e.metaKey || e.ctrlKey
|
|
|
|
|
code = e.which
|
|
|
|
|
return unless command = (switch code
|
|
|
|
|
when 66 then 'bold' # Bold: Ctrl/Cmd + B
|
|
|
|
|
when 73 then 'italic' # Italic: Ctrl/Cmd + I
|
|
|
|
|
when 32 then 'removeFormat' # Clear formatting: Ctrl/Cmd + Space
|
|
|
|
|
when 220 then 'removeFormat' # Clear formatting: Ctrl/Cmd + \
|
|
|
|
|
else null
|
|
|
|
|
)
|
|
|
|
|
document.execCommand command, false, null
|
|
|
|
|
e.preventDefault() if e.preventDefault
|
|
|
|
|
return false
|
|
|
|
|
|
|
|
|
|
# Tell Firefox to use elements for styles instead of CSS
|
|
|
|
|
# See: https://developer.mozilla.org/en/Rich-Text_Editing_in_Mozilla
|
|
|
|
|
document.execCommand 'useCSS', false, true
|
|
|
|
|
document.execCommand 'styleWithCSS', false, false
|
2012-05-03 01:07:36 +00:00
|
|
|
|