From be9d41931301748b3afffa5e438961577cbf6cd1 Mon Sep 17 00:00:00 2001 From: Tyler Renelle Date: Tue, 18 Sep 2012 21:37:49 -0400 Subject: [PATCH] Quarters system, generalized modal dialogs, bug fixes --- lib/app/content.js | 6 +-- lib/app/helpers.js | 15 +++++- lib/app/index.js | 8 +-- lib/app/scoring.js | 2 +- lib/server/auth.js | 14 +++-- src/app/content.coffee | 5 +- src/app/helpers.coffee | 12 +++++ src/app/index.coffee | 4 +- src/app/scoring.coffee | 2 +- test/test.coffee | 51 +++++++++++++----- views/app/index.html | 120 ++++++++++++++++++++++++++++------------- 11 files changed, 169 insertions(+), 70 deletions(-) diff --git a/lib/app/content.js b/lib/app/content.js index 8a86df5017..d55ac53b8f 100644 --- a/lib/app/content.js +++ b/lib/app/content.js @@ -208,11 +208,7 @@ module.exports = { type: 'reroll', text: "Re-Roll", icon: 'favicon', - notes: "Reset your tasks. When you're struggling and everything's red, use for a clean slate. Use sparingly, it costs real money.", - rerollWarning: { - title: "This item costs real money", - content: "Each use is $1, can use 5 times before checkout." - }, + notes: "Resets your tasks. When you're struggling and everything's red, use for a clean slate.", value: 0 } } diff --git a/lib/app/helpers.js b/lib/app/helpers.js index d2b3caf0ae..171bc8a7e5 100644 --- a/lib/app/helpers.js +++ b/lib/app/helpers.js @@ -68,11 +68,24 @@ module.exports.viewHelpers = function(view) { return "0"; } }); - return view.fn("silver", function(num) { + view.fn("silver", function(num) { if (num) { return num.toFixed(1).split('.')[1]; } else { return "0"; } }); + view.fn("money", function(num) { + if (num) { + return num.toFixed(2); + } else { + return "0.00"; + } + }); + view.fn("lessThan", function(a, b) { + return a < b; + }); + return view.fn("quarters", function(money) { + return money / 0.25; + }); }; diff --git a/lib/app/index.js b/lib/app/index.js index ffe329ddc8..cdc6ec824b 100644 --- a/lib/app/index.js +++ b/lib/app/index.js @@ -32,6 +32,7 @@ get('/:uidParam?', function(page, model, _arg, next) { model.set('_userId', sess.userId); return model.subscribe("users." + sess.userId, function(err, user) { model.ref('_user', user); + user.setNull('balance', 2); model.set('_items', { armor: content.items.armor[parseInt(user.get('items.armor')) + 1], weapon: content.items.weapon[parseInt(user.get('items.weapon')) + 1], @@ -51,9 +52,7 @@ get('/:uidParam?', function(page, model, _arg, next) { }); ready(function(model) { - var pathParts, poormanscron, setupSortable, step, tour, type, _i, _j, _len, _len1, _ref1, _ref2; - pathParts = window.location.toString().split('/'); - $('#purl').val("" + pathParts[0] + "//" + pathParts[2] + "/" + (model.get('_userId'))); + var poormanscron, setupSortable, step, tour, type, _i, _j, _len, _len1, _ref1, _ref2; $('[rel=tooltip]').tooltip(); $('[rel=popover]').popover(); model.on('set', '*', function() { @@ -309,7 +308,8 @@ ready(function(model) { model.set('_user.items.armor', 0); model.set('_user.items.weapon', 0); model.set('_items.armor', content.items.armor[1]); - return model.set('_items.weapon', content.items.weapon[1]); + model.set('_items.weapon', content.items.weapon[1]); + return model.set('_user.balance', model.get('_user.balance') - 0.50); }; exports.poormanscron = poormanscron = function() { var daysPassed, lastCron, today; diff --git a/lib/app/scoring.js b/lib/app/scoring.js index 32215834f5..45662df5d8 100644 --- a/lib/app/scoring.js +++ b/lib/app/scoring.js @@ -120,7 +120,7 @@ module.exports.score = score = function(spec) { _ref2 = [user.get('stats.money'), user.get('stats.hp'), user.get('stats.exp'), user.get('stats.lvl')], money = _ref2[0], hp = _ref2[1], exp = _ref2[2], lvl = _ref2[3]; if (type === 'reward') { money -= task.get('value'); - num = task.get('value').toFixed(2); + num = parseFloat(task.get('value')).toFixed(2); statsNotification("GP -" + num, 'success'); if (money < 0) { hp += money; diff --git a/lib/server/auth.js b/lib/server/auth.js index 96e82c5ea2..be27412ac7 100644 --- a/lib/server/auth.js +++ b/lib/server/auth.js @@ -42,8 +42,8 @@ module.exports.newUserAndPurl = function() { } model.set("users." + sess.userId, newUser); } - acceptableUid = require('guid').isGuid(uidParam) || (uidParam === '3' || uidParam === '9'); - if (acceptableUid && sess.userId !== uidParam) { + acceptableUid = require('guid').isGuid(uidParam) || (uidParam === '3'); + if (acceptableUid && sess.userId !== uidParam && !(sess.habitRpgAuth && sess.habitRpgAuth.facebook)) { return sess.userId = uidParam; } }; @@ -53,7 +53,7 @@ module.exports.setupEveryauth = function(everyauth) { everyauth.everymodule.findUserById(function(id, callback) { return callback(null, null); }); - return everyauth.facebook.appId(process.env.FACEBOOK_KEY).appSecret(process.env.FACEBOOK_SECRET).findOrCreateUser(function(session, accessToken, accessTokenExtra, fbUserMetadata) { + everyauth.facebook.appId(process.env.FACEBOOK_KEY).appSecret(process.env.FACEBOOK_SECRET).findOrCreateUser(function(session, accessToken, accessTokenExtra, fbUserMetadata) { var model, q; session.habitRpgAuth || (session.habitRpgAuth = {}); session.habitRpgAuth.facebook = fbUserMetadata.id; @@ -78,6 +78,14 @@ module.exports.setupEveryauth = function(everyauth) { }); return fbUserMetadata; }).redirectPath("/"); + return everyauth.everymodule.handleLogout(function(req, res) { + if (req.session.habitRpgAuth && req.session.habitRpgAuth.facebook) { + req.session.habitRpgAuth.facebook = void 0; + } + req.session.userId = void 0; + req.logout(); + return this.redirect(res, this.logoutRedirectPath()); + }); }; module.exports.setupQueries = function(store) { diff --git a/src/app/content.coffee b/src/app/content.coffee index e9b5e4c6ee..edf776bc91 100644 --- a/src/app/content.coffee +++ b/src/app/content.coffee @@ -81,10 +81,7 @@ module.exports = { type: 'reroll' text: "Re-Roll" icon: 'favicon' - notes: "Reset your tasks. When you're struggling and everything's red, use for a clean slate. Use sparingly, it costs real money." - rerollWarning: - title: "This item costs real money" - content: "Each use is $1, can use 5 times before checkout." + notes: "Resets your tasks. When you're struggling and everything's red, use for a clean slate." value:0 } diff --git a/src/app/helpers.coffee b/src/app/helpers.coffee index 44fb663e08..99b32fd9e5 100644 --- a/src/app/helpers.coffee +++ b/src/app/helpers.coffee @@ -46,3 +46,15 @@ module.exports.viewHelpers = (view) -> num.toFixed(1).split('.')[1] else return "0" + + view.fn "money", (num) -> + if num + return num.toFixed(2) + else + return "0.00" + + view.fn "lessThan", (a, b) -> + a < b + + view.fn "quarters", (money) -> + return money/0.25 diff --git a/src/app/index.coffee b/src/app/index.coffee index 9ac885bac5..db6463d6ae 100644 --- a/src/app/index.coffee +++ b/src/app/index.coffee @@ -25,6 +25,8 @@ get '/:uidParam?', (page, model, {uidParam}, next) -> model.subscribe "users.#{sess.userId}", (err, user) -> model.ref '_user', user + user.setNull 'balance', 2 + # Store model.set '_items' armor: content.items.armor[parseInt(user.get('items.armor')) + 1] @@ -234,7 +236,6 @@ ready (model) -> direction = 'down' if direction == 'false/' user = model.at('_user') task = model.at $(el).parents('li')[0] - scoring.score({user:user, task:task, direction:direction}) exports.revive = (e, el) -> @@ -244,6 +245,7 @@ ready (model) -> model.set '_user.items.weapon', 0 model.set '_items.armor', content.items.armor[1] model.set '_items.weapon', content.items.weapon[1] + model.set '_user.balance', (model.get('_user.balance') - 0.50) # ========== CRON ========== diff --git a/src/app/scoring.coffee b/src/app/scoring.coffee index 70f945a6e0..f543aa8822 100644 --- a/src/app/scoring.coffee +++ b/src/app/scoring.coffee @@ -107,7 +107,7 @@ module.exports.score = score = (spec = {user:null, task:null, direction:null, cr if type == 'reward' # purchase item money -= task.get('value') - num = task.get('value').toFixed(2) + num = parseFloat(task.get('value')).toFixed(2) statsNotification "GP -#{num}", 'success' # if too expensive, reduce health & zero money if money < 0 diff --git a/test/test.coffee b/test/test.coffee index 6021a3678c..83f0404957 100644 --- a/test/test.coffee +++ b/test/test.coffee @@ -1,22 +1,45 @@ url = 'http://localhost:3000' utils = require('utils') casper = require("casper").create() +_ = require('../public/js/underscore-min.js') # ---------- Main Stuff ------------ casper.start url, -> @test.assertTitle "HabitRPG", "homepage title is the one expected" -# ---------- Todos gain delta on cron ------------ +# ---------- Setup Tasks ------------ casper.then -> - todoBefore = @evaluate -> window.DERBY.model.get('_todoList')[0] - @then -> - @evaluate -> - window.DERBY.model.set('_user.lastCron', new Date('09/17/2012')) - @then -> @reload() - @then -> - todoAfter = @evaluate -> window.DERBY.model.get('_todoList')[0] - @then -> @test.assert(todoBefore.value > todoAfter.value, "Incomplete TODO gained value on cron") + _.each ['habit', 'daily', 'todo', 'reward'], (type) -> + # Add 15 of each task type + casper.repeat 15, -> + casper.fill "form#new-#{type}", {'new-task': type } # why can't I use true here? + casper.click "form#new-#{type} input[type=submit]" + # @then -> + # utils.dump @evaluate -> _.pluck(window.DERBY.model.get('_user.tasks'), 'text') + + +# ---------- Run Cron ------------ +casper.then -> + @evaluate -> window.DERBY.model.set('_user.lastCron', new Date('09/01/2012')); + # @then -> @reload -> + # @echo 'Refreshing pag (running cron)' + # @then -> @reload -> + # @echo 'Refreshing page (trying to trigger the database-spaz bug)' + +# ---------- Todos gain delta on cron ------------ +# casper.then -> + # todoBefore = @evaluate -> window.DERBY.model.get('_todoList')[0] + # @then -> + # @evaluate -> + # window.DERBY.model.set('_user.lastCron', new Date('09/17/2012')) + # @then -> @reload() + # @then -> + # @wait 2000, -> + # todoAfter = @evaluate -> window.DERBY.model.get('_todoList')[0] + # @then -> @test.assert(todoBefore.value > todoAfter.value, "Incomplete TODO gained value on cron") + # utils.dump todoBefore + # utils.dump todoAfter # ---------- User Death ------------ # casper.then -> @@ -35,11 +58,11 @@ casper.then -> # ---------- Misc Pages ------------ -casper.thenOpen "#{url}/terms", -> - @test.assertTitle "Terms Of Use", "terms page works" - -casper.thenOpen "#{url}/privacy", -> - @test.assertTitle "Privacy Policy", "privacy page works" +# casper.thenOpen "#{url}/terms", -> + # @test.assertTitle "Terms Of Use", "terms page works" +# +# casper.thenOpen "#{url}/privacy", -> + # @test.assertTitle "Privacy Policy", "privacy page works" casper.run -> @test.renderResults true \ No newline at end of file diff --git a/views/app/index.html b/views/app/index.html index 760416b674..e1769a979d 100644 --- a/views/app/index.html +++ b/views/app/index.html @@ -3,7 +3,8 @@ - + +

A habit tracker app which treats your goals like a Role Playing Game. As you accomplish goals, you level up. If you fail your goals, you lose hit points. Lose all your HP and you die.

@@ -25,24 +26,14 @@
  • Logout
  • - - - - - {/} + + User ID
    + Copy this ID for use in third party applications. +
    {_user.id}

    +
    + {/} -
    @@ -82,16 +73,26 @@
    - +
    - - + + Quarters: {quarters(_user.balance)} + + + + + +
    +

    Game Over

    + {#if lessThan(_user.balance,0.50)} + Buy More Quarters Not enough quarters + {else} +

    + Continue 2 Quarters +

    + {/} +
    +
    @@ -111,12 +112,12 @@
      {#each _habitList as :task}{/}
    - +
      {#each _dailyList as :task}{/}
    - +
    @@ -130,7 +131,7 @@
      {#each _todoList as :task}{/}
    - +
      @@ -161,13 +162,46 @@
    {/} - + + + + Quarters: {quarters(_user.balance)} +

    Highly discouraged because red tasks provide good incentive to improve (read more). However, this becomes necessary after long bouts of bad habits.

    + {#if lessThan(_user.balance,1)} + Buy More Quarters Not enough quarters + {else} + 4 Quarters + {/} +
    - - - + + + +
    + +
    +

    $5

    +
    + + +
    +
    + + +
    +
    + + + / + +
    + +
    +
    + +
    {#unless _mobileDevice} @@ -209,6 +243,18 @@
    + + {{{#if noDismiss}}}{{{/}}} + +
    @@ -218,7 +264,7 @@
    -
    + {{{content}}}
    @@ -315,14 +361,16 @@
    - {{{#unless disabled}}} + {{{#if reroll}}} + + {{{else}}} {:item.value} {{{/}}}
    {:item.text}
    - +