mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 22:57:21 +01:00
PMs rebuild (#11360)
* feat(messages): big PMs refactor * add private messages route * move to page * WIP - header + begin with the sidebar * extract userLabel + style sidebar + extract converstation item * correct conversation item style * toggle switch style * add contributor / backer to conversation user-label * fix shadows * fix the conversations list (ignoring own sent) * selected conversation label * faceAvatar component * fix message / avatar height * fix message list / empty messages height * new message padding/styles/functionality - finished sidebar conversation styling - * fix loading messages + perfect-scrollbar * fix load more line * fix loading label * open new conversation from outside * if the user doesn't have avatar-data inside the conversation and does not exist anymore, just load/set the user name * search bar new icon / style * block using from conversation context-menu * fix lint * fix merge / lint * fix merge * first separate page * fix tooltips + full width private message + card max width + more responsive * separate conversations methods, to prevent circular deps * update eslint config * fix open new private message * remove unneeded close icon + fix toggle-switch layout * same content height on empty conversations - remove border / box-shadow * canLoadMore = false * remove inbox conditions on chat components * hide footer / fix empty sidebar * floating shadow * remove tooltip on selected conversation user + pm always full-size * show avatar on empty conversation * disable face-avatar * fix faceAvatar + story * fix loading conversation messages while switching the conversation * refresh private-messages page when you are already on it * add countbadge knob to change the example * fix lint * fix hide tooltip + align header correctly * disable perfect scroll * load messages on refresh event * fix header label + conversation actions not breaking layout on hover * add gifting banner to the max height calculation * correct chunk name Co-authored-by: negue <negue@users.noreply.github.com> Co-authored-by: Matteo Pagliazzi <matteopagliazzi@gmail.com>
This commit is contained in:
121
website/server/libs/inbox/conversation.methods.js
Normal file
121
website/server/libs/inbox/conversation.methods.js
Normal file
@@ -0,0 +1,121 @@
|
||||
import { inboxModel as Inbox, setUserStyles } from '../../models/message';
|
||||
import { model as User } from '../../models/user';
|
||||
|
||||
/**
|
||||
* Get the users for conversations
|
||||
* 1. Get the user data of last sent message by conversation
|
||||
* 2. If the target user hasn't replied yet ( 'sent:true' ) , list user data by users directly
|
||||
* @param owner
|
||||
* @param users
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function usersMapByConversations (owner, users) {
|
||||
const query = Inbox
|
||||
.aggregate([
|
||||
{
|
||||
$match: {
|
||||
ownerId: owner._id,
|
||||
uuid: { $in: users },
|
||||
sent: false, // only messages the other user sent to you
|
||||
},
|
||||
},
|
||||
{
|
||||
$group: {
|
||||
_id: '$uuid',
|
||||
userStyles: { $last: '$userStyles' },
|
||||
contributor: { $last: '$contributor' },
|
||||
backer: { $last: '$backer' },
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
|
||||
const usersAr = await query.exec();
|
||||
const usersMap = {};
|
||||
|
||||
for (const usr of usersAr) {
|
||||
usersMap[usr._id] = usr;
|
||||
}
|
||||
|
||||
// if a conversation doesn't have a response of the chat-partner,
|
||||
// those won't be listed by the query above
|
||||
const usersStillNeedToBeLoaded = users.filter(userId => !usersMap[userId]);
|
||||
|
||||
if (usersStillNeedToBeLoaded.length > 0) {
|
||||
const usersQuery = {
|
||||
_id: { $in: usersStillNeedToBeLoaded },
|
||||
};
|
||||
|
||||
const loadedUsers = await User.find(usersQuery, {
|
||||
_id: 1,
|
||||
contributor: 1,
|
||||
backer: 1,
|
||||
items: 1,
|
||||
preferences: 1,
|
||||
stats: 1,
|
||||
}).exec();
|
||||
|
||||
for (const usr of loadedUsers) {
|
||||
const loadedUserConversation = {
|
||||
_id: usr._id,
|
||||
backer: usr.backer,
|
||||
contributor: usr.contributor,
|
||||
};
|
||||
// map user values to conversation properties
|
||||
setUserStyles(loadedUserConversation, usr);
|
||||
|
||||
usersMap[usr._id] = loadedUserConversation;
|
||||
}
|
||||
}
|
||||
|
||||
return usersMap;
|
||||
}
|
||||
|
||||
export async function listConversations (owner) {
|
||||
// group messages by user owned by logged-in user
|
||||
const query = Inbox
|
||||
.aggregate([
|
||||
{
|
||||
$match: {
|
||||
ownerId: owner._id,
|
||||
},
|
||||
},
|
||||
{
|
||||
$group: {
|
||||
_id: '$uuid',
|
||||
user: { $last: '$user' },
|
||||
username: { $last: '$username' },
|
||||
timestamp: { $last: '$timestamp' },
|
||||
text: { $last: '$text' },
|
||||
count: { $sum: 1 },
|
||||
},
|
||||
},
|
||||
{ $sort: { timestamp: -1 } }, // sort by latest message
|
||||
]);
|
||||
|
||||
const conversationsList = await query.exec();
|
||||
|
||||
const userIdList = conversationsList.map(c => c._id);
|
||||
|
||||
// get user-info based on conversations
|
||||
const usersMap = await usersMapByConversations(owner, userIdList);
|
||||
|
||||
const conversations = conversationsList.map(res => {
|
||||
const uuid = res._id;
|
||||
|
||||
const conversation = {
|
||||
uuid,
|
||||
...res,
|
||||
};
|
||||
|
||||
if (usersMap[uuid]) {
|
||||
conversation.userStyles = usersMap[uuid].userStyles;
|
||||
conversation.contributor = usersMap[uuid].contributor;
|
||||
conversation.backer = usersMap[uuid].backer;
|
||||
}
|
||||
|
||||
return conversation;
|
||||
});
|
||||
|
||||
return conversations;
|
||||
}
|
||||
Reference in New Issue
Block a user