mirror of
https://github.com/sudoxnym/habitica.git
synced 2026-07-14 07:52:15 +00:00
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:
parent
801753b37a
commit
b5ac0c635a
3 changed files with 69 additions and 25 deletions
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
])
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
Loading…
Reference in a new issue