diff --git a/assets/js/app.coffee b/assets/js/app.coffee deleted file mode 100644 index 918c5aed89..0000000000 --- a/assets/js/app.coffee +++ /dev/null @@ -1,12 +0,0 @@ -"use strict" - -### -The main HabitRPG app module. - -@type {angular.Module} -### - -# .constant('API_URL', 'https://beta.habitrpg.com') -# userServices handles redirect to /login if not authenticated -window.habitrpg = angular.module('habitrpg', ['userServices', 'sharedServices', 'authServices', 'notificationServices', 'ui.bootstrap']) - .constant("API_URL", "") diff --git a/assets/js/app.js b/assets/js/app.js new file mode 100644 index 0000000000..fb13c5ec5e --- /dev/null +++ b/assets/js/app.js @@ -0,0 +1,4 @@ +"use strict"; + +window.habitrpg = angular.module('habitrpg', ['userServices', 'sharedServices', 'authServices', 'notificationServices', 'ui.bootstrap']) + .constant("API_URL", ""); diff --git a/assets/js/controllers/authCtrl.coffee b/assets/js/controllers/authCtrl.coffee deleted file mode 100644 index 9dc3011a00..0000000000 --- a/assets/js/controllers/authCtrl.coffee +++ /dev/null @@ -1,53 +0,0 @@ -"use strict" - -### -The authentication controller (login & facebook) -### -habitrpg.controller "AuthCtrl", ($scope, $rootScope, Facebook, LocalAuth, User, $http, $location, API_URL) -> - $scope.useUUID = false - $scope.toggleUUID = -> - if showedFacebookMessage is false - alert "Until we add Facebook, use your UUID and API Token to log in (found at https://habitrpg.com > Options > Settings)." - showedFacebookMessage = true - $scope.useUUID = not $scope.useUUID - - $scope.logout = -> - localStorage.clear() - location.reload() - - runAuth = (id, token) -> - User.authenticate id, token, (err) -> - $rootScope.modals.login = false - - $scope.register = -> - #TODO highlight invalid inputs - # we have this as a workaround for https://github.com/HabitRPG/habitrpg-mobile/issues/64 - return if $scope.registrationForm.$invalid - $http.post(API_URL + "/api/v1/register", $scope.registerVals).success((data, status, headers, config) -> - runAuth data.id, data.apiToken - ).error (data, status, headers, config) -> - if status is 0 - alert "Server not currently reachable, try again later" - else if !!data and !!data.err - alert data.err - else - alert "ERROR: " + status - - $scope.auth = -> - data = - username: $scope.loginUsername - password: $scope.loginPassword - - if $scope.useUUID - runAuth $scope.loginUsername, $scope.loginPassword - else - $http.post(API_URL + "/api/v1/user/auth/local", data) - .success((data, status, headers, config) -> - runAuth data.id, data.token - ).error (data, status, headers, config) -> - if status is 0 - alert "Server not currently reachable, try again later" - else if !!data and !!data.err - alert data.err - else - alert "ERROR: " + status diff --git a/assets/js/controllers/authCtrl.js b/assets/js/controllers/authCtrl.js new file mode 100644 index 0000000000..021453293e --- /dev/null +++ b/assets/js/controllers/authCtrl.js @@ -0,0 +1,68 @@ +"use strict"; + +/* + The authentication controller (login & facebook) + */ + +habitrpg.controller("AuthCtrl", function($scope, $rootScope, Facebook, LocalAuth, User, $http, $location, API_URL) { + var runAuth; + var showedFacebookMessage; + $scope.useUUID = false; + $scope.toggleUUID = function() { + if (showedFacebookMessage === false) { + alert("Until we add Facebook, use your UUID and API Token to log in (found at https://habitrpg.com > Options > Settings)."); + showedFacebookMessage = true; + } + return $scope.useUUID = !$scope.useUUID; + }; + $scope.logout = function() { + localStorage.clear(); + return location.reload(); + }; + runAuth = function(id, token) { + return User.authenticate(id, token, function(err) { + return $rootScope.modals.login = false; + }); + }; + $scope.register = function() { + /*TODO highlight invalid inputs + we have this as a workaround for https://github.com/HabitRPG/habitrpg-mobile/issues/64 + */ + if ($scope.registrationForm.$invalid) { + return; + } + return $http.post(API_URL + "/api/v1/register", $scope.registerVals).success(function(data, status, headers, config) { + return runAuth(data.id, data.apiToken); + }).error(function(data, status, headers, config) { + if (status === 0) { + return alert("Server not currently reachable, try again later"); + } else if (!!data && !!data.err) { + return alert(data.err); + } else { + return alert("ERROR: " + status); + } + }); + }; + return $scope.auth = function() { + var data; + data = { + username: $scope.loginUsername, + password: $scope.loginPassword + }; + if ($scope.useUUID) { + return runAuth($scope.loginUsername, $scope.loginPassword); + } else { + return $http.post(API_URL + "/api/v1/user/auth/local", data).success(function(data, status, headers, config) { + return runAuth(data.id, data.token); + }).error(function(data, status, headers, config) { + if (status === 0) { + return alert("Server not currently reachable, try again later"); + } else if (!!data && !!data.err) { + return alert(data.err); + } else { + return alert("ERROR: " + status); + } + }); + } + }; +}); diff --git a/assets/js/controllers/taskDetailsCtrl.coffee b/assets/js/controllers/taskDetailsCtrl.coffee deleted file mode 100644 index abedc67664..0000000000 --- a/assets/js/controllers/taskDetailsCtrl.coffee +++ /dev/null @@ -1,35 +0,0 @@ -"use strict" -habitrpg.controller "TaskDetailsCtrl", ($scope, $rootScope, $location, User) -> - - $scope.save = (task) -> - setVal = (k, v) -> - if typeof v isnt "undefined" - op = {op: "set", data: {}} - op.data["tasks." + task.id + "." + k] = v - log.push op - log = [] - setVal "text", task.text - setVal "notes", task.notes - setVal "priority", task.priority - if task.type is "habit" - setVal "up", task.up - setVal "down", task.down - else if task.type is "daily" - setVal "repeat", task.repeat - setVal "streak", task.streak # TODO we'll remove this once rewrite's running for a while. This was a patch for derby issues - # _.each(task.repeat, function(v, k) { - # setVal("repeat." + k, v); - # }) - else if task.type is "todo" - setVal "date", task.date - else setVal "value", task.value if task.type is "reward" - User.log log - task._editing = false - - $scope.cancel = -> - # reset $scope.task to $scope.originalTask - for key of $scope.task - $scope.task[key] = $scope.originalTask[key] - $scope.originalTask = null - $scope.editedTask = null - $scope.editing = false diff --git a/assets/js/controllers/taskDetailsCtrl.js b/assets/js/controllers/taskDetailsCtrl.js new file mode 100644 index 0000000000..4bc5661c5c --- /dev/null +++ b/assets/js/controllers/taskDetailsCtrl.js @@ -0,0 +1,57 @@ +"use strict"; + +habitrpg.controller("TaskDetailsCtrl", function($scope, $rootScope, $location, User) { + $scope.save = function(task) { + var log, setVal; + setVal = function(k, v) { + var op; + if (typeof v !== "undefined") { + op = { + op: "set", + data: {} + }; + op.data["tasks." + task.id + "." + k] = v; + return log.push(op); + } + }; + log = []; + setVal("text", task.text); + setVal("notes", task.notes); + setVal("priority", task.priority); + if (task.type === "habit") { + setVal("up", task.up); + setVal("down", task.down); + } else if (task.type === "daily") { + setVal("repeat", task.repeat); + /* TODO we'll remove this once rewrite's running for a while. This was a patch for derby issues + */ + + setVal("streak", task.streak); + /* _.each(task.repeat, function(v, k) { + setVal("repeat." + k, v); + }) + */ + + } else if (task.type === "todo") { + setVal("date", task.date); + } else { + if (task.type === "reward") { + setVal("value", task.value); + } + } + User.log(log); + return task._editing = false; + }; + return $scope.cancel = function() { + /* reset $scope.task to $scope.originalTask + */ + + var key; + for (key in $scope.task) { + $scope.task[key] = $scope.originalTask[key]; + } + $scope.originalTask = null; + $scope.editedTask = null; + return $scope.editing = false; + }; +}); diff --git a/assets/js/controllers/tasksCtrl.coffee b/assets/js/controllers/tasksCtrl.coffee deleted file mode 100644 index 62634ea184..0000000000 --- a/assets/js/controllers/tasksCtrl.coffee +++ /dev/null @@ -1,102 +0,0 @@ -"use strict" -habitrpg.controller "TasksCtrl", ($scope, $rootScope, $location, User, Algos, Helpers, Notification) -> - - #FIXME - $scope.taskLists = [ - {header: 'Habits', type: 'habit', placeHolder: 'New Habit', main:true, editable:true} - {header: 'Dailies', type: 'daily', placeHolder: 'New Daily', main:true, editable:true} - {header: 'Todos', type: 'todo', placeHolder: 'New Todo', main:true, editable:true} - {header: 'Reward', type: 'reward', placeHolder: 'New Reward', main:true, editable:true} - ] - - $scope.score = (task, direction) -> - - #save current stats to compute the difference after scoring. - statsDiff = {} - oldStats = _.clone(User.user.stats) - Algos.score User.user, task, direction - - #compute the stats change. - _.each oldStats, (value, key) -> - newValue = User.user.stats[key] - statsDiff[key] = newValue - value if newValue isnt value - - #notify user if there are changes in stats. - if Object.keys(statsDiff).length > 0 - Notification.push - type: "stats" - stats: statsDiff - - if task.type is "reward" and _.isEmpty(statsDiff) - Notification.push - type: "text" - text: "Not enough GP." - - User.log - op: "score" - data: task - dir: direction - - $scope.addTask = (text) -> - newTask = window.habitrpgShared.helpers.taskDefaults({text}) - User.user[newTask.type + "s"].unshift newTask - # $scope.showedTasks.unshift newTask # FIXME what's thiss? - User.log - op: "addTask" - data: newTask - delete $scope.list.newTask - - #Add the new task to the actions log - $scope.clearDoneTodos = -> - - $scope.changeCheck = (task) -> - # This is calculated post-change, so task.completed=true if they just checked it - if task.completed - $scope.score task, "up" - else - $scope.score task, "down" - - # TODO this should be somewhere else, but fits the html location better here - $rootScope.revive = -> - window.habitrpgShared.algos.revive User.user - User.log op: "revive" - - $scope.remove = (task) -> - return unless confirm("Are you sure you want to delete this task?") is true - tasks = User.user[task.type + "s"] - User.log {op: "delTask", data: task} - tasks.splice(tasks.indexOf(task), 1) - - ### - ------------------------ - Items - ------------------------ - ### - $scope.$watch "user.items", -> - updated = window.habitrpgShared.items.updateStore(User.user) - # Figure out whether we wanna put this in habitrpg-shared - sorted = [ - updated.weapon - updated.armor - updated.head - updated.shield - updated.potion - updated.reroll - ] - $scope.itemStore = sorted - - $scope.buy = (type) -> - hasEnough = window.habitrpgShared.items.buyItem(User.user, type) - if hasEnough - User.log - op: "buy" - type: type - - Notification.push - type: "text" - text: "Item bought!" - - else - Notification.push - type: "text" - text: "Not enough GP." diff --git a/assets/js/controllers/tasksCtrl.js b/assets/js/controllers/tasksCtrl.js new file mode 100644 index 0000000000..02c8ce0c81 --- /dev/null +++ b/assets/js/controllers/tasksCtrl.js @@ -0,0 +1,155 @@ +"use strict"; + +habitrpg.controller("TasksCtrl", function($scope, $rootScope, $location, User, Algos, Helpers, Notification) { + /*FIXME + */ + $scope.taskLists = [ + { + header: 'Habits', + type: 'habit', + placeHolder: 'New Habit', + main: true, + editable: true + }, { + header: 'Dailies', + type: 'daily', + placeHolder: 'New Daily', + main: true, + editable: true + }, { + header: 'Todos', + type: 'todo', + placeHolder: 'New Todo', + main: true, + editable: true + }, { + header: 'Reward', + type: 'reward', + placeHolder: 'New Reward', + main: true, + editable: true + } + ]; + $scope.score = function(task, direction) { + /*save current stats to compute the difference after scoring. + */ + + var oldStats, statsDiff; + statsDiff = {}; + oldStats = _.clone(User.user.stats); + Algos.score(User.user, task, direction); + /*compute the stats change. + */ + + _.each(oldStats, function(value, key) { + var newValue; + newValue = User.user.stats[key]; + if (newValue !== value) { + return statsDiff[key] = newValue - value; + } + }); + /*notify user if there are changes in stats. + */ + + if (Object.keys(statsDiff).length > 0) { + Notification.push({ + type: "stats", + stats: statsDiff + }); + } + if (task.type === "reward" && _.isEmpty(statsDiff)) { + Notification.push({ + type: "text", + text: "Not enough GP." + }); + } + return User.log({ + op: "score", + data: task, + dir: direction + }); + }; + $scope.addTask = function(text) { + var newTask; + newTask = window.habitrpgShared.helpers.taskDefaults({ + text: text + }); + User.user[newTask.type + "s"].unshift(newTask); + /* $scope.showedTasks.unshift newTask # FIXME what's thiss? + */ + + User.log({ + op: "addTask", + data: newTask + }); + return delete $scope.list.newTask; + }; + /*Add the new task to the actions log + */ + + $scope.clearDoneTodos = function() {}; + $scope.changeCheck = function(task) { + /* This is calculated post-change, so task.completed=true if they just checked it + */ + if (task.completed) { + return $scope.score(task, "up"); + } else { + return $scope.score(task, "down"); + } + }; + /* TODO this should be somewhere else, but fits the html location better here + */ + + $rootScope.revive = function() { + window.habitrpgShared.algos.revive(User.user); + return User.log({ + op: "revive" + }); + }; + $scope.remove = function(task) { + var tasks; + if (confirm("Are you sure you want to delete this task?") !== true) { + return; + } + tasks = User.user[task.type + "s"]; + User.log({ + op: "delTask", + data: task + }); + return tasks.splice(tasks.indexOf(task), 1); + }; + /* + ------------------------ + Items + ------------------------ + */ + + $scope.$watch("user.items", function() { + var sorted, updated; + updated = window.habitrpgShared.items.updateStore(User.user); + /* Figure out whether we wanna put this in habitrpg-shared + */ + + sorted = [updated.weapon, updated.armor, updated.head, updated.shield, updated.potion, updated.reroll]; + return $scope.itemStore = sorted; + }); + return $scope.buy = function(type) { + var hasEnough; + hasEnough = window.habitrpgShared.items.buyItem(User.user, type); + if (hasEnough) { + User.log({ + op: "buy", + type: type + }); + return Notification.push({ + type: "text", + text: "Item bought!" + }); + } else { + return Notification.push({ + type: "text", + text: "Not enough GP." + }); + } + }; +}); diff --git a/assets/js/controllers/userAvatarCtrl.coffee b/assets/js/controllers/userAvatarCtrl.coffee deleted file mode 100644 index 00b00d9ede..0000000000 --- a/assets/js/controllers/userAvatarCtrl.coffee +++ /dev/null @@ -1,37 +0,0 @@ -"use strict" -habitrpg.controller "UserAvatarCtrl", ($scope, $location, filterFilter, User) -> - $scope.profile = User.user - $scope.changeHair = (color) -> - User.user.preferences.hair = color - User.log - op: "set" - data: - "preferences.hair": color - - - $scope.changeSkin = (color) -> - User.user.preferences.skin = color - User.log - op: "set" - data: - "preferences.skin": color - - - $scope.changeSex = (gender) -> - User.user.preferences.gender = gender - User.log - op: "set" - data: - "preferences.gender": gender - - - $scope.changeArmor = (armor) -> - User.user.preferences.armorSet = armor - User.log - op: "set" - data: - "preferences.armorSet": armor - - - $scope.hideUserAvatar = -> - $(".userAvatar").hide() \ No newline at end of file diff --git a/assets/js/services/notificationServices.coffee b/assets/js/services/notificationServices.coffee deleted file mode 100644 index 46a46b16c7..0000000000 --- a/assets/js/services/notificationServices.coffee +++ /dev/null @@ -1,59 +0,0 @@ -angular.module("notificationServices", []).factory "Notification", -> - #FIXME - - fixMe = - push: -> - get: -> - animate: -> - clearTimer: -> - init: -> - return fixMe - - data = message: "" - active = false - timer = null - hide: -> - $("#notification").fadeOut -> - $("#notification").css "webkit-transform", "none" - $("#notification").css "top", "-63px" - $("#notification").css "left", "0px" - setTimeout (-> - $("#notification").show() - ), 190 - - active = false - timer = null - - animate: -> - if timer - clearTimeout timer - timer = setTimeout(@hide, 2000) - if active is false - active = true - $("#notification").transition - y: 63 - x: 0 - - timer = setTimeout(@hide, 2000) - - push: (message) -> - data.message = "" - switch message.type - when "stats" - data.message = "Experience: " + message.stats.exp + "
GP: " + message.stats.gp.toFixed(2) if message.stats.exp? and message.stats.gp? - data.message = "HP: " + message.stats.hp.toFixed(2) if message.stats.hp - data.message = "
GP: " + message.stats.gp.toFixed(2) if message.stats.gp and not message.stats.exp? - when "text" - data.message = message.text - @animate() - - get: -> - data - - clearTimer: -> - clearTimeout timer - timer = null - active = false - - init: -> - timer = setTimeout(@hide, 2000) diff --git a/assets/js/services/notificationServices.js b/assets/js/services/notificationServices.js new file mode 100644 index 0000000000..0b18005699 --- /dev/null +++ b/assets/js/services/notificationServices.js @@ -0,0 +1,75 @@ + +angular.module("notificationServices", []).factory("Notification", function() { + var active, data, fixMe, timer; + fixMe = { + push: function() {}, + get: function() {}, + animate: function() {}, + clearTimer: function() {}, + init: function() {} + }; + return fixMe; + data = { + message: "" + }; + active = false; + timer = null; + return { + hide: function() { + $("#notification").fadeOut(function() { + $("#notification").css("webkit-transform", "none"); + $("#notification").css("top", "-63px"); + $("#notification").css("left", "0px"); + return setTimeout((function() { + return $("#notification").show(); + }), 190); + }); + active = false; + return timer = null; + }, + animate: function() { + if (timer) { + clearTimeout(timer); + timer = setTimeout(this.hide, 2000); + } + if (active === false) { + active = true; + $("#notification").transition({ + y: 63, + x: 0 + }); + return timer = setTimeout(this.hide, 2000); + } + }, + push: function(message) { + data.message = ""; + switch (message.type) { + case "stats": + if ((message.stats.exp != null) && (message.stats.gp != null)) { + data.message = "Experience: " + message.stats.exp + "
GP: " + message.stats.gp.toFixed(2); + } + if (message.stats.hp) { + data.message = "HP: " + message.stats.hp.toFixed(2); + } + if (message.stats.gp && !(message.stats.exp != null)) { + data.message = "
GP: " + message.stats.gp.toFixed(2); + } + break; + case "text": + data.message = message.text; + } + return this.animate(); + }, + get: function() { + return data; + }, + clearTimer: function() { + clearTimeout(timer); + timer = null; + return active = false; + }, + init: function() { + return timer = setTimeout(this.hide, 2000); + } + }; +});