rewrite2 big one: add ngRoute for /#/tasks & /#/options. requires 2

/partial routes on server. code cleanup & reorganization, remove a lot
of return statements (coffeescript compiled)
This commit is contained in:
Tyler Renelle 2013-08-27 21:13:05 -04:00
parent 0cb73505c8
commit 7bfaac80a7
27 changed files with 224 additions and 146 deletions

View file

@ -63,19 +63,5 @@ module.exports.app = (appExports, model) ->
sites.splice(i,1)
user.set 'profile.websites', sites
toggleGamePane = ->
model.set '_gamePane', !model.get('_gamePane'), ->
browser.setupTooltips()
appExports.clickAvatar = (e, el) ->
uid = $(el).attr('data-uid')
if uid is model.get('_userId') # clicked self
toggleGamePane()
else
$("#avatar-modal-#{uid}").modal('show')
appExports.toggleGamePane = -> toggleGamePane()
appExports.toggleResting = ->
model.set '_user.flags.rest', !model.get('_user.flags.rest')

View file

@ -1,4 +1,12 @@
"use strict";
window.habitrpg = angular.module('habitrpg', ['userServices', 'sharedServices', 'authServices', 'notificationServices', 'ui.bootstrap'])
.constant("API_URL", "");
window.habitrpg = angular.module('habitrpg', ['ngRoute', 'userServices', 'sharedServices', 'authServices', 'notificationServices', 'ui.bootstrap'])
.constant("API_URL", "")
.config(['$routeProvider', function($routeProvider) {
$routeProvider
//.when('/login', {templateUrl: 'views/login.html'})
.when('/tasks', {templateUrl: 'partials/tasks'})
.when('/options', {templateUrl: 'partials/options'})
.otherwise({redirectTo: '/tasks'});
}])

View file

