/* 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 { Opts as LinkifyOpts } from 'linkifyjs'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { factoryRenderLinkifyWithMention, getReactCustomHtmlParser, LINKIFY_OPTS, makeHighlightRegex, makeMentionCustomProps, renderMatrixMention, } from '../../plugins/react-custom-html-parser'; import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix'; 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 { UserAvatar } from '../../components/user-avatar'; import { useMentionClickHandler } from '../../hooks/useMentionClickHandler'; import { useSpoilerClickHandler } from '../../hooks/useSpoilerClickHandler'; import { useSpecVersions } from '../../hooks/useSpecVersions'; 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 { versions } = useSpecVersions(); const useAuthentication = versions.includes('v1.11'); const highlightRegex = useMemo(() => makeHighlightRegex(highlights), [highlights]); const mentionClickHandler = useMentionClickHandler(room.roomId); const spoilerClickHandler = useSpoilerClickHandler(); const linkifyOpts = useMemo( () => ({ ...LINKIFY_OPTS, render: factoryRenderLinkifyWithMention((href) => renderMatrixMention(mx, room.roomId, href, makeMentionCustomProps(mentionClickHandler)) ), }), [mx, room, mentionClickHandler] ); const htmlReactParserOptions = useMemo( () => getReactCustomHtmlParser(mx, room.roomId, { linkifyOpts, highlightRegex, useAuthentication, handleSpoilerClick: spoilerClickHandler, handleMentionClick: mentionClickHandler, }), [mx, room, linkifyOpts, highlightRegex, mentionClickHandler, spoilerClickHandler, useAuthentication] ); 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 relation = event.content['m.relates_to']; const mainEventId = relation?.rel_type === RelationType.Replace ? relation.event_id : event.event_id; const getContent = (() => event.content['m.new_content'] ?? event.content) as GetContentCallback; const replyEventId = relation?.['m.in_reply_to']?.event_id; const threadRootId = relation?.rel_type === RelationType.Thread ? relation.event_id : undefined; return ( } /> } > {displayName} Open {replyEventId && ( )} {renderMatrixEvent(event.type, false, event, displayName, getContent)} ); })}
); }