import { isOmnichannelRoom } from '@rocket.chat/core-typings'; import { Icon, SidebarAction, SidebarActions, SidebarItemIcon } from '@rocket.chat/fuselage'; import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts'; import { useLayout } from '@rocket.chat/ui-contexts'; import type { TFunction } from 'i18next'; import type { AllHTMLAttributes, ComponentType, ReactNode } from 'react'; import { memo, useMemo } from 'react'; import { RoomIcon } from '../../components/RoomIcon'; import { useUserStatusTooltip } from '../../hooks/useUserStatusTooltip'; import { roomCoordinator } from '../../lib/rooms/roomCoordinator'; import { getSubscriptionDraft } from '../../lib/utils/getSubscriptionDraft'; import { getUidDirectMessage } from '../../lib/utils/getUidDirectMessage'; import { isIOsDevice } from '../../lib/utils/isIOsDevice'; import { getMessagePreview } from '../../lib/utils/normalizeMessagePreview/getMessagePreview'; import { useOmnichannelPriorities } from '../../views/omnichannel/hooks/useOmnichannelPriorities'; import RoomMenu from '../RoomMenu'; import SidebarItemBadges from '../badges/SidebarItemBadges'; import type { useAvatarTemplate } from '../hooks/useAvatarTemplate'; import { useUnreadDisplay } from '../hooks/useUnreadDisplay'; type RoomListRowProps = { extended: boolean; t: TFunction; SidebarItemTemplate: ComponentType< { icon: ReactNode; title: ReactNode; avatar: ReactNode; actions: ReactNode; href: string; time?: Date; menu?: () => ReactNode; menuOptions?: unknown; subtitle?: ReactNode; titleIcon?: ReactNode; badges?: ReactNode; threadUnread?: boolean; unread?: boolean; selected?: boolean; is?: string; indent?: boolean; } & AllHTMLAttributes >; AvatarTemplate: ReturnType; openedRoom?: string; // sidebarViewMode: 'extended'; isAnonymous?: boolean; userId?: string; room: SubscriptionWithRoom; id?: string; /* @deprecated */ style?: AllHTMLAttributes['style']; selected?: boolean; sidebarViewMode?: unknown; videoConfActions?: { [action: string]: () => void; }; }; const SidebarItemTemplateWithData = ({ room, id, selected, style, extended, SidebarItemTemplate, AvatarTemplate, t, isAnonymous, videoConfActions, userId, }: RoomListRowProps) => { const { sidebar } = useLayout(); const href = roomCoordinator.getRouteLink(room.t, room) || ''; const title = roomCoordinator.getRoomName(room.t, room) || ''; const dmUserId = getUidDirectMessage(room, userId); const dmStatusTooltipHandlers = useUserStatusTooltip(dmUserId, title); const { unreadTitle, showUnread, unreadCount, highlightUnread: highlighted } = useUnreadDisplay(room); const { lastMessage, unread = 0, alert, rid, t: type, cl } = room; const icon = ( } /> ); const titleIcon = getSubscriptionDraft(room) ? ( ) : undefined; const actions = useMemo( () => videoConfActions && ( ), [videoConfActions], ); const isQueued = isOmnichannelRoom(room) && room.status === 'queued'; const { enabled: isPriorityEnabled } = useOmnichannelPriorities(); const message = extended && getMessagePreview(room, lastMessage, t); const subtitle = message ? : null; return ( { if (!selected) sidebar.toggle(); }} aria-label={showUnread ? t('__unreadTitle__from__roomTitle__', { unreadTitle, roomTitle: title }) : title} title={title} time={lastMessage?.ts} subtitle={subtitle} icon={icon} titleIcon={titleIcon} style={style} badges={} avatar={AvatarTemplate && } actions={actions} menu={ !isIOsDevice && !isAnonymous && (!isQueued || (isQueued && isPriorityEnabled)) ? () => ( 0} rid={rid} unread={!!unread} roomOpen={selected} type={type} cl={cl} name={title} hideDefaultOptions={isQueued} /> ) : undefined } {...dmStatusTooltipHandlers} /> ); }; function safeDateNotEqualCheck(a: Date | string | undefined, b: Date | string | undefined): boolean { if (!a || !b) { return a !== b; } return new Date(a).toISOString() !== new Date(b).toISOString(); } const keys: (keyof RoomListRowProps)[] = [ 'id', 'style', 'extended', 'selected', 'SidebarItemTemplate', 'AvatarTemplate', 't', 'sidebarViewMode', 'videoConfActions', ]; export default memo(SidebarItemTemplateWithData, (prevProps, nextProps) => { if (keys.some((key) => prevProps[key] !== nextProps[key])) { return false; } if (prevProps.room === nextProps.room) { return true; } if (prevProps.room._id !== nextProps.room._id) { return false; } if (prevProps.room._updatedAt?.toISOString() !== nextProps.room._updatedAt?.toISOString()) { return false; } if (safeDateNotEqualCheck(prevProps.room.lastMessage?._updatedAt, nextProps.room.lastMessage?._updatedAt)) { return false; } if (prevProps.room.lastMessage?.msg !== nextProps.room.lastMessage?.msg) { return false; } if (prevProps.room.alert !== nextProps.room.alert) { return false; } if (prevProps.room.draft !== nextProps.room.draft) { return false; } if (prevProps.room.threadDrafts !== nextProps.room.threadDrafts) { return false; } if (isOmnichannelRoom(prevProps.room) && isOmnichannelRoom(nextProps.room) && prevProps.room?.v?.status !== nextProps.room?.v?.status) { return false; } if (prevProps.room.teamMain !== nextProps.room.teamMain) { return false; } if ( isOmnichannelRoom(prevProps.room) && isOmnichannelRoom(nextProps.room) && prevProps.room.priorityWeight !== nextProps.room.priorityWeight ) { return false; } return true; });