From 35c4a62de037eccb7dd0009fc6d003b7e3a36110 Mon Sep 17 00:00:00 2001 From: Tyler Renelle Date: Sun, 27 Oct 2013 22:27:07 -0700 Subject: [PATCH] challenges: switch from ngRoute to ui-router --- bower.json | 6 +- public/js/app.js | 118 ++++++++++- public/js/controllers/challengesCtrl.js | 92 +++------ public/js/controllers/groupsCtrl.js | 12 +- public/js/controllers/rootCtrl.js | 8 +- public/js/services/groupServices.js | 4 +- src/models/challenge.js | 2 + src/models/group.js | 35 +--- src/models/task.js | 2 + views/index.jade | 3 +- views/main/index.jade | 2 +- views/options/challenges.html | 176 ---------------- views/options/challenges.jade | 139 ++++++------- views/options/groups/index.jade | 131 ++++++------ views/options/groups/tavern.jade | 2 +- views/options/index.jade | 65 ++---- views/options/inventory.jade | 54 ----- views/options/inventory/index.jade | 15 ++ views/options/inventory/inventory.jade | 55 +++++ views/options/inventory/stable.jade | 30 +++ views/options/pets.jade | 29 --- views/options/profile.jade | 259 +++++++++++++----------- views/options/settings.jade | 83 ++++---- 23 files changed, 614 insertions(+), 708 deletions(-) delete mode 100644 views/options/challenges.html delete mode 100644 views/options/inventory.jade create mode 100644 views/options/inventory/index.jade create mode 100644 views/options/inventory/inventory.jade create mode 100644 views/options/inventory/stable.jade delete mode 100644 views/options/pets.jade diff --git a/bower.json b/bower.json index 37542ee3e8..5150bf06b2 100644 --- a/bower.json +++ b/bower.json @@ -19,7 +19,7 @@ "angular-resource": "1.2.0-rc.2", "angular-ui": "~0.4.0", "angular-bootstrap": "~0.5.0", - "habitrpg-shared": "git://github.com/HabitRPG/habitrpg-shared.git#rewrite", + "habitrpg-shared": "git://github.com/HabitRPG/habitrpg-shared.git#challenges", "bootstrap-tour": "0.5.0", "BrowserQuest": "https://github.com/mozilla/BrowserQuest.git", "github-buttons": "git://github.com/mdo/github-buttons.git", @@ -29,11 +29,11 @@ "sticky": "*", "bootstrap-datepicker": "~1.2.0", "bootstrap": "v2.3.2", - "angular-route": "1.2.0-rc.2", "angular-ui-utils": "~0.0.4", "angular-sanitize": "1.2.0-rc.2", "marked": "~0.2.9", - "JavaScriptButtons": "git://github.com/paypal/JavaScriptButtons.git#master" + "JavaScriptButtons": "git://github.com/paypal/JavaScriptButtons.git#master", + "angular-ui-router": "eda67d2da08cbe2aa1aa39ef154a87c7afe480ec" }, "resolutions": { "jquery": "~2.0.3", diff --git a/public/js/app.js b/public/js/app.js index 73936bae9a..9c38ba99dd 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -1,21 +1,123 @@ "use strict"; window.habitrpg = angular.module('habitrpg', - ['ngRoute', 'ngResource', 'ngSanitize', 'userServices', 'groupServices', 'memberServices', 'challengeServices', 'sharedServices', 'authServices', 'notificationServices', 'guideServices', 'ui.bootstrap', 'ui.keypress']) + ['ngRoute', 'ngResource', 'ngSanitize', 'userServices', 'groupServices', 'memberServices', 'challengeServices', 'sharedServices', 'authServices', 'notificationServices', 'guideServices', 'ui.bootstrap', 'ui.keypress', 'ui.router']) .constant("API_URL", "") .constant("STORAGE_USER_ID", 'habitrpg-user') .constant("STORAGE_SETTINGS_ID", 'habit-mobile-settings') //.constant("STORAGE_GROUPS_ID", "") // if we decide to take groups offline - .config(['$routeProvider', '$httpProvider', 'STORAGE_SETTINGS_ID', - function($routeProvider, $httpProvider, STORAGE_SETTINGS_ID) { - $routeProvider - //.when('/login', {templateUrl: 'views/login.html'}) - .when('/tasks', {templateUrl: 'templates/habitrpg-main.html'}) - .when('/options', {templateUrl: 'templates/habitrpg-options.html'}) + .config(['$stateProvider', '$urlRouterProvider', '$httpProvider', 'STORAGE_SETTINGS_ID', + function($stateProvider, $urlRouterProvider, $httpProvider, STORAGE_SETTINGS_ID) { - .otherwise({redirectTo: '/tasks'}); + $urlRouterProvider + // Setup default selected tabs + .when('/options', '/options/profile/avatar') + .when('/options/profile', '/options/profile/avatar') + .when('/options/groups', '/options/groups/tavern') + .when('/options/inventory', '/options/inventory/inventory') + + // redirect states that don't match + .otherwise("/tasks"); + + $stateProvider + + // Tasks + .state('tasks', { + url: "/tasks", + templateUrl: "partials/main.html" + }) + + // Options + .state('options', { + url: "/options", + templateUrl: "partials/options.html", + controller: function(){} + }) + + // Options > Profile + .state('options.profile', { + url: "/profile", + templateUrl: "partials/options.profile.html", + controller: 'UserCtrl' + }) + .state('options.profile.avatar', { + url: "/avatar", + templateUrl: "partials/options.profile.avatar.html" + }) + .state('options.profile.stats', { + url: "/stats", + templateUrl: "partials/options.profile.stats.html" + }) + .state('options.profile.profile', { + url: "/stats", + templateUrl: "partials/options.profile.profile.html" + }) + + // Options > Groups + .state('options.groups', { + url: "/groups", + templateUrl: "partials/options.groups.html" + }) + .state('options.groups.tavern', { + url: "/tavern", + templateUrl: "partials/options.groups.tavern.html", + controller: 'TavernCtrl' + // TODO this doesn't work, seems ngResource doesn't get the .then() function +// resolve: { +// group: ['Groups', function(Groups){ +// //return Groups.fetchTavern(); +// }] +// } + }) + .state('options.groups.party', { + url: '/party', + templateUrl: "partials/options.groups.party.html", + controller: 'PartyCtrl' + }) + .state('options.groups.guilds', { + url: '/party', + templateUrl: "partials/options.groups.guilds.html", + controller: 'GuildsCtrl' + }) + + // Options > Inventory + .state('options.inventory', { + url: '/inventory', + templateUrl: "partials/options.inventory.html" + }) + .state('options.inventory.inventory', { + url: '/inventory', + templateUrl: "partials/options.inventory.inventory.html" + }) + .state('options.inventory.stable', { + url: '/stable', + templateUrl: "partials/options.inventory.stable.html" + }) + + // Options > Challenges + .state('options.challenges', { + url: "/challenges", + controller: 'ChallengesCtrl', + templateUrl: "partials/options.challenges.html", + resolve: { + groups: ['$http', 'API_URL', function($http, API_URL){ + // TODO come up with more unified ngResource-style approach + return $http.get(API_URL + '/api/v1/groups?minimal=true'); + }], + challenges: ['Challenges', function(Challenges){ + return Challenges.Challenge.query(); + }] + } + }) + + // Options > Settings + .state('options.settings', { + url: "/settings", + controller: 'SettingsCtrl', + templateUrl: "partials/options.settings.html" + }) var settings = JSON.parse(localStorage.getItem(STORAGE_SETTINGS_ID)); if (settings && settings.auth) { diff --git a/public/js/controllers/challengesCtrl.js b/public/js/controllers/challengesCtrl.js index 9a716e0e05..264bc1c5f9 100644 --- a/public/js/controllers/challengesCtrl.js +++ b/public/js/controllers/challengesCtrl.js @@ -1,13 +1,11 @@ "use strict"; -habitrpg.controller("ChallengesCtrl", ['$scope', '$rootScope', 'User', 'Challenges', 'Notification', '$http', 'API_URL', '$compile', - function($scope, $rootScope, User, Challenges, Notification, $http, API_URL, $compile) { +habitrpg.controller("ChallengesCtrl", ['$scope', 'User', 'Challenges', 'Notification', '$compile', 'groups', 'challenges', + function($scope, User, Challenges, Notification, $compile, groups, challenges) { - $http.get(API_URL + '/api/v1/groups?minimal=true').success(function(groups){ - $scope.groups = groups; - }); - - $scope.challenges = Challenges.Challenge.query(); + // groups & challenges are loaded as `resolve` via ui-router (see app.js) + $scope.groups = groups; + $scope.challenges = challenges; //------------------------------------------------------------ // Challenge @@ -92,61 +90,33 @@ habitrpg.controller("ChallengesCtrl", ['$scope', '$rootScope', 'User', 'Challeng // TODO persist } - /** - * 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) + /* + -------------------------- + Unsubscribe functions + -------------------------- + */ - - /* - -------------------------- - Unsubscribe functions - -------------------------- - */ - - $scope.unsubscribe = function(keep) { - if (keep == 'cancel') { - $scope.selectedChal = undefined; - } else { - $scope.selectedChal.$leave({keep:keep}); - } - $scope.popoverEl.popover('destroy'); - } - $scope.clickUnsubscribe = function(chal, $event) { - $scope.selectedChal = chal; - $scope.popoverEl = $($event.target); - var html = $compile( - 'Remove Tasks
\nKeep Tasks
\nCancel
' - )($scope); - $scope.popoverEl.popover('destroy').popover({ - html: true, - placement: 'top', - trigger: 'manual', - title: 'Unsubscribe From Challenge And:', - content: html - }).popover('show'); + $scope.unsubscribe = function(keep) { + if (keep == 'cancel') { + $scope.selectedChal = undefined; + } else { + $scope.selectedChal.$leave({keep:keep}); } + $scope.popoverEl.popover('destroy'); + } + $scope.clickUnsubscribe = function(chal, $event) { + $scope.selectedChal = chal; + $scope.popoverEl = $($event.target); + var html = $compile( + 'Remove Tasks
\nKeep Tasks
\nCancel
' + )($scope); + $scope.popoverEl.popover('destroy').popover({ + html: true, + placement: 'top', + trigger: 'manual', + title: 'Unsubscribe From Challenge And:', + content: html + }).popover('show'); + } }]); \ No newline at end of file diff --git a/public/js/controllers/groupsCtrl.js b/public/js/controllers/groupsCtrl.js index a4f487f109..b0d1fba4e8 100644 --- a/public/js/controllers/groupsCtrl.js +++ b/public/js/controllers/groupsCtrl.js @@ -1,7 +1,7 @@ "use strict"; -habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Groups', '$http', 'API_URL', '$q', 'User', 'Members', '$location', - function($scope, $rootScope, Groups, $http, API_URL, $q, User, Members, $location) { +habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Groups', '$http', 'API_URL', '$q', 'User', 'Members', '$location', '$state', + function($scope, $rootScope, Groups, $http, API_URL, $q, User, Members, $location, $state) { $scope.isMember = function(user, group){ return ~(group.members.indexOf(user._id)); @@ -25,10 +25,10 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Groups', '$http', 'A $scope.clickMember = function(uid, forceShow) { if (User.user._id == uid && !forceShow) { - if ($location.path() == '/tasks') { - $location.path('/options'); + if ($state.is('tasks')) { + $state.go('options'); } else { - $location.path('/tasks'); + $state.go('tasks'); } } else { // We need the member information up top here, but then we pass it down to the modal controller @@ -117,6 +117,7 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Groups', '$http', 'A .controller("GuildsCtrl", ['$scope', 'Groups', 'User', '$rootScope', function($scope, Groups, User, $rootScope) { + Groups.fetchGuilds(); $scope.type = 'guild'; $scope.text = 'Guild'; $scope.newGroup = new Groups.Group({type:'guild', privacy:'private', leader: User.user._id, members: [User.user._id]}); @@ -202,6 +203,7 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Groups', '$http', 'A .controller("TavernCtrl", ['$scope', 'Groups', 'User', function($scope, Groups, User) { + Groups.fetchTavern(); $scope.group = Groups.groups.tavern; $scope.rest = function(){ diff --git a/public/js/controllers/rootCtrl.js b/public/js/controllers/rootCtrl.js index 1ad39e2285..3c4658d764 100644 --- a/public/js/controllers/rootCtrl.js +++ b/public/js/controllers/rootCtrl.js @@ -3,8 +3,8 @@ /* Make user and settings available for everyone through root scope. */ -habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$http', - function($scope, $rootScope, $location, User, $http) { +habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$http', '$state', '$stateParams', + function($scope, $rootScope, $location, User, $http, $state, $stateParams) { $rootScope.modals = {}; $rootScope.modals.achievements = {}; $rootScope.User = User; @@ -12,6 +12,10 @@ habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$ $rootScope.settings = User.settings; $rootScope.flash = {errors: [], warnings: []}; + // Angular UI Router + $rootScope.$state = $state; + $rootScope.$stateParams = $stateParams; + // indexOf helper $scope.indexOf = function(haystack, needle){ return ~haystack.indexOf(needle); diff --git a/public/js/services/groupServices.js b/public/js/services/groupServices.js index 7e441b1839..47c1b610d8 100644 --- a/public/js/services/groupServices.js +++ b/public/js/services/groupServices.js @@ -44,9 +44,9 @@ angular.module('groupServices', ['ngResource']). fetchGuilds: _.once(function(){ $('#loading-indicator').show(); Group.query({type:'guilds'}, function(_groups){ + $('#loading-indicator').hide(); guildsQ.resolve(_groups); Members.populate(_groups); - $('#loading-indicator').hide(); }) Group.query({type:'public'}, function(_groups){ publicQ.resolve(_groups); @@ -58,8 +58,8 @@ angular.module('groupServices', ['ngResource']). $('#loading-indicator').show(); Group.query({type:'tavern'}, function(_groups){ $('#loading-indicator').hide(); - tavernQ.resolve(_groups[0]); Members.populate(_groups[0]); + tavernQ.resolve(_groups[0]); }) }), diff --git a/src/models/challenge.js b/src/models/challenge.js index 0631e648f4..4971dcc992 100644 --- a/src/models/challenge.js +++ b/src/models/challenge.js @@ -20,6 +20,8 @@ var ChallengeSchema = new Schema({ //}, timestamp: {type: Date, 'default': Date.now}, members: [{type: String, ref: 'User'}] +}, { + minimize: 'false' }); ChallengeSchema.virtual('tasks').get(function () { diff --git a/src/models/group.js b/src/models/group.js index b99c5870f8..6aed645bea 100644 --- a/src/models/group.js +++ b/src/models/group.js @@ -7,37 +7,14 @@ var GroupSchema = new Schema({ _id: {type: String, 'default': helpers.uuid}, name: String, description: String, - leader: { - type: String, - ref: 'User' - }, - members: [ - { - type: String, - ref: 'User' - } - ], - invites: [ - { - type: String, - ref: 'User' - } - ], - type: { - type: String, - "enum": ['guild', 'party'] - }, - privacy: { - type: String, - "enum": ['private', 'public'] - }, - _v: { - Number: Number, - 'default': 0 - }, + leader: {type: String, ref: 'User'}, + members: [{type: String, ref: 'User'}], + invites: [{type: String, ref: 'User'}], + type: {type: String, "enum": ['guild', 'party']}, + privacy: {type: String, "enum": ['private', 'public']}, + _v: {Number: Number,'default': 0}, websites: Array, chat: Array, - /* # [{ # timestamp: Date diff --git a/src/models/task.js b/src/models/task.js index 6547170c3a..fd89af35a4 100644 --- a/src/models/task.js +++ b/src/models/task.js @@ -31,6 +31,8 @@ var TaskSchema = new Schema({ broken: String // CHALLENGE_DELETED, TASK_DELETED, UNSUBSCRIBED, etc // group: {type: 'Strign', ref: 'Group'} // if we restore this, rename `id` above to `challenge` } +}, { + minimize: 'false' }); TaskSchema.methods.toJSON = function() { diff --git a/views/index.jade b/views/index.jade index 6de28f9472..4ea8d9a182 100644 --- a/views/index.jade +++ b/views/index.jade @@ -31,6 +31,7 @@ html script(type='text/javascript', src='/bower_components/bootstrap-growl/jquery.bootstrap-growl.min.js') script(type='text/javascript', src='/bower_components/bootstrap-tour/build/js/bootstrap-tour.min.js') script(type='text/javascript', src='/bower_components/angular/angular.js') + script(type='text/javascript', src='/bower_components/angular-ui-router/release/angular-ui-router.js') script(type='text/javascript', src='/bower_components/angular-sanitize/angular-sanitize.min.js') script(type='text/javascript', src='/bower_components/marked/lib/marked.js') @@ -109,7 +110,7 @@ html .exp-chart(ng-show='charts.exp') - #main(ng-view) + #main(ui-view) include ./shared/footer diff --git a/views/main/index.jade b/views/main/index.jade index da4490409a..586ce3ca60 100644 --- a/views/main/index.jade +++ b/views/main/index.jade @@ -1,4 +1,4 @@ -script(id='templates/habitrpg-main.html', type="text/ng-template") +script(id='partials/main.html', type="text/ng-template") include ./filters div(ng-controller='TasksCtrl') habitrpg-tasks(main='true', obj='user') diff --git a/views/options/challenges.html b/views/options/challenges.html deleted file mode 100644 index 23dd937e4a..0000000000 --- a/views/options/challenges.html +++ /dev/null @@ -1,176 +0,0 @@ -
- - - - - - - - - {{#unless _page.party.id}} - Join a party first. - {{else}} - - {{/}} - - - - -
- {{#each _page.guilds as :guild}} -
- -
- {{/}} -
-
- - - - - -
-
- - -
- -
-
- - {#each @list as :challenge} - - {/} -
-
-
- - -
-
-
    -
  • - {count(@challenge.members)} Subscribers -
  • -
  • - - {#if @challenge.prize} -
    {@challenge.prize} Prize
    - {/} -
  • -
  • - - {#with @challenge} - Unsubscribe - Subscribe - {/} -
  • -
- {@challenge.name} (by {@challenge.user.name}) - - -
-
-
- - - - {#if and(not(_page.editing.challenges[@challenge.id]),equal(@challenge.user.uid,_session.userId))} - - {else} - - {/} - - - {#if _page.editing.challenges[@challenge.id]} -
- - - -
- {{#with @challenge}} - Delete - {{/}} - {/} - {#if @challenge.description}
{@challenge.description}
{/} - -
- -
- -

Statistics

- {#each @challenge.members as :member} -

{:member.name}

-
-
- -
-
- -
-
- -
-
- {/} -
-
-
-
- - -
{@header}
-
- {#each @list as :task} - - - -
- - {:task.text}: {challengeMemberScore(@member,:task)} - -
-
- {/} -
-
- - - Create {{@text}} Challenge - - - -
-
- - -
- -
- -
-
- -
- -
-
\ No newline at end of file diff --git a/views/options/challenges.jade b/views/options/challenges.jade index a463456d2d..2abca59c4d 100644 --- a/views/options/challenges.jade +++ b/views/options/challenges.jade @@ -1,73 +1,74 @@ -.row-fluid(ng-controller='ChallengesCtrl') - .span2.well - h4 Filters - ul - li(ng-repeat='group in groups') - input(type='checkbox', ng-model='search.group') - | {{group.name}} - li - input(type='checkbox', ng-model='search.members') - | Subscribed (TODO) - li - input(type='checkbox', ng-model='search.members') - | Available (TODO) - .span10 - // Creation form - a.btn.btn-success(ng-click='create()') Create Challenge - .create-challenge-from(ng-if='newChallenge') - form(ng-submit='save(newChallenge)') - div - input.btn.btn-success(type='submit', value='Save') - input.btn.btn-danger(type='button', ng-click='discard()', value='Discard') - select(ng-model='newChallenge.group', ng-required='required', name='Group', ng-options='g._id as g.name for g in groups') - .challenge-options - input.option-content(type='text', ng-model='newChallenge.name', placeholder='Challenge Title', required='required') +script(type='text/ng-template', id='partials/options.challenges.html') + .row-fluid + .span2.well + h4 Filters + ul + li(ng-repeat='group in groups') + input(type='checkbox', ng-model='search.group') + | {{group.name}} + li + input(type='checkbox', ng-model='search.members') + | Subscribed (TODO) + li + input(type='checkbox', ng-model='search.members') + | Available (TODO) + .span10 + // Creation form + a.btn.btn-success(ng-click='create()') Create Challenge + .create-challenge-from(ng-if='newChallenge') + form(ng-submit='save(newChallenge)') + div + input.btn.btn-success(type='submit', value='Save') + input.btn.btn-danger(type='button', ng-click='discard()', value='Discard') + select(ng-model='newChallenge.group', ng-required='required', name='Group', ng-options='g._id as g.name for g in groups') + .challenge-options + input.option-content(type='text', ng-model='newChallenge.name', placeholder='Challenge Title', required='required') - habitrpg-tasks(main=false, obj='newChallenge') + habitrpg-tasks(main=false, obj='newChallenge') - // Challenges list - .accordion-group(ng-repeat='challenge in challenges | filter:search', ng-init='challenge._locked=true') - .accordion-heading - ul.pull-right.challenge-accordion-header-specs - li {{challenge.members.length}} Subscribers - li(ng-show='challenge.prize') - // prize - table(ng-show='challenge.prize') - tr - td {{challenge.prize}} - td - span.Pet_Currency_Gem1x - td Prize - li - // subscribe / unsubscribe - a.btn.btn-small.btn-danger(ng-show='indexOf(challenge.members, user._id)', ng-click='clickUnsubscribe(challenge, $event)') - i.icon-ban-circle - | Unsubscribe - a.btn.btn-small.btn-success(ng-hide='indexOf(challenge.members, user._id)', ng-click='challenge.$join()') - i.icon-ok - | Subscribe - a.accordion-toggle(data-toggle='collapse', data-target='#accordion-challenge-{{challenge._id}}') {{challenge.name}} (by {{challenge.leader.name}}) - .accordion-body.collapse(id='accordion-challenge-{{challenge._id}}') - .accordion-inner - // Edit button - ul.unstyled() - li(ng-show='challenge.leader==user._id && challenge._locked') - button.btn.btn-default(ng-click='challenge._locked = false') Edit - li(ng-hide='challenge._locked') - button.btn.btn-primary(ng-click='save(challenge)') Save - button.btn.btn-danger(ng-click='delete(challenge)') Delete - button.btn.btn-default(ng-click='challenge._locked=true') Cancel + // Challenges list + .accordion-group(ng-repeat='challenge in challenges | filter:search', ng-init='challenge._locked=true') + .accordion-heading + ul.pull-right.challenge-accordion-header-specs + li {{challenge.members.length}} Subscribers + li(ng-show='challenge.prize') + // prize + table(ng-show='challenge.prize') + tr + td {{challenge.prize}} + td + span.Pet_Currency_Gem1x + td Prize + li + // subscribe / unsubscribe + a.btn.btn-small.btn-danger(ng-show='indexOf(challenge.members, user._id)', ng-click='clickUnsubscribe(challenge, $event)') + i.icon-ban-circle + | Unsubscribe + a.btn.btn-small.btn-success(ng-hide='indexOf(challenge.members, user._id)', ng-click='challenge.$join()') + i.icon-ok + | Subscribe + a.accordion-toggle(data-toggle='collapse', data-target='#accordion-challenge-{{challenge._id}}') {{challenge.name}} (by {{challenge.leader.name}}) + .accordion-body.collapse(id='accordion-challenge-{{challenge._id}}') + .accordion-inner + // Edit button + ul.unstyled() + li(ng-show='challenge.leader==user._id && challenge._locked') + button.btn.btn-default(ng-click='challenge._locked = false') Edit + li(ng-hide='challenge._locked') + button.btn.btn-primary(ng-click='save(challenge)') Save + button.btn.btn-danger(ng-click='delete(challenge)') Delete + button.btn.btn-default(ng-click='challenge._locked=true') Cancel - div(ng-hide='challenge._locked') - .-options - input.option-content(type='text', ng-model='challenge.name') - textarea.option-content(cols='3', placeholder='Description', ng-model='challenge.description') - // - hr + div(ng-hide='challenge._locked') + .-options + input.option-content(type='text', ng-model='challenge.name') + textarea.option-content(cols='3', placeholder='Description', ng-model='challenge.description') + // + hr - div(ng-if='challenge.description') {{challenge.description}} - habitrpg-tasks(obj='challenge', main=false) - h3 Statistics - div(ng-repeat='member in challenge.members', ng-init='member._locked = true') - h4 {{member.profile.name}} - habitrpg-tasks(main=false, obj='member') \ No newline at end of file + div(ng-if='challenge.description') {{challenge.description}} + habitrpg-tasks(obj='challenge', main=false) + h3 Statistics + div(ng-repeat='member in challenge.members', ng-init='member._locked = true') + h4 {{member.profile.name}} + habitrpg-tasks(main=false, obj='member') \ No newline at end of file diff --git a/views/options/groups/index.jade b/views/options/groups/index.jade index 566a25295f..6481d5e79f 100644 --- a/views/options/groups/index.jade +++ b/views/options/groups/index.jade @@ -1,66 +1,79 @@ // FIXME note, due to https://github.com/angular-ui/bootstrap/issues/783 we can't use nested angular-bootstrap tabs // Subscribe to that ticket & change this when they fix -ul.nav.nav-tabs - li.active - a(data-target='#groups-party', data-toggle='tab') Party - li - a(data-target='#groups-guilds', data-toggle='tab', ng-click='fetchGuilds()') Guilds +script(type='text/ng-template', id='partials/options.groups.tavern.html') + include ./tavern -.tab-content(ng-controller='PartyCtrl') - #groups-party.tab-pane.active - div(ng-show='group._id') +script(type='text/ng-template', id='partials/options.groups.party.html') + div(ng-show='group._id') + include ./group + div(ng-hide='group._id') + div(ng-show='user.invitations.party') + // #with required for the accept/reject buttons + // {#with _user.invitations.party as :party} + h2 You're Invited To {{user.invitations.party.name}} + a.btn.btn-success(data-type='party', ng-click='join(user.invitations.party)') Accept + a.btn.btn-danger(ng-click='reject()') Reject + // {/} + div(ng-hide='user.invitations.party', ng-controller='PartyCtrl') + h2 Create A Party + p + | You are not in a party. You can either create one and invite friends, or if you want to join an existing party, have them enter: + pre.prettyprint. + {{user.id}} + include ./create-group + +script(type='text/ng-template', id='partials/options.groups.guilds.html') + ul.nav.nav-tabs + li.active + a(data-target='#groups-public-guilds', data-toggle='tab') Public Guilds + li(ng-repeat='group in groups.guilds') + a(data-target='#groups-guild-{{group._id}}', data-toggle='tab') {{group.name}} + li + a(data-target='#groups-create-guild', data-toggle='tab') Create Guild + .tab-content + .tab-pane.active#groups-public-guilds + div(ng-repeat='invitation in user.invitations.guilds') + h3 You're Invited To {{invitation.name}} + a.btn.btn-success(data-type='guild', ng-click='join(invitation)') Accept + a.btn.btn-danger(ng-click='reject(invitation)') Reject + // Public Groups + .options-group.option-large.whatever-options + input.option-content(type='text',ng-model='guildSearch', placeholder='Search') + table.table.table-striped + tr(ng-repeat='group in groups.public | filter:guildSearch') + td + ul.pull-right.challenge-accordion-header-specs + li {{group.members.length}} member(s) + li + // join / leave + a.btn.btn-small.btn-danger(ng-show='isMember(user, group)', ng-click='leave(group)') + i.icon-ban-circle + | Leave + a.btn.btn-small.btn-success(ng-hide='isMember(user, group)', ng-click='join(group)') + i.icon-ok + | Join + h4 {{group.name}} + p {{group.description}} + .tab-pane(id='groups-guild-{{group._id}}', ng-repeat='group in groups.guilds') include ./group - div(ng-hide='group._id') - div(ng-show='user.invitations.party') - // #with required for the accept/reject buttons - // {#with _user.invitations.party as :party} - h2 You're Invited To {{user.invitations.party.name}} - a.btn.btn-success(data-type='party', ng-click='join(user.invitations.party)') Accept - a.btn.btn-danger(ng-click='reject()') Reject - // {/} - div(ng-hide='user.invitations.party', ng-controller='PartyCtrl') - h2 Create A Party - p - | You are not in a party. You can either create one and invite friends, or if you want to join an existing party, have them enter: - pre.prettyprint. - {{user.id}} - include ./create-group - #groups-guilds.tab-pane(ng-controller='GuildsCtrl') - ul.nav.nav-tabs - li.active - a(data-target='#groups-public-guilds', data-toggle='tab') Public Guilds - li(ng-repeat='group in groups.guilds') - a(data-target='#groups-guild-{{group._id}}', data-toggle='tab') {{group.name}} - li - a(data-target='#groups-create-guild', data-toggle='tab') Create Guild - .tab-content - .tab-pane.active#groups-public-guilds - div(ng-repeat='invitation in user.invitations.guilds') - h3 You're Invited To {{invitation.name}} - a.btn.btn-success(data-type='guild', ng-click='join(invitation)') Accept - a.btn.btn-danger(ng-click='reject(invitation)') Reject - // Public Groups - .options-group.option-large.whatever-options - input.option-content(type='text',ng-model='guildSearch', placeholder='Search') - table.table.table-striped - tr(ng-repeat='group in groups.public | filter:guildSearch') - td - ul.pull-right.challenge-accordion-header-specs - li {{group.members.length}} member(s) - li - // join / leave - a.btn.btn-small.btn-danger(ng-show='isMember(user, group)', ng-click='leave(group)') - i.icon-ban-circle - | Leave - a.btn.btn-small.btn-success(ng-hide='isMember(user, group)', ng-click='join(group)') - i.icon-ok - | Join - h4 {{group.name}} - p {{group.description}} - .tab-pane(id='groups-guild-{{group._id}}', ng-repeat='group in groups.guilds') - include ./group + .tab-pane#groups-create-guild + include ./create-group - .tab-pane#groups-create-guild - include ./create-group \ No newline at end of file +script(type='text/ng-template', id='partials/options.groups.html') + ul.nav.nav-tabs + li(ng-class="{ active: $state.includes('options.groups.tavern') }") + a(ui-sref='options.groups.tavern') + i.icon-eye-close + | Tavern + li(ng-class="{ active: $state.includes('options.groups.party') }") + a(ui-sref='options.groups.party') + | Party + li(ng-class="{ active: $state.includes('options.groups.guilds') }") + a(ui-sref='options.groups.guilds') + | Guilds + + .tab-content + .tab-pane.active + div(ui-view) \ No newline at end of file diff --git a/views/options/groups/tavern.jade b/views/options/groups/tavern.jade index a1f05d5533..54e21ce681 100644 --- a/views/options/groups/tavern.jade +++ b/views/options/groups/tavern.jade @@ -1,4 +1,4 @@ -.row-fluid(ng-controller='TavernCtrl') +.row-fluid .span4 .tavern-pane table diff --git a/views/options/index.jade b/views/options/index.jade index 75d917912f..e17a157089 100644 --- a/views/options/index.jade +++ b/views/options/index.jade @@ -1,64 +1,37 @@ -script(id='templates/habitrpg-options.html', type="text/ng-template") +include ./profile +include ./groups/index +include ./challenges +include ./inventory/index +include ./settings + +script(id='partials/options.html', type="text/ng-template") .grid .module.full-width span.option-box.pull-right.wallet include ../shared/gems ul.nav.nav-tabs - li.active - a(data-toggle='tab', data-target='#profile-tab') + li(ng-class="{ active: $state.includes('options.profile') }") + a(ui-sref='options.profile') i.icon-user | Profile - li - a(data-toggle='tab',data-target='#groups-tab', ng-click='fetchParty()') + li(ng-class="{ active: $state.includes('options.groups') }") + a(ui-sref='options.groups') i.icon-heart | Groups - li(ng-show='user.flags.dropsEnabled') - a(data-toggle='tab',data-target='#inventory-tab') + li(ng-class="{ active: $state.includes('options.inventory') }", ng-if='user.flags.dropsEnabled') + a(ui-sref='options.inventory') i.icon-gift | Inventory - li(ng-show='user.flags.dropsEnabled') - a(data-toggle='tab',data-target='#stable-tab') - i.icon-leaf - | Stable - li - a(data-toggle='tab',data-target='#tavern-tab', ng-click='fetchTavern()') - i.icon-eye-close - | Tavern - li - a(data-toggle='tab',data-target='#achievements-tab') - i.icon-certificate - | Achievements - li - a(data-toggle='tab',data-target='#challenges-tab') + li(ng-class="{ active: $state.includes('options.challenges') }") + a(ui-sref='options.challenges') i.icon-bullhorn | Challenges - li - a(data-toggle='tab',data-target='#settings-tab') + li(ng-class="{ active: $state.includes('options.settings') }") + a(ui-sref='options.settings') i.icon-wrench | Settings .tab-content - .tab-pane.active#profile-tab - include ./profile - - .tab-pane#groups-tab - include ./groups/index - - .tab-pane#inventory-tab - include ./inventory - - .tab-pane#stable-tab - include ./pets - - .tab-pane#tavern-tab - include ./groups/tavern - - .tab-pane#achievements-tab(ng-controller='UserCtrl') - include ../shared/profiles/achievements - - .tab-pane#challenges-tab - include ./challenges - - .tab-pane#settings-tab - include ./settings \ No newline at end of file + .tab-pane.active + div(ui-view) diff --git a/views/options/inventory.jade b/views/options/inventory.jade deleted file mode 100644 index 6fac392ac7..0000000000 --- a/views/options/inventory.jade +++ /dev/null @@ -1,54 +0,0 @@ -.row-fluid(ng-controller='InventoryCtrl') - .span6.border-right - h2 Inventory - p.well Combine eggs with hatching potions to make pets by clicking an egg and then a potion. Sell unwanted drops to Alexander the Merchant. - menu.inventory-list(type='list') - li.customize-menu - menu.pets-menu(label='Eggs ({{userEggs.length}})') - p(ng-show='userEggs.length < 1') You don't have any eggs yet. - div(ng-repeat='egg in userEggs track by $index') - button.customize-option(tooltip='{{egg.text}}', ng-click='chooseEgg(egg, $index)', class='Pet_Egg_{{egg.name}}', ng-class='selectableInventory(egg, selectedPotion.name, $index)') - p {{egg.text}} - li.customize-menu - menu.hatchingPotion-menu(label='Hatching Potions ({{userHatchingPotions.length}})') - p(ng-show='userHatchingPotions.length < 1') You don't have any hatching potions yet. - div(ng-repeat='hatchingPotion in userHatchingPotions track by $index') - button.customize-option(tooltip='{{hatchingPotion}}', ng-click='choosePotion(hatchingPotion, $index)', class='Pet_HatchingPotion_{{hatchingPotion}}', ng-class='selectableInventory(selectedEgg, hatchingPotion, $index)') - p {{hatchingPotion}} - - .span6 - h2 Market - .row-fluid(ng-controller='MarketCtrl') - table.NPC-Alex-container - tr - td - .NPC-Alex.pull-left - td - .popover.static-popover.fade.right.in - .arrow - h3.popover-title - a(target='_blank', href='http://www.kickstarter.com/profile/523661924') Alexander the Merchant - .popover-content - p - | Welcome to the Market. Dying to get that particular pet you're after, but don't want to wait for it to drop? Buy it here! If you have unwanted drops, sell them to me. - p - button.btn.btn-primary(ng-show='selectedEgg', ng-click='sellInventory()') - | Sell {{selectedEgg.name}} for {{selectedEgg.value}} GP - button.btn.btn-primary(ng-show='selectedPotion', ng-click='sellInventory()') - | Sell {{selectedPotion.name}} for {{selectedPotion.value}} GP - - menu.inventory-list(type='list') - li.customize-menu - menu.pets-menu(label='Eggs') - div(ng-repeat='egg in eggs track by $index') - button.customize-option(tooltip='{{egg.text}} - {{egg.value}} Gem(s)', ng-click='buy("egg", egg)', class='Pet_Egg_{{egg.name}}') - p {{egg.text}} - - li.customize-menu - menu.pets-menu(label='Hatching Potions') - div(ng-repeat='hatchingPotion in hatchingPotions track by $index') - button.customize-option(tooltip='{{hatchingPotion.text}} - {{hatchingPotion.value}} Gem(s)', ng-click='buy("hatchingPotion", hatchingPotion)', class='Pet_HatchingPotion_{{hatchingPotion.name}}') - p {{hatchingPotion.text}} - - - diff --git a/views/options/inventory/index.jade b/views/options/inventory/index.jade new file mode 100644 index 0000000000..ff6a64a84d --- /dev/null +++ b/views/options/inventory/index.jade @@ -0,0 +1,15 @@ +include ./inventory +include ./stable + +script(type='text/ng-template', id='partials/options.inventory.html') + ul.nav.nav-tabs + li(ng-class="{ active: $state.includes('options.inventory.inventory') }") + a(ui-sref='options.inventory.inventory') + | Inventory + li(ng-class="{ active: $state.includes('options.inventory.stable') }") + a(ui-sref='options.inventory.stable') + | Stable + + .tab-content + .tab-pane.active + div(ui-view) \ No newline at end of file diff --git a/views/options/inventory/inventory.jade b/views/options/inventory/inventory.jade new file mode 100644 index 0000000000..98c71ea6e7 --- /dev/null +++ b/views/options/inventory/inventory.jade @@ -0,0 +1,55 @@ +script(type='text/ng-template', id='partials/options.inventory.inventory.html') + .row-fluid(ng-controller='InventoryCtrl') + .span6.border-right + h2 Inventory + p.well Combine eggs with hatching potions to make pets by clicking an egg and then a potion. Sell unwanted drops to Alexander the Merchant. + menu.inventory-list(type='list') + li.customize-menu + menu.pets-menu(label='Eggs ({{userEggs.length}})') + p(ng-show='userEggs.length < 1') You don't have any eggs yet. + div(ng-repeat='egg in userEggs track by $index') + button.customize-option(tooltip='{{egg.text}}', ng-click='chooseEgg(egg, $index)', class='Pet_Egg_{{egg.name}}', ng-class='selectableInventory(egg, selectedPotion.name, $index)') + p {{egg.text}} + li.customize-menu + menu.hatchingPotion-menu(label='Hatching Potions ({{userHatchingPotions.length}})') + p(ng-show='userHatchingPotions.length < 1') You don't have any hatching potions yet. + div(ng-repeat='hatchingPotion in userHatchingPotions track by $index') + button.customize-option(tooltip='{{hatchingPotion}}', ng-click='choosePotion(hatchingPotion, $index)', class='Pet_HatchingPotion_{{hatchingPotion}}', ng-class='selectableInventory(selectedEgg, hatchingPotion, $index)') + p {{hatchingPotion}} + + .span6 + h2 Market + .row-fluid(ng-controller='MarketCtrl') + table.NPC-Alex-container + tr + td + .NPC-Alex.pull-left + td + .popover.static-popover.fade.right.in + .arrow + h3.popover-title + a(target='_blank', href='http://www.kickstarter.com/profile/523661924') Alexander the Merchant + .popover-content + p + | Welcome to the Market. Dying to get that particular pet you're after, but don't want to wait for it to drop? Buy it here! If you have unwanted drops, sell them to me. + p + button.btn.btn-primary(ng-show='selectedEgg', ng-click='sellInventory()') + | Sell {{selectedEgg.name}} for {{selectedEgg.value}} GP + button.btn.btn-primary(ng-show='selectedPotion', ng-click='sellInventory()') + | Sell {{selectedPotion.name}} for {{selectedPotion.value}} GP + + menu.inventory-list(type='list') + li.customize-menu + menu.pets-menu(label='Eggs') + div(ng-repeat='egg in eggs track by $index') + button.customize-option(tooltip='{{egg.text}} - {{egg.value}} Gem(s)', ng-click='buy("egg", egg)', class='Pet_Egg_{{egg.name}}') + p {{egg.text}} + + li.customize-menu + menu.pets-menu(label='Hatching Potions') + div(ng-repeat='hatchingPotion in hatchingPotions track by $index') + button.customize-option(tooltip='{{hatchingPotion.text}} - {{hatchingPotion.value}} Gem(s)', ng-click='buy("hatchingPotion", hatchingPotion)', class='Pet_HatchingPotion_{{hatchingPotion.name}}') + p {{hatchingPotion.text}} + + + diff --git a/views/options/inventory/stable.jade b/views/options/inventory/stable.jade new file mode 100644 index 0000000000..e4cf11084e --- /dev/null +++ b/views/options/inventory/stable.jade @@ -0,0 +1,30 @@ +script(type='text/ng-template', id='partials/options.inventory.stable.html') + .stable(ng-controller='PetsCtrl') + .NPC-Matt + .popover.static-popover.fade.right.in(style='max-width: 550px; margin-left: 10px;') + .arrow + h3.popover-title + a(target='_blank', href='http://www.kickstarter.com/profile/mattboch') Matt Boch + .popover-content + p + | Welcome to the Stable! I'm Matt, the beast master. Choose a pet here to adventure at your side - they aren't much help yet, but I forsee a time when they're able to + a(href='https://trello.com/card/mounts/50e5d3684fe3a7266b0036d6/221') grow into powerful steeds + | ! Until that day, + a(target='_blank', href='https://f.cloud.github.com/assets/2374703/164631/3ed5fa6c-78cd-11e2-8743-f65ac477b55e.png') have a look-see + | at all the pets you can collect. + h4 {{userPets.length}} / {{totalPets}} Pets Found + + menu.pets(type='list') + li.customize-menu(ng-repeat='pet in pets') + menu + div(ng-repeat='potion in hatchingPotions', tooltip='{{potion.name}} {{pet.name}}') + button(class="pet-button Pet-{{pet.name}}-{{potion.name}}", ng-show='hasPet(pet.name, potion.name)', ng-class="{active: isCurrentPet(pet.name, potion.name)}", ng-click='choosePet(pet.name, potion.name)') + button(class="pet-button pet-not-owned", ng-hide='hasPet(pet.name, potion.name)') + img(src='/bower_components/habitrpg-shared/img/PixelPaw.png') + + h4 Rare Pets + menu + div(ng-if='hasPet("Wolf", "Veteran")') + button(class="pet-button Pet-Wolf-Veteran", ng-class='{active: isCurrentPet("Wolf", "Veteran")}', ng-click='choosePet("Wolf", "Veteran")', tooltip='Veteran Wolf') + div(ng-if='hasPet("Wolf", "Cerberus")') + button(class="pet-button Pet-Wolf-Cerberus", ng-class='{active: isCurrentPet("Wolf", "Cerberus")}', ng-click='choosePet("Wolf", "Cerberus")', tooltip='Cerberus Pup') \ No newline at end of file diff --git a/views/options/pets.jade b/views/options/pets.jade deleted file mode 100644 index 80d8b1a899..0000000000 --- a/views/options/pets.jade +++ /dev/null @@ -1,29 +0,0 @@ -.stable(ng-controller='PetsCtrl') - .NPC-Matt - .popover.static-popover.fade.right.in(style='max-width: 550px; margin-left: 10px;') - .arrow - h3.popover-title - a(target='_blank', href='http://www.kickstarter.com/profile/mattboch') Matt Boch - .popover-content - p - | Welcome to the Stable! I'm Matt, the beast master. Choose a pet here to adventure at your side - they aren't much help yet, but I forsee a time when they're able to - a(href='https://trello.com/card/mounts/50e5d3684fe3a7266b0036d6/221') grow into powerful steeds - | ! Until that day, - a(target='_blank', href='https://f.cloud.github.com/assets/2374703/164631/3ed5fa6c-78cd-11e2-8743-f65ac477b55e.png') have a look-see - | at all the pets you can collect. - h4 {{userPets.length}} / {{totalPets}} Pets Found - - menu.pets(type='list') - li.customize-menu(ng-repeat='pet in pets') - menu - div(ng-repeat='potion in hatchingPotions', tooltip='{{potion.name}} {{pet.name}}') - button(class="pet-button Pet-{{pet.name}}-{{potion.name}}", ng-show='hasPet(pet.name, potion.name)', ng-class="{active: isCurrentPet(pet.name, potion.name)}", ng-click='choosePet(pet.name, potion.name)') - button(class="pet-button pet-not-owned", ng-hide='hasPet(pet.name, potion.name)') - img(src='/bower_components/habitrpg-shared/img/PixelPaw.png') - - h4 Rare Pets - menu - div(ng-if='hasPet("Wolf", "Veteran")') - button(class="pet-button Pet-Wolf-Veteran", ng-class='{active: isCurrentPet("Wolf", "Veteran")}', ng-click='choosePet("Wolf", "Veteran")', tooltip='Veteran Wolf') - div(ng-if='hasPet("Wolf", "Cerberus")') - button(class="pet-button Pet-Wolf-Cerberus", ng-class='{active: isCurrentPet("Wolf", "Cerberus")}', ng-click='choosePet("Wolf", "Cerberus")', tooltip='Cerberus Pup') \ No newline at end of file diff --git a/views/options/profile.jade b/views/options/profile.jade index 98e1ebebd3..8ee97c5fdb 100644 --- a/views/options/profile.jade +++ b/views/options/profile.jade @@ -1,128 +1,145 @@ -.row-fluid(ng-controller='UserCtrl') - - // ---- Customize ----- - .span4.border-right - menu(type='list') - // gender - li.customize-menu - menu(label='Head') - menu - button.m_head_0.customize-option(type='button', ng-click='set("preferences.gender","m")') - button.f_head_0.customize-option(type='button', ng-click='set("preferences.gender","f")') - label.checkbox - input(type='checkbox', ng-model='user.preferences.showHelm', ng-change='toggleHelm(user.preferences.showHelm)') - | Show Helm - hr - - // hair - li.customize-menu - menu(label='Hair') - button(class='{{user.preferences.gender}}_hair_blond customize-option', type='button', ng-click='set("preferences.hair","blond")') - button(class='{{user.preferences.gender}}_hair_black customize-option', type='button', ng-click='set("preferences.hair","black")') - button(class='{{user.preferences.gender}}_hair_brown customize-option', type='button', ng-click='set("preferences.hair","brown")') - button(class='{{user.preferences.gender}}_hair_white customize-option', type='button', ng-click='set("preferences.hair","white")') - button(class='{{user.preferences.gender}}_hair_red customize-option', type='button', ng-click='set("preferences.hair","red")') - hr - - // skin - li.customize-menu - menu(label='Basic Skins') - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_asian', ng-click='set("preferences.skin","asian")') - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_white', ng-click='set("preferences.skin","white")') - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_ea8349', ng-click='set("preferences.skin","ea8349")') - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_c06534', ng-click='set("preferences.skin","c06534")') - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_98461a', ng-click='set("preferences.skin","98461a")') - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_black', ng-click='set("preferences.skin","black")') - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_dead', ng-click='set("preferences.skin","dead")') - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_orc', ng-click='set("preferences.skin","orc")') - - // Rainbow Skin - h5. - Rainbow Skins - 2/skin - //menu(label='Rainbow Skins (2G / skin)') - menu - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_eb052b', ng-class='{locked: !user.purchased.skin.eb052b}', ng-click='unlock("skin.eb052b")') - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_f69922', ng-class='{locked: !user.purchased.skin.f69922}', ng-click='unlock("skin.f69922")') - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_f5d70f', ng-class='{locked: !user.purchased.skin.f5d70f}', ng-click='unlock("skin.f5d70f")') - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_0ff591', ng-class='{locked: !user.purchased.skin.0ff591}', ng-click='unlock("skin.0ff591")') - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_2b43f6', ng-class='{locked: !user.purchased.skin.2b43f6}', ng-click='unlock("skin.2b43f6")') - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_d7a9f7', ng-class='{locked: !user.purchased.skin.d7a9f7}', ng-click='unlock("skin.d7a9f7")') - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_800ed0', ng-class='{locked: !user.purchased.skin.800ed0}', ng-click='unlock("skin.800ed0")') - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_rainbow', ng-class='{locked: !user.purchased.skin.rainbow}', ng-click='unlock("skin.rainbow")') - button.btn.btn-small.btn-primary(ng-hide='user.purchased.skin.eb052b && user.purchased.skin.f69922 && user.purchased.skin.f5d70f && user.purchased.skin.0ff591 && user.purchased.skin.2b43f6 && user.purchased.skin.d7a9f7 && user.purchased.skin.800ed0 && user.purchased.skin.rainbow', ng-click='unlock(["skin.eb052b", "skin.f69922", "skin.f5d70f", "skin.0ff591", "skin.2b43f6", "skin.d7a9f7", "skin.800ed0", "skin.rainbow"])') Unlock Set - 5 - - // Special Events - div.well.limited-edition - .label.label-info.pull-right(popover='Available for purchase until November 10th (but permanently in your options if purchased).', popover-title='Limited Edition', popover-placement='right', popover-trigger='mouseenter') - | Limited Edition  - i.icon.icon-question-sign - h5. - Spooky Skins - 2/skin - //menu(label='Spooky Skins (2 Gems / skin)') - menu - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_monster', ng-class='{locked: !user.purchased.skin.monster}', ng-click='unlock("skin.monster")') - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_pumpkin', ng-class='{locked: !user.purchased.skin.pumpkin}', ng-click='unlock("skin.pumpkin")') - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_skeleton', ng-class='{locked: !user.purchased.skin.skeleton}', ng-click='unlock("skin.skeleton")') - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_zombie', ng-class='{locked: !user.purchased.skin.zombie}', ng-click='unlock("skin.zombie")') - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_ghost', ng-class='{locked: !user.purchased.skin.ghost}', ng-click='unlock("skin.ghost")') - button.customize-option(type='button', class='{{user.preferences.gender}}_skin_shadow', ng-class='{locked: !user.purchased.skin.shadow}', ng-click='unlock("skin.shadow")') - button.btn.btn-small.btn-primary(ng-hide='user.purchased.skin.monster && user.purchased.skin.pumpkin && user.purchased.skin.skeleton && user.purchased.skin.zombie && user.purchased.skin.ghost && user.purchased.skin.shadow', ng-click='unlock(["skin.monster", "skin.pumpkin", "skin.skeleton", "skin.zombie", "skin.ghost", "skin.shadow"])') Unlock Set - 5 - - - menu(ng-show='user.preferences.gender=="f"', type='list') +script(id='partials/options.profile.avatar.html', type='text/ng-template') + .row-fluid + .span4.border-right + menu(type='list') + // body-type li.customize-menu - menu(label='Clothing') - button.f_armor_0_v1.customize-option(type='button', ng-click='set("preferences.armorSet","v1")') - button.f_armor_0_v2.customize-option(type='button', ng-click='set("preferences.armorSet","v2")') + menu(label='Head') + menu + button.m_head_0.customize-option(type='button', ng-click='set("preferences.gender","m")') + button.f_head_0.customize-option(type='button', ng-click='set("preferences.gender","f")') + label.checkbox + input(type='checkbox', ng-model='user.preferences.showHelm', ng-change='toggleHelm(user.preferences.showHelm)') + | Show Helm - // ------ Stats ------ - .span4.border-right - include ../shared/profiles/stats + menu(ng-show='user.preferences.gender=="f"', type='list') + li.customize-menu + menu(label='Clothing') + button.f_armor_0_v1.customize-option(type='button', ng-click='set("preferences.armorSet","v1")') + button.f_armor_0_v2.customize-option(type='button', ng-click='set("preferences.armorSet","v2")') - // ------- Edit ------- - .span4 - button.btn.btn-default(ng-click='_editing.profile = true', ng-show='!_editing.profile') Edit - button.btn.btn-primary(ng-click='save()', ng-show='_editing.profile') Save - div(ng-show='!_editing.profile') - h4 Display Name - span(ng-show='profile.profile.name') {{profile.profile.name}} - span.muted(ng-hide='profile.profile.name') - None - + .span4.border-right + // hair + li.customize-menu + menu(label='Hair') + button(class='{{user.preferences.gender}}_hair_blond customize-option', type='button', ng-click='set("preferences.hair","blond")') + button(class='{{user.preferences.gender}}_hair_black customize-option', type='button', ng-click='set("preferences.hair","black")') + button(class='{{user.preferences.gender}}_hair_brown customize-option', type='button', ng-click='set("preferences.hair","brown")') + button(class='{{user.preferences.gender}}_hair_white customize-option', type='button', ng-click='set("preferences.hair","white")') + button(class='{{user.preferences.gender}}_hair_red customize-option', type='button', ng-click='set("preferences.hair","red")') - h4 Photo - img(ng-show='profile.profile.imageUrl', ng-src='{{profile.profile.imageUrl}}') - span.muted(ng-hide='profile.profile.imageUrl') - None - + .span4.border-right + // skin + li.customize-menu + menu(label='Basic Skins') + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_asian', ng-click='set("preferences.skin","asian")') + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_white', ng-click='set("preferences.skin","white")') + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_ea8349', ng-click='set("preferences.skin","ea8349")') + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_c06534', ng-click='set("preferences.skin","c06534")') + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_98461a', ng-click='set("preferences.skin","98461a")') + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_black', ng-click='set("preferences.skin","black")') + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_dead', ng-click='set("preferences.skin","dead")') + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_orc', ng-click='set("preferences.skin","orc")') - h4 Blurb - markdown(ng-show='profile.profile.blurb', ng-model='profile.profile.blurb') - span.muted(ng-hide='profile.profile.blurb') - None - - //{{profile.profile.blurb | linky:'_blank'}} + // Rainbow Skin + h5. + Rainbow Skins - 2/skin + //menu(label='Rainbow Skins (2G / skin)') + menu + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_eb052b', ng-class='{locked: !user.purchased.skin.eb052b}', ng-click='unlock("skin.eb052b")') + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_f69922', ng-class='{locked: !user.purchased.skin.f69922}', ng-click='unlock("skin.f69922")') + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_f5d70f', ng-class='{locked: !user.purchased.skin.f5d70f}', ng-click='unlock("skin.f5d70f")') + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_0ff591', ng-class='{locked: !user.purchased.skin.0ff591}', ng-click='unlock("skin.0ff591")') + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_2b43f6', ng-class='{locked: !user.purchased.skin.2b43f6}', ng-click='unlock("skin.2b43f6")') + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_d7a9f7', ng-class='{locked: !user.purchased.skin.d7a9f7}', ng-click='unlock("skin.d7a9f7")') + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_800ed0', ng-class='{locked: !user.purchased.skin.800ed0}', ng-click='unlock("skin.800ed0")') + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_rainbow', ng-class='{locked: !user.purchased.skin.rainbow}', ng-click='unlock("skin.rainbow")') + button.btn.btn-small.btn-primary(ng-hide='user.purchased.skin.eb052b && user.purchased.skin.f69922 && user.purchased.skin.f5d70f && user.purchased.skin.0ff591 && user.purchased.skin.2b43f6 && user.purchased.skin.d7a9f7 && user.purchased.skin.800ed0 && user.purchased.skin.rainbow', ng-click='unlock(["skin.eb052b", "skin.f69922", "skin.f5d70f", "skin.0ff591", "skin.2b43f6", "skin.d7a9f7", "skin.800ed0", "skin.rainbow"])') Unlock Set - 5 - h4 Websites - ul(ng-show='profile.profile.websites.length > 0') - // TODO let's remove links eventually, since we can do markdown on profiles - li(ng-repeat='website in profile.profile.websites') - a(target='_blank', ng-href='{{website}}') {{website}} - span.muted(ng-hide='profile.profile.websites.length > 0') - None - + // Special Events + div.well.limited-edition + .label.label-info.pull-right(popover='Available for purchase until November 10th (but permanently in your options if purchased).', popover-title='Limited Edition', popover-placement='right', popover-trigger='mouseenter') + | Limited Edition  + i.icon.icon-question-sign + h5. + Spooky Skins - 2/skin + //menu(label='Spooky Skins (2 Gems / skin)') + menu + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_monster', ng-class='{locked: !user.purchased.skin.monster}', ng-click='unlock("skin.monster")') + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_pumpkin', ng-class='{locked: !user.purchased.skin.pumpkin}', ng-click='unlock("skin.pumpkin")') + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_skeleton', ng-class='{locked: !user.purchased.skin.skeleton}', ng-click='unlock("skin.skeleton")') + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_zombie', ng-class='{locked: !user.purchased.skin.zombie}', ng-click='unlock("skin.zombie")') + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_ghost', ng-class='{locked: !user.purchased.skin.ghost}', ng-click='unlock("skin.ghost")') + button.customize-option(type='button', class='{{user.preferences.gender}}_skin_shadow', ng-class='{locked: !user.purchased.skin.shadow}', ng-click='unlock("skin.shadow")') + button.btn.btn-small.btn-primary(ng-hide='user.purchased.skin.monster && user.purchased.skin.pumpkin && user.purchased.skin.skeleton && user.purchased.skin.zombie && user.purchased.skin.ghost && user.purchased.skin.shadow', ng-click='unlock(["skin.monster", "skin.pumpkin", "skin.skeleton", "skin.zombie", "skin.ghost", "skin.shadow"])') Unlock Set - 5 - div.whatever-options(ng-show='_editing.profile') - // TODO use photo-upload instead: https://groups.google.com/forum/?fromgroups=#!topic/derbyjs/xMmADvxBOak - .control-group.option-large - label.control-label Display Name - input.option-content(type='text', placeholder='Full Name', ng-model='editingProfile.name') - .control-group.option-large - label.control-label Photo Url - input.option-content(type='url', ng-model='editingProfile.imageUrl', placeholder='Image Url') - .control-group.option-large - label.control-label Blurb - textarea.option-content(style='height:15em;', placeholder='Blurb', ng-model='editingProfile.blurb') - include ../shared/formatting-help - .control-group.option-large - label.control-label Websites - form(ng-submit='addWebsite()') - input.option-content(type='url', ng-model='_newWebsite', placeholder='Add Website') - ul - // would prefer if there were and index in #each, instead using data-website to search with indexOf - li(ng-repeat='website in editingProfile.websites') - | {{website}} - a(ng-click='removeWebsite($index)') - i.icon-remove +script(id='partials/options.profile.stats.html', type='text/ng-template') + .row-fluid + .span6.border-right + include ../shared/profiles/stats + .span6.border-right + include ../shared/profiles/achievements + +script(id='partials/options.profile.profile.html', type='text/ng-template') + button.btn.btn-default(ng-click='_editing.profile = true', ng-show='!_editing.profile') Edit + button.btn.btn-primary(ng-click='save()', ng-show='_editing.profile') Save + div(ng-show='!_editing.profile') + h4 Display Name + span(ng-show='profile.profile.name') {{profile.profile.name}} + span.muted(ng-hide='profile.profile.name') - None - + + h4 Photo + img(ng-show='profile.profile.imageUrl', ng-src='{{profile.profile.imageUrl}}') + span.muted(ng-hide='profile.profile.imageUrl') - None - + + h4 Blurb + markdown(ng-show='profile.profile.blurb', ng-model='profile.profile.blurb') + span.muted(ng-hide='profile.profile.blurb') - None - + //{{profile.profile.blurb | linky:'_blank'}} + + h4 Websites + ul(ng-show='profile.profile.websites.length > 0') + // TODO let's remove links eventually, since we can do markdown on profiles + li(ng-repeat='website in profile.profile.websites') + a(target='_blank', ng-href='{{website}}') {{website}} + span.muted(ng-hide='profile.profile.websites.length > 0') - None - + + div.whatever-options(ng-show='_editing.profile') + // TODO use photo-upload instead: https://groups.google.com/forum/?fromgroups=#!topic/derbyjs/xMmADvxBOak + .control-group.option-large + label.control-label Display Name + input.option-content(type='text', placeholder='Full Name', ng-model='editingProfile.name') + .control-group.option-large + label.control-label Photo Url + input.option-content(type='url', ng-model='editingProfile.imageUrl', placeholder='Image Url') + .control-group.option-large + label.control-label Blurb + textarea.option-content(style='height:15em;', placeholder='Blurb', ng-model='editingProfile.blurb') + br + include ../shared/formatting-help + .control-group.option-large + label.control-label Websites + form(ng-submit='addWebsite()') + input.option-content(type='url', ng-model='_newWebsite', placeholder='Add Website') + ul + // would prefer if there were and index in #each, instead using data-website to search with indexOf + li(ng-repeat='website in editingProfile.websites') + | {{website}} + a(ng-click='removeWebsite($index)') + i.icon-remove + +script(id='partials/options.profile.html', type="text/ng-template") + ul.nav.nav-tabs + li(ng-class="{ active: $state.includes('options.profile.avatar') }") + a(ui-sref='options.profile.avatar') + | Avatar + li(ng-class="{ active: $state.includes('options.profile.stats') }") + a(ui-sref='options.profile.stats') + | Stats & Achievements + li(ng-class="{ active: $state.includes('options.profile.profile') }") + a(ui-sref='options.profile.profile') + | Profile + + .tab-content + .tab-pane.active + div(ui-view) diff --git a/views/options/settings.jade b/views/options/settings.jade index a3f8201d8c..4c957c119b 100644 --- a/views/options/settings.jade +++ b/views/options/settings.jade @@ -1,43 +1,44 @@ -.row-fluid(ng-controller='SettingsCtrl') - .personal-options.span6.border-right - h2 Settings - h4 Custom Day Start - .option-group.option-short - input.option-content.option-time(type='number', min='0', max='24', ng-model='user.preferences.dayStart', ng-change='saveDayStart()') - span.input-suffix :00 (24h clock) - div - small - | Habit defaults to check and reset your dailies at midnight in your time zone each day. You can customize the hour here (enter a number between 0 and 24). - hr - h4 Misc - button.btn(ng-hide='user.preferences.hideHeader', ng-click='set("preferences.hideHeader",true)') Hide Header - button.btn(ng-show='user.preferences.hideHeader', ng-click='set("preferences.hideHeader",false)') Show Header - button.btn(ng-click='showTour()') Show Tour - button.btn(ng-click='showBailey()') Show Bailey - - div(ng-show='user.auth.local') +script(type='text/ng-template', id='partials/options.settings.html') + .row-fluid + .personal-options.span6.border-right + h2 Settings + h4 Custom Day Start + .option-group.option-short + input.option-content.option-time(type='number', min='0', max='24', ng-model='user.preferences.dayStart', ng-change='saveDayStart()') + span.input-suffix :00 (24h clock) + div + small + | Habit defaults to check and reset your dailies at midnight in your time zone each day. You can customize the hour here (enter a number between 0 and 24). hr - h4 Change Password - form(ng-submit='changePassword(changePass)', ng-show='user.auth.local') - .control-group - input(type='password', placeholder='Old Password', ng-model='changePass.oldPassword', required) - .control-group - input(type='password', placeholder='New Password', ng-model='changePass.newPassword', required) - .control-group - input(type='password', placeholder='Confirm New Password', ng-model='changePass.confirmNewPassword', required) - input.btn(type='submit', value='Submit') + h4 Misc + button.btn(ng-hide='user.preferences.hideHeader', ng-click='set("preferences.hideHeader",true)') Hide Header + button.btn(ng-show='user.preferences.hideHeader', ng-click='set("preferences.hideHeader",false)') Show Header + button.btn(ng-click='showTour()') Show Tour + button.btn(ng-click='showBailey()') Show Bailey - hr - h4 Danger Zone - a.btn.btn-danger(ng-click='modals.reset = true', tooltip='Resets your entire account (dangerous).') Reset - a.btn.btn-danger(ng-click='modals.restore = true', tooltip='Restores attributes to your character.') Restore - a.btn.btn-danger(ng-click='modals.delete = true', tooltip='Delete your account.') Delete - .span6 - h2 API - small Copy these for use in third party applications. - h6 User ID - pre.prettyprint {{user.id}} - h6 API Token - pre.prettyprint {{user.apiToken}} - h6 QR Code - img(src='https://chart.googleapis.com/chart?cht=qr&chs=200x200&chl=%7Baddress%3A%22https%3A%2F%2Fhabitrpg.com%22%2Cuser%3A%22{{user.id}}%22%2Ckey%3A%22{{user.apiToken}}%22%7D,&choe=UTF-8&chld=L', alt='qrcode') + div(ng-show='user.auth.local') + hr + h4 Change Password + form(ng-submit='changePassword(changePass)', ng-show='user.auth.local') + .control-group + input(type='password', placeholder='Old Password', ng-model='changePass.oldPassword', required) + .control-group + input(type='password', placeholder='New Password', ng-model='changePass.newPassword', required) + .control-group + input(type='password', placeholder='Confirm New Password', ng-model='changePass.confirmNewPassword', required) + input.btn(type='submit', value='Submit') + + hr + h4 Danger Zone + a.btn.btn-danger(ng-click='modals.reset = true', tooltip='Resets your entire account (dangerous).') Reset + a.btn.btn-danger(ng-click='modals.restore = true', tooltip='Restores attributes to your character.') Restore + a.btn.btn-danger(ng-click='modals.delete = true', tooltip='Delete your account.') Delete + .span6 + h2 API + small Copy these for use in third party applications. + h6 User ID + pre.prettyprint {{user.id}} + h6 API Token + pre.prettyprint {{user.apiToken}} + h6 QR Code + img(src='https://chart.googleapis.com/chart?cht=qr&chs=200x200&chl=%7Baddress%3A%22https%3A%2F%2Fhabitrpg.com%22%2Cuser%3A%22{{user.id}}%22%2Ckey%3A%22{{user.apiToken}}%22%7D,&choe=UTF-8&chld=L', alt='qrcode')