Skip to content

Commit

Permalink
fix(meteor): Respect UI_Use_Real_Name setting for reactions (#30069)
Browse files Browse the repository at this point in the history
  • Loading branch information
yash-rajpal committed Jan 24, 2024
1 parent 718a7c0 commit 9310e84
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 44 deletions.
5 changes: 5 additions & 0 deletions .changeset/seven-pugs-argue.md
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Fixed using real names on messages reactions
10 changes: 5 additions & 5 deletions apps/meteor/client/components/message/content/Reactions.tsx
@@ -1,9 +1,9 @@
import type { IMessage } from '@rocket.chat/core-typings';
import { MessageReactions, MessageReactionAction } from '@rocket.chat/fuselage';
import type { ReactElement } from 'react';
import React from 'react';
import React, { useContext } from 'react';

import { useOpenEmojiPicker, useReactionsFilter, useUserHasReacted } from '../list/MessageListContext';
import { MessageListContext, useOpenEmojiPicker, useUserHasReacted } from '../list/MessageListContext';
import Reaction from './reactions/Reaction';
import { useToggleReactionMutation } from './reactions/useToggleReactionMutation';

Expand All @@ -13,9 +13,8 @@ type ReactionsProps = {

const Reactions = ({ message }: ReactionsProps): ReactElement => {
const hasReacted = useUserHasReacted(message);
const filterReactions = useReactionsFilter(message);
const openEmojiPicker = useOpenEmojiPicker(message);

const { username } = useContext(MessageListContext);
const toggleReactionMutation = useToggleReactionMutation();

return (
Expand All @@ -27,7 +26,8 @@ const Reactions = ({ message }: ReactionsProps): ReactElement => {
counter={reactions.usernames.length}
hasReacted={hasReacted}
name={name}
names={filterReactions(name)}
names={reactions.usernames.filter((user) => user !== username)}
messageId={message._id}
onClick={() => toggleReactionMutation.mutate({ mid: message._id, reaction: name })}
/>
))}
Expand Down
@@ -1,11 +1,14 @@
import { MessageReaction as MessageReactionTemplate, MessageReactionEmoji, MessageReactionCounter } from '@rocket.chat/fuselage';
import type { TranslationKey } from '@rocket.chat/ui-contexts';
import { useTooltipClose, useTooltipOpen, useTranslation } from '@rocket.chat/ui-contexts';
import { useQueryClient } from '@tanstack/react-query';
import type { ReactElement } from 'react';
import React, { useRef } from 'react';
import React, { useContext, useRef } from 'react';

import { getEmojiClassNameAndDataTitle } from '../../../../lib/utils/renderEmoji';
import { useGetMessageByID } from '../../../../views/room/contextualBar/Threads/hooks/useGetMessageByID';
import MarkdownText from '../../../MarkdownText';
import { MessageListContext } from '../../list/MessageListContext';

// TODO: replace it with proper usage of i18next plurals
const getTranslationKey = (users: string[], mine: boolean): TranslationKey => {
Expand Down Expand Up @@ -33,37 +36,80 @@ type ReactionProps = {
counter: number;
name: string;
names: string[];
messageId: string;
onClick: () => void;
};

const Reaction = ({ hasReacted, counter, name, names, ...props }: ReactionProps): ReactElement => {
const Reaction = ({ hasReacted, counter, name, names, messageId, ...props }: ReactionProps): ReactElement => {
const t = useTranslation();
const ref = useRef<HTMLDivElement>(null);
const openTooltip = useTooltipOpen();
const closeTooltip = useTooltipClose();
const { showRealName, username } = useContext(MessageListContext);

const mine = hasReacted(name);

const key = getTranslationKey(names, mine);

const emojiProps = getEmojiClassNameAndDataTitle(name);

const getMessage = useGetMessageByID();

const queryClient = useQueryClient();

const getNames = async () => {
return queryClient.fetchQuery(
['chat.getMessage', 'reactions', messageId, names],
async () => {
// This happens if the only reaction is from the current user
if (!names.length) {
return [];
}

if (!showRealName) {
return names;
}

const data = await getMessage(messageId);

const { reactions } = data;
if (!reactions) {
return [];
}

if (username) {
const index = reactions[name].usernames.indexOf(username);
index >= 0 && reactions[name].names?.splice(index, 1);
return (reactions[name].names || names).filter(Boolean);
}

return reactions[name].names || names;
},
{ staleTime: 1000 * 60 * 5 },
);
};

return (
<MessageReactionTemplate
ref={ref}
key={name}
mine={mine}
tabIndex={0}
role='button'
onMouseOver={(e): void => {
// if data-tooltip is not set, the tooltip will close on first mouse enter
data-tooltip
onMouseEnter={async (e) => {
e.stopPropagation();
e.preventDefault();

const users = await getNames();

ref.current &&
openTooltip(
<MarkdownText
content={t(key, {
counter: names.length > 10 ? names.length - 10 : names.length,
users: names.slice(0, 10).join(', '),
users: users?.slice(0, 10).join(', ') || '',
emoji: name,
})}
variant='inline'
Expand Down
Expand Up @@ -7,7 +7,6 @@ export type MessageListContextValue = {
useShowFollowing: ({ message }: { message: IMessage }) => boolean;
useMessageDateFormatter: () => (date: Date) => string;
useUserHasReacted: (message: IMessage) => (reaction: string) => boolean;
useReactionsFilter: (message: IMessage) => (reaction: string) => string[];
useOpenEmojiPicker: (message: IMessage) => (event: React.MouseEvent) => void;
showRoles: boolean;
showRealName: boolean;
Expand All @@ -25,6 +24,7 @@ export type MessageListContextValue = {
autoTranslateLanguage?: string;
showColors: boolean;
jumpToMessageParam?: string;
username: string | undefined;
scrollMessageList?: (callback: (wrapper: HTMLDivElement | null) => ScrollToOptions | void) => void;
};

Expand All @@ -38,15 +38,12 @@ export const MessageListContext = createContext<MessageListContextValue>({
(date: Date): string =>
date.toString(),
useOpenEmojiPicker: () => (): void => undefined,
useReactionsFilter:
(message) =>
(reaction: string): string[] =>
message.reactions ? message.reactions[reaction]?.usernames || [] : [],
showRoles: false,
showRealName: false,
showUsername: false,
showColors: false,
scrollMessageList: () => undefined,
username: undefined,
});

export const useShowTranslated: MessageListContextValue['useShowTranslated'] = (...args) =>
Expand All @@ -69,5 +66,3 @@ export const useUserHasReacted: MessageListContextValue['useUserHasReacted'] = (
useContext(MessageListContext).useUserHasReacted(message);
export const useOpenEmojiPicker: MessageListContextValue['useOpenEmojiPicker'] = (...args) =>
useContext(MessageListContext).useOpenEmojiPicker(...args);
export const useReactionsFilter: MessageListContextValue['useReactionsFilter'] = (message: IMessage) =>
useContext(MessageListContext).useReactionsFilter(message);
@@ -1,5 +1,4 @@
import type { IMessage } from '@rocket.chat/core-typings';
import { isMessageReactionsNormalized, isThreadMainMessage } from '@rocket.chat/core-typings';
import { isThreadMainMessage } from '@rocket.chat/core-typings';
import { useLayout, useUser, useUserPreference, useSetting, useEndpoint, useSearchParameter } from '@rocket.chat/ui-contexts';
import type { VFC, ReactNode } from 'react';
import React, { useMemo, memo } from 'react';
Expand Down Expand Up @@ -60,29 +59,6 @@ const MessageListProvider: VFC<MessageListProviderProps> = ({ children, scrollMe
const context: MessageListContextValue = useMemo(
() => ({
showColors,
useReactionsFilter: (message: IMessage): ((reaction: string) => string[]) => {
const { reactions } = message;
return !showRealName
? (reaction: string): string[] =>
reactions?.[reaction]?.usernames.filter((user) => user !== username).map((username) => `@${username}`) || []
: (reaction: string): string[] => {
if (!reactions?.[reaction]) {
return [];
}
if (!isMessageReactionsNormalized(message)) {
return message.reactions?.[reaction]?.usernames.filter((user) => user !== username).map((username) => `@${username}`) || [];
}
if (!username) {
return message.reactions[reaction].names;
}
const index = message.reactions[reaction].usernames.indexOf(username);
if (index === -1) {
return message.reactions[reaction].names;
}

return message.reactions[reaction].names.splice(index, 1);
};
},
useUserHasReacted: username
? (message) =>
(reaction): boolean =>
Expand Down Expand Up @@ -126,6 +102,7 @@ const MessageListProvider: VFC<MessageListProviderProps> = ({ children, scrollMe
chat?.emojiPicker.open(e.currentTarget, (emoji: string) => reactToMessage({ messageId: message._id, reaction: emoji }));
}
: () => (): void => undefined,
username,
}),
[
username,
Expand Down
3 changes: 0 additions & 3 deletions packages/core-typings/src/IMessage/IMessage.ts
Expand Up @@ -287,9 +287,6 @@ export interface IMessageReactionsNormalized extends IMessage {
};
}

export const isMessageReactionsNormalized = (message: IMessage): message is IMessageReactionsNormalized =>
Boolean('reactions' in message && message.reactions && message.reactions[0] && 'names' in message.reactions[0]);

export interface IOmnichannelSystemMessage extends IMessage {
navigation?: {
page: {
Expand Down

0 comments on commit 9310e84

Please sign in to comment.