65 lines
2.2 KiB
TypeScript
65 lines
2.2 KiB
TypeScript
import React, { useCallback, useMemo } from 'react';
|
|
import { EventType, Room } from 'matrix-js-sdk';
|
|
import { RenderMessageContent } from '../../components/RenderMessageContent';
|
|
import { getEditedEvent } from '../../utils/room';
|
|
import { GetContentCallback } from '../../../types/matrix/room';
|
|
import { ForumMessageBody } from './ForumMessageBody';
|
|
import { useForumMessageRenderOptions } from './useForumMessageRenderOptions';
|
|
import * as theme from './forumTheme.css';
|
|
|
|
type ForumEventContentProps = {
|
|
room: Room | null;
|
|
eventId: string;
|
|
body: string;
|
|
bodyHtml?: string;
|
|
senderDisplayName?: string;
|
|
};
|
|
|
|
/** Renders a forum post/reply with the same media + rich text pipeline as room messages. */
|
|
export function ForumEventContent({
|
|
room,
|
|
eventId,
|
|
body,
|
|
bodyHtml,
|
|
senderDisplayName,
|
|
}: ForumEventContentProps) {
|
|
const renderOptions = useForumMessageRenderOptions(room);
|
|
const event = room?.findEventById(eventId);
|
|
const timelineSet = room?.getUnfilteredTimelineSet();
|
|
|
|
const editedEvent = useMemo(() => {
|
|
if (!event || !timelineSet) return undefined;
|
|
return getEditedEvent(eventId, event, timelineSet);
|
|
}, [event, eventId, timelineSet]);
|
|
|
|
const getContent = useCallback<GetContentCallback>(
|
|
() => editedEvent?.getContent()['m.new_content'] ?? event?.getContent() ?? { body, msgtype: 'm.text' },
|
|
[editedEvent, event, body]
|
|
);
|
|
|
|
if (!event || event.getType() !== EventType.RoomMessage) {
|
|
return <ForumMessageBody body={body} bodyHtml={bodyHtml} />;
|
|
}
|
|
|
|
const content = getContent();
|
|
const msgType = typeof content.msgtype === 'string' ? content.msgtype : 'm.text';
|
|
|
|
return (
|
|
<div className={theme.ForumEventContentRoot}>
|
|
<RenderMessageContent
|
|
displayName={senderDisplayName ?? event.getSender() ?? ''}
|
|
msgType={msgType}
|
|
ts={event.getTs()}
|
|
edited={Boolean(editedEvent)}
|
|
getContent={getContent}
|
|
mediaAutoLoad={renderOptions.mediaAutoLoad}
|
|
urlPreview={renderOptions.showUrlPreview}
|
|
htmlReactParserOptions={renderOptions.htmlReactParserOptions}
|
|
linkifyOpts={renderOptions.linkifyOpts}
|
|
outlineAttachment={renderOptions.outlineAttachment}
|
|
disabledEmbedPatterns={renderOptions.disabledEmbedPatterns}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|