Compare commits

...

1 Commits

Author SHA1 Message Date
Half-Shot
39af9078fe Add support for sender profiles. 2025-08-01 13:18:45 +01:00
2 changed files with 46 additions and 14 deletions

View File

@@ -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 ? (
<DisambiguatedProfile
fallbackName={mxEvent.getSender() ?? ""}
onClick={onClick}
member={member}
colored={true}
emphasizeDisplayName={true}
withTooltip={withTooltip}
/>
) : (
<></>
);
if (mxEvent.getContent().msgtype === MsgType.Emote) {
return <></>;
}
return ModuleApi.customComponents.renderMessageProfile({
userId: mxEvent.getSender()!,
rawDisplayName: member?.rawDisplayName,
disambiguatedName: member?.name,
avatarUrl: member?.getMxcAvatarUrl(),
}, () => <DisambiguatedProfile
fallbackName={mxEvent.getSender() ?? ""}
onClick={onClick}
member={member}
colored={true}
emphasizeDisplayName={true}
withTooltip={withTooltip}
/>);
}

View File

@@ -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.