@ -13,15 +13,15 @@ habitrpg.controller("AuthCtrl", function($scope, $rootScope, Facebook, LocalAuth
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.useUUID = !$scope.useUUID;
};
$scope.logout = function() {
localStorage.clear();
return location.reload();
location.reload();
};
runAuth = function(id, token) {
return User.authenticate(id, token, function(err) {
return $rootScope.modals.login = false;
User.authenticate(id, token, function(err) {
$rootScope.modals.login = false;
});
};
$scope.register = function() {
@ -31,36 +31,36 @@ habitrpg.controller("AuthCtrl", function($scope, $rootScope, Facebook, LocalAuth
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);
$http.post(API_URL + "/api/v1/register", $scope.registerVals).success(function(data, status, headers, config) {
runAuth(data.id, data.apiToken);
}).error(function(data, status, headers, config) {
if (status === 0) {
return alert("Server not currently reachable, try again later");
alert("Server not currently reachable, try again later");
} else if (!!data && !!data.err) {
return alert(data.err);
alert(data.err);
} else {
return alert("ERROR: " + status);
alert("ERROR: " + status);
}
});
};
return $scope.auth = function() {
$scope.auth = function() {
var data;
data = {
username: $scope.loginUsername,
password: $scope.loginPassword
};
if ($scope.useUUID) {
return runAuth($scope.loginUsername, $scope.loginPassword);
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);
$http.post(API_URL + "/api/v1/user/auth/local", data).success(function(data, status, headers, config) {
runAuth(data.id, data.token);
}).error(function(data, status, headers, config) {
if (status === 0) {
return alert("Server not currently reachable, try again later");
alert("Server not currently reachable, try again later");
} else if (!!data && !!data.err) {
return alert(data.err);
alert(data.err);
} else {
return alert("ERROR: " + status);
alert("ERROR: " + status);
}
});
}

View file

@ -11,13 +11,13 @@ habitrpg.controller('MenuCtrl',
function($scope, $rootScope, $location, User) {
//FIXME where to implement this in rewrite?
$scope.refreshing = function () {
return User.settings.fetching ? "spin" : ""
User.settings.fetching ? "spin" : ""
};
$scope.queueLength = function () {
return User.settings.sync.queue.length || User.settings.sync.sent.length
User.settings.sync.queue.length || User.settings.sync.sent.length
};
}

View file

@ -4,10 +4,10 @@ habitrpg.controller('StatsCtrl',
['$scope', 'User',
function($scope, User) {
$scope.refreshing = function () {
return User.settings.fetching ? "spin" : ""
User.settings.fetching ? "spin" : ""
};
$scope.queueLength = function () {
return User.settings.sync.queue.length || User.settings.sync.sent.length
User.settings.sync.queue.length || User.settings.sync.sent.length
};
$scope.stats = User.user.stats;
}

View file

@ -40,9 +40,9 @@ habitrpg.controller("TaskDetailsCtrl", function($scope, $rootScope, $location, U
}
}
User.log(log);
return task._editing = false;
task._editing = false;
};
return $scope.cancel = function() {
$scope.cancel = function() {
/* reset $scope.task to $scope.originalTask
*/
@ -52,6 +52,6 @@ habitrpg.controller("TaskDetailsCtrl", function($scope, $rootScope, $location, U
}
$scope.originalTask = null;
$scope.editedTask = null;
return $scope.editing = false;
$scope.editing = false;
};
});

View file

@ -45,7 +45,7 @@ habitrpg.controller("TasksCtrl", function($scope, $rootScope, $location, User, A
var newValue;
newValue = User.user.stats[key];
if (newValue !== value) {
return statsDiff[key] = newValue - value;
statsDiff[key] = newValue - value;
}
});
/*notify user if there are changes in stats.
@ -63,7 +63,7 @@ habitrpg.controller("TasksCtrl", function($scope, $rootScope, $location, User, A
text: "Not enough GP."
});
}
return User.log({
User.log({
op: "score",
data: task,
dir: direction
@ -82,7 +82,7 @@ habitrpg.controller("TasksCtrl", function($scope, $rootScope, $location, User, A
op: "addTask",
data: newTask
});
return delete $scope.list.newTask;
delete $scope.list.newTask;
};
/*Add the new task to the actions log
*/
@ -92,9 +92,9 @@ habitrpg.controller("TasksCtrl", function($scope, $rootScope, $location, User, A
/* This is calculated post-change, so task.completed=true if they just checked it
*/
if (task.completed) {
return $scope.score(task, "up");
$scope.score(task, "up");
} else {
return $scope.score(task, "down");
$scope.score(task, "down");
}
};
/* TODO this should be somewhere else, but fits the html location better here
@ -102,7 +102,7 @@ habitrpg.controller("TasksCtrl", function($scope, $rootScope, $location, User, A
$rootScope.revive = function() {
window.habitrpgShared.algos.revive(User.user);
return User.log({
User.log({
op: "revive"
});
};
@ -116,7 +116,7 @@ habitrpg.controller("TasksCtrl", function($scope, $rootScope, $location, User, A
op: "delTask",
data: task
});
return tasks.splice(tasks.indexOf(task), 1);
tasks.splice(tasks.indexOf(task), 1);
};
/*
------------------------
@ -131,9 +131,9 @@ habitrpg.controller("TasksCtrl", function($scope, $rootScope, $location, User, A
*/
sorted = [updated.weapon, updated.armor, updated.head, updated.shield, updated.potion, updated.reroll];
return $scope.itemStore = sorted;
$scope.itemStore = sorted;
});
return $scope.buy = function(type) {
$scope.buy = function(type) {
var hasEnough;
hasEnough = window.habitrpgShared.items.buyItem(User.user, type);
if (hasEnough) {
@ -141,12 +141,12 @@ habitrpg.controller("TasksCtrl", function($scope, $rootScope, $location, User, A
op: "buy",
type: type
});
return Notification.push({
Notification.push({
type: "text",
text: "Item bought!"
});
} else {
return Notification.push({
Notification.push({
type: "text",
text: "Not enough GP."
});

View file

@ -0,0 +1,23 @@
"use strict";
habitrpg.controller("UserAvatarCtrl", function($scope, $location, filterFilter, User) {
debugger
$scope.profile = User.user;
$scope.hideUserAvatar = function() {
$(".userAvatar").hide();
};
$scope.clickAvatar = function(profile) {
debugger
if (User.user.id == profile.id) {
if ($location.path() == '/tasks') {
$location.path('/options')
} else {
$location.path('/tasks');
}
} else {
//TODO show party member modal
//$("#avatar-modal-#{uid}").modal('show')
}
}
});

View file

@ -20,12 +20,12 @@ angular.module("notificationServices", []).factory("Notification", function() {
$("#notification").css("webkit-transform", "none");
$("#notification").css("top", "-63px");
$("#notification").css("left", "0px");
return setTimeout((function() {
return $("#notification").show();
setTimeout((function() {
$("#notification").show();
}), 190);
});
active = false;
return timer = null;
timer = null;
},
animate: function() {
if (timer) {
@ -38,7 +38,7 @@ angular.module("notificationServices", []).factory("Notification", function() {
y: 63,
x: 0
});
return timer = setTimeout(this.hide, 2000);
timer = setTimeout(this.hide, 2000);
}
},
push: function(message) {
@ -58,7 +58,7 @@ angular.module("notificationServices", []).factory("Notification", function() {
case "text":
data.message = message.text;
}
return this.animate();
this.animate();
},
get: function() {
return data;
@ -66,10 +66,10 @@ angular.module("notificationServices", []).factory("Notification", function() {
clearTimer: function() {
clearTimeout(timer);
timer = null;
return active = false;
active = false;
},
init: function() {
return timer = setTimeout(this.hide, 2000);
timer = setTimeout(this.hide, 2000);
}
};
});

View file

@ -30,7 +30,8 @@
"jquery.cookie": "~1.3.1",
"sticky": "*",
"bootstrap-datepicker": "~1.2.0",
"bootstrap": "v2.3.2"
"bootstrap": "v2.3.2",
"angular-route": "1.2.0-rc.1"
},
"resolutions": {
"jquery": "~2.0.3",

View file

@ -1,6 +1,6 @@
express = require 'express'
router = new express.Router()
api = require './controllers/api'
api = require '../controllers/api'
###
---------- /api/v1 API ------------

10
src/routes/pages.coffee Normal file
View file

@ -0,0 +1,10 @@
express = require 'express'
router = new express.Router()
router.get '/', (req, res) ->
res.render 'index', {'HabitRPG | Your Life, The Role Playing Game'}
router.get '/partials/tasks', (req, res) -> res.render 'tasks/index'
router.get '/partials/options', (req, res) -> res.render 'options/index'
module.exports = router

View file

@ -40,9 +40,8 @@ app.use express['static'](path.join(__dirname, "/../public"))
app.use express.errorHandler() if "development" is app.get("env")
# Custom Directives
app.get '/', (req, res) ->
res.render 'index', {'HabitRPG | Your Life, The Role Playing Game'}
app.use('/api/v1', require('./routes').middleware)
app.use(require('./routes/pages').middleware)
app.use('/api/v1', require('./routes/api').middleware)
app.use(require('./controllers/deprecated').middleware)
server = http.createServer(app).listen app.get("port"), ->

View file

@ -1,29 +1,76 @@
extends layout
doctype 5
html
head
title HabitRPG | Your Life The Role Playing Game
block content
div(ng-app="habitrpg", ng-controller="RootCtrl")
include ./modals/index
include ./header/header
// CSS
link(rel='stylesheet', href='/bower_components/bootstrap/docs/assets/css/bootstrap.css')
link(rel='stylesheet', href='/bower_components/bootstrap/docs/assets/css/bootstrap-responsive.css')
link(rel='stylesheet', href='/bower_components/angular-ui/build/angular-ui.css')
!= css('index')
span(ng-hide='_gamePane')
app:filters:filters
// HabitRPG Shared
link(rel='stylesheet', href='/bower_components/habitrpg-shared/spritesheets.css')
// JS
script(type='text/javascript', src='/bower_components/jquery/jquery.min.js')
script(type='text/javascript', src='/bower_components/lodash/lodash.js')
script(type='text/javascript', src='/bower_components/moment/moment.js')
script(type='text/javascript', src='/bower_components/angular/angular.js')
script(type='text/javascript', src='/bower_components/angular-route/angular-route.js')
script(type='text/javascript', src='/bower_components/angular-resource/angular-resource.js')
script(type='text/javascript', src='/bower_components/angular-ui/build/angular-ui.js')
script(type='text/javascript', src='/bower_components/angular-bootstrap/ui-bootstrap.js')
script(type='text/javascript', src='/bower_components/angular-bootstrap/ui-bootstrap-tpls.js')
script(type='text/javascript', src='/bower_components/habitrpg-shared/dist/habitrpg-shared.js')
!= js('app')
!= js('services/authServices')
!= js('services/notificationServices')
!= js('services/sharedServices')
!= js('services/userServices')
!= js('filters/filters')
!= js('directives/directives')
!= js('controllers/authCtrl')
!= js('controllers/characterCtrl')
!= js('controllers/menuCtrl')
!= js('controllers/notificationCtrl')
!= js('controllers/RootCtrl')
!= js('controllers/settingsCtrl')
!= js('controllers/statsCtrl')
!= js('controllers/tasksCtrl')
!= js('controllers/taskDetailsCtrl')
!= js('controllers/userAvatarCtrl')
//webfonts
link(href='//fonts.googleapis.com/css?family=Lato:300,400,700,400italic,700italic', rel='stylesheet', type='text/css')
meta(name='viewport', content='width=device-width')
meta(name='apple-mobile-web-app-capable', content='yes')
body(ng-app="habitrpg", ng-controller="RootCtrl")
include ./shared/modals/index
include ./shared/header/header
app:filters:filters(ng-hide='_gamePane')
br
#notification-area
#wrap
app:alerts:flash
//if they hide the header, we still need user-menu visible
app:settings:menu(ng-show='_user.preferences.hideHeader')
.exp-chart(ng-show='_page.charts.exp')
app:settings:menu(ng-show='user.preferences.hideHeader')
.exp-chart(ng-show='page.charts.exp')
#main.grid
div(ng-hide='_gamePane')
include ./tasks/task-list
div(ng-show='_gamePane')
app:game-pane:main
app:footer:footer
div(ng-view)
//-app:footer:footer
footer.footer
.container
a(target='_blank',href='https://workflowy.com/shared/9c77c53d-a174-d181-73a4-dc611508a936/') Roadmap

View file

@ -1,55 +0,0 @@
doctype 5
html
head
title HabitRPG | Your Life The Role Playing Game
// CSS
link(rel='stylesheet', href='/bower_components/bootstrap/docs/assets/css/bootstrap.css')
link(rel='stylesheet', href='/bower_components/bootstrap/docs/assets/css/bootstrap-responsive.css')
link(rel='stylesheet', href='/bower_components/angular-ui/build/angular-ui.css')
!= css('index')
// HabitRPG Shared
link(rel='stylesheet', href='/bower_components/habitrpg-shared/spritesheets.css')
// JS
script(type='text/javascript', src='/bower_components/jquery/jquery.min.js')
script(type='text/javascript', src='/bower_components/lodash/lodash.js')
script(type='text/javascript', src='/bower_components/moment/moment.js')
script(type='text/javascript', src='/bower_components/angular/angular.js')
script(type='text/javascript', src='/bower_components/angular-resource/angular-resource.js')
script(type='text/javascript', src='/bower_components/angular-ui/build/angular-ui.js')
script(type='text/javascript', src='/bower_components/angular-bootstrap/ui-bootstrap.js')
script(type='text/javascript', src='/bower_components/angular-bootstrap/ui-bootstrap-tpls.js')
script(type='text/javascript', src='/bower_components/habitrpg-shared/dist/habitrpg-shared.js')
!= js('app')
!= js('services/authServices')
!= js('services/notificationServices')
!= js('services/sharedServices')
!= js('services/userServices')
!= js('filters/filters')
!= js('directives/directives')
!= js('controllers/authCtrl')
!= js('controllers/characterCtrl')
!= js('controllers/menuCtrl')
!= js('controllers/notificationCtrl')
!= js('controllers/RootCtrl')
!= js('controllers/settingsCtrl')
!= js('controllers/statsCtrl')
!= js('controllers/tasksCtrl')
!= js('controllers/taskDetailsCtrl')
!= js('controllers/userAvatarCtrl')
//webfonts
link(href='//fonts.googleapis.com/css?family=Lato:300,400,700,400italic,700italic', rel='stylesheet', type='text/css')
meta(name='viewport', content='width=device-width')
meta(name='apple-mobile-web-app-capable', content='yes')
body
block content

View file

@ -1,4 +0,0 @@
include ./achievements
include ./login
include ./reroll
include ./death

View file

@ -8,10 +8,8 @@
<ul class="nav nav-tabs game-tabs">
<li class="active"><a data-toggle='tab' data-target="#profile-customize"><i class='icon-user'></i> Profile</a></li>
<li><a data-toggle='tab' data-target="#profile-groups" id='party-tab-link'><i class='icon-heart'></i> Groups</a></li>
{#if _user.flags.dropsEnabled}
<li><a data-toggle='tab' data-target="#profile-inventory"><i class='icon-gift'></i> Inventory</a></li>
<li><a data-toggle='tab' data-target="#profile-stable"><i class='icon-leaf'></i> Stable</a></li>
{/if}
<li ng-show="user.flags.dropsEnabled"><a data-toggle='tab' data-target="#profile-inventory"><i class='icon-gift'></i> Inventory</a></li>
<li ng-show="user.flags.dropsEnabled"><a data-toggle='tab' data-target="#profile-stable"><i class='icon-leaf'></i> Stable</a></li>
<li><a data-toggle='tab' data-target="#profile-tavern"><i class='icon-eye-close'></i> Tavern</a></li>
<li><a data-toggle='tab' data-target="#profile-achievements"><i class='icon-certificate'></i> Achievements</a></li>
<!--<li><a data-toggle='tab' data-target="#profile-challenges" id='profile-challenges-tab-link' ><i class='icon-bullhorn'></i> Challenges</a></li>-->

62
views/options/index.jade Normal file
View file

@ -0,0 +1,62 @@
.module.full-width
span.option-box.pull-right.wallet
app:rewards:user-gems
ul.nav.nav-tabs.game-tabs
li.active
a(data-toggle='tab', data-target='#profile-customize')
i.icon-user
| Profile
li
a#party-tab-link(data-toggle='tab', data-target='#profile-groups')
i.icon-heart
| Groups
li(ng-show='user.flags.dropsEnabled')
a(data-toggle='tab', data-target='#profile-inventory')
i.icon-gift
| Inventory
li(ng-show='user.flags.dropsEnabled')
a(data-toggle='tab', data-target='#profile-stable')
i.icon-leaf
| Stable
li
a(data-toggle='tab', data-target='#profile-tavern')
i.icon-eye-close
| Tavern
li
a(data-toggle='tab', data-target='#profile-achievements')
i.icon-certificate
| Achievements
// <li><a data-toggle='tab' data-target="#profile-challenges" id='profile-challenges-tab-link' ><i class='icon-bullhorn'></i> Challenges</a></li>
li
a(data-toggle='tab', data-target='#profile-settings')
i.icon-wrench
| Settings
.tab-content
#profile-customize.tab-pane.active
.row-fluid
.span4.border-right
app:avatar:customize
.span4.border-right
app:avatar:profile-stats(profile='{_user}')
.span4
app:avatar:profile-edit
#profile-groups.tab-pane
app:groups:groups-pane
#profile-achievements.tab-pane
app:avatar:achievements(profile='{{_user}}')
#profile-inventory.tab-pane
.row-fluid
.span6.border-right
h2 Inventory
app:avatar:inventory
.span6
h2 Market
app:game-pane:market
#profile-stable.tab-pane
app:pets:stable
#profile-tavern.tab-pane
app:groups:group(group='{_habitRPG}')
#profile-challenges.tab-pane
app:challenges:main
#profile-settings.tab-pane
app:settings:settings-pane

View file

@ -1,4 +1,4 @@
figure.herobox(data-name='{{username(profile.auth, profile.profile.name)}}', ng-class='{isUser: profile.id==user.id, hasPet: profile.items.pet}', data-level='{{profile.stats.lvl}}', data-uid='{{profile.id}}', x-bind='click:clickAvatar', rel='popover', data-placement='bottom', data-trigger='hover', data-html='true', data-content="<div ng-hide='profile.id == user.id'> <div class='progress progress-danger' style='height:5px;'> <div class='bar' style='height: 5px; width: {{percent(profile.stats.hp, 50)}}%;'></div> </div> <div class='progress progress-warning' style='height:5px;'> <div class='bar' style='height: 5px; width: {{percent(profile.stats.exp, tnl(profile.stats.lvl))}}%;'></div> </div> <div>Level: {{profile.stats.lvl}}</div> <div>GP: {{profile.stats.gp | number:0}}</div> <div>{{count(profile.items.pets)}} / 90 Pets Found</div> </div>")
figure.herobox(ng-click='clickAvatar(profile)', data-name='{{username(profile.auth, profile.profile.name)}}', ng-class='{isUser: profile.id==user.id, hasPet: profile.items.pet}', data-level='{{profile.stats.lvl}}', data-uid='{{profile.id}}', rel='popover', data-placement='bottom', data-trigger='hover', data-html='true', data-content="<div ng-hide='profile.id == user.id'> <div class='progress progress-danger' style='height:5px;'> <div class='bar' style='height: 5px; width: {{percent(profile.stats.hp, 50)}}%;'></div> </div> <div class='progress progress-warning' style='height:5px;'> <div class='bar' style='height: 5px; width: {{percent(profile.stats.exp, tnl(profile.stats.lvl))}}%;'></div> </div> <div>Level: {{profile.stats.lvl}}</div> <div>GP: {{profile.stats.gp | number:0}}</div> <div>{{count(profile.items.pets)}} / 90 Pets Found</div> </div>")
.character-sprites
span(ng-class='{zzz:profile.flags.rest}')
span(class='{{profile.preferences.gender}}_skin_{{profile.preferences.skin}}')

View file

@ -1,13 +1,12 @@
// @TODO ui:connectionAlert
.header-wrap
a.label.undo-button(x-bind='click:undo', ng-show='_undo') Undo
include ./menu
include menu
header.site-header(ng-class='{hidden: user.preferences.hideHeader}', role='banner', data-partysize='{{party.members.length>1 ? truarr(party.members.length) : 0}}')
// avatar
.herobox-wrap.main-herobox(ng-controller='UserAvatarCtrl')
include ./avatar
include avatar
//app:avatar:avatar(profile='{{user}}', main='true')
// stat bars

View file

@ -0,0 +1,4 @@
include achievements
include login
include reroll
include death

View file

@ -3,7 +3,7 @@ div(modal='modals.reroll')
.modal-header
h3 Reset Your Tasks
.modal-body
include ../shared/gems
include ../gems
p.
Purchasing a Re-Roll will reset all your tasks to a neutral (yellow) state, as if you'd just added them. Consider
this an option of last resort, red tasks provide good incentive to improve. But if all that red fills you with