rewrite2 all client-side scripts now back to JS. will tackle the api &

habitrpg-shared another day
This commit is contained in:
Tyler Renelle 2013-08-27 20:07:28 -04:00
parent aedb90176d
commit 3c11f76998
11 changed files with 359 additions and 298 deletions

View file

@ -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", "")

4
assets/js/app.js Normal file
View file

@ -0,0 +1,4 @@
"use strict";
window.habitrpg = angular.module('habitrpg', ['userServices', 'sharedServices', 'authServices', 'notificationServices', 'ui.bootstrap'])
.constant("API_URL", "");

View file

@ -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

View file

@ -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);
}
});
}
};
});

View file

@ -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

View file

@ -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;
};
});

View file

@ -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."

View file

@ -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."
});
}
};
});

View file

@ -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()

View file

@ -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 + "<br />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 = "<br />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)

View file

@ -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 + "<br />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 = "<br />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);
}
};
});