add accept quest route

This commit is contained in:
Matteo Pagliazzi
2016-02-10 17:07:34 +01:00
parent 95a3cea297
commit fa14464a0c
2 changed files with 106 additions and 52 deletions

View File

@@ -35,7 +35,7 @@ let api = {};
* *
* @apiParam {string} groupId The group _id (or 'party') * @apiParam {string} groupId The group _id (or 'party')
* *
* @apiSuccess {Object} Quest Object * @apiSuccess {Object} quest Quest Object
*/ */
api.inviteToQuest = { api.inviteToQuest = {
method: 'POST', method: 'POST',
@@ -124,4 +124,58 @@ api.inviteToQuest = {
}, },
}; };
/**
* @api {post} /groups/:groupId/quests/accept Accept a pending quest
* @apiVersion 3.0.0
* @apiName AcceptQuest
* @apiGroup Group
*
* @apiParam {string} groupId The group _id (or 'party')
*
* @apiSuccess {Object} quest Quest Object
*/
api.acceptQuest = {
method: 'POST',
url: '/groups/:groupId/quests/accept',
middlewares: [authWithHeaders(), cron],
async handler (req, res) {
let user = res.locals.user;
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty();
let validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
let group = await Group.getGroup({user, groupId: req.params.groupId, fields: 'type quest'});
if (!group) throw new NotFound(res.t('groupNotFound'));
if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported'));
if (!group.quest.key) throw new NotFound(res.t('questInviteNotFound'));
group.quest.members[user._id] = true;
user.party.quest.RSVPNeeded = false;
if (canStartQuestAutomatically(group)) {
await group.startQuest(user);
}
let [savedGroup] = await Q.all([
group.save(),
user.save(),
]);
res.respond(200, savedGroup.quest);
// track that an user has accepted the quest
analytics.track('quest', {
category: 'behavior',
owner: false,
response: 'accept',
gaLabel: 'accept',
questName: group.quest.key,
uuid: user._id,
});
},
};
export default api; export default api;

View File

@@ -170,6 +170,57 @@ schema.methods.isMember = function isGroupMember (user) {
} }
}; };
export function chatDefaults (msg, user) {
let message = {
id: shared.uuid(),
text: msg,
timestamp: Number(new Date()),
likes: {},
flags: {},
flagCount: 0,
};
if (user) {
_.defaults(message, {
uuid: user._id,
contributor: user.contributor && user.contributor.toObject(),
backer: user.backer && user.backer.toObject(),
user: user.profile.name,
});
} else {
message.uuid = 'system';
}
return message;
}
schema.methods.sendChat = function sendChat (message, user) {
this.chat.unshift(chatDefaults(message, user));
this.chat.splice(200);
// Kick off chat notifications in the background. // TODO refactor
let lastSeenUpdate = {$set: {}, $inc: {_v: 1}};
lastSeenUpdate.$set[`newMessages.${this._id}`] = {name: this.name, value: true};
if (this._id === 'habitrpg') {
// TODO For Tavern, only notify them if their name was mentioned
// var profileNames = [] // get usernames from regex of @xyz. how to handle space-delimited profile names?
// User.update({'profile.name':{$in:profileNames}},lastSeenUpdate,{multi:true}).exec();
} else {
let query = {};
if (this.type === 'party') {
query['party._id'] = this._id;
} else {
query.guilds = this._id;
}
query._id = { $ne: user ? user._id : ''};
User.update(query, lastSeenUpdate, {multi: true}).exec();
}
};
schema.methods.startQuest = async function startQuest (user) { schema.methods.startQuest = async function startQuest (user) {
// not using i18n strings because these errors are meant for devs who forgot to pass some parameters // not using i18n strings because these errors are meant for devs who forgot to pass some parameters
if (this.type !== 'party') throw new InternalServerError('Must be a party to use this method'); if (this.type !== 'party') throw new InternalServerError('Must be a party to use this method');
@@ -249,57 +300,6 @@ schema.methods.startQuest = async function startQuest (user) {
}); });
}; };
export function chatDefaults (msg, user) {
let message = {
id: shared.uuid(),
text: msg,
timestamp: Number(new Date()),
likes: {},
flags: {},
flagCount: 0,
};
if (user) {
_.defaults(message, {
uuid: user._id,
contributor: user.contributor && user.contributor.toObject(),
backer: user.backer && user.backer.toObject(),
user: user.profile.name,
});
} else {
message.uuid = 'system';
}
return message;
}
schema.methods.sendChat = function sendChat (message, user) {
this.chat.unshift(chatDefaults(message, user));
this.chat.splice(200);
// Kick off chat notifications in the background. // TODO refactor
let lastSeenUpdate = {$set: {}, $inc: {_v: 1}};
lastSeenUpdate.$set[`newMessages.${this._id}`] = {name: this.name, value: true};
if (this._id === 'habitrpg') {
// TODO For Tavern, only notify them if their name was mentioned
// var profileNames = [] // get usernames from regex of @xyz. how to handle space-delimited profile names?
// User.update({'profile.name':{$in:profileNames}},lastSeenUpdate,{multi:true}).exec();
} else {
let query = {};
if (this.type === 'party') {
query['party._id'] = this._id;
} else {
query.guilds = this._id;
}
query._id = { $ne: user ? user._id : ''};
User.update(query, lastSeenUpdate, {multi: true}).exec();
}
};
function _cleanQuestProgress (merge) { function _cleanQuestProgress (merge) {
// TODO clone? (also in sendChat message) // TODO clone? (also in sendChat message)
let clean = { let clean = {