mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-15 21:57:22 +01:00
New feature that notifies a user when their group invite is accepted. (#8244)
* New notification feature that notifies a user when their group invite is accepted. fixes #7788 * Updating to a modal instead of a popup notification * Making a generic modal template and using it for notifications of group invitation acceptance. * Working with paglias's comments for doing translation server side. * Final changes based on pr comments.
This commit is contained in:
@@ -134,6 +134,22 @@ describe('POST /group/:groupId/join', () => {
|
|||||||
|
|
||||||
await expect(user.get('/user')).to.eventually.have.deep.property('items.quests.basilist', 1);
|
await expect(user.get('/user')).to.eventually.have.deep.property('items.quests.basilist', 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('notifies inviting user that their invitation was accepted', async () => {
|
||||||
|
await invitedUser.post(`/groups/${guild._id}/join`);
|
||||||
|
|
||||||
|
let inviter = await user.get('/user');
|
||||||
|
let expectedData = {
|
||||||
|
headerText: t('invitationAcceptedHeader'),
|
||||||
|
bodyText: t('invitationAcceptedBody', {
|
||||||
|
username: invitedUser.auth.local.username,
|
||||||
|
groupName: guild.name,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(inviter.notifications[0].type).to.eql('GROUP_INVITE_ACCEPTED');
|
||||||
|
expect(inviter.notifications[0].data).to.eql(expectedData);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -172,6 +188,23 @@ describe('POST /group/:groupId/join', () => {
|
|||||||
await expect(invitedUser.get('/user')).to.eventually.have.deep.property('party._id', party._id);
|
await expect(invitedUser.get('/user')).to.eventually.have.deep.property('party._id', party._id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('notifies inviting user that their invitation was accepted', async () => {
|
||||||
|
await invitedUser.post(`/groups/${party._id}/join`);
|
||||||
|
|
||||||
|
let inviter = await user.get('/user');
|
||||||
|
|
||||||
|
let expectedData = {
|
||||||
|
headerText: t('invitationAcceptedHeader'),
|
||||||
|
bodyText: t('invitationAcceptedBody', {
|
||||||
|
username: invitedUser.auth.local.username,
|
||||||
|
groupName: party.name,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(inviter.notifications[0].type).to.eql('GROUP_INVITE_ACCEPTED');
|
||||||
|
expect(inviter.notifications[0].data).to.eql(expectedData);
|
||||||
|
});
|
||||||
|
|
||||||
it('clears invitation from user when joining party', async () => {
|
it('clears invitation from user when joining party', async () => {
|
||||||
await invitedUser.post(`/groups/${party._id}/join`);
|
await invitedUser.post(`/groups/${party._id}/join`);
|
||||||
|
|
||||||
|
|||||||
@@ -145,7 +145,14 @@ habitrpg.controller('NotificationCtrl',
|
|||||||
Notification.showLoginIncentive(User.user, notification.data, Social.loadWidgets);
|
Notification.showLoginIncentive(User.user, notification.data, Social.loadWidgets);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
markAsRead = false; // If the notification is not implemented, skip it
|
if (notification.data.headerText && notification.data.bodyText) {
|
||||||
|
var modalScope = $rootScope.$new();
|
||||||
|
modalScope.data = notification.data;
|
||||||
|
$rootScope.openModal('generic', {scope: modalScope});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
markAsRead = false; // If the notification is not implemented, skip it
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,8 @@
|
|||||||
"leave": "Leave",
|
"leave": "Leave",
|
||||||
"invitedTo": "Invited to <%= name %>",
|
"invitedTo": "Invited to <%= name %>",
|
||||||
"invitedToNewParty": "You were invited to join a party! Do you want to leave this party and join <%= partyName %>?",
|
"invitedToNewParty": "You were invited to join a party! Do you want to leave this party and join <%= partyName %>?",
|
||||||
|
"invitationAcceptedHeader": "Your Invitation has been Accepted",
|
||||||
|
"invitationAcceptedBody": "<%= username %> accepted your invitation to <%= groupName %>!",
|
||||||
"joinNewParty": "Join New Party",
|
"joinNewParty": "Join New Party",
|
||||||
"declineInvitation": "Decline Invitation",
|
"declineInvitation": "Decline Invitation",
|
||||||
"partyLoading1": "Your party is being summoned. Please wait...",
|
"partyLoading1": "Your party is being summoned. Please wait...",
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { sendTxn as sendTxnEmail } from '../../libs/email';
|
|||||||
import { encrypt } from '../../libs/encryption';
|
import { encrypt } from '../../libs/encryption';
|
||||||
import { sendNotification as sendPushNotification } from '../../libs/pushNotifications';
|
import { sendNotification as sendPushNotification } from '../../libs/pushNotifications';
|
||||||
import pusher from '../../libs/pusher';
|
import pusher from '../../libs/pusher';
|
||||||
|
import common from '../../../common';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @apiDefine GroupBodyInvalid
|
* @apiDefine GroupBodyInvalid
|
||||||
@@ -284,6 +285,7 @@ api.joinGroup = {
|
|||||||
|
|
||||||
if (hasInvitation) {
|
if (hasInvitation) {
|
||||||
isUserInvited = true;
|
isUserInvited = true;
|
||||||
|
inviter = hasInvitation.inviter;
|
||||||
} else {
|
} else {
|
||||||
isUserInvited = group.privacy === 'private' ? false : true;
|
isUserInvited = group.privacy === 'private' ? false : true;
|
||||||
}
|
}
|
||||||
@@ -303,8 +305,29 @@ api.joinGroup = {
|
|||||||
|
|
||||||
let promises = [group.save(), user.save()];
|
let promises = [group.save(), user.save()];
|
||||||
|
|
||||||
|
if (inviter) {
|
||||||
|
inviter = await User.findById(inviter).select('notifications preferences.language items.quests.basilist').exec();
|
||||||
|
|
||||||
|
let data = {
|
||||||
|
headerText: common.i18n.t('invitationAcceptedHeader', inviter.preferences.language),
|
||||||
|
bodyText: common.i18n.t('invitationAcceptedBody', {
|
||||||
|
groupName: group.name,
|
||||||
|
username: user.auth.local.username,
|
||||||
|
}, inviter.preferences.language),
|
||||||
|
};
|
||||||
|
inviter.addNotification('GROUP_INVITE_ACCEPTED', data);
|
||||||
|
|
||||||
|
// Reward Inviter
|
||||||
|
if (group.type === 'party') {
|
||||||
|
if (!inviter.items.quests.basilist) {
|
||||||
|
inviter.items.quests.basilist = 0;
|
||||||
|
}
|
||||||
|
inviter.items.quests.basilist++;
|
||||||
|
}
|
||||||
|
promises.push(inviter.save());
|
||||||
|
}
|
||||||
|
|
||||||
if (group.type === 'party' && inviter) {
|
if (group.type === 'party' && inviter) {
|
||||||
promises.push(User.update({_id: inviter}, {$inc: {'items.quests.basilist': 1}}).exec()); // Reward inviter
|
|
||||||
if (group.memberCount > 1) {
|
if (group.memberCount > 1) {
|
||||||
promises.push(User.update({$or: [{'party._id': group._id}, {_id: user._id}], 'achievements.partyUp': {$ne: true}}, {$set: {'achievements.partyUp': true}}, {multi: true}).exec());
|
promises.push(User.update({$or: [{'party._id': group._id}, {_id: user._id}], 'achievements.partyUp': {$ne: true}}, {$set: {'achievements.partyUp': true}}, {multi: true}).exec());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ const NOTIFICATION_TYPES = [
|
|||||||
'GROUP_TASK_APPROVAL',
|
'GROUP_TASK_APPROVAL',
|
||||||
'GROUP_TASK_APPROVED',
|
'GROUP_TASK_APPROVED',
|
||||||
'LOGIN_INCENTIVE',
|
'LOGIN_INCENTIVE',
|
||||||
|
'GROUP_INVITE_ACCEPTED',
|
||||||
];
|
];
|
||||||
|
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
|
|||||||
7
website/views/shared/modals/generic.jade
Normal file
7
website/views/shared/modals/generic.jade
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
script(type='text/ng-template', id='modals/generic.html')
|
||||||
|
.modal-header
|
||||||
|
h4 {{data.headerText}}
|
||||||
|
.modal-body
|
||||||
|
p {{data.bodyText}}
|
||||||
|
.modal-footer
|
||||||
|
.btn.btn-default.pull-right(ng-click='$close()')=env.t('close')
|
||||||
@@ -23,6 +23,7 @@ include ./modify-inventory.jade
|
|||||||
include ./enable-desktop-notifications.jade
|
include ./enable-desktop-notifications.jade
|
||||||
include ./login-incentives.jade
|
include ./login-incentives.jade
|
||||||
include ./login-incentives-reward-unlocked.jade
|
include ./login-incentives-reward-unlocked.jade
|
||||||
|
include ./generic.jade
|
||||||
|
|
||||||
//- Settings
|
//- Settings
|
||||||
script(type='text/ng-template', id='modals/change-day-start.html')
|
script(type='text/ng-template', id='modals/change-day-start.html')
|
||||||
|
|||||||
Reference in New Issue
Block a user