From bc4798b35439f0a3b37d5f531ea651d75e570ae6 Mon Sep 17 00:00:00 2001 From: Tyler Renelle Date: Sat, 31 Aug 2013 22:59:35 -0400 Subject: [PATCH] groups: big changes here i may decide to revert. GET /api/v1/groups optionally takes ?type=guilds (guilds, party, tavern, public). this allows us to incrementally load the app as they click through the tabs, because guilds is really large (1.5mb!) - gotta cut this down somehow. The big issue is requireing return values as an array, so ngResource can work with the response (subsequent group.$postChat(), group.$join(), etc.). The array format doesn't really work out that well, so I may scrap --- assets/js/controllers/groupsCtrl.js | 73 ++++++++++++++++++++-------- assets/js/services/groupServices.js | 6 ++- public/page-loader.gif | Bin 0 -> 8534 bytes src/controllers/groups.js | 49 +++++++++++++++++-- src/routes/api.js | 3 ++ views/index.jade | 37 ++++++++------ views/options/groups/index.jade | 2 +- views/options/index.jade | 4 +- views/shared/header/header.jade | 2 +- 9 files changed, 130 insertions(+), 46 deletions(-) create mode 100644 public/page-loader.gif diff --git a/assets/js/controllers/groupsCtrl.js b/assets/js/controllers/groupsCtrl.js index f13e4778e3..69b90aec43 100644 --- a/assets/js/controllers/groupsCtrl.js +++ b/assets/js/controllers/groupsCtrl.js @@ -2,26 +2,61 @@ habitrpg - .controller("GroupsCtrl", ['$scope', '$rootScope', 'Groups', '$http', '$location', '$http', 'API_URL', - function($scope, $rootScope, Groups, $http, API_URL) { - $scope._chatMessage = ''; - $scope.groups = Groups.query(function(groups){ - $scope.members = groups.members; + .controller("GroupsCtrl", ['$scope', '$rootScope', 'Groups', '$http', 'API_URL', '$q', + function($scope, $rootScope, Groups, $http, API_URL, $q) { + + // The user may not visit the public guilds, personal guilds, and tavern pages. So + // we defer loading them to the html until they've clicked the tabs + var partyQ = $q.defer(), + guildsQ = $q.defer(), + publicQ = $q.defer(), + tavernQ = $q.defer(); + + $scope.groups = { + party: partyQ.promise, + guilds: guildsQ.promise, + public: publicQ.promise, + tavern: tavernQ.promise + }; + + // But we don't defer triggering Party, since we always need it for the header if nothing else + Groups.query({type:'party'}, function(_groups){ + partyQ.resolve(_groups[0]); + }) + + // Note the _.once() to make sure it can never be called again + $scope.fetchGuilds = _.once(function(){ + $('#loading-indicator').show(); + Groups.query({type:'guilds'}, function(_groups){ + guildsQ.resolve(_groups); + $('#loading-indicator').hide(); + }) + Groups.query({type:'public'}, function(_groups){ + publicQ.resolve(_groups); + }) }); + + $scope.fetchTavern = _.once(function(){ + $('#loading-indicator').show(); + Groups.query({type:'tavern'}, function(_groups){ + $('#loading-indicator').hide(); + tavernQ.resolve(_groups[0]); + }) + }); + + //$scope._chatMessage = ''; $scope.postChat = function(group, message){ //FIXME ng-model makes this painfully slow! using jquery for now, which is really non-angular-like message = $('.chat-textarea').val(); if (_.isEmpty(message)) return $('.chat-btn').addClass('disabled'); - $http.post('/api/v1/groups/'+group._id+'/chat', {message:message}) - .success(function(data){ - //$scope._chatMessage = ''; - $('.chat-textarea').val(''); - group.chat = data; - $('.chat-btn').removeClass('disabled'); - }); + group.$postChat({message:message}, function(data){ + //$scope._chatMessage = ''; + $('.chat-textarea').val(''); + group.chat = data.chat; + $('.chat-btn').removeClass('disabled'); + }); } - $scope.party = true; } ]) @@ -29,6 +64,9 @@ habitrpg function($scope, Groups) { $scope.type = 'guild'; $scope.text = 'Guild'; + $scope.join = function(group){ + + } } ]) @@ -36,17 +74,12 @@ habitrpg function($scope, Groups) { $scope.type = 'party'; $scope.text = 'Party'; - Groups.query(function(groups){ - $scope.group = groups.party; - }) + $scope.group = $scope.groups.party; } ]) .controller("TavernCtrl", ['$scope', 'Groups', function($scope, Groups) { - //FIXME make sure this query is only called once for all these controllers! If not, let's memoize groups at groupServices level - Groups.query(function(groups){ - $scope.group = groups.tavern; - }); + $scope.group = $scope.groups.tavern; } ]) \ No newline at end of file diff --git a/assets/js/services/groupServices.js b/assets/js/services/groupServices.js index 18cb0262d9..caf75ca535 100644 --- a/assets/js/services/groupServices.js +++ b/assets/js/services/groupServices.js @@ -10,8 +10,10 @@ angular.module('groupServices', ['ngResource']). var Group = $resource(API_URL + '/api/v1/groups/:gid', {gid:'@_id'}, { - 'query': {method: "GET", isArray:false} - //postChat: {method: "POST"} + //'query': {method: "GET", isArray:false} + postChat: {method: "POST", url: API_URL + '/api/v1/groups/:gid/chat'}, + join: {method: "POST", url: API_URL + '/api/v1/groups/:gid/join'}, + leave: {method: "POST", url: API_URL + '/api/v1/groups/:gid/leave'} }); return Group; diff --git a/public/page-loader.gif b/public/page-loader.gif new file mode 100644 index 0000000000000000000000000000000000000000..8be8ba338d5b5aec80593295f88bcaf6608bdf18 GIT binary patch literal 8534 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 z z23q;-*;SFu4jB_v(74jA(SHL{koGE`Z@-;!Q$<_1Tf6ZFqo^mL>Sk=0Q6%KkAt z2;Ab0Z#SY?(CF4jwGpNkSy&(}Wnc__?&0A*?yQH3@2zUoo)L;0Ct? z4h8ynHz%JG0`qRkRjL`}SVyZw?`T|aW@a%i#GLKy9P`qXZ_(S2axj-6t$sfnCff|2 zdDW9*@>cdJ|H9ZNuc}i*wt4P{W>TIX!Sc)18KM2=qm@sezL=v0j0m@tTtA5EN$gA? z_Mxto(OwD**Pm(V+o|O{6ecXeBmOlX4f z2w%#$o#5{bEWPY6DT!1*8T(!|!DzPSr~UZz3p{>1=hTVg-+^;#&+VOX4|i*vhizat z?0Q^p7@f9=7$8KeRRZ_F#0rNFQ$kC$_S-5MvjDNJ-fSXA9oUOp)dp$i9TjTR!7i^K zA*-q0Hd7Sh~`+}o)c)Y$( z+?CJi1D=>WrX_D>Uztet5Pvr+-rhB32tLuiQdyqqBSjF`{s?rXr$tEP!K33A!it#Q zsT9z5{bNJRI6FV|@xEb|e?|s)?EhZj{(EEqia!0zv3^OSix67dq)8JfvZp?7m*VoI zx-UP6%c+2r)Pe4$PzWhKyLKBI{*6V2M@F$hJds2qc*iqg#g(lWE{+wkKbeIgtEo{b z`0Sj#e8sF1F&k1=Q*WclcPSs!-NHl>dwSLQ1B{E8 z6rko(7GCwfI{6V3Tc3|DMy{SlVA9O_mrVSSVj|-$10+yq-n|3~(tSL9z-A(5jqr?Y zO&ZzSWpT=nCr7M_XH9W;!>b+a^uR`AnimrgLB@ERr3KHy^!P9_UWI*+C&H*%g?25? z)Do9}5-d^Fi8C)nL4@_DAW25DJgr8dXtWD^F{^xR`AcaZ-FVf^41eeFoHQhBR)XUq z4h-xn-ED%!aM7V1Z2?M6ou2336@X+DE#Lq^Pq`fNGInrOJ_K9~P$U|k-XA`Oq1wn@ z--#H>VLZ2a_)iZPVaraH+x2(lA5;o*lOy{f&^$y*S)p*`lTDk|7RV}m+6?UZ)eMY% ztDQ_c7ZNw%rsJMeZ7}3}lcPPlvF&QHwX$ydDVv{$zy0Qt3*es7NMys2BU*Z))|;v7~DFQRpSu@8%q24%xljgx(wIb6_qM) zk6*6VGsu21OH|QRnN>CXy3)w4S(b{^lDV)Q<3UY25Mn~{oI3|%<&_4tVf`$#uCj8pM`A6Fvq G(|-Y9t#!u$ literal 0 HcmV?d00001 diff --git a/src/controllers/groups.js b/src/controllers/groups.js index fa0baad6bf..9ce51a44ec 100644 --- a/src/controllers/groups.js +++ b/src/controllers/groups.js @@ -16,13 +16,22 @@ var api = module.exports; ------------------------------------------------------------------------ */ +/** + * Get groups. If req.query.type privided, returned as an array (so ngResource can use). If not, returned as + * object {guilds, public, party, tavern}. req.query.type can be comma-separated `type=guilds,party` + * @param req + * @param res + * @param next + */ api.getGroups = function(req, res, next) { var user = res.locals.user; var usernameFields = 'auth.local.username auth.facebook.displayName auth.facebook.givenName auth.facebook.familyName auth.facebook.name'; + var type = req.query.type && req.query.type.split(','); // First get all groups async.parallel({ party: function(cb) { + if (type && !~type.indexOf('party')) return cb(null, {}); Group .findOne({type: 'party', members: {'$in': [user._id]}}) .populate({ @@ -33,13 +42,16 @@ api.getGroups = function(req, res, next) { .exec(cb); }, guilds: function(cb) { + if (type && !~type.indexOf('guilds')) return cb(null, []); Group.find({type: 'guild', members: {'$in': [user._id]}}).populate('members', usernameFields).exec(cb); // Group.find({type: 'guild', members: {'$in': [user._id]}}, cb); }, tavern: function(cb) { + if (type && !~type.indexOf('tavern')) return cb(null, {}); Group.findOne({_id: 'habitrpg'}, cb); }, "public": function(cb) { + if (type && !~type.indexOf('public')) return cb(null, []); Group.find({privacy: 'public'}, {name:1, description:1, members:1}, cb); } }, function(err, results){ @@ -52,7 +64,15 @@ api.getGroups = function(req, res, next) { // Sort public groups by members length (not easily doable in mongoose) results.public = _.sortBy(results.public, function(group){ return -group.members.length; - }) + }); + + // If they're requesting a specific type, let's return it as an array so that $ngResource + // can utilize it properly + if (type) { + results = _.reduce(type, function(m,t){ + return m.concat(_.isArray(results[t]) ? results[t] : [results[t]]); + }, []); + } res.json(results); }) @@ -74,7 +94,7 @@ api.postChat = function(req, res, next) { uuid: user._id, contributor: user.backer && user.backer.contributor, npc: user.backer && user.backer.npc, - text: req.body.message, + text: req.query.message, // FIXME this should be body, but ngResource is funky user: helpers.username(user.auth, user.profile.name), timestamp: +(new Date) }; @@ -87,8 +107,29 @@ api.postChat = function(req, res, next) { user.save(); } - group.save(function(err, group){ + group.save(function(err, saved){ if (err) return res.json(500, {err:err}); - res.json(group.chat); + res.json(saved); + }) +} + +api.join = function(req, res, next) { + var user = res.locals.user, + group = res.locals.group; + + group.members.push(user._id); + group.save(function(err, saved){ + if (err) return res.json(500,{err:err}); + res.json(saved); + }); +} + +api.leave = function(req, res, next) { + var user = res.locals.user, + group = res.locals.group; + + Group.update({_id:group._id},{$pull:{members:user._id}}, function(err){ + if (err) return res.json(500,{err:err}); + res.send(200); }) } \ No newline at end of file diff --git a/src/routes/api.js b/src/routes/api.js index eea0f92157..e59c5ddc49 100644 --- a/src/routes/api.js +++ b/src/routes/api.js @@ -61,6 +61,9 @@ router.get('/groups', auth, groups.getGroups); //PUT /groups/:gid (edit group) //DELETE /groups/:gid +router.post('/groups/:gid/join', auth, groups.attachGroup, groups.join); +router.post('/groups/:gid/leave', auth, groups.attachGroup, groups.leave); + //GET /groups/:gid/chat router.post('/groups/:gid/chat', auth, groups.attachGroup, groups.postChat); //PUT /groups/:gid/chat/:messageId diff --git a/views/index.jade b/views/index.jade index cd232775f5..06fc9c2007 100644 --- a/views/index.jade +++ b/views/index.jade @@ -76,27 +76,32 @@ html meta(name='apple-mobile-web-app-capable', content='yes') body(ng-app="habitrpg", ng-controller="RootCtrl", ng-cloak) - include ./shared/modals/index - include ./shared/header/header + div(ng-controller='GroupsCtrl') + include ./shared/modals/index + include ./shared/header/header - #notification-area(ng-controller='NotificationCtrl') - #wrap + #notification-area(ng-controller='NotificationCtrl') + #wrap - // Errors - ul.unstyled.alert.alert-error(ng-show='_flash.error') - li(ng-repeat='error in _flash.error') {{error}} + // Errors + ul.unstyled.alert.alert-error(ng-show='_flash.error') + li(ng-repeat='error in _flash.error') {{error}} - //if they hide the header, we still need user-menu visible - div(ng-if='user.preferences.hideHeader') - include ./shared/header/menu + //if they hide the header, we still need user-menu visible + div(ng-if='user.preferences.hideHeader') + include ./shared/header/menu - .exp-chart(ng-show='page.charts.exp') + .exp-chart(ng-show='page.charts.exp') - #main(ng-view) + #main(ng-view) - .container - h3 - a(target='_blank',href='https://workflowy.com/shared/9c77c53d-a174-d181-73a4-dc611508a936/') Roadmap - include ./shared/footer + .container + h3 + a(target='_blank',href='https://workflowy.com/shared/9c77c53d-a174-d181-73a4-dc611508a936/') Roadmap + include ./shared/footer + // Modal backdrop for when loading big stuff + #loading-indicator(style='display:none;') + .modal-backdrop + h1(style='position:absolute;top:50%;left:45%;color:white;z-index:9000') Loading... diff --git a/views/options/groups/index.jade b/views/options/groups/index.jade index 83fed721ca..aa1c6c8215 100644 --- a/views/options/groups/index.jade +++ b/views/options/groups/index.jade @@ -8,7 +8,7 @@ div(ng-controller='GroupsCtrl') li.active a(data-target='#groups-party', data-toggle='tab') Party li - a(data-target='#groups-guilds', data-toggle='tab') Guilds + a(data-target='#groups-guilds', data-toggle='tab', ng-click='fetchGuilds()') Guilds .tab-content #groups-party.tab-pane.active Party diff --git a/views/options/index.jade b/views/options/index.jade index 7249141e3c..40afc3de0c 100644 --- a/views/options/index.jade +++ b/views/options/index.jade @@ -9,7 +9,7 @@ i.icon-user | Profile li - a(data-toggle='tab',data-target='#groups-tab') + a(data-toggle='tab',data-target='#groups-tab', ng-click='fetchParty()') i.icon-heart | Groups li(ng-show='user.flags.dropsEnabled') @@ -21,7 +21,7 @@ i.icon-leaf | Stable li - a(data-toggle='tab',data-target='tavern-tab') + a(data-toggle='tab',data-target='#tavern-tab',ng-click='fetchTavern()') i.icon-eye-close | Tavern li diff --git a/views/shared/header/header.jade b/views/shared/header/header.jade index 5828472d54..371e9cdc39 100644 --- a/views/shared/header/header.jade +++ b/views/shared/header/header.jade @@ -26,7 +26,7 @@ a(x-bind='click:toggleChart', ng-click='notPorted()', data-id='exp', tooltip='Progress') i.icon-signal // party - span(ng-controller='GroupsCtrl') + span(ng-controller='PartyCtrl') .herobox-wrap(ng-repeat='profile in groups.party.members') include avatar