From 02fa09f4c00695ff7bacdc75a4d1a1e92a84d35c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrique=20Guimar=C3=A3es=20Ribeiro?= <43561537+rique223@users.noreply.github.com> Date: Mon, 7 Apr 2025 11:05:35 -0300 Subject: [PATCH] chore: Remove meteor functions from `messagePopupConfig.ts` (#35610) Co-authored-by: Guilherme Gazzo --- .../client/popup/messagePopupConfig.ts | 66 ------------- .../room/providers/ComposerPopupProvider.tsx | 95 ++++++++++++++----- 2 files changed, 71 insertions(+), 90 deletions(-) delete mode 100644 apps/meteor/app/ui-message/client/popup/messagePopupConfig.ts diff --git a/apps/meteor/app/ui-message/client/popup/messagePopupConfig.ts b/apps/meteor/app/ui-message/client/popup/messagePopupConfig.ts deleted file mode 100644 index 1bd9f0171c6..00000000000 --- a/apps/meteor/app/ui-message/client/popup/messagePopupConfig.ts +++ /dev/null @@ -1,66 +0,0 @@ -import type { IUser } from '@rocket.chat/core-typings'; -import { Meteor } from 'meteor/meteor'; -import { Tracker } from 'meteor/tracker'; - -import { RoomManager } from '../../../../client/lib/RoomManager'; -import { asReactiveSource } from '../../../../client/lib/tracker'; -import { Messages } from '../../../models/client'; - -type UserFromRoomMessage = { - _id: string; - username: string; - name: string | undefined; - ts: Date; - suggestion?: boolean; -}; - -export const usersFromRoomMessages = new Map(); - -Meteor.startup(() => { - Tracker.autorun(() => { - const uid = Meteor.userId(); - const rid = asReactiveSource( - (cb) => RoomManager.on('changed', cb), - () => RoomManager.opened, - ); - const user = uid ? (Meteor.users.findOne(uid, { fields: { username: 1 } }) as IUser | undefined) : undefined; - if (!rid || !user) { - return; - } - - usersFromRoomMessages.clear(); - - const uniqueMessageUsersControl: Record = {}; - - Messages.find( - { - rid, - 'u.username': { $ne: user.username }, - 't': { $exists: false }, - }, - { - fields: { - 'u.username': 1, - 'u.name': 1, - 'u._id': 1, - 'ts': 1, - }, - sort: { ts: -1 }, - }, - ) - .fetch() - .filter(({ u: { username } }) => { - const notMapped = !uniqueMessageUsersControl[username]; - uniqueMessageUsersControl[username] = true; - return notMapped; - }) - .forEach(({ u: { username, name, _id }, ts }) => { - usersFromRoomMessages.set(_id, { - _id, - username, - name, - ts, - }); - }); - }); -}); diff --git a/apps/meteor/client/views/room/providers/ComposerPopupProvider.tsx b/apps/meteor/client/views/room/providers/ComposerPopupProvider.tsx index 42bdb49f43a..08f4a60b887 100644 --- a/apps/meteor/client/views/room/providers/ComposerPopupProvider.tsx +++ b/apps/meteor/client/views/room/providers/ComposerPopupProvider.tsx @@ -2,7 +2,7 @@ import type { IRoom } from '@rocket.chat/core-typings'; import { isOmnichannelRoom } from '@rocket.chat/core-typings'; import { useLocalStorage } from '@rocket.chat/fuselage-hooks'; import { escapeRegExp } from '@rocket.chat/string-helpers'; -import { useMethod, useSetting, useUserPreference } from '@rocket.chat/ui-contexts'; +import { useMethod, useSetting, useUserId, useUserPreference } from '@rocket.chat/ui-contexts'; import { useQueryClient } from '@tanstack/react-query'; import { useMemo, useState } from 'react'; import type { ReactNode } from 'react'; @@ -10,8 +10,7 @@ import { useTranslation } from 'react-i18next'; import { hasAtLeastOnePermission } from '../../../../app/authorization/client'; import { emoji } from '../../../../app/emoji/client'; -import { Subscriptions } from '../../../../app/models/client'; -import { usersFromRoomMessages } from '../../../../app/ui-message/client/popup/messagePopupConfig'; +import { Messages, Subscriptions } from '../../../../app/models/client'; import { slashCommands } from '../../../../app/utils/client'; import { cannedResponsesQueryKeys } from '../../../lib/queryKeys'; import ComposerBoxPopupCannedResponse from '../composer/ComposerBoxPopupCannedResponse'; @@ -34,6 +33,46 @@ type ComposerPopupProviderProps = { room: IRoom; }; +const getLastRecentUsers = (rid: string, uid: string) => { + const uniqueUsers = new Map< + string, + { + _id: string; + username: string; + name?: string; + ts: Date; + suggestion?: boolean; + } + >(); + Messages.find( + { + rid, + 'u._id': { $ne: uid }, + 't': { $exists: false }, + 'ts': { $exists: true }, + }, + { + fields: { + 'u.username': 1, + 'u.name': 1, + 'u._id': 1, + 'ts': 1, + }, + sort: { ts: -1 }, + }, + ).forEach(({ u: { username, name, _id }, ts }) => { + if (!uniqueUsers.has(username)) { + uniqueUsers.set(username, { + _id, + username, + name, + ts, + }); + } + }); + + return Array.from(uniqueUsers.values()); +}; const ComposerPopupProvider = ({ children, room }: ComposerPopupProviderProps) => { const { _id: rid, encrypted: isRoomEncrypted } = room; @@ -53,8 +92,9 @@ const ComposerPopupProvider = ({ children, room }: ComposerPopupProviderProps) = const unencryptedMessagesAllowed = useSetting('E2E_Allow_Unencrypted_Messages', false); const encrypted = isRoomEncrypted && e2eEnabled && !unencryptedMessagesAllowed; const queryClient = useQueryClient(); - + const uid = useUserId(); const call = useMethod('getSlashCommandPreviews'); + const value: ComposerPopupContextValue = useMemo(() => { return [ createMessageBoxPopupConfig({ @@ -64,14 +104,18 @@ const ComposerPopupProvider = ({ children, room }: ComposerPopupProviderProps) = const filterRegex = filter && new RegExp(escapeRegExp(filter), 'i'); const items: ComposerBoxPopupUserProps[] = []; - const users = Array.from(usersFromRoomMessages.values()) - .filter((u) => !!u.ts && (filterRegex ? u.username.match(filterRegex) || u.name?.match(filterRegex) : true)) + const roomMessageUsers = getLastRecentUsers(rid, uid!) + .filter((u) => { + if (!filterRegex) return true; + return filterRegex.test(u.username) || (u.name && filterRegex.test(u.name)); + }) .sort((a, b) => b.ts.getTime() - a.ts.getTime()) .slice(0, suggestionsCount ?? 5) - .map((u) => { - u.suggestion = true; - return u; - }); + .map((u) => ({ + ...u, + suggestion: true, + })); + if (!filterRegex || filterRegex.test('all')) { items.push({ _id: 'all', @@ -92,17 +136,19 @@ const ComposerPopupProvider = ({ children, room }: ComposerPopupProviderProps) = }); } - return [...users, ...items]; + return [...roomMessageUsers, ...items]; }, getItemsFromServer: async (filter: string) => { const filterRegex = filter && new RegExp(escapeRegExp(filter), 'i'); - const usernames = Array.from(usersFromRoomMessages.values()) - .filter((u) => !!u.ts && (filterRegex ? u.username.match(filterRegex) || u.name?.match(filterRegex) : true)) + const usernames = getLastRecentUsers(rid, uid!) + .filter((u) => { + if (!filterRegex) return true; + return filterRegex.test(u.username) || (u.name && filterRegex.test(u.name)); + }) .sort((a, b) => b.ts.getTime() - a.ts.getTime()) .slice(0, suggestionsCount ?? 5) - .map((u) => { - return u.username; - }); + .map((u) => u.username); + const { users = [] } = await userSpotlight(filter, usernames, { users: true, mentions: true }, rid); return users.map(({ _id, username, nickname, name, status, avatarETag, outside }) => { @@ -359,19 +405,20 @@ const ComposerPopupProvider = ({ children, room }: ComposerPopupProviderProps) = }), ].filter(Boolean); }, [ - t, - useEmoji, - encrypted, + call, cannedResponseEnabled, + encrypted, + i18n, isOmnichannel, previewTitle, + queryClient, + recentEmojis, + rid, suggestionsCount, + t, + uid, + useEmoji, userSpotlight, - rid, - recentEmojis, - i18n, - queryClient, - call, ]); return ;