diff --git a/src/app/character.coffee b/src/app/character.coffee
index d7e87a8abb..e62e577757 100644
--- a/src/app/character.coffee
+++ b/src/app/character.coffee
@@ -72,20 +72,6 @@ module.exports.app = (appExports, model) ->
model.del "users.#{user.get('id')}", ->
window.location.href = "/logout"
- user.on 'set', 'flags.customizationsNotification', (captures, args) ->
- return unless captures == true
- $('.main-herobox').popover('destroy') #remove previous popovers
- html = """
- Click your avatar to customize your appearance. [Close]
- """
- $('.main-herobox').popover
- title: "Customize Your Avatar"
- placement: 'bottom'
- trigger: 'manual'
- html: true
- content: html
- $('.main-herobox').popover 'show'
-
userSchema =
# _id
stats: { gp: 0, exp: 0, lvl: 1, hp: 50 }
diff --git a/src/app/index.coffee b/src/app/index.coffee
index c05ca0daec..9033213301 100644
--- a/src/app/index.coffee
+++ b/src/app/index.coffee
@@ -97,4 +97,5 @@ ready (model) ->
require('../server/private').app(exports, model)
require('./debug').app(exports, model) if model.flags.nodeEnv != 'production'
require('./browser').app(exports, model, app)
+ require('./unlock').app(exports, model)
diff --git a/src/app/items.coffee b/src/app/items.coffee
index 03e1eeb2a0..7b2efa23da 100644
--- a/src/app/items.coffee
+++ b/src/app/items.coffee
@@ -119,38 +119,6 @@ module.exports.app = (appExports, model) ->
model.set '_activeTabPets', true
model.set '_activeTabRewards', false
- model.on 'set', '_user.flags.itemsEnabled', (captures, args) ->
- return unless captures is true
- html = """
-
-

- Congratulations, you have unlocked the Item Store! You can now buy weapons, armor, potions, etc. Read each item's comment for more information.
-
[Close]
-
- """
- $('div.rewards').popover({
- title: "Item Store Unlocked"
- placement: 'left'
- trigger: 'manual'
- html: true
- content: html
- }).popover 'show'
-
- user.on 'set', 'flags.petsEnabled', (captures, args) ->
- return unless captures == true
- html = """
-
- You have unlocked Pets! You can now buy pets with tokens (note, you replenish tokens with real-life money - so chose your pets wisely!)
- [Close]
- """
- $('#rewardsTabs').popover
- title: "Pets Unlocked"
- placement: 'left'
- trigger: 'manual'
- html: true
- content: html
- $('#rewardsTabs').popover 'show'
-
###
update store
###
diff --git a/src/app/party.coffee b/src/app/party.coffee
index b4f1ccb9c6..8baeacf869 100644
--- a/src/app/party.coffee
+++ b/src/app/party.coffee
@@ -72,24 +72,6 @@ module.exports.app = (appExports, model) ->
user = model.at('_user')
- user.on 'set', 'flags.partyEnabled', (captures, args) ->
- return if (captures != true) or user.get('party.current')
- $('.user-menu').popover('destroy') #remove previous popovers
- html = """
-
-

- Be social, join a party and play Habit with your friends! You'll be better at your habits with accountability partners. LFG anyone?
-
[Close]
-
- """
- $('.user-menu').popover
- title: "Party System"
- placement: 'bottom'
- trigger: 'manual'
- html: true
- content: html
- $('.user-menu').popover 'show'
-
model.on 'set', '_user.party.invitation', (after, before) ->
if !before? and after? # they just got invited
partyQ = model.query('parties').withId(after)
diff --git a/src/app/pets.coffee b/src/app/pets.coffee
index 93d11d703e..023cbaa84e 100644
--- a/src/app/pets.coffee
+++ b/src/app/pets.coffee
@@ -8,19 +8,6 @@ _ = require 'underscore'
module.exports.app = (appExports, model) ->
user = model.at '_user'
- user.on 'set', 'flags.dropsEnabled', (captures, args) ->
- return unless captures == true
-
- egg = randomVal pets
-
- dontPersist = model._dontPersist
-
- model._dontPersist = false
- user.push 'items.eggs', egg
- model._dontPersist = dontPersist
-
- $('#drops-enabled-modal').modal 'show'
-
appExports.chooseEgg = (e, el) ->
model.ref '_hatchEgg', e.at()
diff --git a/src/app/scoring.coffee b/src/app/scoring.coffee
index 09bf01a9e2..07b181250f 100644
--- a/src/app/scoring.coffee
+++ b/src/app/scoring.coffee
@@ -235,16 +235,22 @@ updateStats = (model, newStats, batch) ->
#user.pass(true).set('stats.exp', obj.stats.exp)
# Set flags when they unlock features
+ # NOTE we have to first model.set() the flag to true, then AFTER that obj.flags.flag = true
+ # The reason is model.on() listeners still track object references, so if obj.flags.flags = true and then we
+ # model.set(), the second argument of .on() listeners will be true (in otherwords, before/after tests will fail)
if !obj.flags.customizationsNotification and (obj.stats.exp > 10 or obj.stats.lvl > 1)
batch.set 'flags.customizationsNotification', true
obj.flags.customizationsNotification = true
if !obj.flags.itemsEnabled and obj.stats.lvl >= 2
# Set to object, then also send to browser right away to get model.on() subscription notification
- batch.set 'flags.itemsEnabled', obj.flags.itemsEnabled = true
+ batch.set 'flags.itemsEnabled', true
+ obj.flags.itemsEnabled = true
if !obj.flags.partyEnabled and obj.stats.lvl >= 3
- batch.set 'flags.partyEnabled', obj.flags.partyEnabled = true
+ batch.set 'flags.partyEnabled', true
+ obj.flags.partyEnabled = true
if !obj.flags.dropsEnabled and obj.stats.lvl >= 4
- batch.set 'flags.dropsEnabled', obj.flags.dropsEnabled = true
+ batch.set 'flags.dropsEnabled', true
+ obj.flags.dropsEnabled = true
if newStats.gp?
#FIXME what was I doing here? I can't remember, gp isn't defined
diff --git a/src/app/unlock.coffee b/src/app/unlock.coffee
new file mode 100644
index 0000000000..fec56b163a
--- /dev/null
+++ b/src/app/unlock.coffee
@@ -0,0 +1,66 @@
+###
+ Listeners to enabled flags, set notifications to the user when they've unlocked features
+###
+
+module.exports.app = (appExports, model) ->
+ user = model.at('_user')
+
+ alreadyShown = (before, after) ->
+ debugger
+ !(!before and after is true)
+
+ showPopover = (selector, title, html, placement='bottom') ->
+ $(selector).popover('destroy')
+ html += " [Close]"
+ $(selector).popover({
+ title: title
+ placement: placement
+ trigger: 'manual'
+ html: true
+ content: html
+ }).popover 'show'
+
+
+ user.on 'set', 'flags.customizationsNotification', (after, before) ->
+ return if alreadyShown(before,after)
+ $('.main-herobox').popover('destroy') #remove previous popovers
+ html = "Click your avatar to customize your appearance."
+ showPopover '.main-herobox', 'Customize Your Avatar', html, 'bottom'
+
+ user.on 'set', 'flags.itemsEnabled', (after, before) ->
+ return if alreadyShown(before,after)
+ html = """
+
+ Congratulations, you have unlocked the Item Store! You can now buy weapons, armor, potions, etc. Read each item's comment for more information.
+ """
+ showPopover 'div.rewards', 'Item Store Unlocked', html, 'left'
+
+ user.on 'set', 'flags.petsEnabled', (after, before) ->
+ return if alreadyShown(before,after)
+ html = """
+
+ You have unlocked Pets! You can now buy pets with tokens (note, you replenish tokens with real-life money - so chose your pets wisely!)
+ """
+ showPopover '#rewardsTabs', 'Pets Unlocked', html, 'left'
+
+ user.on 'set', 'flags.partyEnabled', (after, before) ->
+ return if user.get('party.current') or alreadyShown(before,after)
+ $('.user-menu').popover('destroy') #remove previous popovers
+ html = """
+
+ Be social, join a party and play Habit with your friends! You'll be better at your habits with accountability partners. LFG anyone?
+ """
+ showPopover '.user-menu', 'Party System', html, 'bottom'
+
+ user.on 'set', 'flags.dropsEnabled', (after, before) ->
+ return if alreadyShown(before,after)
+
+ egg = randomVal pets
+
+ dontPersist = model._dontPersist
+
+ model._dontPersist = false
+ user.push 'items.eggs', egg
+ model._dontPersist = dontPersist
+
+ $('#drops-enabled-modal').modal 'show'