From 3e653c92821ac03851ad8206c40c5d0bd0d8aac7 Mon Sep 17 00:00:00 2001 From: Kevin Gisi Date: Sat, 28 Mar 2015 02:40:03 -0400 Subject: [PATCH 1/7] Reimplemented single challenge view code from #3319 --- website/public/css/challenges.styl | 2 +- .../public/js/controllers/challengesCtrl.js | 37 ++++++++++++++----- website/views/options/social/challenges.jade | 6 ++- website/views/options/social/index.jade | 2 +- 4 files changed, 34 insertions(+), 13 deletions(-) diff --git a/website/public/css/challenges.styl b/website/public/css/challenges.styl index feb3fcb558..23add6cd34 100644 --- a/website/public/css/challenges.styl +++ b/website/public/css/challenges.styl @@ -13,7 +13,7 @@ ul.challenge-accordion-header-specs color: white; margin-right: 5px; -#create-challenge-btn +#back-to-challenges, #create-challenge-btn margin-bottom: 10px #challenges-filters h3 diff --git a/website/public/js/controllers/challengesCtrl.js b/website/public/js/controllers/challengesCtrl.js index c17f76e5e8..fe793ac367 100644 --- a/website/public/js/controllers/challengesCtrl.js +++ b/website/public/js/controllers/challengesCtrl.js @@ -3,15 +3,34 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User', 'Challenges', 'Notification', '$compile', 'Groups', '$state', function($rootScope, $scope, Shared, User, Challenges, Notification, $compile, Groups, $state) { + // Use presence of cid to determine whether to show a list or a single + // challenge + $scope.cid = $state.params.cid; + + // Fetch single challenge if a cid is present; fetch multiple challenges + // otherwise + var getChallenges = function() { + if ($scope.cid) { + Challenges.Challenge.get({cid: $scope.cid}, function(challenge) { + $scope.challenges = [challenge]; + }); + } else { + Challenges.Challenge.query(function(challenges){ + $scope.challenges = challenges; + $scope.groupsFilter = _.uniq(_.pluck(challenges, 'group'), function(g){return g._id}); + $scope.search = { + group: _.transform($scope.groups, function(m,g){m[g._id]=true;}) + }; + }); + } + }; + + getChallenges(); + // FIXME $scope.challenges needs to be resolved first (see app.js) $scope.groups = Groups.Group.query({type:'party,guilds,tavern'}); - Challenges.Challenge.query(function(challenges){ - $scope.challenges = challenges; - $scope.groupsFilter = _.uniq(_.pluck(challenges, 'group'), function(g){return g._id}); - $scope.search = { - group: _.transform($scope.groups, function(m,g){m[g._id]=true;}) - }; - }); + + // we should fix this, that's pretty brittle // override score() for tasks listed in challenges-editing pages, so that nothing happens @@ -178,7 +197,7 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User', $scope.join = function(challenge){ challenge.$join(function(){ - $scope.challenges = Challenges.Challenge.query(); + getChallenges() User.log({}); }); @@ -189,7 +208,7 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User', $scope.selectedChal = undefined; } else { $scope.selectedChal.$leave({keep:keep}, function(){ - $scope.challenges = Challenges.Challenge.query(); + getChallenges() User.log({}); }); } diff --git a/website/views/options/social/challenges.jade b/website/views/options/social/challenges.jade index 191a465112..a2115db07c 100644 --- a/website/views/options/social/challenges.jade +++ b/website/views/options/social/challenges.jade @@ -67,7 +67,7 @@ script(type='text/ng-template', id='partials/options.social.challenges.html') .container-fluid .row .col-md-2 - .well#challenges-filters + .well#challenges-filters(ng-hide="cid") h3=env.t('filter') + ':' h4=env.t('groups') ul.list-unstyled @@ -92,6 +92,8 @@ script(type='text/ng-template', id='partials/options.social.challenges.html') input(type='radio', name='search-participation-radio', ng-click='search._isMember = undefined', checked='checked') =env.t('either') .col-md-10 + a.btn.btn-info#back-to-challenges(ng-show="cid", ui-sref='options.social.challenges', ui-sref-opts='{reload: true}') + | Back to all challenges // Creation form button.btn.btn-success#create-challenge-btn(ng-click='create()', ng-hide='newChallenge')=env.t('createChallenge') .create-challenge-from.well(ng-if='newChallenge') @@ -163,7 +165,7 @@ script(type='text/ng-template', id='partials/options.social.challenges.html') a.btn.btn-sm.btn-success(ng-hide='challenge._isMember', ng-click='join(challenge)') span.glyphicon.glyphicon-ok =env.t('join') - a.accordion-toggle(ng-click='toggle(challenge._id)') {{challenge.name}} + a.accordion-toggle(id="{{challenge._id}}" ng-click='toggle(challenge._id)') {{challenge.name}} .panel-body(ng-class='{collapse: !$stateParams.cid == challenge._id}') .accordion-inner(ng-if='$stateParams.cid == challenge._id') div(ui-view) diff --git a/website/views/options/social/index.jade b/website/views/options/social/index.jade index 61c2afc194..54469e5ca5 100644 --- a/website/views/options/social/index.jade +++ b/website/views/options/social/index.jade @@ -104,7 +104,7 @@ script(type='text/ng-template', id='partials/options.social.html') a(ui-sref='options.social.guilds.public') =env.t('guilds') li(ng-class="{ active: $state.includes('options.social.challenges') }") - a(ui-sref='options.social.challenges') + a(ui-sref='options.social.challenges', ui-sref-opts='{reload: true}') =env.t('challenges') li(ng-class="{ active: $state.includes('options.social.hall') }") a(ui-sref='options.social.hall.heroes') From 79fe0b53c5e7171cfc610668c9a5310a104c11fd Mon Sep 17 00:00:00 2001 From: Kevin Gisi Date: Sat, 28 Mar 2015 02:49:56 -0400 Subject: [PATCH 2/7] Added _isMember to APIv2 challenges/:cid endpoint (requires user auth) --- website/src/controllers/challenges.js | 6 +++++- website/src/routes/apiv2.coffee | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/website/src/controllers/challenges.js b/website/src/controllers/challenges.js index 5fabd0fb1c..9240986649 100644 --- a/website/src/controllers/challenges.js +++ b/website/src/controllers/challenges.js @@ -56,6 +56,7 @@ api.list = function(req, res, next) { // GET api.get = function(req, res, next) { + var user = res.locals.user; // TODO use mapReduce() or aggregate() here to // 1) Find the sum of users.tasks.values within the challnege (eg, {'profile.name':'tyler', 'sum': 100}) // 2) Sort by the sum @@ -65,8 +66,11 @@ api.get = function(req, res, next) { .exec(function(err, challenge){ if(err) return next(err); if (!challenge) return res.json(404, {err: 'Challenge ' + req.params.cid + ' not found'}); + challenge._isMember = !!(_.find(challenge.members, function(member) { + return member._id === user._id; + })); res.json(challenge); - }) + }); } api.csv = function(req, res, next) { diff --git a/website/src/routes/apiv2.coffee b/website/src/routes/apiv2.coffee index ad2c457129..f30b03cb53 100644 --- a/website/src/routes/apiv2.coffee +++ b/website/src/routes/apiv2.coffee @@ -688,6 +688,7 @@ module.exports = (swagger, v2) -> path: '/challenges/{cid}' description: 'Get a challenge' parameters: [path('cid','Challenge id','string')] + middleware: [auth.auth, i18n.getUserLanguage] action: challenges.get "/challenges/{cid}/csv": From 6fb95ec27b7fb93468ea725e9cf3269660817e3a Mon Sep 17 00:00:00 2001 From: Kevin Gisi Date: Sat, 28 Mar 2015 02:57:29 -0400 Subject: [PATCH 3/7] Unset .cid for challenge on challenge delete --- website/public/js/controllers/challengesCtrl.js | 1 + 1 file changed, 1 insertion(+) diff --git a/website/public/js/controllers/challengesCtrl.js b/website/public/js/controllers/challengesCtrl.js index fe793ac367..eec3e3c4df 100644 --- a/website/public/js/controllers/challengesCtrl.js +++ b/website/public/js/controllers/challengesCtrl.js @@ -113,6 +113,7 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User', */ function backToChallenges(){ $scope.popoverEl.popover('destroy'); + $scope.cid = null; $state.go('options.social.challenges'); $scope.challenges = Challenges.Challenge.query(); User.log({}); From da81241ebe8696a9f14d84ae0792f9f8731ce34d Mon Sep 17 00:00:00 2001 From: Kevin Gisi Date: Sat, 28 Mar 2015 05:01:44 -0400 Subject: [PATCH 4/7] Transition Challenge -> Edit to the Singleton challenge view, to address issues associated with #4814 --- website/public/js/app.js | 10 ++++++++++ website/public/js/controllers/challengesCtrl.js | 12 ++++++++++-- website/views/options/social/challenges.jade | 2 +- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/website/public/js/app.js b/website/public/js/app.js index 0450302389..2f8e2fd512 100644 --- a/website/public/js/app.js +++ b/website/public/js/app.js @@ -146,6 +146,16 @@ window.habitrpg = angular.module('habitrpg', }); }] }) + .state('options.social.challenges.edit', { + url: '/:cid/edit', + templateUrl: 'partials/options.social.challenges.detail.html', + controller: ['$scope', 'Challenges', '$stateParams', + function($scope, Challenges, $stateParams){ + $scope.obj = $scope.challenge = Challenges.Challenge.get({cid:$stateParams.cid}, function(){ + $scope.challenge._locked = false; + }); + }] + }) .state('options.social.challenges.detail.member', { url: '/:uid', templateUrl: 'partials/options.social.challenges.detail.member.html', diff --git a/website/public/js/controllers/challengesCtrl.js b/website/public/js/controllers/challengesCtrl.js index eec3e3c4df..14925b2ac1 100644 --- a/website/public/js/controllers/challengesCtrl.js +++ b/website/public/js/controllers/challengesCtrl.js @@ -1,7 +1,7 @@ "use strict"; -habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User', 'Challenges', 'Notification', '$compile', 'Groups', '$state', - function($rootScope, $scope, Shared, User, Challenges, Notification, $compile, Groups, $state) { +habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User', 'Challenges', 'Notification', '$compile', 'Groups', '$state', '$stateParams', + function($rootScope, $scope, Shared, User, Challenges, Notification, $compile, Groups, $state, $stateParams) { // Use presence of cid to determine whether to show a list or a single // challenge @@ -40,6 +40,13 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User', // Challenge //------------------------------------------------------------ + // Use this to force the top view to change, not just the nested view. + $scope.edit = function(challenge) { + $state.transitionTo('options.social.challenges.edit', {cid: challenge._id}, { + reload: true, inherit: false, notify: true + }); + }; + /** * Create */ @@ -95,6 +102,7 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User', // TODO figure out a more elegant way about this //challenge._editing = false; challenge._locked = true; + getChallenges(); } }); }; diff --git a/website/views/options/social/challenges.jade b/website/views/options/social/challenges.jade index a2115db07c..e01d31f76d 100644 --- a/website/views/options/social/challenges.jade +++ b/website/views/options/social/challenges.jade @@ -24,7 +24,7 @@ script(type='text/ng-template', id='partials/options.social.challenges.detail.ht // Edit button div(bindonce='challenge', ng-if='challenge.leader==user._id') div(ng-hide='challenge._locked==false') - button.btn.btn-sm.btn-default(ng-click='challenge._locked = false')=env.t('edit') + button.btn.btn-sm.btn-default(ng-click='edit(challenge)')=env.t('edit') button.btn.btn-sm.btn-warning(ng-click='close(challenge, $event)', tooltip=env.t('deleteOrSelect'))=env.t('endChallenge') form(ng-show='challenge._locked==false') From eef3e293e28d1d456022c494e5fe5410b026976d Mon Sep 17 00:00:00 2001 From: Kevin Gisi Date: Sat, 4 Apr 2015 07:15:01 -0400 Subject: [PATCH 5/7] Populate group and challenge leader on challenge GET request --- website/src/controllers/challenges.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/src/controllers/challenges.js b/website/src/controllers/challenges.js index 9240986649..f38b1d6071 100644 --- a/website/src/controllers/challenges.js +++ b/website/src/controllers/challenges.js @@ -63,6 +63,8 @@ api.get = function(req, res, next) { // 3) Limit 30 (only show the 30 users currently in the lead) Challenge.findById(req.params.cid) .populate('members', 'profile.name _id') + .populate('group', '_id name') + .populate('leader', 'profile.name') .exec(function(err, challenge){ if(err) return next(err); if (!challenge) return res.json(404, {err: 'Challenge ' + req.params.cid + ' not found'}); From 145f4c0fa79048be61d646209156ba9f6e43f147 Mon Sep 17 00:00:00 2001 From: Kevin Gisi Date: Mon, 6 Apr 2015 02:32:24 -0400 Subject: [PATCH 6/7] Check leader._id, rather than just leader for checking challenge ownership --- website/views/options/social/challenges.jade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/views/options/social/challenges.jade b/website/views/options/social/challenges.jade index e01d31f76d..6e5b8c7553 100644 --- a/website/views/options/social/challenges.jade +++ b/website/views/options/social/challenges.jade @@ -22,7 +22,7 @@ script(type='text/ng-template', id='partials/options.social.challenges.detail.me script(type='text/ng-template', id='partials/options.social.challenges.detail.html') // Edit button - div(bindonce='challenge', ng-if='challenge.leader==user._id') + div(bindonce='challenge', ng-if='challenge.leader._id==user._id') div(ng-hide='challenge._locked==false') button.btn.btn-sm.btn-default(ng-click='edit(challenge)')=env.t('edit') button.btn.btn-sm.btn-warning(ng-click='close(challenge, $event)', tooltip=env.t('deleteOrSelect'))=env.t('endChallenge') From 6cfdfc5225f15487474e7b9057a2483f28798340 Mon Sep 17 00:00:00 2001 From: Kevin Gisi Date: Mon, 6 Apr 2015 02:44:43 -0400 Subject: [PATCH 7/7] Added group type to challenge API, link to guild/party on challenges --- website/src/controllers/challenges.js | 4 ++-- website/views/options/social/challenges.jade | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/website/src/controllers/challenges.js b/website/src/controllers/challenges.js index f38b1d6071..a522746b8f 100644 --- a/website/src/controllers/challenges.js +++ b/website/src/controllers/challenges.js @@ -40,7 +40,7 @@ api.list = function(req, res, next) { .select('name leader description group memberCount prize official') .select({members:{$elemMatch:{$in:[user._id]}}}) .sort('-official -timestamp') - .populate('group', '_id name') + .populate('group', '_id name type') .populate('leader', 'profile.name') .exec(cb); } @@ -63,7 +63,7 @@ api.get = function(req, res, next) { // 3) Limit 30 (only show the 30 users currently in the lead) Challenge.findById(req.params.cid) .populate('members', 'profile.name _id') - .populate('group', '_id name') + .populate('group', '_id name type') .populate('leader', 'profile.name') .exec(function(err, challenge){ if(err) return next(err); diff --git a/website/views/options/social/challenges.jade b/website/views/options/social/challenges.jade index 6e5b8c7553..d53dd64781 100644 --- a/website/views/options/social/challenges.jade +++ b/website/views/options/social/challenges.jade @@ -143,7 +143,11 @@ script(type='text/ng-template', id='partials/options.social.challenges.html') ul.pull-right.challenge-accordion-header-specs li.bg-transparent(ng-if='challenge.official') span.label.label-success=env.t('officialChallenge') - li {{challenge.group.name}} + li + a(ui-sref="options.social.guilds.detail({gid:challenge.group._id})" ng-if="challenge.group.type=='guild'") + | {{challenge.group.name}} + a(ui-sref="options.social.party" ng-if="challenge.group.type=='party'") + | {{challenge.group.name}} li =env.t('by') + ' ' a(ng-click='clickMember(challenge.leader._id, true)') {{challenge.leader.profile.name}}