diff --git a/.gitignore b/.gitignore index 94ad5f5766..911f7f45e9 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,7 @@ newrelic_agent.log .bower-cache .vagrant Vagrantfile - +TODO *.log src/*/*.map src/*/*/*.map diff --git a/.nvmrc b/.nvmrc deleted file mode 100644 index 1d8df22149..0000000000 --- a/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -0.10.40 diff --git a/EXTENDEDCHANGELOG.md b/EXTENDEDCHANGELOG.md deleted file mode 100644 index 0fe028c6dd..0000000000 --- a/EXTENDEDCHANGELOG.md +++ /dev/null @@ -1,64 +0,0 @@ -HabitRPG -# (2014-01-28) - - -## Documentation - -- **rebirth:** Bullet point about repurchase of limited ed gear after Rebirth - ([d3f4a561](https://github.com/habitrpg/habitrpg/commits/d3f4a561fdf137e5d8f406bae03be4fef1caff22)) - - -## Bug Fixes - -- **#2003:** healer gear not showing - ([949cd97b](https://github.com/habitrpg/habitrpg/commits/949cd97b91b42e9450eba559bbfea17e239ab100)) -- **#2375:** merge in @SabreCat's stats.jade changes "More elegant show/hide setup for attribute bonuses" - ([518f200a](https://github.com/habitrpg/habitrpg/commits/518f200a8fc7373b44ed7d7b5f016d921b0746bd)) -- **beastmaster:** fixes #2557, adds opacity to previously-owned pets after they're mounted. You can earn them back again - ([5caaff1c](https://github.com/habitrpg/habitrpg/commits/5caaff1cea1a68fe572e7ddf4aac50248b13df5d)) -- **bosses:** don't reset progress.up when starting a new quest. We want to be able to carry over damage from the same day a boss battle begins, even if the dailies were completed before battle-start. Fixes #2168 - ([4efd0f5e](https://github.com/habitrpg/habitrpg/commits/4efd0f5ed8708f2491dd483f93e3d7a268a6337d)) -- **classes:** - - misc fixes - ([d2121a85](https://github.com/habitrpg/habitrpg/commits/d2121a858716cb5a532a53ee9c5a1adaa74a7f69)) - - misc class fixes (not @snicker, ng-if on item store since we dynamically swap it sometimes) - ([478be611](https://github.com/habitrpg/habitrpg/commits/478be6111337cd200374f7f31b959725c6a0b945)) -- **find_uniq_user:** fix - ([ecbe780e](https://github.com/habitrpg/habitrpg/commits/ecbe780e70549b1470504efe052f238c89a9db14)) -- **mounts:** Move avatar upward when mounted regardless of pet - ([bc1adeb1](https://github.com/habitrpg/habitrpg/commits/bc1adeb1277103a5ca1f756e175ed68bbe837a2f)) -- **nodemon:** ignore CHANGELOG.md on watch - ([d6c55952](https://github.com/habitrpg/habitrpg/commits/d6c55952da8b49f36e9d8e4570d80931d081343d)) -- **party:** Round boss health up instead of to nearest integer - ([626da568](https://github.com/habitrpg/habitrpg/commits/626da5681f5ea95700f8ddf40587c7184926971c), - [#2504](https://github.com/habitrpg/habitrpg/issues/2504)) -- **paypal:** fixes #2492, remove environment check for now, only have production-mode option. revisit - ([1dc68112](https://github.com/habitrpg/habitrpg/commits/1dc68112d131e4ebdec32ddff938eb6311d6565f)) -- **profile:** fix bug where empty profile displayed on username click - ([0579c432](https://github.com/habitrpg/habitrpg/commits/0579c432489c4a038e8c9f95ea3b285f5abc146f), - [#2465](https://github.com/habitrpg/habitrpg/issues/2465)) -- **quests:** - - bug fix to multi-drop - ([f478d10c](https://github.com/habitrpg/habitrpg/commits/f478d10c20f816cd104b3f0da814c189957f45f5)) - - list multiple rewards in dialog - ([e48c7277](https://github.com/habitrpg/habitrpg/commits/e48c7277f8256cf827790aece51e897fe0439374)) -- **settings:** reintroduce space between captions and help bubbles stripped during localization - ([5ddf09fe](https://github.com/habitrpg/habitrpg/commits/5ddf09fe13c7f8d844c8c47be0fb8f8b2fd1df33)) -- **spells:** - - more $rootScope spell-casting bug fixes - ([47bd6dcb](https://github.com/habitrpg/habitrpg/commits/47bd6dcb79778d90d6f3ddeb003c3d8e45433333)) - - add some spells tests, don't send up body to spell paths - ([e0646bb9](https://github.com/habitrpg/habitrpg/commits/e0646bb98d44b6874b5259107c9be5fa34c58933)) - - some $rootScope.applying action fixes so cast-ending is immediate instead of waiting on response. Also, slim down party population to the essentials to avoid RequestEntityTooLarge - ([c6f7ab8a](https://github.com/habitrpg/habitrpg/commits/c6f7ab8a5c6f4e382208a928b90ba5f4eba9cd37)) - - to cancel spell-casting - ([a1df41ad](https://github.com/habitrpg/habitrpg/commits/a1df41ad8165cd9eb6d2d5d59c7fe404edde716c)) -- **stable:** show hatchable combo when petOwned>0 (fyi @deilann) - ([51bff238](https://github.com/habitrpg/habitrpg/commits/51bff23885ca0080e7e71ff752daa0950ae923ae)) -- **stats:** Better layout for attribute point allocation - ([d782fc6b](https://github.com/habitrpg/habitrpg/commits/d782fc6b6a3cd7e90d327c93a5764626b2990c74)) -- **tests:** - - include select2 in test manifest - ([38b4cea7](https://github.com/habitrpg/habitrpg/commits/38b4cea73299f51c4db7f6b2eb12533d219745f8)) - - don't use cluster in tests, else we get "connection refused" - ([7a479098](https://github.com/habitrpg/habitrpg/commits/7a479098dc6535654e322c737d80813790967941) \ No newline at end of file diff --git a/archive/CHANGELOG_ARCHIVED.md b/archive/CHANGELOG_ARCHIVED.md deleted file mode 100644 index 59950d5c4c..0000000000 --- a/archive/CHANGELOG_ARCHIVED.md +++ /dev/null @@ -1,34 +0,0 @@ -My app - Changelog -# (2015-05-08) - -## Bug Fixes - -- **Spring:** WHO IS LESLIE - ([6685e935](watch/commits/6685e93554a1274dedb55dae054e787fb80eb440)) -- **invite-friends:** text should be valid for both parties and guilds - ([54e82a14](watch/commits/54e82a14a252c3b9923449a7ef7cee6033a5d160)) -- **mystery:** It's 2015 now, Sabe - ([00252f20](watch/commits/00252f200481f06de9bccd1e55275d5366b03919)) -- **scoring:** move gainMP into score - ([2fc0cb8f](watch/commits/2fc0cb8fa1b3b5975c16653cb110be2f03b5427e)) -- **slimes:** Tweaks and missing sprite - ([7d1a58ca](watch/commits/7d1a58ca002af9dac19aba65d6465bd23b28d649)) - - -## Features - -- **Spring:** Flung - ([d50d4ad8](watch/commits/d50d4ad8bb0f89e39ceb6562e0f8f392f94b5444)) -- **emails:** add support for weekly recap emails - ([37f7db3c](watch/commits/37f7db3c4e3859d03fd55a44e63819e273a06442)) -- **i18n:** upload japanese, serbian and chinese (taiwan) - ([ee7ba19e](watch/commits/ee7ba19ed17e72b33cbef8a324266617d384f852)) -- **mystery:** April Subscribee Items - ([7a7fc968](watch/commits/7a7fc96818ffd7f92738e8c6cc8a59e48d60597d)) -- **pets:** Slime Quest - ([f13c6cba](watch/commits/f13c6cba0026c645b19a0b1355ba2c5b27f80878)) -- **quests:** Boss damage from Habits - ([43dcded0](watch/commits/43dcded051b602d8a4efc30eef45365abfd238b4)) -- **scoring:** MP gain from Habits and Dailies - ([7b22244f](watch/commits/7b22244f0123cf649c9f2aada0811f35a565688d)) - diff --git a/archive/README.md b/archive/README.md deleted file mode 100644 index a1e5cc1ee4..0000000000 --- a/archive/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# What's This? - -I'm consolidating @litenull's rewrite branch with the old code, and removing files from both sources once they've been -successfully merged into the new platform. While @litenull's "from scratch" approach was really clean, it will take -us longer to implemente all the original features. This approach will (1) let us leverage code we already have, (2) merge -in litenull's hard work from the last few weeks. - -Once this archive/ directory is completely empty, we should be fully merged and ready to deploy the rewrite! \ No newline at end of file diff --git a/archive/derby_controllers/browser.coffee b/archive/derby_controllers/browser.coffee deleted file mode 100644 index 5efa078558..0000000000 --- a/archive/derby_controllers/browser.coffee +++ /dev/null @@ -1,46 +0,0 @@ -_ = require 'lodash' -moment = require 'moment' - -### - Loads JavaScript files from public/vendor/* - Use require() to min / concatinate for faster page load -### -loadJavaScripts = (model) -> - - # Turns out you can't have expressions in browserify require() statements - #vendor = '../../public/vendor' - #require "#{vendor}/jquery-ui-1.10.2/jquery-1.9.1" - - ### - Internal Scripts - ### - require "../vendor/jquery.cookie.min.js" - require "../vendor/bootstrap/js/bootstrap.min.js" - require "../vendor/datepicker/js/bootstrap-datepicker" - require "../vendor/bootstrap-tour/bootstrap-tour" - - unless (model.get('_mobileDevice') is true) - require "../vendor/sticky" - - # note: external script loading is handled in app.on('render') near the bottom of this file (see https://groups.google.com/forum/?fromgroups=#!topic/derbyjs/x8FwdTLEuXo) - - -# jquery sticky header on scroll, no need for position fixed -initStickyHeader = (model) -> - $('.header-wrap').sticky({topSpacing:0}) - - -module.exports.app = (appExports, model, app) -> - - app.on 'render', (ctx) -> - #restoreRefs(model) - unless model.get('_mobileDevice') - setupTooltips(model) - initStickyHeader(model) - setupSortable(model) - - $('.datepicker').datepicker({autoclose:true, todayBtn:true}) - .on 'changeDate', (ev) -> - #for some reason selecting a date doesn't fire a change event on the field, meaning our changes aren't saved - model.at(ev.target).set 'date', moment(ev.date).format('MM/DD/YYYY') - diff --git a/archive/derby_controllers/challenges.coffee b/archive/derby_controllers/challenges.coffee deleted file mode 100644 index d89ebef890..0000000000 --- a/archive/derby_controllers/challenges.coffee +++ /dev/null @@ -1,239 +0,0 @@ -_ = require 'lodash' -{helpers} = require 'habitrpg-shared' -async = require 'async' - -module.exports.app = (app) -> - - ### - Sync any updates to challenges since last refresh. Do it after cron, so we don't punish them for new tasks - This is challenge->user sync. user->challenge happens when user interacts with their tasks - ### - app.on 'ready', (model) -> - window.setTimeout -> - _.each model.get('groups'), (g) -> - if (@uid in g.members) and g.challenges - _.each(g.challenges, ->app.challenges.syncChalToUser g) - true - , 500 - - ### - Sync user to challenge (when they score, add to statistics) - ### - app.model.on "change", "_page.user.priv.tasks.*.value", (id, value, previous, passed) -> - ### Sync to challenge, but do it later ### - async.nextTick => - model = app.model - ctx = {model: model} - task = model.at "_page.user.priv.tasks.#{id}" - tobj = task.get() - pub = model.get "_page.user.pub" - - if (chalTask = helpers.taskInChallenge.call ctx, tobj)? and chalTask.get() - chalTask.increment "value", value - previous - chal = model.at "groups.#{tobj.group.id}.challenges.#{tobj.challenge}" - chalUser = -> helpers.indexedAt.call(ctx, chal.path(), 'members', {id:pub.id}) - cu = chalUser() - unless cu?.get() - chal.push "members", {id: pub.id, name: model.get(pub.profile.name)} - cu = model.at chalUser() - else - cu.set 'name', pub.profile.name # update their name incase it changed - cu.set "#{tobj.type}s.#{tobj.id}", - value: tobj.value - history: tobj.history - - ### - Render graphs for user scores when the "Challenges" tab is clicked - ### - - ### - TODO - 1) on main tab click or party - * sort & render graphs for party - 2) guild -> all guilds - 3) public -> all public - ### - - - ### - $('#profile-challenges-tab-link').on 'shown', -> - async.each _.toArray(model.get('groups')), (g) -> - async.each _.toArray(g.challenges), (chal) -> - async.each _.toArray(chal.tasks), (task) -> - async.each _.toArray(chal.members), (member) -> - if (history = member?["#{task.type}s"]?[task.id]?.history) and !!history - data = google.visualization.arrayToDataTable _.map(history, (h)-> [h.date,h.value]) - options = - backgroundColor: { fill:'transparent' } - width: 150 - height: 50 - chartArea: width: '80%', height: '80%' - axisTitlePosition: 'none' - legend: position: 'bottom' - hAxis: gridlines: color: 'transparent' # since you can't seem to *remove* gridlines... - vAxis: gridlines: color: 'transparent' - chart = new google.visualization.LineChart $(".challenge-#{chal.id}-member-#{member.id}-history-#{task.id}")[0] - chart.draw(data, options) - ### - - app.fn - challenges: - - ### - Create - ### - create: (e,el) -> - [type, gid] = [$(el).attr('data-type'), $(el).attr('data-gid')] - cid = @model.id() - @model.set '_page.new.challenge', - id: cid - name: '' - habits: [] - dailys: [] - todos: [] - rewards: [] - user: - uid: @uid - name: @pub.get('profile.name') - group: {type, id:gid} - timestamp: +new Date - - ### - Save - ### - save: -> - newChal = @model.get('_page.new.challenge') - [gid, cid] = [newChal.group.id, newChal.id] - @model.push "_page.lists.challenges.#{gid}", newChal, -> - app.browser.growlNotification('Challenge Created','success') - app.challenges.discard() - app.browser.resetDom() # something is going absolutely haywire here, all model data at end of reflist after chal created - - ### - Toggle Edit - ### - toggleEdit: (e, el) -> - path = "_page.editing.challenges.#{$(el).attr('data-id')}" - @model.set path, !@model.get(path) - - ### - Discard - ### - discard: -> - @model.del '_page.new.challenge' - - ### - Delete - ### - delete: (e) -> - return unless confirm("Delete challenge, are you sure?") is true - e.at().remove() - - ### - Add challenge name as a tag for user - ### - syncChalToUser: (chal) -> - return unless chal - ### Sync tags ### - tags = @priv.get('tags') or [] - idx = _.findIndex tags, {id: chal.id} - if ~idx and (tags[idx].name isnt chal.name) - ### update the name - it's been changed since ### - @priv.set "tags.#{idx}.name", chal.name - else - @priv.push 'tags', {id: chal.id, name: chal.name, challenge: true} - - tags = {}; tags[chal.id] = true - _.each chal.habits.concat(chal.dailys.concat(chal.todos.concat(chal.rewards))), (task) => - _.defaults task, { tags, challenge: chal.id, group: {id: chal.group.id, type: chal.group.type} } - path = "tasks.#{task.id}" - if @priv.get path - @priv.set path, _.defaults(@priv.get(path), task) - else - @model.push "_page.lists.tasks.#{@uid}.#{task.type}s", task - true - - ### - Subscribe - ### - subscribe: (e) -> - chal = e.get() - ### Add all challenge's tasks to user's tasks ### - currChallenges = @pub.get('challenges') - @pub.unshift('challenges', chal.id) unless currChallenges and ~currChallenges.indexOf(chal.id) - e.at().push "members", - id: @uid - name: @pub.get('profile.name') - app.challenges.syncChalToUser(chal) - - ### - -------------------------- - Unsubscribe functions - -------------------------- - ### - - unsubscribe: (chal, keep=true) -> - - ### Remove challenge from user ### - i = @pub.get('challenges')?.indexOf(chal.id) - if i? and ~i - @pub.remove("challenges", i, 1) - - ### Remove user from challenge ### - if ~(i = _.findIndex chal.members, {id: @uid}) - @model.remove "groups.#{chal.group.id}.challenges.#{chal.id}.members", i, 1 - - ### Remove tasks from user ### - async.each chal.habits.concat(chal.dailys.concat(chal.todos.concat(chal.rewards))), (task) => - if keep is true - @priv.del "tasks.#{task.id}.challenge" - else - path = "_page.lists.tasks.#{@uid}.#{task.type}s" - if ~(i = _.findIndex(@model.get(path), {id:task.id})) - @model.remove(path, i, 1) - true - - taskUnsubscribe: (e, el) -> - - ### - since the challenge was deleted, we don't have its data to unsubscribe from - but we have the vestiges on the task - FIXME this is a really dumb way of doing this - ### - tasks = @priv.get('tasks') - tobj = tasks[$(el).attr("data-tid")] - deletedChal = - id: tobj.challenge - members: [@uid] - habits: _.where tasks, {type: 'habit', challenge: tobj.challenge} - dailys: _.where tasks, {type: 'daily', challenge: tobj.challenge} - todos: _.where tasks, {type: 'todo', challenge: tobj.challenge} - rewards: _.where tasks, {type: 'reward', challenge: tobj.challenge} - - switch $(el).attr('data-action') - when 'keep' - @priv.del "tasks.#{tobj.id}.challenge" - @priv.del "tasks.#{tobj.id}.group" - when 'keep-all' - app.challenges.unsubscribe.call @, deletedChal, true - when 'remove' - path = "_page.lists.tasks.#{@uid}.#{tobj.type}s" - if ~(i = _.findIndex @model.get(path), {id: tobj.id}) - @model.remove path, i - when 'remove-all' - app.challenges.unsubscribe.call @, deletedChal, false - - challengeUnsubscribe: (e, el) -> - $(el).popover('destroy').popover({ - html: true - placement: 'top' - trigger: 'manual' - title: 'Unsubscribe From Challenge And:' - content: """ - Remove Tasks
- Keep Tasks
- Cancel
- """ - }).popover('show') - $('.challenge-unsubscribe-and-remove').click => app.challenges.unsubscribe.call @, e.get(), false - $('.challenge-unsubscribe-and-keep').click => app.challenges.unsubscribe.call @, e.get(), true - $('[class^=challenge-unsubscribe]').click => $(el).popover('destroy') \ No newline at end of file diff --git a/archive/derby_controllers/filters.coffee b/archive/derby_controllers/filters.coffee deleted file mode 100644 index d03d8424e4..0000000000 --- a/archive/derby_controllers/filters.coffee +++ /dev/null @@ -1,22 +0,0 @@ -_ = require 'lodash' - -module.exports.app = (appExports, model) -> - user = model.at('_user') - - appExports.filtersDeleteTag = (e, el) -> - tags = user.get('tags') - tag = e.at "_user.tags." + $(el).attr('data-index') - tagId = tag.get('id') - - ###something got corrupted, let's clear the corrupt tags### - unless tagId - user.set 'tags', _.filter( tags, ((t)-> t?.id) ) - user.set 'filters', {} - return - - model.del "_user.filters.#{tagId}" - tag.remove() - - ### remove tag from all tasks### - _.each user.get("tasks"), (task) -> user.del "tasks.#{task.id}.tags.#{tagId}"; true - diff --git a/archive/derby_controllers/groups.coffee b/archive/derby_controllers/groups.coffee deleted file mode 100644 index 79992f0f6a..0000000000 --- a/archive/derby_controllers/groups.coffee +++ /dev/null @@ -1,139 +0,0 @@ -_ = require('lodash') -helpers = require('habitrpg-shared/script/helpers') - -module.exports.app = (appExports, model, app) -> - browser = require './browser' - - _currentTime = model.at '_currentTime' - _currentTime.setNull +new Date - # Every 60 seconds, reset the current time so that the chat can update relative times - setInterval (->_currentTime.set +new Date), 60000 - - appExports.groupCreate = (e,el) -> - type = $(el).attr('data-type') - newGroup = - name: model.get("_new.group.name") - description: model.get("_new.group.description") - leader: user.get('id') - members: [user.get('id')] - type: type - - # parties - free - if type is 'party' - return model.add 'groups', newGroup, ->location.reload() - - # guilds - 4G - unless user.get('balance') >= 1 - return $('#more-gems-modal').modal 'show' - if confirm "Create Guild for 4 Gems?" - newGroup.privacy = (model.get("_new.group.privacy") || 'public') if type is 'guild' - newGroup.balance = 1 # they spent $ to open the guild, it goes into their guild bank - model.add 'groups', newGroup, -> - user.incr 'balance', -1, ->location.reload() - - appExports.toggleGroupEdit = (e, el) -> - path = "_editing.groups.#{$(el).attr('data-gid')}" - model.set path, !model.get(path) - - appExports.toggleLeaderMessageEdit = (e, el) -> - path = "_editing.leaderMessage.#{$(el).attr('data-gid')}" - model.set path, !model.get(path) - - appExports.groupAddWebsite = (e, el) -> - test = e.get() - e.at().unshift 'websites', model.get('_newGroupWebsite') - model.del '_newGroupWebsite' - - appExports.groupInvite = (e,el) -> - uid = model.get('_groupInvitee').replace(/[\s"]/g, '') - model.set '_groupInvitee', '' - return if _.isEmpty(uid) - - model.query('users').publicInfo([uid]).fetch (err, profiles) -> - throw err if err - profile = profiles.at(0).get() - return model.set("_groupError", "User with id #{uid} not found.") unless profile - model.query('groups').withMember(uid).fetch (err, g) -> - throw err if err - group = e.get(); groups = g.get() - {type, name} = group; gid = group.id - groupError = (msg) -> model.set("_groupError", msg) - invite = -> - $.bootstrapGrowl "Invitation Sent." - switch type - when 'guild' then model.push "users.#{uid}.invitations.guilds", {id:gid, name}, ->location.reload() - when 'party' then model.set "users.#{uid}.invitations.party", {id:gid, name}, ->location.reload() - - switch type - when 'guild' - if profile.invitations?.guilds and _.find(profile.invitations.guilds, {id:gid}) - return groupError("User already invited to that group") - else if uid in group.members - return groupError("User already in that group") - else invite() - when 'party' - if profile.invitations?.party - return groupError("User already pending invitation.") - else if _.find(groups, {type:'party'}) - return groupError("User already in a party.") - else invite() - - - appExports.acceptInvitation = (e,el) -> - gid = e.get('id') - if $(el).attr('data-type') is 'party' - user.set 'invitations.party', null, ->joinGroup(gid) - else - e.at().remove ->joinGroup(gid) - - appExports.rejectInvitation = (e, el) -> - clear = -> browser.resetDom(model) - if e.at().path().indexOf('party') != -1 - model.del e.at().path(), clear - else e.at().remove clear - - appExports.groupLeave = (e,el) -> - if confirm("Leave this group, are you sure?") is true - uid = user.get('id') - group = model.at "groups.#{$(el).attr('data-id')}" - index = group.get('members').indexOf(uid) - if index != -1 - group.remove 'members', index, 1, -> - updated = group.get() - # last member out, delete the party - if _.isEmpty(updated.members) and (updated.type is 'party') - group.del ->location.reload() - # assign new leader, so the party is editable #TODO allow old leader to assign new leader, this is just random - else if (updated.leader is uid) - group.set "leader", updated.members[0], ->location.reload() - else location.reload() - - ### - Chat Functionality - ### - - model.on 'unshift', '_party.chat', -> $('.chat-message').tooltip() - model.on 'unshift', '_habitrpg.chat', -> $('.chat-message').tooltip() - - appExports.chatKeyup = (e, el, next) -> - return next() unless e.keyCode is 13 - appExports.sendChat(e, el) - - appExports.deleteChatMessage = (e) -> - if confirm("Delete chat message?") is true - e.at().remove() #requires the {#with} - - app.on 'render', (ctx) -> - $('#party-tab-link').on 'shown', (e) -> - messages = model.get('_party.chat') - return false unless messages?.length > 0 - model.set '_user.party.lastMessageSeen', messages[0].id - - appExports.gotoPartyChat = -> - model.set '_gamePane', true, -> - $('#party-tab-link').tab('show') - - appExports.assignGroupLeader = (e, el) -> - newLeader = model.get('_new.groupLeader') - if newLeader and (confirm("Assign new leader, you sure?") is true) - e.at().set('leader', newLeader, ->browser.resetDom(model)) if newLeader diff --git a/archive/derby_controllers/i18n.coffee b/archive/derby_controllers/i18n.coffee deleted file mode 100644 index b9ed898876..0000000000 --- a/archive/derby_controllers/i18n.coffee +++ /dev/null @@ -1,7 +0,0 @@ -i18n = require 'derby-i18n' - -i18n.plurals.add 'he', (n) -> n -i18n.plurals.add 'bg', (n) -> n -i18n.plurals.add 'nl', (n) -> n - -module.exports = i18n diff --git a/archive/derby_controllers/index.coffee b/archive/derby_controllers/index.coffee deleted file mode 100644 index e88b23c79b..0000000000 --- a/archive/derby_controllers/index.coffee +++ /dev/null @@ -1,20 +0,0 @@ -# Translations -i18n = require './i18n' -i18n.localize app, - availableLocales: ['en', 'he', 'bg', 'nl'] - defaultLocale: 'en' - urlScheme: false - checkHeader: true - - -# ========== CONTROLLER FUNCTIONS ========== - -ready (model) -> - misc.fixCorruptUser(model) # https://github.com/lefnire/habitrpg/issues/634 - - # used for things like remove website, chat, etc - exports.removeAt = (e, el) -> - if (confirmMessage = $(el).attr 'data-confirm')? - return unless confirm(confirmMessage) is true - e.at().remove() - browser.resetDom(model) if $(el).attr('data-refresh') diff --git a/archive/derby_controllers/items.coffee b/archive/derby_controllers/items.coffee deleted file mode 100644 index 9c118be29b..0000000000 --- a/archive/derby_controllers/items.coffee +++ /dev/null @@ -1,39 +0,0 @@ -items = require 'habitrpg-shared/script/items' -_ = require 'lodash' - -updateStore = (model) -> - nextItems = items.updateStore(model.get('_user')) - _.each nextItems, (v,k) -> model.set("_items.next.#{k}",v); true - -### - server exports -### -module.exports.server = (model) -> - model.set '_items', items.items - updateStore(model) - -### - app exports -### -module.exports.app = (appExports, model) -> - misc = require './misc' - - model.on "set", "_user.items.*", -> updateStore(model) - - appExports.buyItem = (e, el) -> - misc.batchTxn model, (uObj, paths) -> - ret = items.buyItem uObj, $(el).attr('data-type'), {paths} - alert("Not enough GP") if ret is false - - appExports.activateRewardsTab = -> - model.set '_activeTabRewards', true - model.set '_activeTabPets', false - appExports.activatePetsTab = -> - model.set '_activeTabPets', true - model.set '_activeTabRewards', false - - - - - - diff --git a/archive/derby_controllers/misc.coffee b/archive/derby_controllers/misc.coffee deleted file mode 100644 index 06e74249c1..0000000000 --- a/archive/derby_controllers/misc.coffee +++ /dev/null @@ -1,152 +0,0 @@ -_ = require 'lodash' -algos = require 'habitrpg-shared/script/algos' -items = require('habitrpg-shared/script/items').items -helpers = require('habitrpg-shared/script/helpers') - -#TODO put this in habitrpg-shared -### - We can't always use refLists, but we often still need to get a positional path by id: eg, users.1234.tasks.5678.value - For arrays (which use indexes, not id-paths), here's a helper function so we can run indexedPath('users',:user.id,'tasks',:task.id,'value) -### -indexedPath = -> - _.reduce arguments, (m,v) => - return v if !m #first iteration - return "#{m}.#{v}" if _.isString v #string paths - return "#{m}." + _.findIndex(@model.get(m),v) - , '' - -taskInChallenge = (task) -> - return undefined unless task?.challenge - @model.at indexedPath.call(@, "groups.#{task.group.id}.challenges", {id:task.challenge}, "#{task.type}s", {id:task.id}) - -### - algos.score wrapper for habitrpg-helpers to work in Derby. We need to do model.set() instead of simply setting the - object properties, and it's very difficult to diff the two objects and find dot-separated paths to set. So we to first - clone our user object (if we don't do that, it screws with model.on() listeners, ping Tyler for an explaination), - perform the updates while tracking paths, then all the values at those paths -### -module.exports.score = (model, taskId, direction, allowUndo=false) -> - drop = undefined - delta = batchTxn model, (uObj, paths) -> - tObj = uObj.tasks[taskId] - - # Stuff for undo - if allowUndo - tObjBefore = _.cloneDeep tObj - tObjBefore.completed = !tObjBefore.completed if tObjBefore.type in ['daily', 'todo'] - previousUndo = model.get('_undo') - clearTimeout(previousUndo.timeoutId) if previousUndo?.timeoutId - timeoutId = setTimeout (-> model.del('_undo')), 20000 - model.set '_undo', {stats:_.cloneDeep(uObj.stats), task:tObjBefore, timeoutId: timeoutId} - - delta = algos.score(uObj, tObj, direction, {paths}) - model.set('_streakBonus', uObj._tmp.streakBonus) if uObj._tmp?.streakBonus - drop = uObj._tmp?.drop - - # Update challenge statistics - # FIXME put this in it's own batchTxn, make batchTxn model.at() ref aware (not just _user) - # FIXME use reflists for users & challenges - if (chalTask = taskInChallenge.call({model}, tObj)) and chalTask?.get() - model._dontPersist = false - chalTask.incr "value", delta - chal = model.at indexedPath.call({model}, "groups.#{tObj.group.id}.challenges", {id:tObj.challenge}) - chalUser = -> indexedPath.call({model}, chal.path(), 'users', {id:uObj.id}) - cu = model.at chalUser() - unless cu?.get() - chal.push "users", {id: uObj.id, name: helpers.username(uObj.auth, uObj.profile?.name)} - cu = model.at chalUser() - else - cu.set 'name', helpers.username(uObj.auth, uObj.profile?.name) # update their name incase it changed - cu.set "#{tObj.type}s.#{tObj.id}", - value: tObj.value - history: tObj.history - model._dontPersist = true - , done:-> - if drop and $? - model.set '_drop', drop - $('#item-dropped-modal').modal 'show' - - delta - -### - Cleanup task-corruption (null tasks, rogue/invisible tasks, etc) - Obviously none of this should be happening, but we'll stop-gap until we can find & fix - Gotta love refLists! see https://github.com/lefnire/habitrpg/issues/803 & https://github.com/lefnire/habitrpg/issues/6343 -### -module.exports.fixCorruptUser = (model) -> - user = model.at('_user') - tasks = user.get('tasks') - - ## Remove corrupted tasks - _.each tasks, (task, key) -> - unless task?.id? and task?.type? - user.del("tasks.#{key}") - delete tasks[key] - true - resetDom = false - batchTxn model, (uObj, paths, batch) -> - ## fix https://github.com/lefnire/habitrpg/issues/1086 - uniqPets = _.uniq(uObj.items.pets) - batch.set('items.pets', uniqPets) if !_.isEqual(uniqPets, uObj.items.pets) - - if uObj.invitations?.guilds - uniqInvites = _.uniq(uObj.invitations.guilds) - batch.set('invitations.guilds', uniqInvites) if !_.isEqual(uniqInvites, uObj.invitations.guilds) - - ## Task List Cleanup - ['habit','daily','todo','reward'].forEach (type) -> - - # 1. remove duplicates - # 2. restore missing zombie tasks back into list - idList = uObj["#{type}Ids"] - taskIds = _.pluck( _.where(tasks, {type}), 'id') - union = _.union idList, taskIds - - # 2. remove empty (grey) tasks - preened = _.filter union, (id) -> id and _.contains(taskIds, id) - - # There were indeed issues found, set the new list - if !_.isEqual(idList, preened) - batch.set("#{type}Ids", preened) - console.error uObj.id + "'s #{type}s were corrupt." - true - resetDom = !_.isEmpty(paths) - require('./browser').resetDom(model) if resetDom - -module.exports.viewHelpers = (view) -> - - #misc - view.fn "percent", (x, y) -> - x=1 if x==0 - Math.round(x/y*100) - view.fn 'indexOf', (str1, str2) -> - return false unless str1 && str2 - str1.indexOf(str2) != -1 - view.fn "round", Math.round - view.fn "floor", Math.floor - view.fn "ceil", Math.ceil - view.fn "truarr", (num) -> num-1 - view.fn 'count', (arr) -> arr?.length or 0 - view.fn 'int', - get: (num) -> num - set: (num) -> [parseInt(num)] - view.fn 'indexedPath', indexedPath - - - #iCal - view.fn "encodeiCalLink", helpers.encodeiCalLink - - #User - view.fn "gems", (balance) -> balance * 4 - - #Challenges - view.fn 'taskInChallenge', (task) -> - taskInChallenge.call(@,task)?.get() - view.fn 'taskAttrFromChallenge', (task, attr) -> - taskInChallenge.call(@,task)?.get(attr) - view.fn 'brokenChallengeLink', (task) -> - task?.challenge and !(taskInChallenge.call(@,task)?.get()) - - view.fn 'challengeMemberScore', (member, tType, tid) -> - Math.round(member["#{tType}s"]?[tid]?.value) - diff --git a/archive/derby_controllers/pets.coffee b/archive/derby_controllers/pets.coffee deleted file mode 100644 index 46288b5164..0000000000 --- a/archive/derby_controllers/pets.coffee +++ /dev/null @@ -1,73 +0,0 @@ -_ = require 'lodash' -{ randomVal } = require 'habitrpg-shared/script/helpers' -{ pets, hatchingPotions } = require('habitrpg-shared/script/items').items - -### - app exports -### -module.exports.app = (appExports, model) -> - user = model.at '_user' - - appExports.chooseEgg = (e, el) -> - model.ref '_hatchEgg', e.at() - - appExports.hatchEgg = (e, el) -> - hatchingPotionName = $(el).children('select').val() - myHatchingPotion = user.get 'items.hatchingPotions' - egg = model.get '_hatchEgg' - eggs = user.get 'items.eggs' - myPets = user.get 'items.pets' - - hatchingPotionIdx = myHatchingPotion.indexOf hatchingPotionName - eggIdx = eggs.indexOf egg - - return alert "You don't own that hatching potion yet, complete more tasks!" if hatchingPotionIdx is -1 - return alert "You don't own that egg yet, complete more tasks!" if eggIdx is -1 - return alert "You already have that pet, hatch a different combo." if myPets and myPets.indexOf("#{egg.name}-#{hatchingPotionName}") != -1 - - user.push 'items.pets', egg.name + '-' + hatchingPotionName, -> - eggs.splice eggIdx, 1 - myHatchingPotion.splice hatchingPotionIdx, 1 - user.set 'items.eggs', eggs - user.set 'items.hatchingPotions', myHatchingPotion - - alert 'Your egg hatched! Visit your stable to equip your pet.' - - #FIXME Bug: this removes from the array properly in the browser, but on refresh is has removed all items from the arrays -# user.remove 'items.hatchingPotions', hatchingPotionIdx, 1 -# user.remove 'items.eggs', eggIdx, 1 - - appExports.choosePet = (e, el, next) -> - petStr = $(el).attr('data-pet') - - return next() if user.get('items.pets').indexOf(petStr) == -1 - # If user's pet is already active, deselect it - return user.set 'items.currentPet', {} if user.get('items.currentPet.str') is petStr - - [name, modifier] = petStr.split('-') - pet = _.find pets, {name: name} - pet.modifier = modifier - pet.str = petStr - user.set 'items.currentPet', pet - - appExports.buyHatchingPotion = (e, el) -> - name = $(el).attr 'data-hatchingPotion' - newHatchingPotion = _.find hatchingPotions, {name: name} - gems = user.get('balance') * 4 - if gems >= newHatchingPotion.value - if confirm "Buy this hatching potion with #{newHatchingPotion.value} of your #{gems} Gems?" - user.push 'items.hatchingPotions', newHatchingPotion.name - user.set 'balance', (gems - newHatchingPotion.value) / 4 - else - $('#more-gems-modal').modal 'show' - - appExports.buyEgg = (e, el) -> - name = $(el).attr 'data-egg' - newEgg = _.find pets, {name: name} - gems = user.get('balance') * 4 - if gems >= newEgg.value - if confirm "Buy this egg with #{newEgg.value} of your #{gems} Gems?" - user.push 'items.eggs', newEgg - user.set 'balance', (gems - newEgg.value) / 4 - else - $('#more-gems-modal').modal 'show' diff --git a/archive/derby_controllers/tasks.coffee b/archive/derby_controllers/tasks.coffee deleted file mode 100644 index 1a01c095e0..0000000000 --- a/archive/derby_controllers/tasks.coffee +++ /dev/null @@ -1,29 +0,0 @@ -algos = require 'habitrpg-shared/script/algos' -helpers = require 'habitrpg-shared/script/helpers' -_ = require 'lodash' -moment = require 'moment' -misc = require './misc' - - appExports.clearCompleted = (e, el) -> - completedIds = _.pluck( _.where(model.get('_todoList'), {completed:true}), 'id') - todoIds = user.get('todoIds') - _.each completedIds, (id) -> user.del "tasks.#{id}"; true - user.set 'todoIds', _.difference(todoIds, completedIds) - - - ### - Undo - ### - appExports.undo = () -> - undo = model.get '_undo' - clearTimeout(undo.timeoutId) if undo?.timeoutId - model.del '_undo' - _.each undo.stats, (val, key) -> user.set "stats.#{key}", val; true - taskPath = "tasks.#{undo.task.id}" - _.each undo.task, (val, key) -> - return true if key in ['id', 'type'] # strange bugs in this world: https://workflowy.com/shared/a53582ea-43d6-bcce-c719-e134f9bf71fd/ - if key is 'completed' - user.pass({cron:true}).set("#{taskPath}.completed",val) - else - user.set "#{taskPath}.#{key}", val - true diff --git a/archive/derby_controllers/unlock.coffee b/archive/derby_controllers/unlock.coffee deleted file mode 100644 index 73527b9d8a..0000000000 --- a/archive/derby_controllers/unlock.coffee +++ /dev/null @@ -1,95 +0,0 @@ -_ = require 'lodash' -{ randomVal } = require 'habitrpg-shared/script/helpers' -{ pets, hatchingPotions } = require('habitrpg-shared/script/items').items - -### - 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) -> !(!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 Gems (note, you replenish Gems 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) - html = """ - Be social, join a party and play Habit with your friends! You'll be better at your habits with accountability partners. Click User -> Options -> Party, and follow the instructions. 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' - - user.on 'push', 'items.pets', (after, before) -> - return if user.get('achievements.beastMaster') - if before >= 90 # evidently before is the count? - dontPersist = model._dontPersist; model._dontPersist = false - user.set 'achievements.beastMaster', true, (-> model._dontPersist = dontPersist) - $('#beastmaster-achievement-modal').modal('show') - - user.on 'set', 'items.*', (after, before) -> - return if user.get('achievements.ultimateGear') - items = user.get('items') - if parseInt(items.weapon) >= 6 and parseInt(items.armor) >= 5 and parseInt(items.head) >= 5 and parseInt(items.shield) >= 5 - dontPersist = model._dontPersist; model._dontPersist = false - user.set 'achievements.ultimateGear', true, (->model._dontPersist = dontPersist) - $('#max-gear-achievement-modal').modal('show') - - user.on 'set', 'tasks.*.streak', (id, after, before) -> - if after > 0 - - # 21-day streak, as per the old philosophy of doign a thing 21-days in a row makes a habit - if (after % 21) is 0 - dontPersist = model._dontPersist; model._dontPersist = false - user.incr 'achievements.streak', 1, (-> model._dontPersist = dontPersist) - $('#streak-achievement-modal').modal('show') - - # they're undoing a task at the 21 mark, take back their badge - else if (before - after is 1) and (before % 21 is 0) - dontPersist = model._dontPersist; model._dontPersist = false - user.incr 'achievements.streak', -1, (-> model._dontPersist = dontPersist) diff --git a/newrelic.js b/newrelic.js deleted file mode 100644 index 682f608e42..0000000000 --- a/newrelic.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * New Relic agent configuration. - * - * See lib/config.defaults.js in the agent distribution for a more complete - * description of configuration variables and their potential values. - */ -var nconf = require('nconf') -exports.config = { - /** - * Array of application names. - */ - app_name : ['HabitRPG'], - /** - * Your New Relic license key. - */ - license_key : nconf.get('NEW_RELIC_LICENSE_KEY'), - logging : { - /** - * Level at which to log. 'trace' is most useful to New Relic when diagnosing - * issues with the agent, 'info' and higher will impose the least overhead on - * production applications. - */ - level : 'warning' - } -}; diff --git a/validate-commit-msg.js b/validate-commit-msg.js deleted file mode 100755 index 56becc5136..0000000000 --- a/validate-commit-msg.js +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env node - -/** - * Git COMMIT-MSG hook for validating commit message - * From: https://github.com/angular/angular.js - * See https://docs.google.com/document/d/1rk04jEuGfk9kYzfqCuOlPTSJw3hEDZJTBN5E5f1SALo/edit - * - * Installation: - * >> cd - * >> ln -s ../../validate-commit-msg.js .git/hooks/commit-msg - */ -var fs = require('fs'); -var util = require('util'); - - -var MAX_LENGTH = 999; -var PATTERN = /^(?:fixup!\s*)?(\w*)(\(([\w\$\.\-\*/]*)\))?\: (.*)$/; -var IGNORED = /^WIP\:/; -var TYPES = { - feat: true, - fix: true, - docs: true, - style: true, - refactor: true, - perf: true, - test: true, - chore: true, - revert: true, - 'interface': true, - i18n: true -}; - - -var error = function() { - // gitx does not display it - // http://gitx.lighthouseapp.com/projects/17830/tickets/294-feature-display-hook-error-message-when-hook-fails - // https://groups.google.com/group/gitx/browse_thread/thread/a03bcab60844b812 - console.error('INVALID COMMIT MSG: ' + util.format.apply(null, arguments)); -}; - - -var validateMessage = function(message) { - var isValid = true; - - if (IGNORED.test(message)) { - console.log('Commit message validation ignored.'); - return true; - } - - if (message.length > MAX_LENGTH) { - error('is longer than %d characters !', MAX_LENGTH); - isValid = false; - } - - var match = PATTERN.exec(message); - - if (!match) { - error('does not match "(): " ! was: ' + message); - return false; - } - - var type = match[1]; - var scope = match[3]; - var subject = match[4]; - - if (!TYPES.hasOwnProperty(type)) { - error('"%s" is not allowed type !', type); - return false; - } - - // Some more ideas, do want anything like this ? - // - allow only specific scopes (eg. fix(docs) should not be allowed ? - // - auto correct the type to lower case ? - // - auto correct first letter of the subject to lower case ? - // - auto add empty line after subject ? - // - auto remove empty () ? - // - auto correct typos in type ? - // - store incorrect messages, so that we can learn - - return isValid; -}; - - -var firstLineFromBuffer = function(buffer) { - return buffer.toString().split('\n').shift(); -}; - - - -// publish for testing -exports.validateMessage = validateMessage; - -// hacky start if not run by jasmine :-D -if (process.argv.join('').indexOf('jasmine-node') === -1) { - var commitMsgFile = process.argv[2]; - var incorrectLogFile = commitMsgFile.replace('COMMIT_EDITMSG', 'logs/incorrect-commit-msgs'); - - fs.readFile(commitMsgFile, function(err, buffer) { - var msg = firstLineFromBuffer(buffer); - - if (!validateMessage(msg)) { - fs.appendFile(incorrectLogFile, msg + '\n', function() { - process.exit(1); - }); - } else { - process.exit(0); - } - }); -} diff --git a/validate-commit-msg.spec.js b/validate-commit-msg.spec.js deleted file mode 100644 index 4edbfdea5f..0000000000 --- a/validate-commit-msg.spec.js +++ /dev/null @@ -1,71 +0,0 @@ -describe('validate-commit-msg.js', function() { - var m = require('./validate-commit-msg'); - var errors = []; - var logs = []; - - var VALID = true; - var INVALID = false; - - beforeEach(function() { - errors.length = 0; - logs.length = 0; - - spyOn(console, 'error').andCallFake(function(msg) { - errors.push(msg.replace(/\x1B\[\d+m/g, '')); // uncolor - }); - - spyOn(console, 'log').andCallFake(function(msg) { - logs.push(msg.replace(/\x1B\[\d+m/g, '')); // uncolor - }); - }); - - describe('validateMessage', function() { - - it('should be valid', function() { - expect(m.validateMessage('fixup! fix($compile): something')).toBe(VALID); - expect(m.validateMessage('fix($compile): something')).toBe(VALID); - expect(m.validateMessage('feat($location): something')).toBe(VALID); - expect(m.validateMessage('docs($filter): something')).toBe(VALID); - expect(m.validateMessage('style($http): something')).toBe(VALID); - expect(m.validateMessage('refactor($httpBackend): something')).toBe(VALID); - expect(m.validateMessage('test($resource): something')).toBe(VALID); - expect(m.validateMessage('chore($controller): something')).toBe(VALID); - expect(m.validateMessage('chore(foo-bar): something')).toBe(VALID); - expect(m.validateMessage('chore(*): something')).toBe(VALID); - expect(m.validateMessage('chore(guide/location): something')).toBe(VALID); - expect(m.validateMessage('revert(foo): something')).toBe(VALID); - expect(m.validateMessage('i18n(translate): something')).toBe(VALID); - expect(m.validateMessage('interface(ui-change): something')).toBe(VALID); - expect(errors).toEqual([]); - }); - - - it('should validate "(): " format', function() { - var msg = 'not correct format'; - - expect(m.validateMessage(msg)).toBe(INVALID); - expect(errors).toEqual(['INVALID COMMIT MSG: does not match "(): " ! was: not correct format']); - }); - - - it('should validate type', function() { - expect(m.validateMessage('weird($filter): something')).toBe(INVALID); - expect(errors).toEqual(['INVALID COMMIT MSG: "weird" is not allowed type !']); - }); - - - it('should allow empty scope', function() { - expect(m.validateMessage('fix: blablabla')).toBe(VALID); - }); - - - it('should allow dot in scope', function() { - expect(m.validateMessage('chore(mocks.$httpBackend): something')).toBe(VALID); - }); - - - it('should ignore msg prefixed with "WIP: "', function() { - expect(m.validateMessage('WIP: bullshit')).toBe(VALID); - }); - }); -});