/* Copyright 2024 New Vector Ltd. Copyright 2020-2023 The Matrix.org Foundation C.I.C. SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ import React, { ReactNode } from "react"; import { MatrixEvent, Room } from "matrix-js-sdk/src/matrix"; import { logger } from "matrix-js-sdk/src/logger"; import { _t } from "../../../languageHandler"; import { Pill, PillType } from "../elements/Pill"; import { makeUserPermalink } from "../../../utils/permalinks/Permalinks"; import BaseAvatar from "../avatars/BaseAvatar"; import SettingsStore from "../../../settings/SettingsStore"; import { isUrlPermitted } from "../../../HtmlUtils"; import { mediaFromMxc } from "../../../customisations/Media"; interface IProps { ev: MatrixEvent; room: Room; } /** * This should match https://github.com/matrix-org/matrix-doc/blob/hs/msc-bridge-inf/proposals/2346-bridge-info-state-event.md#mbridge */ interface IBridgeStateEvent { bridgebot: string; creator?: string; protocol: { id: string; displayname?: string; // eslint-disable-next-line camelcase avatar_url?: string; // eslint-disable-next-line camelcase external_url?: string; }; network?: { id: string; displayname?: string; // eslint-disable-next-line camelcase avatar_url?: string; // eslint-disable-next-line camelcase external_url?: string; }; channel: { id: string; displayname?: string; // eslint-disable-next-line camelcase avatar_url?: string; // eslint-disable-next-line camelcase external_url?: string; }; } export default class BridgeTile extends React.PureComponent { public render(): React.ReactNode { const content: IBridgeStateEvent = this.props.ev.getContent(); // Validate if (!content.channel?.id || !content.protocol?.id) { logger.warn(`Bridge info event ${this.props.ev.getId()} has missing content. Tile will not render`); return null; } if (!content.bridgebot) { // Bridgebot was not required previously, so in order to not break rooms we are allowing // the sender to be used in place. When the proposal is merged, this should be removed. logger.warn( `Bridge info event ${this.props.ev.getId()} does not provide a 'bridgebot' key which` + "is deprecated behaviour. Using sender for now.", ); content.bridgebot = this.props.ev.getSender()!; } const { channel, network, protocol } = content; const protocolName = protocol.displayname || protocol.id; const channelName = channel.displayname || channel.id; let creator: JSX.Element | undefined; if (content.creator) { creator = (
  • {_t( "labs|bridge_state_creator", {}, { user: () => ( ), }, )}
  • ); } const bot = (
  • {_t( "labs|bridge_state_manager", {}, { user: () => ( ), }, )}
  • ); let networkIcon; if (protocol.avatar_url) { const avatarUrl = mediaFromMxc(protocol.avatar_url).getSquareThumbnailHttp(64) ?? undefined; networkIcon = ( ); } else { networkIcon =
    ; } let networkItem: ReactNode | undefined; if (network) { const networkName = network.displayname || network.id; let networkLink = {networkName}; if (typeof network.external_url === "string" && isUrlPermitted(network.external_url)) { networkLink = ( {networkName} ); } networkItem = _t( "labs|bridge_state_workspace", {}, { networkLink: () => networkLink, }, ); } let channelLink = {channelName}; if (typeof channel.external_url === "string" && isUrlPermitted(channel.external_url)) { channelLink = ( {channelName} ); } const id = this.props.ev.getId(); return (
  • {networkIcon}

    {protocolName}

    {networkItem} {_t( "labs|bridge_state_channel", {}, { channelLink: () => channelLink, }, )}

      {creator} {bot}
  • ); } }