diff --git a/res/css/views/dialogs/_RoomSettingsDialog.scss b/res/css/views/dialogs/_RoomSettingsDialog.scss index aa66e97f9e..0e8deb018e 100644 --- a/res/css/views/dialogs/_RoomSettingsDialog.scss +++ b/res/css/views/dialogs/_RoomSettingsDialog.scss @@ -63,9 +63,59 @@ limitations under the License. .mx_RoomSettingsDialog_BridgeList li { list-style-type: none; padding: 5px; - margin-bottom: 5px; - border-width: 1px 0px; - border-color: #dee1f3; - border-style: solid; + margin-bottom: 8px; + border-width: 1px 1px; + border-color: $primary-hairline-color; + border-radius: 5px; + + .protocol-icon { + float: left; + margin-right: 30px; + img { + border-radius: 5px; + border-width: 1px 1px; + border-color: $primary-hairline-color; + border-style: solid; + } + span { + /* Correct letter placement */ + left: auto; + } + } + + h3 { + margin-top: 0; + margin-bottom: 4px; + font-size: 16pt; + } + + .column-icon { + float: left; + } + + .column-data { + display: inline-block; + width: 85%; + } + + .workspace-channel-details { + margin-top: 0; + color: $primary-fg-color; + } + + .metadata { + color: $muted-fg-color; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + margin-bottom: 0; + } + + .metadata.visible { + overflow-y: visible; + text-overflow: ellipsis; + white-space: normal; + } + } diff --git a/src/components/views/dialogs/RoomSettingsDialog.js b/src/components/views/dialogs/RoomSettingsDialog.js index a99141870b..76faf60eef 100644 --- a/src/components/views/dialogs/RoomSettingsDialog.js +++ b/src/components/views/dialogs/RoomSettingsDialog.js @@ -54,9 +54,6 @@ export default class RoomSettingsDialog extends React.Component { _getTabs() { const tabs = []; - const featureFlag = SettingsStore.isFeatureEnabled("feature_bridge_state"); - const shouldShowBridgeIcon = featureFlag && - BridgeSettingsTab.getBridgeStateEvents(this.props.roomId).length > 0; tabs.push(new Tab( _td("General"), @@ -79,9 +76,9 @@ export default class RoomSettingsDialog extends React.Component { , )); - if (shouldShowBridgeIcon) { + if (SettingsStore.isFeatureEnabled("feature_bridge_state")) { tabs.push(new Tab( - _td("Bridge Info"), + _td("Bridges"), "mx_RoomSettingsDialog_bridgesIcon", , )); diff --git a/src/components/views/settings/tabs/room/BridgeSettingsTab.js b/src/components/views/settings/tabs/room/BridgeSettingsTab.js index 19c19d3bc6..8090cf7d4d 100644 --- a/src/components/views/settings/tabs/room/BridgeSettingsTab.js +++ b/src/components/views/settings/tabs/room/BridgeSettingsTab.js @@ -33,6 +33,21 @@ export default class BridgeSettingsTab extends React.Component { roomId: PropTypes.string.isRequired, }; + constructor() { + super(); + + this.state = { + showMoreCard: null, + }; + } + + + _showMoreDetails(eventId) { + this.setState({ + showMoreCard: eventId, + }); + } + _renderBridgeCard(event, room) { const content = event.getContent(); if (!content || !content.channel || !content.protocol) { @@ -45,90 +60,59 @@ export default class BridgeSettingsTab extends React.Component { let creator = null; if (content.creator) { - creator =

{ _t("This bridge was provisioned by ", {}, { + creator = _t("This bridge was provisioned by .", {}, { user: , - })}

; + }); } - const bot = (

{_t("This bridge is managed by .", {}, { + const bot = _t("This bridge is managed by .", {}, { user: , - })}

); - let channelLink = channelName; - if (channel.external_url) { - channelLink = {channelName}; - } - - let networkLink = networkName; - if (network && network.external_url) { - networkLink = {networkName}; - } - - const chanAndNetworkInfo = ( - _t("Bridged into , on ", {}, { - channelLink, - networkLink, - protocolName, - }) - ); - - let networkIcon = null; - if (networkName && network.avatar) { - const avatarUrl = getHttpUriForMxc( - MatrixClientPeg.get().getHomeserverUrl(), - network.avatar, 32, 32, "crop", - ); - networkIcon = ; - } - - let channelIcon = null; - if (channel.avatar) { - const avatarUrl = getHttpUriForMxc( - MatrixClientPeg.get().getHomeserverUrl(), - channel.avatar, 32, 32, "crop", - ); - channelIcon = ; - } - - const heading = _t("Connected to on ", { }, { - channelIcon, - channelName, - networkName, - networkIcon, }); - return (
  • -
    -

    {heading}

    -

    {_t("Connected via %(protocolName)s", { protocolName })}

    -
    - {creator} - {bot} -

    {chanAndNetworkInfo}

    -
    + const avatarUrl = network.avatar ? getHttpUriForMxc( + MatrixClientPeg.get().getHomeserverUrl(), + network.avatar, 32, 32, "crop", + ) : null; + + const networkIcon = ; + + const workspaceChannelDetails = _t("Workspace: %(networkName)s Channel: %(channelName)s", { + networkName, + channelName, + }); + const id = event.getId(); + const isVisible = this.state.showMoreCard === id; + const metadataClassname = "metadata " + (isVisible ? "visible" : ""); + return (
  • +
    + {networkIcon} +
    +
    +

    {protocolName}

    +

    + {workspaceChannelDetails} +

    +

    + {creator} {bot} +

    + this._showMoreDetails(isVisible ? null : id)}>Show { isVisible ? "less" : "more" }
  • ); } @@ -151,14 +135,40 @@ export default class BridgeSettingsTab extends React.Component { const client = MatrixClientPeg.get(); const room = client.getRoom(this.props.roomId); + let content = null; + + if (bridgeEvents.length > 0) { + content =
    +

    {_t( + "This room is bridging messages to the following platforms. " + + "Learn more.", {}, + { + // TODO: We don't have this link yet: this will prevent the translators + // having to re-translate the string when we do. + a: sub => '', + }, + )}

    +
      + { bridgeEvents.map((event) => this._renderBridgeCard(event, room)) } +
    +
    + } else { + content =

    {_t( + "This room isn’t bridging messages to any platforms. " + + "Learn more.", {}, + { + // TODO: We don't have this link yet: this will prevent the translators + // having to re-translate the string when we do. + a: sub => '', + }, + )}

    + } + return (
    -
    {_t("Bridge Info")}
    +
    {_t("Bridges")}
    -

    { _t("Below is a list of bridges connected to this room.") }

    -
      - { bridgeEvents.map((event) => this._renderBridgeCard(event, room)) } -
    + {content}
    ); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index f0eab6b12d..e4ab764989 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -781,13 +781,12 @@ "Room version:": "Room version:", "Developer options": "Developer options", "Open Devtools": "Open Devtools", - "This bridge was provisioned by ": "This bridge was provisioned by ", + "This bridge was provisioned by .": "This bridge was provisioned by .", "This bridge is managed by .": "This bridge is managed by .", - "Bridged into , on ": "Bridged into , on ", - "Connected to on ": "Connected to on ", - "Connected via %(protocolName)s": "Connected via %(protocolName)s", - "Bridge Info": "Bridge Info", - "Below is a list of bridges connected to this room.": "Below is a list of bridges connected to this room.", + "Workspace: %(networkName)s Channel: %(channelName)s": "Workspace: %(networkName)s Channel: %(channelName)s", + "This room is bridging messages to the following platforms. Learn more.": "This room is bridging messages to the following platforms. Learn more.", + "This room isn’t bridging messages to any platforms. Learn more.": "This room isn’t bridging messages to any platforms. Learn more.", + "Bridges": "Bridges", "Room Addresses": "Room Addresses", "Publish this room to the public in %(domain)s's room directory?": "Publish this room to the public in %(domain)s's room directory?", "URL Previews": "URL Previews",