improve new code for cancelling quests in invitation stage and for handling the cases where the quest owner is no longer in the quest or in the party

This commit is contained in:
Alice Harris 2014-09-08 18:46:39 +10:00
parent 801753b37a
commit b5ac0c635a
3 changed files with 69 additions and 25 deletions

View file

@ -3,6 +3,24 @@
habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', '$http', 'API_URL', '$q', 'User', 'Members', '$state',
function($scope, $rootScope, Shared, Groups, $http, API_URL, $q, User, Members, $state) {
$scope.isMemberOfPendingQuest = function(userid, group){
if (!group.quest || !group.quest.members) return false;
if (group.quest.active) return false; // quest is started, not pending
return userid in group.quest.members && group.quest.members[userid] != false;
}
$scope.isMemberOfRunningQuest = function(userid, group){
if (!group.quest || !group.quest.members) return false;
if (!group.quest.active) return false; // quest is pending, not started
return group.quest.members[userid];
}
$scope.isMemberOfGroup = function(userid, group){
if (!group.members) return false;
var memberIds = _.map(group.members, function(x){return x._id});
return ~(memberIds.indexOf(userid));
}
$scope.isMember = function(user, group){
return ~(group.members.indexOf(user._id));
}
@ -362,11 +380,17 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', '
User.set({'invitations.party':{}});
}
$scope.questCancel = function(){
if (!confirm(window.env.t('sureCancel'))) return;
$rootScope.party.$questCancel();
}
$scope.questAbort = function(){
if (!confirm(window.env.t('sureAbort'))) return;
if (!confirm(window.env.t('doubleSureAbort'))) return;
$rootScope.party.$questAbort();
}
}
])

View file

