Files
ThreadNet-Web/src/widgets/ManagedHybrid.ts
T
renovate[bot]GitHubrenovate[bot] <29139614+renovate[bot]@users.noreply.github.com>Michael Telatynski
e1b2e3a101 Update react monorepo to v19 (major) (#28914)
* Update react monorepo to v19

* Import JSX explicitly for React 19 compatibility

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update usages of refs for React 19 compatibility

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update react imports

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Avoid legacy contexts as much as possible

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Avoid deprecated React symbols

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Stash

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update usages of refs for React 19 compatibility

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Switch pillify to use a html-react-parser approach rather than DOM muddling

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate react html parsing

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate react html parsing

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate html parsing

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Memoize the EventContentBody component

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate html parsing

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Simplify

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Discard changes to src/Linkify.tsx

* Discard changes to src/components/views/messages/TextualBody.tsx

* Discard changes to src/settings/handlers/AbstractLocalStorageSettingsHandler.ts

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Prepare for React 19 upgrade

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Remove stale comment

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2025-04-09 19:03:09 +00:00

113 lines
3.9 KiB
TypeScript

/*
Copyright 2024 New Vector Ltd.
Copyright 2021 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import { type IWidget } from "matrix-widget-api";
import { logger } from "matrix-js-sdk/src/logger";
import { type Room } from "matrix-js-sdk/src/matrix";
import { getCallBehaviourWellKnown } from "../utils/WellKnownUtils";
import WidgetUtils from "../utils/WidgetUtils";
import { type IStoredLayout, WidgetLayoutStore } from "../stores/widgets/WidgetLayoutStore";
import WidgetEchoStore from "../stores/WidgetEchoStore";
import WidgetStore, { type IApp } from "../stores/WidgetStore";
import SdkConfig from "../SdkConfig";
import { getJoinedNonFunctionalMembers } from "../utils/room/getJoinedNonFunctionalMembers";
/* eslint-disable camelcase */
interface IManagedHybridWidgetData {
widget_id: string;
widget: IWidget;
layout: IStoredLayout;
}
/* eslint-enable camelcase */
function getWidgetBuildUrl(room: Room): string | undefined {
const functionalMembers = getJoinedNonFunctionalMembers(room);
const isDm = functionalMembers.length === 2;
if (SdkConfig.get().widget_build_url) {
if (isDm && SdkConfig.get().widget_build_url_ignore_dm) {
return undefined;
}
return SdkConfig.get().widget_build_url;
}
const wellKnown = getCallBehaviourWellKnown(room.client);
if (isDm && wellKnown?.ignore_dm) {
return undefined;
}
/* eslint-disable-next-line camelcase */
return wellKnown?.widget_build_url;
}
export function isManagedHybridWidgetEnabled(room: Room): boolean {
return !!getWidgetBuildUrl(room);
}
export async function addManagedHybridWidget(room: Room): Promise<void> {
// Check for permission
if (!WidgetUtils.canUserModifyWidgets(room.client, room.roomId)) {
logger.error(`User not allowed to modify widgets in ${room.roomId}`);
return;
}
// Get widget data
/* eslint-disable-next-line camelcase */
const widgetBuildUrl = getWidgetBuildUrl(room);
if (!widgetBuildUrl) {
return;
}
let widgetData: IManagedHybridWidgetData;
try {
const response = await fetch(`${widgetBuildUrl}?roomId=${room.roomId}`);
widgetData = await response.json();
} catch (e) {
logger.error(`Managed hybrid widget builder failed for room ${room.roomId}`, e);
return;
}
if (!widgetData) {
return;
}
const { widget_id: widgetId, widget: widgetContent, layout } = widgetData;
// Ensure the widget is not already present in the room
let widgets = WidgetStore.instance.getApps(room.roomId);
const existing = widgets.some((w) => w.id === widgetId) || WidgetEchoStore.roomHasPendingWidgets(room.roomId, []);
if (existing) {
logger.error(`Managed hybrid widget already present in room ${room.roomId}`);
return;
}
// Add the widget
try {
await WidgetUtils.setRoomWidgetContent(room.client, room.roomId, widgetId, {
...widgetContent,
"io.element.managed_hybrid": true,
});
} catch (e) {
logger.error(`Unable to add managed hybrid widget in room ${room.roomId}`, e);
return;
}
// Move the widget into position
if (!WidgetLayoutStore.instance.canCopyLayoutToRoom(room)) {
return;
}
widgets = WidgetStore.instance.getApps(room.roomId);
const installedWidget = widgets.find((w) => w.id === widgetId);
if (!installedWidget) {
return;
}
WidgetLayoutStore.instance.moveToContainer(room, installedWidget, layout.container);
WidgetLayoutStore.instance.setContainerHeight(room, layout.container, layout.height);
WidgetLayoutStore.instance.copyLayoutToRoom(room);
}
export function isManagedHybridWidget(widget: IApp): boolean {
return !!widget["io.element.managed_hybrid"];
}