/* eslint-disable react/destructuring-assignment */ import React, { MouseEventHandler, useMemo } from 'react'; import { IEventWithRoomId, JoinRule, RelationType, Room } from 'matrix-js-sdk'; import { HTMLReactParserOptions } from 'html-react-parser'; import { Avatar, Box, Chip, Header, Icon, Icons, Text, config } from 'folds'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { getReactCustomHtmlParser, makeHighlightRegex, } from '../../plugins/react-custom-html-parser'; import { getMxIdLocalPart, isRoomId, isUserId } from '../../utils/matrix'; import { openJoinAlias, openProfileViewer } from '../../../client/action/navigation'; import { useMatrixEventRenderer } from '../../hooks/useMatrixEventRenderer'; import { GetContentCallback, MessageEvent, StateEvent } from '../../../types/matrix/room'; import { AvatarBase, ImageContent, MSticker, ModernLayout, RedactedContent, Reply, Time, Username, } from '../../components/message'; import { RenderMessageContent } from '../../components/RenderMessageContent'; import { Image } from '../../components/media'; import { ImageViewer } from '../../components/image-viewer'; import * as customHtmlCss from '../../styles/CustomHtml.css'; import { RoomAvatar, RoomIcon } from '../../components/room-avatar'; import { getMemberAvatarMxc, getMemberDisplayName, getRoomAvatarUrl } from '../../utils/room'; import colorMXID from '../../../util/colorMXID'; import { ResultItem } from './useMessageSearch'; import { SequenceCard } from '../../components/sequence-card'; import { useRoomNavigate } from '../../hooks/useRoomNavigate'; import { UserAvatar } from '../../components/user-avatar'; type SearchResultGroupProps = { room: Room; highlights: string[]; items: ResultItem[]; mediaAutoLoad?: boolean; urlPreview?: boolean; onOpen: (roomId: string, eventId: string) => void; }; export function SearchResultGroup({ room, highlights, items, mediaAutoLoad, urlPreview, onOpen, }: SearchResultGroupProps) { const mx = useMatrixClient(); const { navigateRoom, navigateSpace } = useRoomNavigate(); const highlightRegex = useMemo(() => makeHighlightRegex(highlights), [highlights]); const htmlReactParserOptions = useMemo( () => getReactCustomHtmlParser(mx, room, { highlightRegex, handleSpoilerClick: (evt) => { const target = evt.currentTarget; if (target.getAttribute('aria-pressed') === 'true') { evt.stopPropagation(); target.setAttribute('aria-pressed', 'false'); target.style.cursor = 'initial'; } }, handleMentionClick: (evt) => { const target = evt.currentTarget; const mentionId = target.getAttribute('data-mention-id'); if (typeof mentionId !== 'string') return; if (isUserId(mentionId)) { openProfileViewer(mentionId, room.roomId); return; } if (isRoomId(mentionId) && mx.getRoom(mentionId)) { if (mx.getRoom(mentionId)?.isSpaceRoom()) navigateSpace(mentionId); else navigateRoom(mentionId); return; } openJoinAlias(mentionId); }, }), [mx, room, highlightRegex, navigateRoom, navigateSpace] ); const renderMatrixEvent = useMatrixEventRenderer<[IEventWithRoomId, string, GetContentCallback]>( { [MessageEvent.RoomMessage]: (event, displayName, getContent) => { if (event.unsigned?.redacted_because) { return ; } return ( ); }, [MessageEvent.Reaction]: (event, displayName, getContent) => { if (event.unsigned?.redacted_because) { return ; } return ( ( } renderViewer={(p) => } /> )} /> ); }, [StateEvent.RoomTombstone]: (event) => { const { content } = event; return ( Room Tombstone. {content.body} ); }, }, undefined, (event) => { if (event.unsigned?.redacted_because) { return ; } return ( {event.type} {' event'} ); } ); const handleOpenClick: MouseEventHandler = (evt) => { const eventId = evt.currentTarget.getAttribute('data-event-id'); if (!eventId) return; onOpen(room.roomId, eventId); }; return (
( )} /> {room.name}
{items.map((item) => { const { event } = item; const displayName = getMemberDisplayName(room, event.sender) ?? getMxIdLocalPart(event.sender) ?? event.sender; const senderAvatarMxc = getMemberAvatarMxc(room, event.sender); const mainEventId = event.content['m.relates_to']?.rel_type === RelationType.Replace ? event.content['m.relates_to'].event_id : event.event_id; const getContent = (() => event.content['m.new_content'] ?? event.content) as GetContentCallback; const replyEventId = event.content['m.relates_to']?.['m.in_reply_to']?.event_id; return ( } /> } > {displayName} Open {replyEventId && ( )} {renderMatrixEvent(event.type, false, event, displayName, getContent)} ); })}
); }