Proper reward processing & updating user-stats on vote save

This commit is contained in:
Tyler Renelle 2012-02-11 02:26:09 -05:00
parent d39dae354b
commit e2429632a1
9 changed files with 83 additions and 57 deletions

View file

@ -11,17 +11,23 @@ class HabitTracker.Models.Habit extends Backbone.Model
done: false done: false
position: 0 position: 0
isHabit: -> isHabit: =>
@get("habit_type")==1 @get("habit_type")==1
isDaily: -> isDaily: =>
@get("habit_type")==2 @get("habit_type")==2
isTodo: =>
@get('habit_type')==3
isDoneTodo: -> isDoneTodo: =>
@get("habit_type")==3 and @get("done") @isTodo() and @get("done")
isRemainingTodo: -> isRemainingTodo: =>
@get("habit_type")==3 and !@get("done") @isTodo() and !@get("done")
isReward: =>
@get('habit_type')==4
vote: (direction) -> vote: (direction) ->
# For negative values, use a line: something like y=-.1x+1 # For negative values, use a line: something like y=-.1x+1
@ -34,18 +40,20 @@ class HabitTracker.Models.Habit extends Backbone.Model
delta = (( -0.1 * score + 1 ) * sign) delta = (( -0.1 * score + 1 ) * sign)
else else
delta = (( Math.pow(0.9, score) ) * sign) delta = (( Math.pow(0.9, score) ) * sign)
score += delta score += delta unless @isReward
# up/down -voting as checkbox & assigning as done, 2 birds one stone # up/down -voting as checkbox & assigning as done, 2 birds one stone
done = @get("done") done = @get("done")
if !@isHabit() if !@isHabit()
done = true if direction=="up" done = true if direction=="up"
done = false if direction=="down" done = false if direction=="down"
@set({ score: score, done: done })
@save({ score: score, done: done })
window.userStats.updateStats(this, delta) window.userStats.updateStats(this, delta)
#send all the update information, as well as tack on userStats which will save to Users
@save({ user_stats: window.userStats })
class HabitTracker.Collections.HabitsCollection extends Backbone.Collection class HabitTracker.Collections.HabitsCollection extends Backbone.Collection
model: HabitTracker.Models.Habit model: HabitTracker.Models.Habit
url: '/habits' url: '/habits'

View file

@ -15,8 +15,11 @@ class HabitTracker.Models.User extends Backbone.Model
@set({ lvl: @get('lvl') + 1 }) @set({ lvl: @get('lvl') + 1 })
# also add money. Only take away money if it was a mistake (aka, a checkbox) # also add money. Only take away money if it was a mistake (aka, a checkbox)
if delta>0 or !habit.isHabit() if delta>0 or (habit.isDaily() or habit.isTodo())
@set({money: @get('money')+delta}) @set({money: @get('money')+delta})
# if buying an item, deduct cost
if habit.isReward()
@set({money: @get('money')-habit.get('score')})
@trigger('updatedStats') @trigger('updatedStats')

View file

@ -0,0 +1,7 @@
<!-- TODO buy link -->
<a class="buy-link" href=#><img src="assets/dollar.png" /></a>
<%= name %>
($<%= score %>)
<div class='edit'>
<a href="#/<%= id %>/edit">Edit</a>
</div>

View file

@ -8,15 +8,15 @@ class HabitTracker.Views.Habits.HabitView extends Backbone.View
"click .vote-up" : "voteUp" "click .vote-up" : "voteUp"
"click .vote-down" : "voteDown" "click .vote-down" : "voteDown"
destroy: () -> destroy: () =>
@model.destroy() @model.destroy()
this.remove() this.remove()
return false return false
voteUp: -> voteUp: =>
@model.vote("up") @model.vote("up")
voteDown: -> voteDown: =>
@model.vote("down") @model.vote("down")
tagName: "li" tagName: "li"

View file

@ -11,9 +11,10 @@ class HabitTracker.Views.Habits.IndexView extends Backbone.View
# TODO create a view & template, bind to existing element # TODO create a view & template, bind to existing element
updateStats: () => updateStats: () =>
stats = window.userStats stats = window.userStats
@$('#tnl').html( "(Level #{stats.get('lvl')})&nbsp;&nbsp;&nbsp;#{Math.round(stats.get('exp'))} / #{stats.tnl()}" ) $('#tnl').html( "(Level #{stats.get('lvl')})&nbsp;&nbsp;&nbsp;#{Math.round(stats.get('exp'))} / #{stats.tnl()}" )
@$( "#progressbar" ).progressbar value: stats.get('exp')/stats.tnl() * 100 $( "#progressbar" ).progressbar value: stats.get('exp')/stats.tnl() * 100
# TODO for some reason this has to be @$, but above has to be $
money = stats.get('money').toFixed(1).split('.') money = stats.get('money').toFixed(1).split('.')
@$('#money').html("#{money[0]} <img src='assets/coin_single_gold.png'/> #{money[1]} <img src='assets/coin_single_silver.png'/>") @$('#money').html("#{money[0]} <img src='assets/coin_single_gold.png'/> #{money[1]} <img src='assets/coin_single_silver.png'/>")
@ -26,6 +27,9 @@ class HabitTracker.Views.Habits.IndexView extends Backbone.View
if habit.isDaily() then @$("#habits-daily").append(view.render().el) if habit.isDaily() then @$("#habits-daily").append(view.render().el)
if habit.isDoneTodo() then @$("#habits-todos-done").append(view.render().el) if habit.isDoneTodo() then @$("#habits-todos-done").append(view.render().el)
if habit.isRemainingTodo() then @$("#habits-todos-remaining").append(view.render().el) if habit.isRemainingTodo() then @$("#habits-todos-remaining").append(view.render().el)
if habit.isReward()
view = new HabitTracker.Views.Habits.RewardView({model : habit})
@$("#rewards").append(view.render().el)
render: => render: =>
$(@el).html(@template(habits: @options.habits.toJSON() )) $(@el).html(@template(habits: @options.habits.toJSON() ))

