Skip to content

Commit

Permalink
[IMPROVE] Add message name container component to message name header…
Browse files Browse the repository at this point in the history
… and system message (#27184)
  • Loading branch information
Filipe Marins authored Nov 22, 2022
1 parent c480a85 commit 8706c3f
Show file tree
Hide file tree
Showing 15 changed files with 248 additions and 71 deletions.
2 changes: 1 addition & 1 deletion apps/meteor/client/views/room/MessageList/MessageList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { MessageProvider } from '../providers/MessageProvider';
import { SelectedMessagesProvider } from '../providers/SelectedMessagesProvider';
import Message from './components/Message';
import MessageSystem from './components/MessageSystem';
import { ThreadMessagePreview } from './components/ThreadMessagePreview';
import ThreadMessagePreview from './components/ThreadMessagePreview';
import { useMessages } from './hooks/useMessages';
import { isMessageFirstUnread } from './lib/isMessageFirstUnread';
import { isMessageNewDay } from './lib/isMessageNewDay';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
MessageTimestamp,
MessageUsername,
MessageStatusPrivateIndicator,
MessageNameContainer,
} from '@rocket.chat/fuselage';
import { useTranslation } from '@rocket.chat/ui-contexts';
import React, { FC, memo } from 'react';
Expand Down Expand Up @@ -36,25 +37,30 @@ const MessageHeader: FC<{ message: IMessage }> = ({ message }) => {

return (
<MessageHeaderTemplate>
<MessageName
{...(!showUsername && { 'data-qa-type': 'username' })}
title={!showUsername && !usernameAndRealNameAreSame ? `@${user.username}` : undefined}
data-username={user.username}
onClick={user.username !== undefined ? openUserCard(user.username) : undefined}
style={{ cursor: 'pointer' }}
>
{message.alias || getUserDisplayName(user.name, user.username, showRealName)}
</MessageName>
{showUsername && (
<MessageUsername
<MessageNameContainer>
<MessageName
{...(!showUsername && { 'data-qa-type': 'username' })}
title={!showUsername && !usernameAndRealNameAreSame ? `@${user.username}` : undefined}
data-username={user.username}
data-qa-type='username'
onClick={user.username !== undefined ? openUserCard(user.username) : undefined}
style={{ cursor: 'pointer' }}
>
@{user.username}
</MessageUsername>
)}
{message.alias || getUserDisplayName(user.name, user.username, showRealName)}
</MessageName>
{showUsername && (
<>
{' '}
<MessageUsername
data-username={user.username}
data-qa-type='username'
onClick={user.username !== undefined ? openUserCard(user.username) : undefined}
style={{ cursor: 'pointer' }}
>
@{user.username}
</MessageUsername>
</>
)}
</MessageNameContainer>

{shouldShowRolesList && <RolesList roles={roles} isBot={message.bot} />}
<MessageTimestamp title={formatters.dateAndTime(message.ts)}>{formatters.time(message.ts)}</MessageTimestamp>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
MessageSystemBlock,
CheckBox,
MessageUsername,
MessageNameContainer,
} from '@rocket.chat/fuselage';
import { TranslationKey, useTranslation } from '@rocket.chat/ui-contexts';
import React, { FC, memo } from 'react';
Expand Down Expand Up @@ -57,18 +58,26 @@ export const MessageSystem: FC<{ message: IMessage }> = ({ message }) => {
</MessageSystemLeftContainer>
<MessageSystemContainer>
<MessageSystemBlock>
<MessageSystemName onClick={user.username !== undefined ? openUserCard(user.username) : undefined} style={{ cursor: 'pointer' }}>
{getUserDisplayName(user.name, user.username, showRealName)}
</MessageSystemName>
{showUsername && (
<MessageUsername
data-username={user.username}
<MessageNameContainer>
<MessageSystemName
onClick={user.username !== undefined ? openUserCard(user.username) : undefined}
style={{ cursor: 'pointer' }}
>
@{user.username}
</MessageUsername>
)}
{getUserDisplayName(user.name, user.username, showRealName)}
</MessageSystemName>
{showUsername && (
<>
{' '}
<MessageUsername
data-username={user.username}
onClick={user.username !== undefined ? openUserCard(user.username) : undefined}
style={{ cursor: 'pointer' }}
>
@{user.username}
</MessageUsername>
</>
)}
</MessageNameContainer>
{messageType && (
<MessageSystemBody
data-qa-type='system-message-body'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,29 @@ import {
import { useTranslation } from '@rocket.chat/ui-contexts';
import React, { FC } from 'react';

import { MessageTypes } from '../../../../../app/ui-utils/client';
import UserAvatar from '../../../../components/avatar/UserAvatar';
import { AsyncStatePhase } from '../../../../lib/asyncState';
import { useMessageActions } from '../../contexts/MessageContext';
import { useIsSelecting, useToggleSelect, useIsSelectedMessage, useCountSelected } from '../contexts/SelectedMessagesContext';
import { useMessageBody } from '../hooks/useMessageBody';
import { useParentMessage } from '../hooks/useParentMessage';
import ThreadMessagePreviewBody from './ThreadMessagePreviewBody';

export const ThreadMessagePreview: FC<{ message: IThreadMessage; sequential: boolean }> = ({ message, sequential, ...props }) => {
const ThreadMessagePreview: FC<{ message: IThreadMessage; sequential: boolean }> = ({ message, sequential, ...props }) => {
const {
actions: { openThread },
} = useMessageActions();
const parentMessage = useParentMessage(message.tmid);
const body = useMessageBody(parentMessage.value);
const body = useMessageBody(parentMessage.data);
const t = useTranslation();

const isSelecting = useIsSelecting();
const toggleSelected = useToggleSelect(message._id);
const isSelected = useIsSelectedMessage(message._id);
useCountSelected();

const messageType = parentMessage.isSuccess ? MessageTypes.getType(parentMessage.data) : null;

return (
<ThreadMessageTemplate
{...props}
Expand All @@ -48,12 +50,10 @@ export const ThreadMessagePreview: FC<{ message: IThreadMessage; sequential: boo
<ThreadMessageIconThread />
</ThreadMessageLeftContainer>
<ThreadMessageContainer>
<ThreadMessageOrigin>
{parentMessage.phase === AsyncStatePhase.RESOLVED ? (
<ThreadMessagePreviewBody message={{ ...parentMessage.value, msg: body }} />
) : (
<Skeleton />
)}
<ThreadMessageOrigin system={!!messageType}>
{parentMessage.isSuccess && !messageType && <ThreadMessagePreviewBody message={{ ...parentMessage.data, msg: body }} />}
{messageType && t(messageType.message, messageType.data ? messageType.data(message) : {})}
{parentMessage.isLoading && <Skeleton />}
</ThreadMessageOrigin>
<ThreadMessageUnfollow />
</ThreadMessageContainer>
Expand All @@ -75,3 +75,5 @@ export const ThreadMessagePreview: FC<{ message: IThreadMessage; sequential: boo
</ThreadMessageTemplate>
);
};

export default ThreadMessagePreview;
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
import { IMessage } from '@rocket.chat/core-typings';
import { useEffect } from 'react';
import { useQuery, UseQueryResult } from '@tanstack/react-query';

import { findParentMessage } from '../../../../../app/ui-message/client/messageThread';
import { AsyncState, useAsyncState } from '../../../../hooks/useAsyncState';

export const useParentMessage = (mid: IMessage['_id']): AsyncState<IMessage> => {
const { resolve, reject, error, phase, value } = useAsyncState<IMessage>();

useEffect(() => {
findParentMessage(mid).then(resolve).catch(reject);
}, [mid, reject, resolve]);

return { phase, value, error } as AsyncState<IMessage>;
};
export const useParentMessage = (mid: IMessage['_id']): UseQueryResult<IMessage> =>
useQuery(['parent-message', { mid }], async () => findParentMessage(mid));
2 changes: 1 addition & 1 deletion apps/meteor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@
"@rocket.chat/favicon": "workspace:^",
"@rocket.chat/forked-matrix-appservice-bridge": "^4.0.1",
"@rocket.chat/forked-matrix-bot-sdk": "^0.6.0-beta.2",
"@rocket.chat/fuselage": "0.31.21",
"@rocket.chat/fuselage": "next",
"@rocket.chat/fuselage-hooks": "0.31.21",
"@rocket.chat/fuselage-polyfills": "0.31.21",
"@rocket.chat/fuselage-toastbar": "0.31.21",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { render, screen } from '@testing-library/react';
import { expect } from 'chai';
import proxyquire from 'proxyquire';
import React from 'react';

const date = new Date('2021-10-27T00:00:00.000Z');
const baseMessage = {
ts: date,
u: {
_id: 'userId',
name: 'userName',
username: 'userName',
},
msg: 'message',
md: [
{
type: 'PARAGRAPH',
value: [
{
type: 'PLAIN_TEXT',
value: 'message',
},
],
},
],
rid: 'roomId',
_id: 'messageId',
_updatedAt: date,
urls: [],
};
const COMPONENT_PATH = '../../../../../../client/views/room/MessageList/components/ThreadMessagePreview';
const defaultConfig = {
'../../contexts/MessageContext': {
useMessageActions: () => ({
actions: {
openThread: () => () => '',
},
}),
},
'../hooks/useParentMessage': {
useParentMessage: () => '',
},
'../hooks/useMessageBody': {
useMessageBody: () => <p>Parent Message</p>,
},
'../../../../../app/ui-utils/client': {
MessageTypes: {
getType: () => false,
},
},
'./ThreadMessagePreviewBody': ({ message }: { message: any }) => <span>{message.msg}</span>,
};

describe('ThreadMessagePreview', () => {
it('should render the message when exists', () => {
const ThreadMessagePreview = proxyquire.noCallThru().load(COMPONENT_PATH, defaultConfig).default;

render(<ThreadMessagePreview message={baseMessage} sequential={true} />);

expect(screen.getByText(baseMessage.msg)).to.exist;
});

it('should render ignored message', () => {
const ThreadMessagePreview = proxyquire.noCallThru().load(COMPONENT_PATH, defaultConfig).default;

const message = { ...baseMessage, ignored: true };
render(<ThreadMessagePreview message={message} sequential={true} />);

expect(screen.getByText('Message_Ignored')).to.exist;
});

it('should render parent message', () => {
const ThreadMessagePreview = proxyquire.noCallThru().load(COMPONENT_PATH, {
...defaultConfig,
'../hooks/useParentMessage': {
useParentMessage: () => ({
isSuccess: true,
}),
},
}).default;

render(<ThreadMessagePreview message={baseMessage} sequential={false} />);

expect(screen.getByText('Parent Message')).to.exist;
});

it('should render parent system message', () => {
const ThreadMessagePreview = proxyquire.noCallThru().load(COMPONENT_PATH, {
...defaultConfig,
'../hooks/useParentMessage': {
useParentMessage: () => ({
isSuccess: true,
}),
},
'../../../../../app/ui-utils/client': {
MessageTypes: {
getType: () => ({
message: 'System Message',
}),
},
},
}).default;

render(<ThreadMessagePreview message={baseMessage} sequential={false} />);

expect(screen.getByText('System Message')).to.exist;
});
});
2 changes: 1 addition & 1 deletion ee/packages/ui-theming/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"private": true,
"devDependencies": {
"@rocket.chat/css-in-js": "0.31.21",
"@rocket.chat/fuselage": "0.31.21",
"@rocket.chat/fuselage": "next",
"@rocket.chat/fuselage-hooks": "0.31.21",
"@rocket.chat/icons": "0.31.21",
"@rocket.chat/ui-contexts": "workspace:~",
Expand Down
2 changes: 1 addition & 1 deletion packages/fuselage-ui-kit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"devDependencies": {
"@rocket.chat/apps-engine": "~1.30.0",
"@rocket.chat/eslint-config": "workspace:^",
"@rocket.chat/fuselage": "0.31.21",
"@rocket.chat/fuselage": "next",
"@rocket.chat/fuselage-hooks": "0.31.21",
"@rocket.chat/fuselage-polyfills": "0.31.21",
"@rocket.chat/icons": "0.31.21",
Expand Down
6 changes: 4 additions & 2 deletions packages/fuselage-ui-kit/src/stories/Message.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ const createStory = (blocks: readonly UiKit.LayoutBlock[]) => {
</Message.LeftContainer>
<Message.Container>
<Message.Header>
<Message.Name>Haylie George</Message.Name>
<Message.Username>@haylie.george</Message.Username>
<Message.NameContainer>
<Message.Name>Haylie George</Message.Name>
<Message.Username>@haylie.george</Message.Username>
</Message.NameContainer>
<Message.Role>Admin</Message.Role>
<Message.Role>User</Message.Role>
<Message.Role>Owner</Message.Role>
Expand Down
2 changes: 1 addition & 1 deletion packages/gazzodown/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"@mdx-js/react": "^1.6.22",
"@rocket.chat/core-typings": "workspace:^",
"@rocket.chat/css-in-js": "0.31.21",
"@rocket.chat/fuselage": "0.31.21",
"@rocket.chat/fuselage": "next",
"@rocket.chat/fuselage-tokens": "0.31.21",
"@rocket.chat/message-parser": "next",
"@rocket.chat/styled": "0.31.21",
Expand Down
2 changes: 1 addition & 1 deletion packages/ui-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"private": true,
"devDependencies": {
"@rocket.chat/css-in-js": "0.31.21",
"@rocket.chat/fuselage": "0.31.21",
"@rocket.chat/fuselage": "next",
"@rocket.chat/fuselage-hooks": "0.31.21",
"@rocket.chat/icons": "0.31.21",
"@rocket.chat/ui-contexts": "workspace:~",
Expand Down
2 changes: 1 addition & 1 deletion packages/ui-composer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"devDependencies": {
"@babel/core": "~7.18.13",
"@rocket.chat/eslint-config": "workspace:^",
"@rocket.chat/fuselage": "0.31.21",
"@rocket.chat/fuselage": "next",
"@rocket.chat/icons": "0.31.21",
"@storybook/addon-actions": "~6.5.12",
"@storybook/addon-docs": "~6.5.12",
Expand Down
2 changes: 1 addition & 1 deletion packages/ui-video-conf/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"devDependencies": {
"@rocket.chat/css-in-js": "0.31.21",
"@rocket.chat/eslint-config": "workspace:^",
"@rocket.chat/fuselage": "0.31.21",
"@rocket.chat/fuselage": "next",
"@rocket.chat/fuselage-hooks": "0.31.21",
"@rocket.chat/styled": "0.31.21",
"@types/jest": "^27.4.1",
Expand Down
Loading

0 comments on commit 8706c3f

Please sign in to comment.