@ -464,7 +464,15 @@ api.removeMember = function(req, res, next){
}
if(_.contains(group.members, uuid)){
Group.update({_id:group._id},{$pull:{members:uuid},$inc:{memberCount:-1}}, function(err, saved){
var update = {$pull:{members:uuid}};
if(group.quest && group.quest.members){
// remove member from quest
update['$unset'] = {};
update['$unset']['quest.members.' + uuid] = "";
// TODO: run cleanQuestProgress and return scroll to member if member was quest owner
}
update['$inc'] = {memberCount: -1};
Group.update({_id:group._id},update, function(err, saved){
if (err) return next(err);
// Sending an empty 204 because Group.update doesn't return the group
@ -530,7 +538,6 @@ questStart = function(req, res, next) {
quest = shared.content.quests[key],
collected = quest.collect ? _.transform(quest.collect, function(m,v,k){m[k]=0}) : {};
// TODO will this handle appropriately when people leave/join party between quest invite?
_.each(group.members, function(m){
var updates = {$set:{},$inc:{'_v':1}};
if (m == group.quest.leader)
@ -611,12 +618,19 @@ api.questReject = function(req, res, next) {
api.questCancel = function(req, res, next){
// Cancel a quest BEFORE it has begun (i.e., in the invitation stage)
// Quest scroll has not yet left quest owner's inventory so no need to return it.
// Do not wipe quest progress for members because they'll want it to be applied to the next quest that's started.
var group = res.locals.group;
async.parallel([
function(cb){
group.quest = {key:null,progress:{},leader:null};
group.markModified('quest');
group.save(cb);
if (! group.quest.active) {
// Do not cancel active quests because this function does
// not do the clean-up required for that.
// TODO: return an informative error when quest is active
group.quest = {key:null,progress:{},leader:null};
group.markModified('quest');
group.save(cb);
}
}
], function(err){
if (err) return next(err);

View file

@ -9,25 +9,27 @@ mixin boss(tavern, mobile)
table.table.table-striped
tr(ng-repeat='member in group.members')
td
span(ng-if=':: group.quest.leader && group.quest.leader==member._id')
span(ng-if=':: group.quest.leader && group.quest.leader==member._id && isMemberOfGroup(group.quest.leader,group) && isMemberOfPendingQuest(group.quest.leader,group)')
|* 
// XXX does this trigger badly when ex-leader reenters group?
{{::member.profile.name}}
td {{group.quest.members[member._id] === true ? env.t('accepted') : group.quest.members[member._id] === false ? env.t('rejected') : env.t('pending')}}
//span(ng-if=':: group.quest.leader && group.members.indexOf(group.quest.leader) > -1')
|* 
=env.t('questOwner')
br
span(ng-if=':: !group.quest.leader') no quest leader
br
span(ng-if=':: group.members.indexOf(group.quest.leader) == -1') not in group
// span(ng-if=':: !group.quest.leader || group.members.indexOf(group.quest.leader) == -1')=env.t('questOwnerMIA')
span(ng-if=':: group.quest.leader && isMemberOfGroup(group.quest.leader,group) && isMemberOfPendingQuest(group.quest.leader,group)')
|* 
=env.t('questOwner')
span(ng-if=':: group.quest.leader && isMemberOfGroup(group.quest.leader,group) && ! isMemberOfPendingQuest(group.quest.leader,group)')
=env.t('questOwnerNotInPendingQuest')
span(ng-if=':: ! group.quest.leader || ! isMemberOfGroup(group.quest.leader,group)')
=env.t('questOwnerNotInPendingQuestParty')
hr
.npc_ian.pull-left
p=env.t('questStart')
button.btn.btn-sm.btn-warning(ng-if=':: !group.quest.leader || group.members.indexOf(group.quest.leader) == -1 || group.quest.leader==user._id', ng-click='party.$questAccept({"force":true})')=env.t('begin')
//button.btn.btn-sm.btn-warning(ng-if=':: !group.quest.leader || group.members.indexOf(group.quest.leader) == -1 || group.quest.leader==user._id', ng-click='party.$questCancel()')=env.t('cancel')
//-TODO Cancel button
//-TODO Both force-start & cancel should only be available to quest-initiator
// only the quest owner sees the begin button:
button.btn.btn-sm.btn-warning(ng-if=':: group.quest.leader && group.quest.leader==user._id && isMemberOfGroup(group.quest.leader,group) && isMemberOfPendingQuest(group.quest.leader,group)', ng-click='party.$questAccept({"force":true})')=env.t('begin')
// only the quest owner sees the cancel button UNLESS the quest owner is no longer in the quest/party and then everyone sees it:
button.btn.btn-sm.btn-danger(ng-if=':: (group.quest.leader && group.quest.leader==user._id && isMemberOfGroup(group.quest.leader,group) && isMemberOfPendingQuest(group.quest.leader,group)) || (! group.quest.leader || ! isMemberOfGroup(group.quest.leader,group) || ! isMemberOfPendingQuest(group.quest.leader,group))', ng-click='questCancel()')=env.t('cancel')
div(ng-if='group.quest.active==true')
div(ng-if='::Content.quests[group.quest.key].boss',ng-init='boss=Content.quests[group.quest.key].boss;progress=group.quest.progress')
@ -69,13 +71,17 @@ mixin boss(tavern, mobile)
table.table.table-striped
tr(ng-repeat='(k,v) in group.members', ng-show='group.quest.members[v._id]')
td
span(ng-if=':: group.quest.leader==v._id')
span(ng-if=':: group.quest.leader && group.quest.leader==v._id && isMemberOfGroup(group.quest.leader,group) && isMemberOfRunningQuest(group.quest.leader,group)')
|* 
{{::v.profile.name}}
// span(ng-if=':: group.quest.leader && group.members.indexOf(group.quest.leader) > -1')
// |* 
// =env.t('questOwner')
// span(ng-if=':: !group.quest.leader || group.members.indexOf(group.quest.leader) == -1')=env.t('questOwnerMIA')
span(ng-if=':: group.quest.leader && isMemberOfGroup(group.quest.leader,group) && isMemberOfRunningQuest(group.quest.leader,group)')
|* 
=env.t('questOwner')
span(ng-if=':: group.quest.leader && isMemberOfGroup(group.quest.leader,group) && ! isMemberOfRunningQuest(group.quest.leader,group)')
=env.t('questOwnerNotInRunningQuest')
span(ng-if=':: ! group.quest.leader || ! isMemberOfGroup(group.quest.leader,group)')
=env.t('questOwnerNotInRunningQuestParty')
quest-rewards(key='{{::group.quest.key}}')
div(ng-if='::Content.quests[group.quest.key].boss')
@ -93,6 +99,6 @@ mixin boss(tavern, mobile)
br
p=env.t('bossColl2')
unless tavern
button.btn.btn-xs.btn-danger(ng-if='::!group.quest.leader || group.members.indexOf(group.quest.leader) == -1 || group.quest.leader==user._id', ng-click='questAbort()')=env.t('abort')
// only the quest owner sees the abort button UNLESS the quest owner is no longer in the quest/party and then everyone sees it:
button.btn.btn-sm.btn-warning(ng-if=':: (group.quest.leader && group.quest.leader==user._id && isMemberOfGroup(group.quest.leader,group) && isMemberOfRunningQuest(group.quest.leader,group)) || ! group.quest.leader || ! isMemberOfGroup(group.quest.leader,group) || ! isMemberOfRunningQuest(group.quest.leader,group)', ng-click='questAbort()')=env.t('abort')