diff --git a/.changeset/cyan-countries-impress.md b/.changeset/cyan-countries-impress.md new file mode 100644 index 000000000000..6bd78b6f62f8 --- /dev/null +++ b/.changeset/cyan-countries-impress.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': patch +--- + +Fixed matrix homeserver domain setting not being visible in admin panel diff --git a/.changeset/rich-dingos-mix.md b/.changeset/rich-dingos-mix.md new file mode 100644 index 000000000000..d514535a97b4 --- /dev/null +++ b/.changeset/rich-dingos-mix.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': patch +--- + +Added reactions tooltip loader diff --git a/.gitignore b/.gitignore index 13ee265952bb..fcf2b8cd07c7 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,5 @@ yarn-error.log* .envrc *.sublime-workspace + +**/.vim/ diff --git a/apps/meteor/app/ui-utils/client/lib/messageActionDefault.ts b/apps/meteor/app/ui-utils/client/lib/messageActionDefault.ts index 5807673188e5..834fd0bb05a2 100644 --- a/apps/meteor/app/ui-utils/client/lib/messageActionDefault.ts +++ b/apps/meteor/app/ui-utils/client/lib/messageActionDefault.ts @@ -10,7 +10,7 @@ import { dispatchToastMessage } from '../../../../client/lib/toast'; import { messageArgs } from '../../../../client/lib/utils/messageArgs'; import { router } from '../../../../client/providers/RouterProvider'; import ForwardMessageModal from '../../../../client/views/room/modals/ForwardMessageModal/ForwardMessageModal'; -import ReactionList from '../../../../client/views/room/modals/ReactionListModal'; +import ReactionListModal from '../../../../client/views/room/modals/ReactionListModal'; import ReportMessageModal from '../../../../client/views/room/modals/ReportMessageModal'; import { hasAtLeastOnePermission, hasPermission } from '../../../authorization/client'; import { ChatRoom, Subscriptions } from '../../../models/client'; @@ -266,10 +266,10 @@ Meteor.startup(async () => { label: 'Reactions', context: ['message', 'message-mobile', 'threads', 'videoconf', 'videoconf-threads'], type: 'interaction', - action(this: unknown, _, { message: { reactions = {} } = messageArgs(this).msg }) { + action(this: unknown, _, { message: { reactions = {} } = messageArgs(this).msg, chat }) { imperativeModal.open({ - component: ReactionList, - props: { reactions, onClose: imperativeModal.close }, + component: ReactionListModal, + props: { reactions, onOpenUserCard: chat?.userCard.openUserCard, onClose: imperativeModal.close }, }); }, condition({ message: { reactions } }) { diff --git a/apps/meteor/app/ui/client/lib/ChatMessages.ts b/apps/meteor/app/ui/client/lib/ChatMessages.ts index 9c87defa0b3b..b46c240877c2 100644 --- a/apps/meteor/app/ui/client/lib/ChatMessages.ts +++ b/apps/meteor/app/ui/client/lib/ChatMessages.ts @@ -51,7 +51,10 @@ export class ChatMessages implements ChatAPI { public ActionManager: any; - public userCard: { open(username: string): (event: UIEvent) => void; close(): void }; + public userCard: { + openUserCard(event: UIEvent, username: string): void; + closeUserCard(): void; + }; public emojiPicker: { open(el: Element, cb: (emoji: string) => void): void; @@ -166,8 +169,8 @@ export class ChatMessages implements ChatAPI { this.readStateManager = new ReadStateManager(rid); this.userCard = { - open: unimplemented, - close: unimplemented, + openUserCard: unimplemented, + closeUserCard: unimplemented, }; this.emojiPicker = { diff --git a/apps/meteor/app/ui/client/lib/userCard.ts b/apps/meteor/app/ui/client/lib/userCard.ts deleted file mode 100644 index 90b3d4ec5201..000000000000 --- a/apps/meteor/app/ui/client/lib/userCard.ts +++ /dev/null @@ -1,64 +0,0 @@ -import type { ComponentProps } from 'react'; -import { createElement } from 'react'; -import { createPortal } from 'react-dom'; - -import { registerPortal } from '../../../../client/lib/portals/portalsSubscription'; -import { queueMicrotask } from '../../../../client/lib/utils/queueMicrotask'; -import UserCardHolder from '../../../../client/views/room/UserCardHolder'; - -type UserCardProps = ReturnType['getProps']>; - -let props: UserCardProps; - -const subscribers = new Set<() => void>(); - -const updateProps = (newProps: Partial) => { - props = { ...props, ...newProps }; - subscribers.forEach((subscriber) => subscriber()); -}; - -const getProps = () => props; - -const subscribeToProps = (callback: () => void) => { - subscribers.add(callback); - - return () => { - subscribers.delete(callback); - }; -}; - -const createContainer = () => { - const container = document.createElement('div'); - container.id = 'react-user-card'; - document.body.appendChild(container); - - return container; -}; - -let container: HTMLDivElement | undefined; -let unregisterPortal: (() => void) | undefined; - -export const closeUserCard = () => { - queueMicrotask(() => { - if (unregisterPortal) { - unregisterPortal(); - unregisterPortal = undefined; - } - }); -}; - -export const openUserCard = (params: Omit) => { - updateProps({ ...params, onClose: closeUserCard }); - - if (!container) { - container = createContainer(); - } - - if (!unregisterPortal) { - const children = createElement(UserCardHolder, { getProps, subscribeToProps }); - const portal = createPortal(children, container); - unregisterPortal = registerPortal(container, portal); - } - - return closeUserCard; -}; diff --git a/apps/meteor/client/components/GazzodownText.tsx b/apps/meteor/client/components/GazzodownText.tsx index fe86cbd86fd1..76232984a594 100644 --- a/apps/meteor/client/components/GazzodownText.tsx +++ b/apps/meteor/client/components/GazzodownText.tsx @@ -25,7 +25,9 @@ type GazzodownTextProps = { }; const GazzodownText = ({ mentions, channels, searchText, children }: GazzodownTextProps) => { + const chat = useChat(); const highlights = useMessageListHighlights(); + const highlightRegex = useMemo(() => { if (!highlights?.length) { return; @@ -51,8 +53,6 @@ const GazzodownText = ({ mentions, channels, searchText, children }: GazzodownTe const ownUserId = useUserId(); const showMentionSymbol = Boolean(useUserPreference('mentionsWithSymbol')); - const chat = useChat(); - const resolveUserMention = useCallback( (mention: string) => { if (mention === 'all' || mention === 'here') { @@ -75,7 +75,7 @@ const GazzodownText = ({ mentions, channels, searchText, children }: GazzodownTe return (event: UIEvent): void => { event.stopPropagation(); - chat?.userCard.open(username)(event); + chat?.userCard.openUserCard(event, username); }; }, [chat?.userCard], diff --git a/apps/meteor/client/components/RoomAutoComplete/Avatar.tsx b/apps/meteor/client/components/RoomAutoComplete/Avatar.tsx index d28546428513..1437c4ebbe89 100644 --- a/apps/meteor/client/components/RoomAutoComplete/Avatar.tsx +++ b/apps/meteor/client/components/RoomAutoComplete/Avatar.tsx @@ -1,9 +1,8 @@ import { Options } from '@rocket.chat/fuselage'; +import { RoomAvatar } from '@rocket.chat/ui-avatar'; import type { FC } from 'react'; import React from 'react'; -import RoomAvatar from '../avatar/RoomAvatar'; - type AvatarProps = { value: string; type: string; diff --git a/apps/meteor/client/components/RoomAutoComplete/RoomAutoComplete.tsx b/apps/meteor/client/components/RoomAutoComplete/RoomAutoComplete.tsx index 93509618827c..39fbf9577776 100644 --- a/apps/meteor/client/components/RoomAutoComplete/RoomAutoComplete.tsx +++ b/apps/meteor/client/components/RoomAutoComplete/RoomAutoComplete.tsx @@ -1,11 +1,11 @@ import { AutoComplete, Option, Box } from '@rocket.chat/fuselage'; import { useDebouncedValue } from '@rocket.chat/fuselage-hooks'; +import { RoomAvatar } from '@rocket.chat/ui-avatar'; import { useEndpoint } from '@rocket.chat/ui-contexts'; import { useQuery } from '@tanstack/react-query'; import type { ReactElement, ComponentProps } from 'react'; import React, { memo, useMemo, useState } from 'react'; -import RoomAvatar from '../avatar/RoomAvatar'; import Avatar from './Avatar'; const generateQuery = ( diff --git a/apps/meteor/client/components/RoomAutoCompleteMultiple/RoomAutoCompleteMultiple.tsx b/apps/meteor/client/components/RoomAutoCompleteMultiple/RoomAutoCompleteMultiple.tsx index eb0414e7da14..49006e025111 100644 --- a/apps/meteor/client/components/RoomAutoCompleteMultiple/RoomAutoCompleteMultiple.tsx +++ b/apps/meteor/client/components/RoomAutoCompleteMultiple/RoomAutoCompleteMultiple.tsx @@ -1,12 +1,11 @@ import { AutoComplete, Option, Chip, Box, Skeleton } from '@rocket.chat/fuselage'; import { useDebouncedValue } from '@rocket.chat/fuselage-hooks'; +import { RoomAvatar } from '@rocket.chat/ui-avatar'; import { useEndpoint } from '@rocket.chat/ui-contexts'; import { useQuery } from '@tanstack/react-query'; import type { ReactElement, ComponentProps } from 'react'; import React, { memo, useMemo, useState } from 'react'; -import RoomAvatar from '../avatar/RoomAvatar'; - const generateQuery = ( term = '', ): { diff --git a/apps/meteor/client/components/UserAndRoomAutoCompleteMultiple/UserAndRoomAutoCompleteMultiple.tsx b/apps/meteor/client/components/UserAndRoomAutoCompleteMultiple/UserAndRoomAutoCompleteMultiple.tsx index f96c198865cc..b8ff0b472fa4 100644 --- a/apps/meteor/client/components/UserAndRoomAutoCompleteMultiple/UserAndRoomAutoCompleteMultiple.tsx +++ b/apps/meteor/client/components/UserAndRoomAutoCompleteMultiple/UserAndRoomAutoCompleteMultiple.tsx @@ -2,13 +2,12 @@ import { isDirectMessageRoom } from '@rocket.chat/core-typings'; import { AutoComplete, Box, Option, OptionAvatar, OptionContent, Chip } from '@rocket.chat/fuselage'; import { useDebouncedValue } from '@rocket.chat/fuselage-hooks'; import { escapeRegExp } from '@rocket.chat/string-helpers'; +import { RoomAvatar, UserAvatar } from '@rocket.chat/ui-avatar'; import { useUser, useUserSubscriptions } from '@rocket.chat/ui-contexts'; import type { ComponentProps, ReactElement } from 'react'; import React, { memo, useMemo, useState } from 'react'; import { roomCoordinator } from '../../lib/rooms/roomCoordinator'; -import RoomAvatar from '../avatar/RoomAvatar'; -import UserAvatar from '../avatar/UserAvatar'; type UserAndRoomAutoCompleteMultipleProps = Omit, 'filter'>; diff --git a/apps/meteor/client/components/UserAutoComplete/UserAutoComplete.tsx b/apps/meteor/client/components/UserAutoComplete/UserAutoComplete.tsx index ebe3ecc5ee72..1f12f29ee13b 100644 --- a/apps/meteor/client/components/UserAutoComplete/UserAutoComplete.tsx +++ b/apps/meteor/client/components/UserAutoComplete/UserAutoComplete.tsx @@ -1,12 +1,11 @@ import { AutoComplete, Option, Box, Chip, Options } from '@rocket.chat/fuselage'; import { useDebouncedValue } from '@rocket.chat/fuselage-hooks'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { useEndpoint } from '@rocket.chat/ui-contexts'; import { useQuery } from '@tanstack/react-query'; import type { ComponentProps, ReactElement } from 'react'; import React, { memo, useMemo, useState } from 'react'; -import UserAvatar from '../avatar/UserAvatar'; - const query = ( term = '', conditions = {}, diff --git a/apps/meteor/client/components/UserAutoCompleteMultiple/UserAutoCompleteMultiple.tsx b/apps/meteor/client/components/UserAutoCompleteMultiple/UserAutoCompleteMultiple.tsx index 857af5e9c43f..f9887d693ca0 100644 --- a/apps/meteor/client/components/UserAutoCompleteMultiple/UserAutoCompleteMultiple.tsx +++ b/apps/meteor/client/components/UserAutoCompleteMultiple/UserAutoCompleteMultiple.tsx @@ -1,12 +1,11 @@ import { AutoComplete, Box, OptionAvatar, Option, OptionContent, Chip, OptionDescription } from '@rocket.chat/fuselage'; import { useDebouncedValue } from '@rocket.chat/fuselage-hooks'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { useEndpoint } from '@rocket.chat/ui-contexts'; import { useQuery } from '@tanstack/react-query'; import type { ComponentProps, ReactElement } from 'react'; import React, { memo, useMemo, useState } from 'react'; -import UserAvatar from '../avatar/UserAvatar'; - const query = ( term = '', ): { diff --git a/apps/meteor/client/components/UserAutoCompleteMultiple/UserAutoCompleteMultipleFederated.tsx b/apps/meteor/client/components/UserAutoCompleteMultiple/UserAutoCompleteMultipleFederated.tsx index 457593e2c5db..5a372ee39dd2 100644 --- a/apps/meteor/client/components/UserAutoCompleteMultiple/UserAutoCompleteMultipleFederated.tsx +++ b/apps/meteor/client/components/UserAutoCompleteMultiple/UserAutoCompleteMultipleFederated.tsx @@ -1,11 +1,11 @@ import { MultiSelectFiltered, Icon, Box, Chip } from '@rocket.chat/fuselage'; import { useDebouncedValue } from '@rocket.chat/fuselage-hooks'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { useEndpoint } from '@rocket.chat/ui-contexts'; import { useQuery } from '@tanstack/react-query'; import type { ReactElement, AllHTMLAttributes } from 'react'; import React, { memo, useState, useCallback, useMemo } from 'react'; -import UserAvatar from '../avatar/UserAvatar'; import AutocompleteOptions, { OptionsContext } from './UserAutoCompleteMultipleOptions'; type UserAutoCompleteMultipleFederatedProps = { diff --git a/apps/meteor/client/components/UserAutoCompleteMultiple/UserAutoCompleteMultipleOption.tsx b/apps/meteor/client/components/UserAutoCompleteMultiple/UserAutoCompleteMultipleOption.tsx index e6762c188abd..0dc773af9596 100644 --- a/apps/meteor/client/components/UserAutoCompleteMultiple/UserAutoCompleteMultipleOption.tsx +++ b/apps/meteor/client/components/UserAutoCompleteMultiple/UserAutoCompleteMultipleOption.tsx @@ -1,10 +1,9 @@ import type { IUser } from '@rocket.chat/core-typings'; import { Option, OptionDescription } from '@rocket.chat/fuselage'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import type { ReactElement } from 'react'; import React from 'react'; -import UserAvatar from '../avatar/UserAvatar'; - type UserAutoCompleteMultipleOptionProps = { label: { _federated?: boolean; diff --git a/apps/meteor/client/components/UserCard/UserCard.stories.tsx b/apps/meteor/client/components/UserCard/UserCard.stories.tsx index b07d4a09cc7d..e3174381d85d 100644 --- a/apps/meteor/client/components/UserCard/UserCard.stories.tsx +++ b/apps/meteor/client/components/UserCard/UserCard.stories.tsx @@ -1,7 +1,7 @@ import type { ComponentMeta, ComponentStory } from '@storybook/react'; import React from 'react'; -import UserCard from '.'; +import { UserCard, UserCardRole, UserCardAction } from '.'; export default { title: 'Components/UserCard', @@ -14,16 +14,16 @@ export default { customStatus: '🛴 currently working on User Card', roles: ( <> - Admin - Rocket.Chat - Team + Admin + Rocket.Chat + Team ), bio: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla tempus, eros convallis vulputate cursus, nisi neque eleifend libero, eget lacinia justo purus nec est. In at sodales ipsum. Sed lacinia quis purus eget pulvinar. Aenean eu pretium nunc, at aliquam magna. Praesent dignissim, tortor sed volutpat mattis, mauris diam pulvinar leo, porta commodo risus est non purus. Mauris in justo vel lorem ullamcorper hendrerit. Nam est metus, viverra a pellentesque vitae, ornare eget odio. Morbi tempor feugiat mattis. Morbi non felis tempor, aliquam justo sed, sagittis nibh. Mauris consequat ex metus. Praesent sodales sit amet nibh a vulputate. Integer commodo, mi vel bibendum sollicitudin, urna lectus accumsan ante, eget faucibus augue ex id neque. Aenean consectetur, orci a pellentesque mattis, tortor tellus fringilla elit, non ullamcorper risus nunc feugiat risus. Fusce sit amet nisi dapibus turpis commodo placerat. In tortor ante, vehicula sit amet augue et, imperdiet porta sem.', actions: ( <> - - + + ), localTime: 'Local Time: 7:44 AM', diff --git a/apps/meteor/client/components/UserCard/UserCard.tsx b/apps/meteor/client/components/UserCard/UserCard.tsx index 5678f360af38..2d440427ccbd 100644 --- a/apps/meteor/client/components/UserCard/UserCard.tsx +++ b/apps/meteor/client/components/UserCard/UserCard.tsx @@ -1,13 +1,14 @@ import { css } from '@rocket.chat/css-in-js'; -import { Box, Button, IconButton, Skeleton } from '@rocket.chat/fuselage'; +import { Box, Button, IconButton } from '@rocket.chat/fuselage'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { useTranslation } from '@rocket.chat/ui-contexts'; -import type { ReactNode, ComponentProps, MouseEvent } from 'react'; +import type { ReactNode, ComponentProps } from 'react'; import React, { forwardRef } from 'react'; import { useEmbeddedLayout } from '../../hooks/useEmbeddedLayout'; import MarkdownText from '../MarkdownText'; import * as Status from '../UserStatus'; -import UserAvatar from '../avatar/UserAvatar'; +import UserCardActions from './UserCardActions'; import UserCardContainer from './UserCardContainer'; import UserCardInfo from './UserCardInfo'; import UserCardRoles from './UserCardRoles'; @@ -22,9 +23,7 @@ const clampStyle = css` `; type UserCardProps = { - className?: string; - style?: ComponentProps['style']; - open?: (e: MouseEvent) => void; + onOpenUserInfo?: () => void; name?: string; username?: string; etag?: string; @@ -36,61 +35,40 @@ type UserCardProps = { localTime?: ReactNode; onClose?: () => void; nickname?: string; - isLoading?: boolean; -}; +} & ComponentProps; -const UserCard = forwardRef(function UserCard( +const UserCard = forwardRef(function UserCard( { - className, - style, - open, + onOpenUserInfo, name, username, etag, - customStatus = , - roles = ( - <> - - - - - ), - bio = , + customStatus, + roles, + bio, status = , actions, - localTime = , + localTime, onClose, nickname, - isLoading, - }: UserCardProps, + ...props + }, ref, ) { const t = useTranslation(); const isLayoutEmbedded = useEmbeddedLayout(); return ( - - - {!isLoading && username ? ( - - ) : ( - - )} + +
+ {username && } - {isLoading ? ( - <> - - - - - ) : ( - actions - )} + {actions} - +
- {isLoading ? : } + {nickname && ( ({nickname}) @@ -113,9 +91,9 @@ const UserCard = forwardRef(function UserCard( {typeof bio === 'string' ? : bio} )} - {!isLoading && open && !isLayoutEmbedded && ( + {onOpenUserInfo && !isLayoutEmbedded && (
-
diff --git a/apps/meteor/client/components/UserCard/UserCardAction.tsx b/apps/meteor/client/components/UserCard/UserCardAction.tsx index f13e71b601b5..c96e742be94e 100644 --- a/apps/meteor/client/components/UserCard/UserCardAction.tsx +++ b/apps/meteor/client/components/UserCard/UserCardAction.tsx @@ -5,7 +5,7 @@ import React from 'react'; type UserCardActionProps = ComponentProps; const UserCardAction = ({ label, icon, ...props }: UserCardActionProps): ReactElement => ( - + ); export default UserCardAction; diff --git a/apps/meteor/client/components/UserCard/UserCardActions.tsx b/apps/meteor/client/components/UserCard/UserCardActions.tsx new file mode 100644 index 000000000000..6a1258c02997 --- /dev/null +++ b/apps/meteor/client/components/UserCard/UserCardActions.tsx @@ -0,0 +1,15 @@ +import { useToolbar } from '@react-aria/toolbar'; +import { ButtonGroup } from '@rocket.chat/fuselage'; +import type { ReactElement, ComponentProps } from 'react'; +import React, { useRef } from 'react'; + +type UserCardActionsProps = ComponentProps; + +const UserCardActions = (props: UserCardActionsProps): ReactElement => { + const ref = useRef(null); + const { toolbarProps } = useToolbar(props, ref); + + return ; +}; + +export default UserCardActions; diff --git a/apps/meteor/client/components/UserCard/UserCardContainer.tsx b/apps/meteor/client/components/UserCard/UserCardContainer.tsx index c1279e4ff513..2434077922e3 100644 --- a/apps/meteor/client/components/UserCard/UserCardContainer.tsx +++ b/apps/meteor/client/components/UserCard/UserCardContainer.tsx @@ -3,7 +3,21 @@ import type { ComponentProps } from 'react'; import React, { forwardRef } from 'react'; const UserCardContainer = forwardRef(function UserCardContainer(props: ComponentProps, ref) { - return ; + return ( + + ); }); export default UserCardContainer; diff --git a/apps/meteor/client/components/UserCard/UserCardSkeleton.tsx b/apps/meteor/client/components/UserCard/UserCardSkeleton.tsx new file mode 100644 index 000000000000..9339eca8f665 --- /dev/null +++ b/apps/meteor/client/components/UserCard/UserCardSkeleton.tsx @@ -0,0 +1,34 @@ +import { Box, Skeleton } from '@rocket.chat/fuselage'; +import type { ComponentProps } from 'react'; +import React, { forwardRef } from 'react'; + +import UserCardContainer from './UserCardContainer'; + +const UserCardSkeleton = forwardRef>(function UserCardSkeleton(props, ref) { + return ( + + + + + {Array.from({ length: 3 }).map((_, i) => ( + + ))} + + + + + + + + {Array.from({ length: 3 }).map((_, i) => ( + + ))} + {Array.from({ length: 2 }).map((_, i) => ( + + ))} + + + ); +}); + +export default UserCardSkeleton; diff --git a/apps/meteor/client/components/UserCard/index.ts b/apps/meteor/client/components/UserCard/index.ts index defc7140be15..75a5ad84cd6c 100644 --- a/apps/meteor/client/components/UserCard/index.ts +++ b/apps/meteor/client/components/UserCard/index.ts @@ -3,12 +3,7 @@ import UserCardAction from './UserCardAction'; import UserCardInfo from './UserCardInfo'; import UserCardRole from './UserCardRole'; import UserCardRoles from './UserCardRoles'; +import UserCardSkeleton from './UserCardSkeleton'; import UserCardUsername from './UserCardUsername'; -export default Object.assign(UserCard, { - Action: UserCardAction, - Role: UserCardRole, - Roles: UserCardRoles, - Info: UserCardInfo, - Username: UserCardUsername, -}); +export { UserCard, UserCardAction, UserCardInfo, UserCardRole, UserCardRoles, UserCardUsername, UserCardSkeleton }; diff --git a/apps/meteor/client/components/UserInfo/UserInfo.tsx b/apps/meteor/client/components/UserInfo/UserInfo.tsx index bdce27d028ad..72722e8e9156 100644 --- a/apps/meteor/client/components/UserInfo/UserInfo.tsx +++ b/apps/meteor/client/components/UserInfo/UserInfo.tsx @@ -12,7 +12,7 @@ import { ContextualbarScrollableContent } from '../Contextualbar'; import InfoPanel from '../InfoPanel'; import MarkdownText from '../MarkdownText'; import UTCClock from '../UTCClock'; -import UserCard from '../UserCard'; +import { UserCardRoles } from '../UserCard'; import UserInfoAvatar from './UserInfoAvatar'; type UserInfoDataProps = Serialized< @@ -90,7 +90,7 @@ const UserInfo = ({ {roles.length !== 0 && ( {t('Roles')} - {roles} + {roles} )} diff --git a/apps/meteor/client/components/UserInfo/UserInfoAvatar.tsx b/apps/meteor/client/components/UserInfo/UserInfoAvatar.tsx index 2fbe4a05ed55..c15992489264 100644 --- a/apps/meteor/client/components/UserInfo/UserInfoAvatar.tsx +++ b/apps/meteor/client/components/UserInfo/UserInfoAvatar.tsx @@ -1,8 +1,7 @@ +import { UserAvatar } from '@rocket.chat/ui-avatar'; import type { ComponentProps, ReactElement } from 'react'; import React from 'react'; -import UserAvatar from '../avatar/UserAvatar'; - const UserInfoAvatar = ({ username, ...props }: ComponentProps): ReactElement => ( ); diff --git a/apps/meteor/client/components/UserInfo/UserInfoUsername.tsx b/apps/meteor/client/components/UserInfo/UserInfoUsername.tsx index 75d2c87a82c0..171c5c68d8c4 100644 --- a/apps/meteor/client/components/UserInfo/UserInfoUsername.tsx +++ b/apps/meteor/client/components/UserInfo/UserInfoUsername.tsx @@ -3,16 +3,15 @@ import type { Box } from '@rocket.chat/fuselage'; import type { ReactElement, ComponentProps } from 'react'; import React from 'react'; -import UserCard from '../UserCard'; +import { UserCardUsername } from '../UserCard'; type UserInfoUsernameProps = { username: IUser['username']; status: ReactElement; } & ComponentProps; -// TODO: Remove UserCard.Username const UserInfoUsername = ({ username, status, ...props }: UserInfoUsernameProps): ReactElement => ( - + ); export default UserInfoUsername; diff --git a/apps/meteor/client/components/avatar/AppAvatar.tsx b/apps/meteor/client/components/avatar/AppAvatar.tsx deleted file mode 100644 index c146eb4b10fc..000000000000 --- a/apps/meteor/client/components/avatar/AppAvatar.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { Box } from '@rocket.chat/fuselage'; -import type { ComponentProps, ReactElement } from 'react'; -import React from 'react'; - -import BaseAvatar from './BaseAvatar'; - -type AppAvatarProps = { - iconFileContent: string; - iconFileData: string; - size: ComponentProps['size']; -} & ComponentProps; - -export default function AppAvatar({ iconFileContent, size, iconFileData, ...props }: AppAvatarProps): ReactElement { - return ( - - - - ); -} diff --git a/apps/meteor/client/components/avatar/BaseAvatar.tsx b/apps/meteor/client/components/avatar/BaseAvatar.tsx deleted file mode 100644 index d32f96f57881..000000000000 --- a/apps/meteor/client/components/avatar/BaseAvatar.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import type { AvatarProps } from '@rocket.chat/fuselage'; -import { Avatar, Skeleton } from '@rocket.chat/fuselage'; -import type { FC } from 'react'; -import React, { useState } from 'react'; - -export type BaseAvatarProps = Omit; - -const BaseAvatar: FC = ({ onError, ...props }) => { - const [isLoading, setIsLoading] = useState(false); - - if (isLoading) { - return ; - } - - return ( - { - setIsLoading(true); - onError?.(event); - }} - {...props} - /> - ); -}; - -export default BaseAvatar; diff --git a/apps/meteor/client/components/avatar/RoomAvatar.tsx b/apps/meteor/client/components/avatar/RoomAvatar.tsx deleted file mode 100644 index bf3c96509046..000000000000 --- a/apps/meteor/client/components/avatar/RoomAvatar.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { useRoomAvatarPath } from '@rocket.chat/ui-contexts'; -import type { ReactElement } from 'react'; -import React, { memo } from 'react'; - -import BaseAvatar from './BaseAvatar'; - -// TODO: frontend chapter day - Remove inline Styling - -type RoomAvatarProps = { - /* @deprecated */ - size?: 'x16' | 'x20' | 'x28' | 'x36' | 'x40' | 'x124' | 'x332'; - /* @deprecated */ - url?: string; - - room: { - _id: string; - type?: string; - t?: string; - avatarETag?: string; - }; -}; - -const RoomAvatar = function RoomAvatar({ room, ...rest }: RoomAvatarProps): ReactElement { - const getRoomPathAvatar = useRoomAvatarPath(); - const { url = getRoomPathAvatar(room), ...props } = rest; - return ; -}; - -export default memo(RoomAvatar); diff --git a/apps/meteor/client/components/avatar/RoomAvatarEditor.tsx b/apps/meteor/client/components/avatar/RoomAvatarEditor.tsx index 4a780e4ab173..de4108d8f866 100644 --- a/apps/meteor/client/components/avatar/RoomAvatarEditor.tsx +++ b/apps/meteor/client/components/avatar/RoomAvatarEditor.tsx @@ -3,6 +3,7 @@ import type { IRoom, RoomAdminFieldsType } from '@rocket.chat/core-typings'; import { css } from '@rocket.chat/css-in-js'; import { Box, Button, ButtonGroup } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { RoomAvatar } from '@rocket.chat/ui-avatar'; import { useToastMessageDispatch, useTranslation } from '@rocket.chat/ui-contexts'; import type { ReactElement } from 'react'; import React, { useEffect } from 'react'; @@ -10,7 +11,6 @@ import React, { useEffect } from 'react'; import { getAvatarURL } from '../../../app/utils/client/getAvatarURL'; import { useSingleFileInput } from '../../hooks/useSingleFileInput'; import { isValidImageFormat } from '../../lib/utils/isValidImageFormat'; -import RoomAvatar from './RoomAvatar'; type RoomAvatarEditorProps = { room: Pick; diff --git a/apps/meteor/client/components/avatar/UserAvatarEditor/UserAvatarEditor.tsx b/apps/meteor/client/components/avatar/UserAvatarEditor/UserAvatarEditor.tsx index eda44e98d87f..05d96d9536be 100644 --- a/apps/meteor/client/components/avatar/UserAvatarEditor/UserAvatarEditor.tsx +++ b/apps/meteor/client/components/avatar/UserAvatarEditor/UserAvatarEditor.tsx @@ -1,13 +1,13 @@ import type { IUser, AvatarObject } from '@rocket.chat/core-typings'; -import { Box, Button, TextInput, Avatar, IconButton, Label } from '@rocket.chat/fuselage'; +import { Box, Button, Avatar, TextInput, IconButton, Label } from '@rocket.chat/fuselage'; import { useUniqueId } from '@rocket.chat/fuselage-hooks'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { useToastMessageDispatch, useSetting, useTranslation } from '@rocket.chat/ui-contexts'; import type { ReactElement, ChangeEvent } from 'react'; import React, { useState, useCallback } from 'react'; import { useSingleFileInput } from '../../../hooks/useSingleFileInput'; import { isValidImageFormat } from '../../../lib/utils/isValidImageFormat'; -import UserAvatar from '../UserAvatar'; import type { UserAvatarSuggestion } from './UserAvatarSuggestion'; import UserAvatarSuggestions from './UserAvatarSuggestions'; import { readFileAsDataURL } from './readFileAsDataURL'; @@ -81,11 +81,11 @@ function UserAvatarEditor({ currentUsername, username, setAvatarObj, disabled, e data-qa-id='UserAvatarEditor' username={currentUsername || ''} etag={etag} - onError={() => dispatchToastMessage({ type: 'error', message: t('error-invalid-image-url') })} style={{ - objectFit: 'contain', imageOrientation: rotateImages ? 'from-image' : 'none', + objectFit: 'contain', }} + onError={() => dispatchToastMessage({ type: 'error', message: t('error-invalid-image-url') })} /> diff --git a/apps/meteor/client/components/message/MessageHeader.tsx b/apps/meteor/client/components/message/MessageHeader.tsx index 3189aa2972bc..c12ee8c3ac20 100644 --- a/apps/meteor/client/components/message/MessageHeader.tsx +++ b/apps/meteor/client/components/message/MessageHeader.tsx @@ -52,7 +52,7 @@ const MessageHeader = ({ message }: MessageHeaderProps): ReactElement => { data-username={user.username} {...(user.username !== undefined && chat?.userCard && { - onClick: chat?.userCard.open(message.u.username), + onClick: (e) => chat?.userCard.openUserCard(e, message.u.username), style: { cursor: 'pointer' }, })} > @@ -66,7 +66,7 @@ const MessageHeader = ({ message }: MessageHeaderProps): ReactElement => { data-qa-type='username' {...(user.username !== undefined && chat?.userCard && { - onClick: chat?.userCard.open(message.u.username), + onClick: (e) => chat?.userCard.openUserCard(e, message.u.username), style: { cursor: 'pointer' }, })} > @@ -75,7 +75,6 @@ const MessageHeader = ({ message }: MessageHeaderProps): ReactElement => { )} - {shouldShowRolesList && } {formatTime(message.ts)} {message.private && {t('Only_you_can_see_this_message')}} diff --git a/apps/meteor/client/components/message/content/attachments/structure/AttachmentAuthorAvatar.tsx b/apps/meteor/client/components/message/content/attachments/structure/AttachmentAuthorAvatar.tsx index 22e1f107b027..fb0b3e448f12 100644 --- a/apps/meteor/client/components/message/content/attachments/structure/AttachmentAuthorAvatar.tsx +++ b/apps/meteor/client/components/message/content/attachments/structure/AttachmentAuthorAvatar.tsx @@ -1,8 +1,7 @@ +import { BaseAvatar } from '@rocket.chat/ui-avatar'; import type { ReactElement } from 'react'; import React from 'react'; -import BaseAvatar from '../../../../avatar/BaseAvatar'; - const AttachmentAuthorAvatar = ({ url }: { url: string }): ReactElement => ; export default AttachmentAuthorAvatar; diff --git a/apps/meteor/client/components/message/content/reactions/ReactionTooltip.tsx b/apps/meteor/client/components/message/content/reactions/ReactionTooltip.tsx index e36d5640e7cb..6888233ac212 100644 --- a/apps/meteor/client/components/message/content/reactions/ReactionTooltip.tsx +++ b/apps/meteor/client/components/message/content/reactions/ReactionTooltip.tsx @@ -1,3 +1,4 @@ +import { Skeleton } from '@rocket.chat/fuselage'; import { useTranslation } from '@rocket.chat/ui-contexts'; import type { TranslationKey } from '@rocket.chat/ui-contexts'; import { useQuery } from '@tanstack/react-query'; @@ -42,7 +43,7 @@ const ReactionTooltip = ({ emojiName, usernames, mine, messageId, showRealName, const getMessage = useGetMessageByID(); - const { data: users } = useQuery( + const { data: users, isLoading } = useQuery( ['chat.getMessage', 'reactions', messageId, usernames], async () => { // This happens if the only reaction is from the current user @@ -73,6 +74,17 @@ const ReactionTooltip = ({ emojiName, usernames, mine, messageId, showRealName, { staleTime: 1000 * 60 * 5 }, ); + if (isLoading) { + return ( + <> + + + {usernames.length > 5 && } + {usernames.length > 8 && } + + ); + } + return ( {!sequential && message.u.username && !selecting && showUserAvatar && ( : undefined} avatarUrl={message.avatar} username={message.u.username} size='x36' {...(chat?.userCard && { - onClick: chat?.userCard.open(message.u.username), + onClick: (e) => chat?.userCard.openUserCard(e, message.u.username), style: { cursor: 'pointer' }, })} /> diff --git a/apps/meteor/client/components/message/variants/SystemMessage.tsx b/apps/meteor/client/components/message/variants/SystemMessage.tsx index bef39112bb11..bb0a198061fc 100644 --- a/apps/meteor/client/components/message/variants/SystemMessage.tsx +++ b/apps/meteor/client/components/message/variants/SystemMessage.tsx @@ -11,6 +11,7 @@ import { MessageUsername, MessageNameContainer, } from '@rocket.chat/fuselage'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import type { TranslationKey } from '@rocket.chat/ui-contexts'; import { useTranslation } from '@rocket.chat/ui-contexts'; import type { ReactElement } from 'react'; @@ -29,7 +30,6 @@ import { useCountSelected, } from '../../../views/room/MessageList/contexts/SelectedMessagesContext'; import { useChat } from '../../../views/room/contexts/ChatContext'; -import UserAvatar from '../../avatar/UserAvatar'; import Attachments from '../content/Attachments'; import MessageActions from '../content/MessageActions'; import { useMessageListShowRealName, useMessageListShowUsername } from '../list/MessageListContext'; @@ -75,7 +75,7 @@ const SystemMessage = ({ message, showUserAvatar }: SystemMessageProps): ReactEl user.username && chat?.userCard.openUserCard(e, user.username), style: { cursor: 'pointer' }, })} > @@ -88,7 +88,7 @@ const SystemMessage = ({ message, showUserAvatar }: SystemMessageProps): ReactEl data-username={user.username} {...(user.username !== undefined && chat?.userCard && { - onClick: chat?.userCard.open(user.username), + onClick: (e) => user.username && chat?.userCard.openUserCard(e, user.username), style: { cursor: 'pointer' }, })} > diff --git a/apps/meteor/client/components/message/variants/ThreadMessage.tsx b/apps/meteor/client/components/message/variants/ThreadMessage.tsx index 7c2b219b546f..343b56dc54a8 100644 --- a/apps/meteor/client/components/message/variants/ThreadMessage.tsx +++ b/apps/meteor/client/components/message/variants/ThreadMessage.tsx @@ -1,6 +1,7 @@ import { type IThreadMessage, type IThreadMainMessage, isVideoConfMessage } from '@rocket.chat/core-typings'; import { Message, MessageLeftContainer, MessageContainer } from '@rocket.chat/fuselage'; import { useToggle } from '@rocket.chat/fuselage-hooks'; +import { MessageAvatar } from '@rocket.chat/ui-avatar'; import { useUserId } from '@rocket.chat/ui-contexts'; import type { ReactElement } from 'react'; import React, { memo, useRef } from 'react'; @@ -9,11 +10,11 @@ import type { MessageActionContext } from '../../../../app/ui-utils/client/lib/M import { useIsMessageHighlight } from '../../../views/room/MessageList/contexts/MessageHighlightContext'; import { useJumpToMessage } from '../../../views/room/MessageList/hooks/useJumpToMessage'; import { useChat } from '../../../views/room/contexts/ChatContext'; +import Emoji from '../../Emoji'; import IgnoredContent from '../IgnoredContent'; import MessageHeader from '../MessageHeader'; import MessageToolbarHolder from '../MessageToolbarHolder'; import StatusIndicators from '../StatusIndicators'; -import MessageAvatar from '../header/MessageAvatar'; import ThreadMessageContent from './thread/ThreadMessageContent'; type ThreadMessageProps = { @@ -54,12 +55,12 @@ const ThreadMessage = ({ message, sequential, unread, showUserAvatar }: ThreadMe {!sequential && message.u.username && showUserAvatar && ( : undefined} avatarUrl={message.avatar} username={message.u.username} size='x36' {...(chat?.userCard && { - onClick: chat?.userCard.open(message.u.username), + onClick: (e) => chat?.userCard.openUserCard(e, message.u.username), style: { cursor: 'pointer' }, })} /> diff --git a/apps/meteor/client/components/message/variants/ThreadMessagePreview.tsx b/apps/meteor/client/components/message/variants/ThreadMessagePreview.tsx index eb6fe03d9d0f..0aa8efc76402 100644 --- a/apps/meteor/client/components/message/variants/ThreadMessagePreview.tsx +++ b/apps/meteor/client/components/message/variants/ThreadMessagePreview.tsx @@ -12,6 +12,7 @@ import { CheckBox, MessageStatusIndicatorItem, } from '@rocket.chat/fuselage'; +import { MessageAvatar } from '@rocket.chat/ui-avatar'; import { useTranslation } from '@rocket.chat/ui-contexts'; import type { ReactElement } from 'react'; import React, { memo } from 'react'; @@ -27,7 +28,7 @@ import { useMessageBody } from '../../../views/room/MessageList/hooks/useMessage import { useParentMessage } from '../../../views/room/MessageList/hooks/useParentMessage'; import { isParsedMessage } from '../../../views/room/MessageList/lib/isParsedMessage'; import { useGoToThread } from '../../../views/room/hooks/useGoToThread'; -import MessageAvatar from '../header/MessageAvatar'; +import Emoji from '../../Emoji'; import { useShowTranslated } from '../list/MessageListContext'; import ThreadMessagePreviewBody from './threadPreview/ThreadMessagePreviewBody'; @@ -101,7 +102,13 @@ const ThreadMessagePreview = ({ message, showUserAvatar, sequential, ...props }: )} goToThread({ rid: message.rid, tmid: message.tmid, msg: message._id }) : undefined}> - {!isSelecting && showUserAvatar && } + {!isSelecting && showUserAvatar && ( + : undefined} + username={message.u.username} + size='x18' + /> + )} {isSelecting && } diff --git a/apps/meteor/client/lib/chats/ChatAPI.ts b/apps/meteor/client/lib/chats/ChatAPI.ts index d5de3d9fc4e4..bfdf01ad5d4e 100644 --- a/apps/meteor/client/lib/chats/ChatAPI.ts +++ b/apps/meteor/client/lib/chats/ChatAPI.ts @@ -134,8 +134,8 @@ export type ChatAPI = { | undefined; readonly userCard: { - open(username: string): (event: UIEvent) => void; - close(): void; + openUserCard(event: UIEvent, username: string): void; + closeUserCard(): void; }; readonly emojiPicker: { diff --git a/apps/meteor/client/sidebar/Item/Condensed.stories.tsx b/apps/meteor/client/sidebar/Item/Condensed.stories.tsx index 61e392e77e2e..f63893a30a81 100644 --- a/apps/meteor/client/sidebar/Item/Condensed.stories.tsx +++ b/apps/meteor/client/sidebar/Item/Condensed.stories.tsx @@ -1,10 +1,10 @@ import { Box, IconButton } from '@rocket.chat/fuselage'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { action } from '@storybook/addon-actions'; import type { ComponentMeta, ComponentStory } from '@storybook/react'; import React from 'react'; import * as Status from '../../components/UserStatus'; -import UserAvatar from '../../components/avatar/UserAvatar'; import Condensed from './Condensed'; export default { diff --git a/apps/meteor/client/sidebar/Item/Extended.stories.tsx b/apps/meteor/client/sidebar/Item/Extended.stories.tsx index 7e2b79ad1d6f..a6392eae5d61 100644 --- a/apps/meteor/client/sidebar/Item/Extended.stories.tsx +++ b/apps/meteor/client/sidebar/Item/Extended.stories.tsx @@ -1,10 +1,10 @@ import { Box, IconButton, Badge } from '@rocket.chat/fuselage'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { action } from '@storybook/addon-actions'; import type { ComponentMeta, ComponentStory } from '@storybook/react'; import React from 'react'; import * as Status from '../../components/UserStatus'; -import UserAvatar from '../../components/avatar/UserAvatar'; import Extended from './Extended'; export default { diff --git a/apps/meteor/client/sidebar/Item/Medium.stories.tsx b/apps/meteor/client/sidebar/Item/Medium.stories.tsx index 823244047c51..0c03cf33c500 100644 --- a/apps/meteor/client/sidebar/Item/Medium.stories.tsx +++ b/apps/meteor/client/sidebar/Item/Medium.stories.tsx @@ -1,10 +1,10 @@ import { Box, IconButton } from '@rocket.chat/fuselage'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { action } from '@storybook/addon-actions'; import type { ComponentMeta, ComponentStory } from '@storybook/react'; import React from 'react'; import * as Status from '../../components/UserStatus'; -import UserAvatar from '../../components/avatar/UserAvatar'; import Medium from './Medium'; export default { diff --git a/apps/meteor/client/sidebar/header/UserAvatarWithStatus.tsx b/apps/meteor/client/sidebar/header/UserAvatarWithStatus.tsx index f962125f681c..6fa08f5e0253 100644 --- a/apps/meteor/client/sidebar/header/UserAvatarWithStatus.tsx +++ b/apps/meteor/client/sidebar/header/UserAvatarWithStatus.tsx @@ -1,10 +1,10 @@ import { css } from '@rocket.chat/css-in-js'; import { Box } from '@rocket.chat/fuselage'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { useSetting, useUser, useTranslation } from '@rocket.chat/ui-contexts'; import React from 'react'; import { UserStatus } from '../../components/UserStatus'; -import UserAvatar from '../../components/avatar/UserAvatar'; const anon = { _id: '', diff --git a/apps/meteor/client/sidebar/header/UserMenuHeader.tsx b/apps/meteor/client/sidebar/header/UserMenuHeader.tsx index 515d4153576d..511b2c2a1e45 100644 --- a/apps/meteor/client/sidebar/header/UserMenuHeader.tsx +++ b/apps/meteor/client/sidebar/header/UserMenuHeader.tsx @@ -1,11 +1,11 @@ import type { IUser } from '@rocket.chat/core-typings'; import { Box, Margins } from '@rocket.chat/fuselage'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { useSetting, useTranslation } from '@rocket.chat/ui-contexts'; import React from 'react'; import MarkdownText from '../../components/MarkdownText'; import { UserStatus } from '../../components/UserStatus'; -import UserAvatar from '../../components/avatar/UserAvatar'; import { useUserDisplayName } from '../../hooks/useUserDisplayName'; const UserMenuHeader = ({ user }: { user: IUser }) => { diff --git a/apps/meteor/client/sidebar/hooks/useAvatarTemplate.tsx b/apps/meteor/client/sidebar/hooks/useAvatarTemplate.tsx index 5bb49da37418..9fd1023a32e7 100644 --- a/apps/meteor/client/sidebar/hooks/useAvatarTemplate.tsx +++ b/apps/meteor/client/sidebar/hooks/useAvatarTemplate.tsx @@ -1,10 +1,9 @@ import type { IRoom } from '@rocket.chat/core-typings'; +import { RoomAvatar } from '@rocket.chat/ui-avatar'; import { useUserPreference } from '@rocket.chat/ui-contexts'; import type { ComponentType } from 'react'; import React, { useMemo } from 'react'; -import RoomAvatar from '../../components/avatar/RoomAvatar'; - export const useAvatarTemplate = ( sidebarViewMode?: 'extended' | 'medium' | 'condensed', sidebarDisplayAvatar?: boolean, diff --git a/apps/meteor/client/views/admin/moderation/UserReports/UserReportInfo.tsx b/apps/meteor/client/views/admin/moderation/UserReports/UserReportInfo.tsx index 5d1d99ba8f86..7b410f5e6705 100644 --- a/apps/meteor/client/views/admin/moderation/UserReports/UserReportInfo.tsx +++ b/apps/meteor/client/views/admin/moderation/UserReports/UserReportInfo.tsx @@ -18,7 +18,7 @@ import React, { useMemo } from 'react'; import { ContextualbarScrollableContent } from '../../../../components/Contextualbar'; import GenericNoResults from '../../../../components/GenericNoResults'; -import UserCard from '../../../../components/UserCard'; +import { UserCardRole } from '../../../../components/UserCard'; import { useFormatDate } from '../../../../hooks/useFormatDate'; import ReportReason from '../helpers/ReportReason'; import UserColumn from '../helpers/UserColumn'; @@ -79,7 +79,7 @@ const UserReportInfo = ({ userId }: { userId: string }) => { {t('Roles')} {report.user.roles.map((role, index) => ( - {role} + {role} ))} diff --git a/apps/meteor/client/views/admin/moderation/helpers/ContextMessage.tsx b/apps/meteor/client/views/admin/moderation/helpers/ContextMessage.tsx index c835bb0ad22e..51a2be087276 100644 --- a/apps/meteor/client/views/admin/moderation/helpers/ContextMessage.tsx +++ b/apps/meteor/client/views/admin/moderation/helpers/ContextMessage.tsx @@ -1,10 +1,10 @@ import type { IMessage, MessageReport } from '@rocket.chat/core-typings'; import { isE2EEMessage } from '@rocket.chat/core-typings'; import { Message, MessageName, MessageToolbarItem, MessageToolbarWrapper, MessageUsername } from '@rocket.chat/fuselage'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { useSetting, useTranslation } from '@rocket.chat/ui-contexts'; import React from 'react'; -import UserAvatar from '../../../../components/avatar/UserAvatar'; import MessageContentBody from '../../../../components/message/MessageContentBody'; import Attachments from '../../../../components/message/content/Attachments'; import UiKitMessageBlock from '../../../../components/message/uikit/UiKitMessageBlock'; diff --git a/apps/meteor/client/views/admin/moderation/helpers/UserColumn.tsx b/apps/meteor/client/views/admin/moderation/helpers/UserColumn.tsx index b6289fdff9b8..baaddc1cb6c2 100644 --- a/apps/meteor/client/views/admin/moderation/helpers/UserColumn.tsx +++ b/apps/meteor/client/views/admin/moderation/helpers/UserColumn.tsx @@ -1,14 +1,14 @@ import { Box } from '@rocket.chat/fuselage'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; +import type { ComponentProps } from 'react'; import React from 'react'; -import UserAvatar from '../../../../components/avatar/UserAvatar'; - type UserColumnProps = { name?: string; username?: string; isDesktopOrLarger?: boolean; isProfile?: boolean; - size?: string; + size: ComponentProps['size']; fontSize?: string; }; @@ -17,7 +17,7 @@ const UserColumn = ({ name, username, fontSize, size }: UserColumnProps) => { {username && ( - + )} diff --git a/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRoleTable/UsersInRoleTableRow.tsx b/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRoleTable/UsersInRoleTableRow.tsx index 1fbce402a21b..ea4b999d694e 100644 --- a/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRoleTable/UsersInRoleTableRow.tsx +++ b/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRoleTable/UsersInRoleTableRow.tsx @@ -1,12 +1,12 @@ import type { IUserInRole } from '@rocket.chat/core-typings'; import { Box, Button, Icon } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import type { ReactElement } from 'react'; import React, { memo } from 'react'; import { getUserEmailAddress } from '../../../../../../lib/getUserEmailAddress'; import { GenericTableRow, GenericTableCell } from '../../../../../components/GenericTable'; -import UserAvatar from '../../../../../components/avatar/UserAvatar'; type UsersInRoleTableRowProps = { user: IUserInRole; diff --git a/apps/meteor/client/views/admin/rooms/RoomRow.tsx b/apps/meteor/client/views/admin/rooms/RoomRow.tsx index 2c0dbb8c31a6..73a30e647764 100644 --- a/apps/meteor/client/views/admin/rooms/RoomRow.tsx +++ b/apps/meteor/client/views/admin/rooms/RoomRow.tsx @@ -2,11 +2,11 @@ import { isDiscussion } from '@rocket.chat/core-typings'; import type { IRoom, RoomAdminFieldsType } from '@rocket.chat/core-typings'; import { Box, Icon } from '@rocket.chat/fuselage'; import { useMediaQuery } from '@rocket.chat/fuselage-hooks'; +import { RoomAvatar } from '@rocket.chat/ui-avatar'; import { useRouter, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useCallback } from 'react'; import { GenericTableCell, GenericTableRow } from '../../../components/GenericTable'; -import RoomAvatar from '../../../components/avatar/RoomAvatar'; import { roomCoordinator } from '../../../lib/rooms/roomCoordinator'; const roomTypeI18nMap = { diff --git a/apps/meteor/client/views/admin/settings/groups/voip/VoipExtensionsPage.tsx b/apps/meteor/client/views/admin/settings/groups/voip/VoipExtensionsPage.tsx index 857fd034c91e..7494a249818c 100644 --- a/apps/meteor/client/views/admin/settings/groups/voip/VoipExtensionsPage.tsx +++ b/apps/meteor/client/views/admin/settings/groups/voip/VoipExtensionsPage.tsx @@ -1,4 +1,5 @@ import { Box, Chip, Button, Pagination } from '@rocket.chat/fuselage'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { useSetModal, useTranslation, useEndpoint } from '@rocket.chat/ui-contexts'; import { useQuery } from '@tanstack/react-query'; import React, { useMemo } from 'react'; @@ -15,7 +16,6 @@ import { } from '../../../../../components/GenericTable'; import { usePagination } from '../../../../../components/GenericTable/hooks/usePagination'; import { PageContent } from '../../../../../components/Page'; -import UserAvatar from '../../../../../components/avatar/UserAvatar'; import AssignAgentButton from './AssignAgentButton'; import AssignAgentModal from './AssignAgentModal'; import RemoveAgentButton from './RemoveAgentButton'; diff --git a/apps/meteor/client/views/admin/users/AdminUserInfoWithData.tsx b/apps/meteor/client/views/admin/users/AdminUserInfoWithData.tsx index d0580b90c642..f9b8bb01e129 100644 --- a/apps/meteor/client/views/admin/users/AdminUserInfoWithData.tsx +++ b/apps/meteor/client/views/admin/users/AdminUserInfoWithData.tsx @@ -10,7 +10,7 @@ import React, { useMemo } from 'react'; import { getUserEmailAddress } from '../../../../lib/getUserEmailAddress'; import { ContextualbarContent } from '../../../components/Contextualbar'; import { FormSkeleton } from '../../../components/Skeleton'; -import UserCard from '../../../components/UserCard'; +import { UserCardRole } from '../../../components/UserCard'; import UserInfo from '../../../components/UserInfo'; import { UserStatus } from '../../../components/UserStatus'; import { getUserEmailVerified } from '../../../lib/utils/getUserEmailVerified'; @@ -76,7 +76,7 @@ const AdminUserInfoWithData = ({ uid, onReload }: AdminUserInfoWithDataProps): R name, username, lastLogin, - roles: getRoles(roles).map((role, index) => {role}), + roles: getRoles(roles).map((role, index) => {role}), bio, canViewAllInfo, phone, diff --git a/apps/meteor/client/views/admin/users/UsersTable/UsersTableRow.tsx b/apps/meteor/client/views/admin/users/UsersTable/UsersTableRow.tsx index 2572b7446c42..4010b118e57d 100644 --- a/apps/meteor/client/views/admin/users/UsersTable/UsersTableRow.tsx +++ b/apps/meteor/client/views/admin/users/UsersTable/UsersTableRow.tsx @@ -1,6 +1,7 @@ import type { IRole, IUser } from '@rocket.chat/core-typings'; import { Box } from '@rocket.chat/fuselage'; import { capitalize } from '@rocket.chat/string-helpers'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import type { TranslationKey } from '@rocket.chat/ui-contexts'; import { useTranslation } from '@rocket.chat/ui-contexts'; import type { ReactElement } from 'react'; @@ -8,7 +9,6 @@ import React from 'react'; import { Roles } from '../../../../../app/models/client'; import { GenericTableRow, GenericTableCell } from '../../../../components/GenericTable'; -import UserAvatar from '../../../../components/avatar/UserAvatar'; type UsersTableRowProps = { user: Pick; diff --git a/apps/meteor/client/views/directory/tabs/users/UsersTable/UsersTableRow.tsx b/apps/meteor/client/views/directory/tabs/users/UsersTable/UsersTableRow.tsx index 976bb95ba926..864b0657b6e4 100644 --- a/apps/meteor/client/views/directory/tabs/users/UsersTable/UsersTableRow.tsx +++ b/apps/meteor/client/views/directory/tabs/users/UsersTable/UsersTableRow.tsx @@ -1,10 +1,10 @@ import type { IUser, Serialized } from '@rocket.chat/core-typings'; import { Box, Flex } from '@rocket.chat/fuselage'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import React from 'react'; import { GenericTableRow, GenericTableCell } from '../../../../../components/GenericTable'; import MarkdownText from '../../../../../components/MarkdownText'; -import UserAvatar from '../../../../../components/avatar/UserAvatar'; import { useFormatDate } from '../../../../../hooks/useFormatDate'; type UsersTableRowProps = { diff --git a/apps/meteor/client/views/marketplace/AppDetailsPage/AppDetailsPageHeader.tsx b/apps/meteor/client/views/marketplace/AppDetailsPage/AppDetailsPageHeader.tsx index ef0c7259fddd..a4a65f061252 100644 --- a/apps/meteor/client/views/marketplace/AppDetailsPage/AppDetailsPageHeader.tsx +++ b/apps/meteor/client/views/marketplace/AppDetailsPage/AppDetailsPageHeader.tsx @@ -1,11 +1,11 @@ import type { App } from '@rocket.chat/core-typings'; import { Box, Tag } from '@rocket.chat/fuselage'; +import { AppAvatar } from '@rocket.chat/ui-avatar'; import { useTranslation } from '@rocket.chat/ui-contexts'; import moment from 'moment'; import type { ReactElement } from 'react'; import React from 'react'; -import AppAvatar from '../../../components/avatar/AppAvatar'; import AppMenu from '../AppMenu'; import BundleChips from '../BundleChips'; import { appIncompatibleStatusProps } from '../helpers'; @@ -37,7 +37,9 @@ const AppDetailsPageHeader = ({ app }: { app: App }): ReactElement => { return ( - + + + diff --git a/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppRequests/AppRequestItem.tsx b/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppRequests/AppRequestItem.tsx index 4cdba9f22360..78be4577940c 100644 --- a/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppRequests/AppRequestItem.tsx +++ b/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppRequests/AppRequestItem.tsx @@ -1,9 +1,9 @@ import { Badge, Box } from '@rocket.chat/fuselage'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { usePermission } from '@rocket.chat/ui-contexts'; import type { ReactElement } from 'react'; import React from 'react'; -import UserAvatar from '../../../../../components/avatar/UserAvatar'; import { useFormatDateAndTime } from '../../../../../hooks/useFormatDateAndTime'; type AppRequestItemProps = { diff --git a/apps/meteor/client/views/marketplace/AppsList/AppRow.tsx b/apps/meteor/client/views/marketplace/AppsList/AppRow.tsx index dffa23d7a2c8..33e54edd90bb 100644 --- a/apps/meteor/client/views/marketplace/AppsList/AppRow.tsx +++ b/apps/meteor/client/views/marketplace/AppsList/AppRow.tsx @@ -1,11 +1,11 @@ import type { App } from '@rocket.chat/core-typings'; import { Badge, Card, CardBody, CardCol, CardControls, CardHeader, CardRow, CardTitle } from '@rocket.chat/fuselage'; +import { AppAvatar } from '@rocket.chat/ui-avatar'; import { useRouteParameter, useRouter } from '@rocket.chat/ui-contexts'; import type { KeyboardEvent, MouseEvent, ReactElement } from 'react'; import React, { memo } from 'react'; import semver from 'semver'; -import AppAvatar from '../../../components/avatar/AppAvatar'; import AppStatus from '../AppDetailsPage/tabs/AppStatus/AppStatus'; import AppMenu from '../AppMenu'; import BundleChips from '../BundleChips'; diff --git a/apps/meteor/client/views/meet/CallPage.tsx b/apps/meteor/client/views/meet/CallPage.tsx index 01c4bdc0de0c..87188221c091 100644 --- a/apps/meteor/client/views/meet/CallPage.tsx +++ b/apps/meteor/client/views/meet/CallPage.tsx @@ -1,4 +1,5 @@ import { Box, Flex, ButtonGroup, Button, Icon } from '@rocket.chat/fuselage'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { useTranslation, useStream } from '@rocket.chat/ui-contexts'; import moment from 'moment'; import type { FC } from 'react'; @@ -7,7 +8,6 @@ import React, { useEffect, useState } from 'react'; import { sdk } from '../../../app/utils/client/lib/SDKClient'; import { WebRTC } from '../../../app/webrtc/client'; import { WEB_RTC_EVENTS } from '../../../app/webrtc/lib/constants'; -import UserAvatar from '../../components/avatar/UserAvatar'; import OngoingCallDuration from './OngoingCallDuration'; import './styles.css'; @@ -217,15 +217,14 @@ const CallPage: FC = ({ display: isCameraOn ? 'block' : 'none', }} > - + > + + = ({ top: isRemoteMobileDevice || isLocalMobileDevice ? '10%' : '30%', }} > - + > + + + @@ -336,15 +335,14 @@ const CallPage: FC = ({ backgroundColor='dark' alignItems='center' > - + > + + = ({ }} alignItems='center' > - + > + + Calling... diff --git a/apps/meteor/client/views/meet/MeetPage.tsx b/apps/meteor/client/views/meet/MeetPage.tsx index 8dc27d5ef84e..e7a34b78fd1d 100644 --- a/apps/meteor/client/views/meet/MeetPage.tsx +++ b/apps/meteor/client/views/meet/MeetPage.tsx @@ -1,10 +1,10 @@ import { Button, Box, Flex } from '@rocket.chat/fuselage'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { useRouteParameter, useSearchParameter, useTranslation } from '@rocket.chat/ui-contexts'; import { Meteor } from 'meteor/meteor'; import React, { useEffect, useState, useCallback } from 'react'; import { sdk } from '../../../app/utils/client/lib/SDKClient'; -import UserAvatar from '../../components/avatar/UserAvatar'; import { useEmbeddedLayout } from '../../hooks/useEmbeddedLayout'; import NotFoundPage from '../notFound/NotFoundPage'; import PageLoading from '../root/PageLoading'; @@ -90,15 +90,14 @@ const MeetPage = () => { backgroundColor='dark' alignItems='center' > - + > + + { }} alignItems='center' > - + > + +

Call Ended!

= ({ className, ...props }) => ( - + ); export default Info; diff --git a/apps/meteor/client/views/omnichannel/contactHistory/ContactHistoryItem.tsx b/apps/meteor/client/views/omnichannel/contactHistory/ContactHistoryItem.tsx index 1b9e723c0efa..2bfc10ef0dfe 100644 --- a/apps/meteor/client/views/omnichannel/contactHistory/ContactHistoryItem.tsx +++ b/apps/meteor/client/views/omnichannel/contactHistory/ContactHistoryItem.tsx @@ -8,11 +8,11 @@ import { MessageSystemBody, } from '@rocket.chat/fuselage'; import type { VisitorSearchChatsResult } from '@rocket.chat/rest-typings'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { useTranslation } from '@rocket.chat/ui-contexts'; import type { Dispatch, ReactElement, SetStateAction } from 'react'; import React, { memo } from 'react'; -import UserAvatar from '../../../components/avatar/UserAvatar'; import { useFormatDateAndTime } from '../../../hooks/useFormatDateAndTime'; import { clickableItem } from '../../../lib/clickableItem'; @@ -32,9 +32,7 @@ function ContactHistoryItem({ history, setChatId, ...props }: ContactHistoryItem return ( - - {username && } - + {username && } {username} diff --git a/apps/meteor/client/views/omnichannel/contactHistory/MessageList/ContactHistoryMessage.tsx b/apps/meteor/client/views/omnichannel/contactHistory/MessageList/ContactHistoryMessage.tsx index c6ad907a14e1..a1b9ba1ca3af 100644 --- a/apps/meteor/client/views/omnichannel/contactHistory/MessageList/ContactHistoryMessage.tsx +++ b/apps/meteor/client/views/omnichannel/contactHistory/MessageList/ContactHistoryMessage.tsx @@ -17,12 +17,12 @@ import { MessageSystemBody, MessageSystemTimestamp, } from '@rocket.chat/fuselage'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { useTranslation } from '@rocket.chat/ui-contexts'; import type { FC } from 'react'; import React, { memo } from 'react'; import { getUserDisplayName } from '../../../../../lib/getUserDisplayName'; -import UserAvatar from '../../../../components/avatar/UserAvatar'; import MessageContentBody from '../../../../components/message/MessageContentBody'; import StatusIndicators from '../../../../components/message/StatusIndicators'; import Attachments from '../../../../components/message/content/Attachments'; @@ -52,7 +52,7 @@ const ContactHistoryMessage: FC<{ url={message.avatar} username={message.u.username} size='x18' - onClick={chat?.userCard.open(message.u.username)} + onClick={(e) => chat?.userCard.openUserCard(e, message.u.username)} style={{ cursor: 'pointer' }} /> )} @@ -80,7 +80,7 @@ const ContactHistoryMessage: FC<{ url={message.avatar} username={message.u.username} size='x36' - onClick={chat?.userCard.open(message.u.username)} + onClick={(e) => chat?.userCard.openUserCard(e, message.u.username)} style={{ cursor: 'pointer' }} /> )} diff --git a/apps/meteor/client/views/omnichannel/departments/DepartmentAgentsTable/AgentAvatar.tsx b/apps/meteor/client/views/omnichannel/departments/DepartmentAgentsTable/AgentAvatar.tsx index 168b7c007ced..681c3556b845 100644 --- a/apps/meteor/client/views/omnichannel/departments/DepartmentAgentsTable/AgentAvatar.tsx +++ b/apps/meteor/client/views/omnichannel/departments/DepartmentAgentsTable/AgentAvatar.tsx @@ -1,9 +1,8 @@ import { Box } from '@rocket.chat/fuselage'; import { useMediaQuery } from '@rocket.chat/fuselage-hooks'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import React, { memo } from 'react'; -import UserAvatar from '../../../../components/avatar/UserAvatar'; - const AgentAvatar = ({ name, username, eTag }: { name: string; username: string; eTag?: string }) => { const mediaQuery = useMediaQuery('(min-width: 1024px)'); diff --git a/apps/meteor/client/views/omnichannel/directory/calls/contextualBar/VoipInfo.tsx b/apps/meteor/client/views/omnichannel/directory/calls/contextualBar/VoipInfo.tsx index 2aff3776f84c..65792b6d73e2 100644 --- a/apps/meteor/client/views/omnichannel/directory/calls/contextualBar/VoipInfo.tsx +++ b/apps/meteor/client/views/omnichannel/directory/calls/contextualBar/VoipInfo.tsx @@ -1,5 +1,6 @@ import type { IVoipRoom } from '@rocket.chat/core-typings'; import { Box, Icon, Chip, ButtonGroup } from '@rocket.chat/fuselage'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { useTranslation } from '@rocket.chat/ui-contexts'; import moment from 'moment'; import type { ReactElement } from 'react'; @@ -16,7 +17,6 @@ import { } from '../../../../../components/Contextualbar'; import InfoPanel from '../../../../../components/InfoPanel'; import { UserStatus } from '../../../../../components/UserStatus'; -import UserAvatar from '../../../../../components/avatar/UserAvatar'; import { useIsCallReady } from '../../../../../contexts/CallContext'; import AgentInfoDetails from '../../../components/AgentInfoDetails'; import AgentField from '../../components/AgentField'; diff --git a/apps/meteor/client/views/omnichannel/directory/components/AgentField.tsx b/apps/meteor/client/views/omnichannel/directory/components/AgentField.tsx index d0e0b91ae4e9..91b21d219ffe 100644 --- a/apps/meteor/client/views/omnichannel/directory/components/AgentField.tsx +++ b/apps/meteor/client/views/omnichannel/directory/components/AgentField.tsx @@ -1,10 +1,10 @@ import type { IOmnichannelRoom } from '@rocket.chat/core-typings'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { useEndpoint, useTranslation } from '@rocket.chat/ui-contexts'; import { useQuery } from '@tanstack/react-query'; import React from 'react'; import { UserStatus } from '../../../../components/UserStatus'; -import UserAvatar from '../../../../components/avatar/UserAvatar'; import AgentInfoDetails from '../../components/AgentInfoDetails'; import Field from '../../components/Field'; import Info from '../../components/Info'; diff --git a/apps/meteor/client/views/omnichannel/directory/contacts/contextualBar/ContactInfo.tsx b/apps/meteor/client/views/omnichannel/directory/contacts/contextualBar/ContactInfo.tsx index 30d9aeee33da..9578c6a07b83 100644 --- a/apps/meteor/client/views/omnichannel/directory/contacts/contextualBar/ContactInfo.tsx +++ b/apps/meteor/client/views/omnichannel/directory/contacts/contextualBar/ContactInfo.tsx @@ -1,5 +1,6 @@ import { Box, Margins, ButtonGroup, Button, Divider } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import type { RouteName } from '@rocket.chat/ui-contexts'; import { useToastMessageDispatch, useRoute, useTranslation, useEndpoint, usePermission, useRouter } from '@rocket.chat/ui-contexts'; import { useQuery } from '@tanstack/react-query'; @@ -10,7 +11,6 @@ import { parseOutboundPhoneNumber } from '../../../../../../ee/client/lib/voip/p import ContactManagerInfo from '../../../../../../ee/client/omnichannel/ContactManagerInfo'; import { ContextualbarScrollableContent, ContextualbarFooter } from '../../../../../components/Contextualbar'; import { UserStatus } from '../../../../../components/UserStatus'; -import UserAvatar from '../../../../../components/avatar/UserAvatar'; import { useIsCallReady } from '../../../../../contexts/CallContext'; import { useFormatDate } from '../../../../../hooks/useFormatDate'; import AgentInfoDetails from '../../../components/AgentInfoDetails'; diff --git a/apps/meteor/client/views/omnichannel/managers/ManagersTable.tsx b/apps/meteor/client/views/omnichannel/managers/ManagersTable.tsx index 49ecf27d14d3..7662f740c7d3 100644 --- a/apps/meteor/client/views/omnichannel/managers/ManagersTable.tsx +++ b/apps/meteor/client/views/omnichannel/managers/ManagersTable.tsx @@ -1,5 +1,6 @@ import { Box, Pagination } from '@rocket.chat/fuselage'; import { useDebouncedValue } from '@rocket.chat/fuselage-hooks'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { useTranslation, useEndpoint } from '@rocket.chat/ui-contexts'; import { hashQueryKey, useQuery } from '@tanstack/react-query'; import React, { useMemo, useState } from 'react'; @@ -17,7 +18,6 @@ import { } from '../../../components/GenericTable'; import { usePagination } from '../../../components/GenericTable/hooks/usePagination'; import { useSort } from '../../../components/GenericTable/hooks/useSort'; -import UserAvatar from '../../../components/avatar/UserAvatar'; import AddManager from './AddManager'; import RemoveManagerButton from './RemoveManagerButton'; diff --git a/apps/meteor/client/views/omnichannel/queueList/QueueListTable.tsx b/apps/meteor/client/views/omnichannel/queueList/QueueListTable.tsx index 525611c8237e..b6508658e520 100644 --- a/apps/meteor/client/views/omnichannel/queueList/QueueListTable.tsx +++ b/apps/meteor/client/views/omnichannel/queueList/QueueListTable.tsx @@ -1,6 +1,7 @@ import { UserStatus } from '@rocket.chat/core-typings'; import { Box, Pagination } from '@rocket.chat/fuselage'; import { useMediaQuery } from '@rocket.chat/fuselage-hooks'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { useTranslation, useEndpoint } from '@rocket.chat/ui-contexts'; import { useQuery } from '@tanstack/react-query'; import type { ReactElement } from 'react'; @@ -18,7 +19,6 @@ import { } from '../../../components/GenericTable'; import { usePagination } from '../../../components/GenericTable/hooks/usePagination'; import { useSort } from '../../../components/GenericTable/hooks/useSort'; -import UserAvatar from '../../../components/avatar/UserAvatar'; import { QueueListFilter } from './QueueListFilter'; const QueueListTable = (): ReactElement => { diff --git a/apps/meteor/client/views/room/Header/RoomHeader.tsx b/apps/meteor/client/views/room/Header/RoomHeader.tsx index 951305d63f4f..05f80a984982 100644 --- a/apps/meteor/client/views/room/Header/RoomHeader.tsx +++ b/apps/meteor/client/views/room/Header/RoomHeader.tsx @@ -1,11 +1,11 @@ import type { IRoom } from '@rocket.chat/core-typings'; import { isRoomFederated } from '@rocket.chat/core-typings'; +import { RoomAvatar } from '@rocket.chat/ui-avatar'; import { Header, HeaderAvatar, HeaderContent, HeaderContentRow, HeaderSubtitle, HeaderToolbar } from '@rocket.chat/ui-client'; import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { Suspense } from 'react'; import MarkdownText from '../../../components/MarkdownText'; -import RoomAvatar from '../../../components/avatar/RoomAvatar'; import FederatedRoomOriginServer from './FederatedRoomOriginServer'; import ParentRoomWithData from './ParentRoomWithData'; import ParentTeam from './ParentTeam'; diff --git a/apps/meteor/client/views/room/UserCard/UserCardWithData.tsx b/apps/meteor/client/views/room/UserCard/UserCardWithData.tsx index 2c8668434985..0337c794f245 100644 --- a/apps/meteor/client/views/room/UserCard/UserCardWithData.tsx +++ b/apps/meteor/client/views/room/UserCard/UserCardWithData.tsx @@ -2,14 +2,14 @@ import type { IRoom } from '@rocket.chat/core-typings'; import { PositionAnimated, AnimatedVisibility } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; import { useSetting, useRolesDescription, useTranslation } from '@rocket.chat/ui-contexts'; -import type { ReactElement, UIEvent } from 'react'; +import type { ReactElement } from 'react'; import React, { useMemo, useRef } from 'react'; import { getUserDisplayName } from '../../../../lib/getUserDisplayName'; import { Backdrop } from '../../../components/Backdrop'; import GenericMenu from '../../../components/GenericMenu/GenericMenu'; import LocalTime from '../../../components/LocalTime'; -import UserCard from '../../../components/UserCard'; +import { UserCard, UserCardAction, UserCardRole, UserCardSkeleton } from '../../../components/UserCard'; import { ReactiveUserStatus } from '../../../components/UserStatus'; import { useUserInfoQuery } from '../../../hooks/useUserInfoQuery'; import { useUserInfoActions } from '../hooks/useUserInfoActions'; @@ -18,11 +18,11 @@ type UserCardWithDataProps = { username: string; target: Element; rid: IRoom['_id']; - open: (e: UIEvent) => void; + onOpenUserInfo: () => void; onClose: () => void; }; -const UserCardWithData = ({ username, target, rid, open, onClose }: UserCardWithDataProps): ReactElement => { +const UserCardWithData = ({ username, target, rid, onOpenUserInfo, onClose }: UserCardWithDataProps) => { const t = useTranslation(); const ref = useRef(target); const getRoles = useRolesDescription(); @@ -50,7 +50,7 @@ const UserCardWithData = ({ username, target, rid, open, onClose }: UserCardWith _id, name: getUserDisplayName(name, username, showRealNames), username, - roles: roles && getRoles(roles).map((role, index) => {role}), + roles: roles && getRoles(roles).map((role, index) => {role}), bio, etag: avatarETag, localTime: utcOffset && Number.isInteger(utcOffset) && , @@ -60,9 +60,9 @@ const UserCardWithData = ({ username, target, rid, open, onClose }: UserCardWith }; }, [data, username, showRealNames, isLoading, getRoles]); - const handleOpen = useMutableCallback((e: UIEvent) => { - open?.(e); - onClose?.(); + const handleOpenUserInfo = useMutableCallback(() => { + onOpenUserInfo(); + onClose(); }); const { actions: actionsDefinition, menuActions: menuOptions } = useUserInfoActions( @@ -80,7 +80,7 @@ const UserCardWithData = ({ username, target, rid, open, onClose }: UserCardWith const actions = useMemo(() => { const mapAction = ([key, { content, icon, onClick }]: any): ReactElement => ( - + ); return [...actionsDefinition.map(mapAction), menu].filter(Boolean); @@ -90,7 +90,7 @@ const UserCardWithData = ({ username, target, rid, open, onClose }: UserCardWith <> - + {isLoading ? : } ); diff --git a/apps/meteor/client/views/room/UserCardHolder.tsx b/apps/meteor/client/views/room/UserCardHolder.tsx deleted file mode 100644 index 0f9729217b4c..000000000000 --- a/apps/meteor/client/views/room/UserCardHolder.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import type { ComponentProps } from 'react'; -import React, { Suspense, lazy } from 'react'; -import { useSyncExternalStore } from 'use-sync-external-store/shim'; - -const UserCard = lazy(() => import('./UserCard')); - -type UserCardHolderProps = { - getProps: () => ComponentProps; - subscribeToProps: (callback: () => void) => () => void; -}; - -function UserCardHolder({ getProps, subscribeToProps }: UserCardHolderProps) { - const props = useSyncExternalStore(subscribeToProps, getProps); - - return ( - - - - ); -} - -export default UserCardHolder; diff --git a/apps/meteor/client/views/room/body/LeaderBar.tsx b/apps/meteor/client/views/room/body/LeaderBar.tsx index ff0503971369..6de7c3d52e8e 100644 --- a/apps/meteor/client/views/room/body/LeaderBar.tsx +++ b/apps/meteor/client/views/room/body/LeaderBar.tsx @@ -1,13 +1,13 @@ import type { IUser } from '@rocket.chat/core-typings'; import { css } from '@rocket.chat/css-in-js'; import { Box, Button } from '@rocket.chat/fuselage'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { useTranslation } from '@rocket.chat/ui-contexts'; import type { ReactElement, UIEvent } from 'react'; import React, { memo, useCallback, useMemo } from 'react'; import { isTruthy } from '../../../../lib/isTruthy'; import { ReactiveUserStatus } from '../../../components/UserStatus'; -import UserAvatar from '../../../components/avatar/UserAvatar'; import { roomCoordinator } from '../../../lib/rooms/roomCoordinator'; type LeaderBarProps = { diff --git a/apps/meteor/client/views/room/body/RoomBody.tsx b/apps/meteor/client/views/room/body/RoomBody.tsx index d2722200b2df..1a6a11c07f79 100644 --- a/apps/meteor/client/views/room/body/RoomBody.tsx +++ b/apps/meteor/client/views/room/body/RoomBody.tsx @@ -174,13 +174,13 @@ const RoomBody = (): ReactElement => { }; }); - const handleOpenUserCardButtonClick = useCallback( + const handleOpenUserCard = useCallback( (event: UIEvent, username: IUser['username']) => { if (!username) { return; } - chat?.userCard.open(username)(event); + chat?.userCard.openUserCard(event, username); }, [chat?.userCard], ); @@ -585,7 +585,7 @@ const RoomBody = (): ReactElement => { username={roomLeader.username} name={roomLeader.name} visible={!hideLeaderHeader} - onAvatarClick={handleOpenUserCardButtonClick} + onAvatarClick={handleOpenUserCard} /> ) : null}

void; + closeUserCard: () => void; +}; + +export const UserCardContext = createContext({ + openUserCard: () => undefined, + closeUserCard: () => undefined, +}); + +export const useUserCard = () => useContext(UserCardContext); diff --git a/apps/meteor/client/views/room/contextualBar/Discussions/components/DiscussionsListItem.tsx b/apps/meteor/client/views/room/contextualBar/Discussions/components/DiscussionsListItem.tsx index 6253ab9e3fac..6fabbaff4a1a 100644 --- a/apps/meteor/client/views/room/contextualBar/Discussions/components/DiscussionsListItem.tsx +++ b/apps/meteor/client/views/room/contextualBar/Discussions/components/DiscussionsListItem.tsx @@ -1,10 +1,11 @@ import type { IDiscussionMessage } from '@rocket.chat/core-typings'; import { Box, Message } from '@rocket.chat/fuselage'; +import { MessageAvatar } from '@rocket.chat/ui-avatar'; import { useTranslation } from '@rocket.chat/ui-contexts'; import type { ComponentProps, ReactElement, ReactNode } from 'react'; import React, { memo } from 'react'; -import MessageAvatar from '../../../../../components/message/header/MessageAvatar'; +import Emoji from '../../../../../components/Emoji'; import { clickableItem } from '../../../../../lib/clickableItem'; type DiscussionListItemProps = { @@ -36,7 +37,7 @@ const DiscussionListItem = ({ return ( - + : undefined} username={username} size='x36' /> diff --git a/apps/meteor/client/views/room/contextualBar/Info/RoomInfo/RoomInfo.tsx b/apps/meteor/client/views/room/contextualBar/Info/RoomInfo/RoomInfo.tsx index 7828363227ac..38a7593937ff 100644 --- a/apps/meteor/client/views/room/contextualBar/Info/RoomInfo/RoomInfo.tsx +++ b/apps/meteor/client/views/room/contextualBar/Info/RoomInfo/RoomInfo.tsx @@ -1,5 +1,6 @@ import type { IRoom } from '@rocket.chat/core-typings'; import { Box, Callout, Menu, Option } from '@rocket.chat/fuselage'; +import { RoomAvatar } from '@rocket.chat/ui-avatar'; import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { useMemo } from 'react'; @@ -14,7 +15,6 @@ import { import InfoPanel from '../../../../../components/InfoPanel'; import RetentionPolicyCallout from '../../../../../components/InfoPanel/RetentionPolicyCallout'; import MarkdownText from '../../../../../components/MarkdownText'; -import RoomAvatar from '../../../../../components/avatar/RoomAvatar'; import type { Action } from '../../../../hooks/useActionSpread'; import { useActionSpread } from '../../../../hooks/useActionSpread'; import { useRetentionPolicy } from '../../../body/hooks/useRetentionPolicy'; diff --git a/apps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersItem.tsx b/apps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersItem.tsx index 4fa3c48039e4..8b4d5ad8cb52 100644 --- a/apps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersItem.tsx +++ b/apps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersItem.tsx @@ -11,12 +11,12 @@ import { OptionSkeleton, } from '@rocket.chat/fuselage'; import { usePrefersReducedMotion } from '@rocket.chat/fuselage-hooks'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import type { ReactElement, MouseEvent } from 'react'; import React, { useState } from 'react'; import { getUserDisplayNames } from '../../../../../lib/getUserDisplayNames'; import { ReactiveUserStatus } from '../../../../components/UserStatus'; -import UserAvatar from '../../../../components/avatar/UserAvatar'; import { usePreventPropagation } from '../../../../hooks/usePreventPropagation'; import UserActions from './RoomMembersActions'; diff --git a/apps/meteor/client/views/room/contextualBar/Threads/components/ThreadListMessage.tsx b/apps/meteor/client/views/room/contextualBar/Threads/components/ThreadListMessage.tsx index d7d7469f2adb..03a80c496028 100644 --- a/apps/meteor/client/views/room/contextualBar/Threads/components/ThreadListMessage.tsx +++ b/apps/meteor/client/views/room/contextualBar/Threads/components/ThreadListMessage.tsx @@ -1,10 +1,11 @@ import type { IMessage } from '@rocket.chat/core-typings'; import { Message, Box, IconButton } from '@rocket.chat/fuselage'; +import { MessageAvatar } from '@rocket.chat/ui-avatar'; import { useTranslation } from '@rocket.chat/ui-contexts'; import type { ComponentProps, MouseEventHandler, ReactElement, ReactNode } from 'react'; import React, { memo } from 'react'; -import MessageAvatar from '../../../../../components/message/header/MessageAvatar'; +import Emoji from '../../../../../components/Emoji'; import { followStyle, anchor } from '../../../../../components/message/helpers/followSyle'; import AllMentionNotification from '../../../../../components/message/notification/AllMentionNotification'; import MeMentionNotification from '../../../../../components/message/notification/MeMentionNotification'; @@ -55,7 +56,7 @@ const ThreadListMessage = ({ - + : undefined} username={username} size='x36' /> diff --git a/apps/meteor/client/views/room/contextualBar/UserInfo/ReportUserModal.tsx b/apps/meteor/client/views/room/contextualBar/UserInfo/ReportUserModal.tsx index cb28cf2b7ba8..d62ebb96befa 100644 --- a/apps/meteor/client/views/room/contextualBar/UserInfo/ReportUserModal.tsx +++ b/apps/meteor/client/views/room/contextualBar/UserInfo/ReportUserModal.tsx @@ -1,11 +1,11 @@ import { Box, FieldGroup, Field, FieldLabel, FieldRow, FieldError, TextAreaInput } from '@rocket.chat/fuselage'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import type { ComponentProps } from 'react'; import React from 'react'; import { useForm } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import GenericModal from '../../../../components/GenericModal/GenericModal'; -import UserAvatar from '../../../../components/avatar/UserAvatar'; type ReportUserModalProps = { onConfirm: (description: string) => void; diff --git a/apps/meteor/client/views/room/contextualBar/UserInfo/UserInfoWithData.tsx b/apps/meteor/client/views/room/contextualBar/UserInfo/UserInfoWithData.tsx index 47383259a0c4..d5e2f36625f4 100644 --- a/apps/meteor/client/views/room/contextualBar/UserInfo/UserInfoWithData.tsx +++ b/apps/meteor/client/views/room/contextualBar/UserInfo/UserInfoWithData.tsx @@ -14,7 +14,7 @@ import { ContextualbarContent, } from '../../../../components/Contextualbar'; import { FormSkeleton } from '../../../../components/Skeleton'; -import UserCard from '../../../../components/UserCard'; +import { UserCardRole } from '../../../../components/UserCard'; import UserInfo from '../../../../components/UserInfo'; import { ReactiveUserStatus } from '../../../../components/UserStatus'; import { AsyncStatePhase } from '../../../../hooks/useAsyncState'; @@ -68,7 +68,7 @@ const UserInfoWithData = ({ uid, username, rid, onClose, onClickBack }: UserInfo name, username, lastLogin, - roles: roles && getRoles(roles).map((role, index) => {role}), + roles: roles && getRoles(roles).map((role, index) => {role}), bio, canViewAllInfo, phone, diff --git a/apps/meteor/client/views/room/contextualBar/VideoConference/VideoConfList/VideoConfListItem.tsx b/apps/meteor/client/views/room/contextualBar/VideoConference/VideoConfList/VideoConfListItem.tsx index 41cabe61bf90..0e155bc2b0b6 100644 --- a/apps/meteor/client/views/room/contextualBar/VideoConference/VideoConfList/VideoConfListItem.tsx +++ b/apps/meteor/client/views/room/contextualBar/VideoConference/VideoConfList/VideoConfListItem.tsx @@ -2,11 +2,11 @@ import type { IGroupVideoConference } from '@rocket.chat/core-typings'; import { css } from '@rocket.chat/css-in-js'; import { Button, Message, Box, Avatar, Palette } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import { useTranslation, useSetting } from '@rocket.chat/ui-contexts'; import type { ReactElement } from 'react'; import React from 'react'; -import UserAvatar from '../../../../../components/avatar/UserAvatar'; import { useVideoConfJoinCall } from '../../../../../contexts/VideoConfContext'; import { useTimeAgo } from '../../../../../hooks/useTimeAgo'; import { VIDEOCONF_STACK_MAX_USERS } from '../../../../../lib/constants'; @@ -61,9 +61,7 @@ const VideoConfListItem = ({ pb={8} > - - {username && } - + {username && } {showRealName ? name : username} diff --git a/apps/meteor/client/views/room/contextualBar/VideoConference/VideoConfPopups/VideoConfPopup/VideoConfPopupRoomInfo.tsx b/apps/meteor/client/views/room/contextualBar/VideoConference/VideoConfPopups/VideoConfPopup/VideoConfPopupRoomInfo.tsx index e8a7160e07e5..3d1f52746510 100644 --- a/apps/meteor/client/views/room/contextualBar/VideoConference/VideoConfPopups/VideoConfPopup/VideoConfPopupRoomInfo.tsx +++ b/apps/meteor/client/views/room/contextualBar/VideoConference/VideoConfPopups/VideoConfPopup/VideoConfPopupRoomInfo.tsx @@ -1,5 +1,6 @@ import type { IRoom } from '@rocket.chat/core-typings'; import { isDirectMessageRoom, isMultipleDirectMessageRoom } from '@rocket.chat/core-typings'; +import { RoomAvatar } from '@rocket.chat/ui-avatar'; import { useUser, useUserSubscription } from '@rocket.chat/ui-contexts'; import { VideoConfPopupInfo } from '@rocket.chat/ui-video-conf'; import type { ReactElement } from 'react'; @@ -7,7 +8,6 @@ import React from 'react'; import { RoomIcon } from '../../../../../../components/RoomIcon'; import ReactiveUserStatus from '../../../../../../components/UserStatus/ReactiveUserStatus'; -import RoomAvatar from '../../../../../../components/avatar/RoomAvatar'; import { useUserDisplayName } from '../../../../../../hooks/useUserDisplayName'; const VideoConfPopupRoomInfo = ({ room }: { room: IRoom }): ReactElement => { diff --git a/apps/meteor/client/views/room/hooks/useUserInfoActions/actions/useCallAction.tsx b/apps/meteor/client/views/room/hooks/useUserInfoActions/actions/useCallAction.tsx index fa0fc46fe804..27fd6de58520 100644 --- a/apps/meteor/client/views/room/hooks/useUserInfoActions/actions/useCallAction.tsx +++ b/apps/meteor/client/views/room/hooks/useUserInfoActions/actions/useCallAction.tsx @@ -3,9 +3,9 @@ import { isRoomFederated } from '@rocket.chat/core-typings'; import { useTranslation, useUserRoom, useUserId, useUserSubscriptionByName, useSetting, usePermission } from '@rocket.chat/ui-contexts'; import { useMemo } from 'react'; -import { closeUserCard } from '../../../../../../app/ui/client/lib/userCard'; import { useVideoConfDispatchOutgoing, useVideoConfIsCalling, useVideoConfIsRinging } from '../../../../../contexts/VideoConfContext'; import { VideoConfManager } from '../../../../../lib/VideoConfManager'; +import { useUserCard } from '../../../contexts/UserCardContext'; import { useVideoConfWarning } from '../../../contextualBar/VideoConference/hooks/useVideoConfWarning'; import type { UserInfoAction, UserInfoActionType } from '../useUserInfoActions'; @@ -13,6 +13,7 @@ export const useCallAction = (user: Pick): UserInfoAc const t = useTranslation(); const usernameSubscription = useUserSubscriptionByName(user.username ?? ''); const room = useUserRoom(usernameSubscription?.rid || ''); + const { closeUserCard } = useUserCard(); const dispatchWarning = useVideoConfWarning(); const dispatchPopup = useVideoConfDispatchOutgoing(); @@ -49,7 +50,19 @@ export const useCallAction = (user: Pick): UserInfoAc type: 'communication' as UserInfoActionType, } : undefined; - }, [room, user._id, ownUserId, enabledForDMs, permittedToCallManagement, isCalling, isRinging, t, dispatchPopup, dispatchWarning]); + }, [ + room, + user._id, + ownUserId, + enabledForDMs, + permittedToCallManagement, + isCalling, + isRinging, + t, + dispatchPopup, + dispatchWarning, + closeUserCard, + ]); return videoCallOption; }; diff --git a/apps/meteor/client/views/room/modals/ReactionListModal/ReactionListModal.tsx b/apps/meteor/client/views/room/modals/ReactionListModal/ReactionListModal.tsx index 162c8dd3071b..596d74977b3d 100644 --- a/apps/meteor/client/views/room/modals/ReactionListModal/ReactionListModal.tsx +++ b/apps/meteor/client/views/room/modals/ReactionListModal/ReactionListModal.tsx @@ -1,38 +1,25 @@ import type { IMessage } from '@rocket.chat/core-typings'; -import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; import { useTranslation } from '@rocket.chat/ui-contexts'; -import type { ReactElement } from 'react'; +import type { ReactElement, UIEvent } from 'react'; import React from 'react'; import GenericModal from '../../../../components/GenericModal'; -import { useChat } from '../../contexts/ChatContext'; import Reactions from './Reactions'; -type ReactionListProps = { +type ReactionListModalProps = { reactions: Required['reactions']; + onOpenUserCard?: (e: UIEvent, username: string) => void; onClose: () => void; }; -const ReactionList = ({ reactions, onClose }: ReactionListProps): ReactElement => { +const ReactionListModal = ({ reactions, onOpenUserCard, onClose }: ReactionListModalProps): ReactElement => { const t = useTranslation(); - const chat = useChat(); - - const onClick = useMutableCallback((e) => { - const { username } = e.currentTarget.dataset; - - if (!username) { - return; - } - - chat?.userCard.open(username)(e); - }); - return ( - - + + ); }; -export default ReactionList; +export default ReactionListModal; diff --git a/apps/meteor/client/views/room/modals/ReactionListModal/ReactionUserTag.tsx b/apps/meteor/client/views/room/modals/ReactionListModal/ReactionUserTag.tsx index 258751d18095..4c13ac8af532 100644 --- a/apps/meteor/client/views/room/modals/ReactionListModal/ReactionUserTag.tsx +++ b/apps/meteor/client/views/room/modals/ReactionListModal/ReactionUserTag.tsx @@ -1,18 +1,30 @@ import type { IUser } from '@rocket.chat/core-typings'; import { Box, Tag } from '@rocket.chat/fuselage'; -import type { ReactElement } from 'react'; +import { useEffectEvent } from '@rocket.chat/fuselage-hooks'; +import type { ReactElement, UIEvent } from 'react'; import React from 'react'; type ReactionUserTagProps = { username: IUser['username']; - onClick: (e: React.MouseEvent) => void; displayName: string; + onOpenUserCard?: (e: UIEvent, username: string) => void; }; -const ReactionUserTag = ({ username, onClick, displayName }: ReactionUserTagProps): ReactElement => ( - - {displayName} - -); +const ReactionUserTag = ({ username, displayName, onOpenUserCard }: ReactionUserTagProps): ReactElement => { + const handleOpenCard = useEffectEvent((e: UIEvent) => { + if (!username) { + return; + } + onOpenUserCard?.(e, username); + }); + + return ( + + + {displayName} + + + ); +}; export default ReactionUserTag; diff --git a/apps/meteor/client/views/room/modals/ReactionListModal/Reactions.tsx b/apps/meteor/client/views/room/modals/ReactionListModal/Reactions.tsx index 235cdfc0a269..d766661de3e5 100644 --- a/apps/meteor/client/views/room/modals/ReactionListModal/Reactions.tsx +++ b/apps/meteor/client/views/room/modals/ReactionListModal/Reactions.tsx @@ -1,7 +1,7 @@ import type { IMessage } from '@rocket.chat/core-typings'; import { Box } from '@rocket.chat/fuselage'; import { useSetting } from '@rocket.chat/ui-contexts'; -import type { ReactElement } from 'react'; +import type { ReactElement, UIEvent } from 'react'; import React from 'react'; import Emoji from '../../../../components/Emoji'; @@ -9,11 +9,12 @@ import ReactionUserTag from './ReactionUserTag'; type ReactionsProps = { reactions: Required['reactions']; - onClick: (e: React.MouseEvent) => void; + onOpenUserCard?: (e: UIEvent, username: string) => void; }; -const Reactions = ({ reactions, onClick }: ReactionsProps): ReactElement => { +const Reactions = ({ reactions, onOpenUserCard }: ReactionsProps): ReactElement => { const useRealName = useSetting('UI_Use_Real_Name'); + return ( {Object.entries(reactions).map(([reaction, { names = [], usernames }]) => ( @@ -25,7 +26,7 @@ const Reactions = ({ reactions, onClick }: ReactionsProps): ReactElement => { key={username} displayName={useRealName ? names[i] || username : username} username={username} - onClick={onClick} + onOpenUserCard={onOpenUserCard} /> ))} diff --git a/apps/meteor/client/views/room/modals/ReadReceiptsModal/ReadReceiptRow.tsx b/apps/meteor/client/views/room/modals/ReadReceiptsModal/ReadReceiptRow.tsx index 81df1d8adf7c..81748dab2dcd 100644 --- a/apps/meteor/client/views/room/modals/ReadReceiptsModal/ReadReceiptRow.tsx +++ b/apps/meteor/client/views/room/modals/ReadReceiptsModal/ReadReceiptRow.tsx @@ -1,10 +1,10 @@ import type { ReadReceipt } from '@rocket.chat/core-typings'; import { css } from '@rocket.chat/css-in-js'; import { Box, Palette } from '@rocket.chat/fuselage'; +import { UserAvatar } from '@rocket.chat/ui-avatar'; import type { ReactElement } from 'react'; import React from 'react'; -import UserAvatar from '../../../../components/avatar/UserAvatar'; import { useFormatDateAndTime } from '../../../../hooks/useFormatDateAndTime'; import { useUserDisplayName } from '../../../../hooks/useUserDisplayName'; diff --git a/apps/meteor/client/views/room/providers/RoomProvider.tsx b/apps/meteor/client/views/room/providers/RoomProvider.tsx index 88884d01439d..65c83100b1c0 100644 --- a/apps/meteor/client/views/room/providers/RoomProvider.tsx +++ b/apps/meteor/client/views/room/providers/RoomProvider.tsx @@ -17,6 +17,7 @@ import { useRoomRolesManagement } from '../body/hooks/useRoomRolesManagement'; import { RoomContext } from '../contexts/RoomContext'; import ComposerPopupProvider from './ComposerPopupProvider'; import RoomToolboxProvider from './RoomToolboxProvider'; +import UserCardProvider from './UserCardProvider'; import { useRedirectOnSettingsChanged } from './hooks/useRedirectOnSettingsChanged'; import { useRoomQuery } from './hooks/useRoomQuery'; import { useUsersNameChanged } from './hooks/useUsersNameChanged'; @@ -110,7 +111,9 @@ const RoomProvider = ({ rid, children }: RoomProviderProps): ReactElement => { - {children} + + {children} + diff --git a/apps/meteor/client/views/room/providers/UserCardProvider.tsx b/apps/meteor/client/views/room/providers/UserCardProvider.tsx new file mode 100644 index 000000000000..47a9f1cd744e --- /dev/null +++ b/apps/meteor/client/views/room/providers/UserCardProvider.tsx @@ -0,0 +1,70 @@ +import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import type { ComponentProps, ReactNode } from 'react'; +import React, { Suspense, lazy, useCallback, useMemo, useState } from 'react'; + +import { useRoom } from '../contexts/RoomContext'; +import { useRoomToolbox } from '../contexts/RoomToolboxContext'; +import { UserCardContext } from '../contexts/UserCardContext'; + +const UserCard = lazy(() => import('../UserCard')); + +const UserCardProvider = ({ children }: { children: ReactNode }) => { + const room = useRoom(); + const [userCardData, setUserCardData] = useState | null>(null); + + const { openTab } = useRoomToolbox(); + + const openUserInfo = useMutableCallback((username?: string) => { + switch (room.t) { + case 'l': + openTab('room-info', username); + break; + + case 'v': + openTab('voip-room-info', username); + break; + + case 'd': + (room.uids?.length ?? 0) > 2 ? openTab('user-info-group', username) : openTab('user-info', username); + break; + + default: + openTab('members-list', username); + break; + } + }); + + const handleSetUserCard = useCallback( + (e, username) => { + setUserCardData({ + username, + rid: room._id, + target: e.target, + onOpenUserInfo: () => openUserInfo(username), + onClose: () => setUserCardData(null), + }); + }, + [openUserInfo, room._id], + ); + + const contextValue = useMemo( + () => ({ + openUserCard: handleSetUserCard, + closeUserCard: () => setUserCardData(null), + }), + [handleSetUserCard], + ); + + return ( + + {children} + {userCardData && ( + + + + )} + + ); +}; + +export default UserCardProvider; diff --git a/apps/meteor/client/views/room/providers/hooks/useChatMessagesInstance.ts b/apps/meteor/client/views/room/providers/hooks/useChatMessagesInstance.ts index a468efd68fc6..023e99a99dd9 100644 --- a/apps/meteor/client/views/room/providers/hooks/useChatMessagesInstance.ts +++ b/apps/meteor/client/views/room/providers/hooks/useChatMessagesInstance.ts @@ -7,8 +7,8 @@ import { useEmojiPicker } from '../../../../contexts/EmojiPickerContext'; import type { ChatAPI } from '../../../../lib/chats/ChatAPI'; import { useUiKitActionManager } from '../../../../uikit/hooks/useUiKitActionManager'; import { useRoomSubscription } from '../../contexts/RoomContext'; +import { useUserCard } from '../../contexts/UserCardContext'; import { useInstance } from './useInstance'; -import { useUserCard } from './useUserCard'; export function useChatMessagesInstance({ rid, tmid }: { rid: IRoom['_id']; tmid?: IMessage['_id'] }): ChatAPI { const uid = useUserId(); @@ -26,8 +26,8 @@ export function useChatMessagesInstance({ rid, tmid }: { rid: IRoom['_id']; tmid } }, [subscription, chatMessages?.readStateManager]); - chatMessages.userCard = useUserCard(); chatMessages.emojiPicker = useEmojiPicker(); + chatMessages.userCard = useUserCard(); return chatMessages; } diff --git a/apps/meteor/client/views/room/providers/hooks/useUserCard.ts b/apps/meteor/client/views/room/providers/hooks/useUserCard.ts deleted file mode 100644 index f04774df3da5..000000000000 --- a/apps/meteor/client/views/room/providers/hooks/useUserCard.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; -import type { UIEvent } from 'react'; -import { useCallback, useEffect } from 'react'; - -import { openUserCard, closeUserCard } from '../../../../../app/ui/client/lib/userCard'; -import { useRoom } from '../../contexts/RoomContext'; -import { useRoomToolbox } from '../../contexts/RoomToolboxContext'; - -export const useUserCard = () => { - useEffect(() => { - return () => { - closeUserCard(); - }; - }, []); - - const room = useRoom(); - const { openTab } = useRoomToolbox(); - - const openUserInfo = useMutableCallback((username?: string) => { - switch (room.t) { - case 'l': - openTab('room-info', username); - break; - - case 'v': - openTab('voip-room-info', username); - break; - - case 'd': - (room.uids?.length ?? 0) > 2 ? openTab('user-info-group', username) : openTab('user-info', username); - break; - - default: - openTab('members-list', username); - break; - } - }); - - const open = useCallback( - (username: string) => (event: UIEvent) => { - event.preventDefault(); - openUserCard({ - username, - target: event.currentTarget, - rid: room._id, - open: (event: UIEvent) => { - event.preventDefault(); - openUserInfo(username); - }, - }); - }, - [openUserInfo, room._id], - ); - - return { open, close: closeUserCard }; -}; diff --git a/apps/meteor/client/views/teams/contextualBar/TeamAutocomplete/Avatar.js b/apps/meteor/client/views/teams/contextualBar/TeamAutocomplete/Avatar.js deleted file mode 100644 index a547a15f0c30..000000000000 --- a/apps/meteor/client/views/teams/contextualBar/TeamAutocomplete/Avatar.js +++ /dev/null @@ -1,10 +0,0 @@ -import { Options } from '@rocket.chat/fuselage'; -import React from 'react'; - -import RoomAvatar from '../../../../components/avatar/RoomAvatar'; - -const Avatar = ({ _id, type, avatarETag, ...props }) => ( - -); - -export default Avatar; diff --git a/apps/meteor/client/views/teams/contextualBar/TeamAutocomplete/TeamAutocomplete.tsx b/apps/meteor/client/views/teams/contextualBar/TeamAutocomplete/TeamAutocomplete.tsx index 8084336a57ab..0c3a03fdfe68 100644 --- a/apps/meteor/client/views/teams/contextualBar/TeamAutocomplete/TeamAutocomplete.tsx +++ b/apps/meteor/client/views/teams/contextualBar/TeamAutocomplete/TeamAutocomplete.tsx @@ -1,11 +1,10 @@ import { AutoComplete, Option, Box } from '@rocket.chat/fuselage'; +import { RoomAvatar } from '@rocket.chat/ui-avatar'; import { useEndpoint } from '@rocket.chat/ui-contexts'; import { useQuery } from '@tanstack/react-query'; import type { ComponentProps } from 'react'; import React, { memo, useMemo, useState } from 'react'; -import Avatar from './Avatar'; - type TeamAutocompleteProps = Omit, 'filter'>; const TeamAutocomplete = ({ value, onChange, ...props }: TeamAutocompleteProps) => { @@ -32,12 +31,14 @@ const TeamAutocomplete = ({ value, onChange, ...props }: TeamAutocompleteProps) onChange={onChange} filter={filter} setFilter={setFilter} - renderSelected={({ selected: { value, label } }) => ( + renderSelected={({ selected: { value, label: room } }) => ( - {label.name} + {room.name} )} - renderItem={({ value, label, ...props }) =>