mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-18 07:07:35 +01:00
v3 and adapted v2: bugs fixes for groups, challenges and tasks
This commit is contained in:
@@ -3,7 +3,7 @@ import content from '../content/index';
|
||||
import i18n from '../i18n';
|
||||
import { daysSince } from '../cron';
|
||||
import { diminishingReturns } from '../statHelpers';
|
||||
import { predictableRandom } from './predictableRandom';
|
||||
import predictableRandom from './predictableRandom';
|
||||
import randomVal from './randomVal';
|
||||
|
||||
// Clone a drop object maintaining its functions so that we can change it without affecting the original item
|
||||
|
||||
@@ -52,7 +52,9 @@ api.list = async function(req, res, next) {
|
||||
let obj = challenge.toJSON();
|
||||
|
||||
obj._isMember = user.challenges.indexOf(challenge._id) !== -1;
|
||||
return obj;
|
||||
});
|
||||
|
||||
// TODO Instead of populate we make a find call manually because of https://github.com/Automattic/mongoose/issues/3833
|
||||
await Q.all(resChals.map((chal, index) => {
|
||||
return Q.all([
|
||||
@@ -195,7 +197,8 @@ api.create = async function(req, res, next){
|
||||
req.body.rewards = req.body.rewards || [];
|
||||
|
||||
var chalTasks = req.body.habits.concat(req.body.rewards)
|
||||
.concat(req.body.dailys).concat(req.body.todos);
|
||||
.concat(req.body.dailys).concat(req.body.todos)
|
||||
.map(v2Task => Tasks.Task.fromJSONV2(v2Task));
|
||||
|
||||
chalTasks = chalTasks.map(function(task) {
|
||||
var newTask = new Tasks[task.type](Tasks.Task.sanitize(task));
|
||||
@@ -318,7 +321,7 @@ api.selectWinner = async function(req, res, next) {
|
||||
if (!challenge) return next('Challenge ' + req.params.cid + ' not found');
|
||||
if (!challenge.canModify(res.locals.user)) return next(shared.i18n.t('noPermissionCloseChallenge'));
|
||||
|
||||
let winner = await User.findOne({_id: req.params.uid}).exec();
|
||||
let winner = await User.findOne({_id: req.query.uid}).exec();
|
||||
if (!winner || winner.challenges.indexOf(challenge._id) === -1) return next('Winner ' + req.query.uid + ' not found.');
|
||||
|
||||
// Close channel in background, some ops are run in the background without `await`ing
|
||||
|
||||
@@ -676,7 +676,14 @@ api.cast = async function(req, res, next) {
|
||||
|
||||
if (!partyMembers) throw new NotFound(res.t('userWithIDNotFound', {userId: targetId}));
|
||||
spell.cast(user, partyMembers, req);
|
||||
await partyMembers.save();
|
||||
if (partyMembers === user) {
|
||||
await partyMembers.save();
|
||||
} else {
|
||||
await Q.all([
|
||||
await partyMembers.save(),
|
||||
await user.save(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if (party && !spell.silent) {
|
||||
|
||||
@@ -350,7 +350,15 @@ api.castSpell = {
|
||||
if (task.challenge.id) throw new BadRequest(res.t('challengeTasksNoCast'));
|
||||
|
||||
spell.cast(user, task, req);
|
||||
await task.save();
|
||||
if (user.isModified()) {
|
||||
await Q.all([
|
||||
user.save(),
|
||||
task.save(),
|
||||
]);
|
||||
} else {
|
||||
await task.save();
|
||||
}
|
||||
|
||||
res.respond(200, task);
|
||||
} else if (targetType === 'self') {
|
||||
spell.cast(user, null, req);
|
||||
@@ -370,7 +378,8 @@ api.castSpell = {
|
||||
|
||||
let toSave = tasks.filter(t => t.isModified());
|
||||
let isUserModified = user.isModified();
|
||||
toSave.unshift(user.save());
|
||||
|
||||
if (isUserModified) toSave.unshift(user.save());
|
||||
let saved = await Q.all(toSave);
|
||||
|
||||
let response = {
|
||||
@@ -403,7 +412,14 @@ api.castSpell = {
|
||||
|
||||
if (!partyMembers) throw new NotFound(res.t('userWithIDNotFound', {userId: targetId}));
|
||||
spell.cast(user, partyMembers, req);
|
||||
await partyMembers.save();
|
||||
if (user.isModified()) {
|
||||
await Q.all([
|
||||
user.save(),
|
||||
partyMembers.save(),
|
||||
]);
|
||||
} else {
|
||||
await partyMembers.save();
|
||||
}
|
||||
}
|
||||
res.respond(200, partyMembers);
|
||||
|
||||
|
||||
@@ -631,32 +631,32 @@ schema.methods.leave = async function leaveGroup (user, keep = 'keep-all') {
|
||||
|
||||
let promises = [];
|
||||
|
||||
// If user is the last one in group and group is private, delete it
|
||||
if (group.memberCount <= 1 && group.privacy === 'private') {
|
||||
return await group.remove();
|
||||
}
|
||||
|
||||
// otherwise just remove a member TODO create User.methods.removeFromGroup?
|
||||
// remove the group from the user's groups
|
||||
if (group.type === 'guild') {
|
||||
promises.push(User.update({_id: user._id}, {$pull: {guilds: group._id}}).exec());
|
||||
} else {
|
||||
promises.push(User.update({_id: user._id}, {$set: {party: {}}}).exec());
|
||||
}
|
||||
|
||||
// If the leader is leaving (or if the leader previously left, and this wasn't accounted for)
|
||||
let update = {
|
||||
$inc: {memberCount: -1},
|
||||
};
|
||||
// If user is the last one in group and group is private, delete it
|
||||
if (group.memberCount <= 1 && group.privacy === 'private') {
|
||||
return await group.remove();
|
||||
} else { // otherwise If the leader is leaving (or if the leader previously left, and this wasn't accounted for)
|
||||
let update = {
|
||||
$inc: {memberCount: -1},
|
||||
};
|
||||
|
||||
if (group.leader === user._id) {
|
||||
let query = group.type === 'party' ? {'party._id': group._id} : {guilds: group._id};
|
||||
query._id = {$ne: user._id};
|
||||
let seniorMember = await User.findOne(query).select('_id').exec();
|
||||
if (group.leader === user._id) {
|
||||
let query = group.type === 'party' ? {'party._id': group._id} : {guilds: group._id};
|
||||
query._id = {$ne: user._id};
|
||||
let seniorMember = await User.findOne(query).select('_id').exec();
|
||||
|
||||
// could be missing in case of public guild (that can have 0 members) with 1 member who is leaving
|
||||
if (seniorMember) update.$set = {leader: seniorMember._id};
|
||||
// could be missing in case of public guild (that can have 0 members) with 1 member who is leaving
|
||||
if (seniorMember) update.$set = {leader: seniorMember._id};
|
||||
}
|
||||
promises.push(group.update(update).exec());
|
||||
}
|
||||
promises.push(group.update(update).exec());
|
||||
|
||||
firebase.removeUserFromGroup(group._id, user._id);
|
||||
|
||||
return Q.all(promises);
|
||||
@@ -730,7 +730,7 @@ if (!nconf.get('IS_TEST')) {
|
||||
new model({ // eslint-disable-line babel/new-cap
|
||||
_id: TAVERN_ID,
|
||||
leader: '7bde7864-ebc5-4ee2-a4b7-1070d464cdb0', // Siena Leslie
|
||||
name: 'HabitRPG',
|
||||
name: 'Tavern',
|
||||
type: 'guild',
|
||||
privacy: 'public',
|
||||
}).save();
|
||||
|
||||
Reference in New Issue
Block a user