View file

@ -0,0 +1,32 @@
HabitTracker.Views.Habits ||= {}
class HabitTracker.Views.Habits.RewardView extends Backbone.View
template: JST["backbone/templates/habits/reward"]
events:
"click .destroy" : "destroy"
"click .buy-link" : "voteDown"
destroy: () ->
@model.destroy()
this.remove()
return false
voteDown: =>
if @model.get('score') > window.userStats.get('money')
$('#money').effect("pulsate", 100);
else
@model.vote("down")
tagName: "li"
className: "reward"
render: ->
$(@el).attr('id', "habit_#{@model.get('id')}")
$(@el).html(@template(@model.toJSON() ))
@$(".comment").qtip content:
text: (api) ->
$(this).next().html()
return this

View file

@ -2,7 +2,6 @@ class HabitsController < ApplicationController
before_filter :authenticate_user! before_filter :authenticate_user!
# GET /habits.json
def index def index
@user = current_user @user = current_user
respond_to do |format| respond_to do |format|
@ -11,84 +10,56 @@ class HabitsController < ApplicationController
end end
end end
# GET /habits/new
# GET /habits/new.json
def new def new
@habit = Habit.new render :json => Habit.new
@habit.position = (Habit.maximum('position') || 0) + 1
respond_to do |format|
format.html # new.html.erb
format.json { render json: @habit }
end
end end
# GET /habits/1/edit
def edit def edit
@habit = current_user.habits.find(params[:id]) render :json => current_user.habits.find(params[:id])
end end
# POST /habits
# POST /habits.json
def create def create
@habit = Habit.new(params[:habit]) @habit = Habit.new(params[:habit])
@habit.position ||= (Habit.maximum('position') || 0) + 1
@habit.user_id = current_user.id @habit.user_id = current_user.id
respond_to do |format| respond_to do |format|
if @habit.save if @habit.save
format.html { redirect_to habits_url, notice: 'Habit was successfully created.' }
format.json { render json: @habit, status: :created, location: @habit } format.json { render json: @habit, status: :created, location: @habit }
else else
format.html { render action: "new" }
format.json { render json: @habit.errors, status: :unprocessable_entity } format.json { render json: @habit.errors, status: :unprocessable_entity }
end end
end end
end end
# PUT /habits/1
# PUT /habits/1.json
def update def update
@habit = current_user.habits.find(params[:id]) @habit = current_user.habits.find(params[:id])
test = params[:habit]
user_stats = params[:habit][:user_stats]
params[:habit].delete('user_stats')
@habit.user.lvl = user_stats['lvl']
@habit.user.exp = user_stats['exp']
@habit.user.money = user_stats['money']
@habit.user.save
respond_to do |format| respond_to do |format|
if @habit.update_attributes(params[:habit]) if @habit.update_attributes(params[:habit])
format.html { redirect_to habits_url, notice: 'Habit was successfully updated.' }
format.json { head :no_content } format.json { head :no_content }
else else
format.html { render action: "edit" }
format.json { render json: @habit.errors, status: :unprocessable_entity } format.json { render json: @habit.errors, status: :unprocessable_entity }
end end
end end
end end
# DELETE /habits/1
# DELETE /habits/1.json
def destroy def destroy
@habit = current_user.habits.find(params[:id]) @habit = current_user.habits.find(params[:id])
@habit.destroy @habit.destroy
respond_to do |format| respond_to do |format|
format.html { redirect_to habits_url }
format.json { head :no_content } format.json { head :no_content }
end end
end end
def vote
@habit = current_user.habits.find(params[:id])
# habit.vote() saves money to the user, this hack prevents having to
# reload current_user to catch that change
@habit.user=current_user
@habit.vote(params[:vote])
respond_to do |format|
# format.html { render action: "edit" }
# format.json { render json: @habit.errors, status: :unprocessable_entity }
format.js
end
end
def sort def sort
current_user.habits.each do |habit| current_user.habits.each do |habit|
logger.fatal params['habit'].index(habit.id.to_s) logger.fatal params['habit'].index(habit.id.to_s)

View file

@ -2,6 +2,7 @@ class Habit < ActiveRecord::Base
ALWAYS = 1 ALWAYS = 1
DAILY = 2 DAILY = 2
ONE_TIME = 3 ONE_TIME = 3
REWARD = 4
belongs_to :user belongs_to :user
default_scope :order => 'position ASC' default_scope :order => 'position ASC'
@ -45,4 +46,4 @@ class Habit < ActiveRecord::Base
save save
end end
end end

View file

@ -32,4 +32,4 @@ class MergeRewardsIntoHabits < ActiveRecord::Migration
end end
end end
end end