Skip to content

Commit 1d1aff6

Browse files
committed
Implement module API method
1 parent f1037d5 commit 1d1aff6

3 files changed

Lines changed: 40 additions & 3 deletions

File tree

src/modules/BuiltinsApi.tsx

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { type RoomViewProps, type BuiltinsApi } from "@element-hq/element-web-mo
1010

1111
import { MatrixClientPeg } from "../MatrixClientPeg";
1212
import type { Room } from "matrix-js-sdk/src/matrix";
13+
import type { ModuleNotificationDecorationProps } from "./components/ModuleNotificationDecoration";
1314

1415
interface RoomViewPropsWithRoomId extends RoomViewProps {
1516
/**
@@ -26,11 +27,14 @@ interface RoomAvatarProps {
2627
interface Components {
2728
roomView: React.ComponentType<RoomViewPropsWithRoomId>;
2829
roomAvatar: React.ComponentType<RoomAvatarProps>;
30+
notificationDecoration: React.ComponentType<ModuleNotificationDecorationProps>;
2931
}
3032

3133
export class ElementWebBuiltinsApi implements BuiltinsApi {
3234
private _roomView?: Components["roomView"];
3335
private _roomAvatar?: Components["roomAvatar"];
36+
private _notificationDecoration?: Components["notificationDecoration"];
37+
3438
/**
3539
* Sets the components used by the API.
3640
*
@@ -43,24 +47,30 @@ export class ElementWebBuiltinsApi implements BuiltinsApi {
4347
public setComponents(components: Components): void {
4448
this._roomView = components.roomView;
4549
this._roomAvatar = components.roomAvatar;
50+
this._notificationDecoration = components.notificationDecoration;
4651
}
4752

4853
public getRoomViewComponent(): React.ComponentType<RoomViewPropsWithRoomId> {
4954
if (!this._roomView) {
5055
throw new Error("No RoomView component has been set");
5156
}
52-
5357
return this._roomView;
5458
}
5559

5660
public getRoomAvatarComponent(): React.ComponentType<RoomAvatarProps> {
5761
if (!this._roomAvatar) {
5862
throw new Error("No RoomAvatar component has been set");
5963
}
60-
6164
return this._roomAvatar;
6265
}
6366

67+
public getNotificationDecorationComponent(): React.ComponentType<ModuleNotificationDecorationProps> {
68+
if (!this._notificationDecoration) {
69+
throw new Error("No NotificationDecoration component has been set");
70+
}
71+
return this._notificationDecoration;
72+
}
73+
6474
public renderRoomView(roomId: string, props?: RoomViewProps): React.ReactNode {
6575
const Component = this.getRoomViewComponent();
6676
return <Component roomId={roomId} {...props} />;
@@ -74,4 +84,13 @@ export class ElementWebBuiltinsApi implements BuiltinsApi {
7484
const Component = this.getRoomAvatarComponent();
7585
return <Component room={room} size={size} />;
7686
}
87+
88+
public renderNotificationDecoration(roomId: string): React.ReactNode {
89+
const room = MatrixClientPeg.safeGet().getRoom(roomId);
90+
if (!room) {
91+
throw new Error(`No room such room: ${roomId}`);
92+
}
93+
const Component = this.getNotificationDecorationComponent();
94+
return <Component room={room} />;
95+
}
7796
}

src/vector/app.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { UserFriendlyError } from "../languageHandler";
3333
import { ModuleApi } from "../modules/Api";
3434
import { RoomView } from "../components/structures/RoomView";
3535
import RoomAvatar from "../components/views/avatars/RoomAvatar";
36+
import { ModuleNotificationDecoration } from "../modules/components/ModuleNotificationDecoration";
3637

3738
logger.log(`Application is running in ${process.env.NODE_ENV} mode`);
3839

@@ -58,7 +59,11 @@ function onTokenLoginCompleted(): void {
5859
export async function loadApp(fragParams: QueryDict, matrixChatRef: React.Ref<MatrixChat>): Promise<ReactElement> {
5960
// XXX: This lives here because certain components import so many things that importing it in a sensible place (eg.
6061
// the builtins module or init.tsx) causes a circular dependency.
61-
ModuleApi.instance.builtins.setComponents({ roomView: RoomView, roomAvatar: RoomAvatar });
62+
ModuleApi.instance.builtins.setComponents({
63+
roomView: RoomView,
64+
roomAvatar: RoomAvatar,
65+
notificationDecoration: ModuleNotificationDecoration,
66+
});
6267

6368
initRouting();
6469
const platform = PlatformPeg.get();

test/unit-tests/modules/BuiltinsApi-test.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,19 @@ describe("ElementWebBuiltinsApi", () => {
4444
expect(container).toHaveTextContent("50");
4545
});
4646

47+
it("returns rendered NotificationDecoration component", () => {
48+
stubClient();
49+
const builtinsApi = new ElementWebBuiltinsApi();
50+
const NotificationDecoration = () => <div>notification decoration</div>;
51+
builtinsApi.setComponents({
52+
roomView: {},
53+
roomAvatar: Avatar,
54+
notificationDecoration: NotificationDecoration,
55+
} as any);
56+
const { container } = render(<> {builtinsApi.renderNotificationDecoration("!foo:m.org")}</>);
57+
expect(container).toHaveTextContent("notification decoration");
58+
});
59+
4760
it("should throw error if called before components are set", () => {
4861
stubClient();
4962
const builtinsApi = new ElementWebBuiltinsApi();

0 commit comments

Comments
 (0)