Add support for Widget & Room Header Buttons module APIs (#32734)

* Add support for Widget & Room Header Buttons module APIs

To support https://github.com/element-hq/element-modules/pull/217

* Update for new api

* Test addRoomHeaderButtonCallback

* Extra mock api

* Test for widgetapi

* Convert enum

* Convert other enum usage

* Add tests for widget context menu move buttons

Which have just changed because of the enum

* Add tests for moving the widgets

* Fix copyright

Co-authored-by: Florian Duros <florianduros@element.io>

* Update module API

* A little import/export

---------

Co-authored-by: Florian Duros <florianduros@element.io>
This commit is contained in:
David Baker
2026-03-13 13:44:18 +00:00
committed by GitHub
parent 86692ce0a7
commit 09bbf796dc
30 changed files with 553 additions and 225 deletions
@@ -90,7 +90,7 @@ import { CallView } from "../views/voip/CallView";
import { UPDATE_EVENT } from "../../stores/AsyncStore";
import Notifier from "../../Notifier";
import { showToast as showNotificationsToast } from "../../toasts/DesktopNotificationsToast";
import { Container, WidgetLayoutStore } from "../../stores/widgets/WidgetLayoutStore";
import { WidgetLayoutStore } from "../../stores/widgets/WidgetLayoutStore";
import { getKeyBindingsManager } from "../../KeyBindingsManager";
import { objectHasDiff } from "../../utils/objects";
import SpaceRoomView from "./SpaceRoomView";
@@ -141,6 +141,7 @@ import { isRoomEncrypted } from "../../hooks/useIsEncrypted";
import { type RoomViewStore } from "../../stores/RoomViewStore.tsx";
import { RoomStatusBarViewModel } from "../../viewmodels/room/RoomStatusBar.ts";
import { EncryptionEventViewModel } from "../../viewmodels/event-tiles/EncryptionEventViewModel.ts";
import { ModuleApi } from "../../modules/Api.ts";
const DEBUG = false;
const PREVENT_MULTIPLE_JITSI_WITHIN = 30_000;
@@ -953,7 +954,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
// Otherwise (in case the user set hideWidgetDrawer by clicking the button) follow the parameter.
const isManuallyShown = hideWidgetDrawer ? hideWidgetDrawer === "false" : true;
const widgets = this.context.widgetLayoutStore.getContainerWidgets(room, Container.Top);
const widgets = this.context.widgetLayoutStore.getContainerWidgets(room, "top");
return isManuallyShown && widgets.length > 0;
}
@@ -2727,6 +2728,12 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
this.state.mainSplitContentType === MainSplitContentType.Call ? "video_room" : "maximised_widget";
}
const extraButtons: JSX.Element[] = [];
for (const cb of ModuleApi.instance.extras.roomHeaderButtonsCallbacks) {
const b = cb(this.state.room.roomId);
if (b) extraButtons.push(b);
}
return (
<ScopedRoomContextProvider {...this.state} roomViewStore={this.roomViewStore}>
<div
@@ -2754,7 +2761,8 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
{!this.props.hideHeader && (
<RoomHeader
room={this.state.room}
additionalButtons={this.state.viewRoomOpts.buttons}
legacyAdditionalButtons={this.state.viewRoomOpts.buttons}
extraButtons={<>{extraButtons}</>}
/>
)}
{mainSplitBody}