diff --git a/src/components/views/messages/SenderProfile.tsx b/src/components/views/messages/SenderProfile.tsx index 2e51c1b50a..2d0caaa2ef 100644 --- a/src/components/views/messages/SenderProfile.tsx +++ b/src/components/views/messages/SenderProfile.tsx @@ -12,6 +12,7 @@ import { type MatrixEvent, MsgType } from "matrix-js-sdk/src/matrix"; import DisambiguatedProfile from "./DisambiguatedProfile"; import { useRoomMemberProfile } from "../../../hooks/room/useRoomMemberProfile"; +import ModuleApi from "../../../modules/Api"; interface IProps { mxEvent: MatrixEvent; @@ -25,16 +26,21 @@ export default function SenderProfile({ mxEvent, onClick, withTooltip }: IProps) member: mxEvent.sender, }); - return mxEvent.getContent().msgtype !== MsgType.Emote ? ( - - ) : ( - <> - ); + if (mxEvent.getContent().msgtype === MsgType.Emote) { + return <>; + } + + return ModuleApi.customComponents.renderMessageProfile({ + userId: mxEvent.getSender()!, + rawDisplayName: member?.rawDisplayName, + disambiguatedName: member?.name, + avatarUrl: member?.getMxcAvatarUrl(), + }, () => ); } diff --git a/src/modules/customComponentApi.ts b/src/modules/customComponentApi.ts index db2f9ab58a..9a3c187f38 100644 --- a/src/modules/customComponentApi.ts +++ b/src/modules/customComponentApi.ts @@ -12,9 +12,11 @@ import type { CustomComponentsApi as ICustomComponentsApi, CustomMessageRenderFunction, CustomMessageComponentProps as ModuleCustomMessageComponentProps, - OriginalComponentProps, + OriginalMessageComponentProps, CustomMessageRenderHints as ModuleCustomCustomMessageRenderHints, MatrixEvent as ModuleMatrixEvent, + MessageProfileRenderFunction, + MessageProfileComponentProps, } from "@element-hq/element-web-module-api"; import type React from "react"; @@ -64,6 +66,7 @@ export class CustomComponentsApi implements ICustomComponentsApi { } private readonly registeredMessageRenderers: EventRenderer[] = []; + private readonly messageProfileRenderer?: MessageProfileRenderFunction; public registerMessageRenderer( eventTypeOrFilter: EventTypeOrFilter, @@ -72,6 +75,16 @@ export class CustomComponentsApi implements ICustomComponentsApi { ): void { this.registeredMessageRenderers.push({ eventTypeOrFilter: eventTypeOrFilter, renderer, hints }); } + + public registerMessageProfile( + renderer: MessageProfileRenderFunction, + ): void { + if (this.messageProfileRenderer) { + throw Error('Renderer already registered'); + } + this.messageProfileRenderer = renderer; + } + /** * Select the correct renderer based on the event information. * @param mxEvent The message event being rendered. @@ -100,7 +113,7 @@ export class CustomComponentsApi implements ICustomComponentsApi { */ public renderMessage( props: CustomMessageComponentProps, - originalComponent?: (props?: OriginalComponentProps) => React.JSX.Element, + originalComponent?: (props?: OriginalMessageComponentProps) => React.JSX.Element, ): React.JSX.Element | null { const moduleEv = CustomComponentsApi.getModuleMatrixEvent(props.mxEvent); const renderer = moduleEv && this.selectRenderer(moduleEv); @@ -115,6 +128,19 @@ export class CustomComponentsApi implements ICustomComponentsApi { return originalComponent?.() ?? null; } + /** + * Render the component for a message event. + * @param props Props to be passed to the custom renderer. + * @param originalComponent Function that will be rendered if no custom renderers are present, or as a child of a custom component. + * @returns A component if a custom renderer exists, or originalComponent returns a value. Otherwise null. + */ + public renderMessageProfile( + props: MessageProfileComponentProps, + originalComponent: (props?: MessageProfileComponentProps) => React.JSX.Element, + ): React.JSX.Element { + return this.messageProfileRenderer?.(props, originalComponent) ?? originalComponent(props); + } + /** * Get hints about an message before rendering it. * @param mxEvent The message event being rendered.