Add basic bridge show support
This commit is contained in:
parent
29ddcfa1f9
commit
18907f06c7
6 changed files with 149 additions and 24 deletions
23
src/app/hooks/useRoomStateUpdate.js
Normal file
23
src/app/hooks/useRoomStateUpdate.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
/* eslint-disable import/prefer-default-export */
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import initMatrix from '../../client/initMatrix';
|
||||
|
||||
import { useForceUpdate } from './useForceUpdate';
|
||||
|
||||
export function useRoomStateUpdate(roomId) {
|
||||
const [, forceUpdate] = useForceUpdate();
|
||||
const mx = initMatrix.matrixClient;
|
||||
|
||||
useEffect(() => {
|
||||
const handleStateEvent = (event) => {
|
||||
if (event.getRoomId() !== roomId) return;
|
||||
forceUpdate();
|
||||
};
|
||||
|
||||
mx.on('RoomState.events', handleStateEvent);
|
||||
return () => {
|
||||
mx.removeListener('RoomState.events', handleStateEvent);
|
||||
};
|
||||
}, [roomId]);
|
||||
}
|
82
src/app/molecules/room-integrations/RoomIntegrations.jsx
Normal file
82
src/app/molecules/room-integrations/RoomIntegrations.jsx
Normal file
|
@ -0,0 +1,82 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import './RoomIntegrations.scss';
|
||||
|
||||
import { getHttpUriForMxc } from 'matrix-js-sdk';
|
||||
import { blurOnBubbling } from '../../atoms/button/script';
|
||||
|
||||
import initMatrix from '../../../client/initMatrix';
|
||||
import colorMXID from '../../../util/colorMXID';
|
||||
|
||||
import Avatar from '../../atoms/avatar/Avatar';
|
||||
import Text from '../../atoms/text/Text';
|
||||
import { MenuHeader } from '../../atoms/context-menu/ContextMenu';
|
||||
import { useRoomStateUpdate } from '../../hooks/useRoomStateUpdate';
|
||||
|
||||
function Bridge({
|
||||
name, bot, avatarSrc, channel, url,
|
||||
}) {
|
||||
return (
|
||||
<div className="bridge__container">
|
||||
<a
|
||||
className="bridge"
|
||||
href={url}
|
||||
onMouseUp={(e) => blurOnBubbling(e, '.bridge')}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Avatar imageSrc={avatarSrc} bgColor={colorMXID(bot)} text={name} size="small" />
|
||||
<div className="bridge__text">
|
||||
<Text variant="b1">{name}</Text>
|
||||
<Text variant="b3">{channel}</Text>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Bridge.defaultProps = {
|
||||
bot: null,
|
||||
avatarSrc: null,
|
||||
url: null,
|
||||
};
|
||||
|
||||
Bridge.propTypes = {
|
||||
name: PropTypes.string.isRequired,
|
||||
bot: PropTypes.string,
|
||||
avatarSrc: PropTypes.string,
|
||||
channel: PropTypes.string.isRequired,
|
||||
url: PropTypes.string,
|
||||
};
|
||||
|
||||
function RoomIntegrations({ roomId }) {
|
||||
useRoomStateUpdate(roomId);
|
||||
const mx = initMatrix.matrixClient;
|
||||
const room = mx.getRoom(roomId);
|
||||
const bEvents = room.currentState.getStateEvents('uk.half-shot.bridge');
|
||||
|
||||
return (
|
||||
<div className="room-integrations__bridges">
|
||||
<MenuHeader>Bridges</MenuHeader>
|
||||
{bEvents.map((event) => {
|
||||
const { protocol, channel, bridgebot } = event.getContent();
|
||||
return (
|
||||
<Bridge
|
||||
key={event.state_key}
|
||||
name={protocol?.displayname}
|
||||
bot={bridgebot}
|
||||
avatarSrc={getHttpUriForMxc(mx.baseUrl, protocol?.avatar_url, 36, 36, 'crop')}
|
||||
channel={channel?.displayname || channel?.id}
|
||||
url={channel?.external_url || protocol?.external_url}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
RoomIntegrations.propTypes = {
|
||||
roomId: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default RoomIntegrations;
|
28
src/app/molecules/room-integrations/RoomIntegrations.scss
Normal file
28
src/app/molecules/room-integrations/RoomIntegrations.scss
Normal file
|
@ -0,0 +1,28 @@
|
|||
.bridge {
|
||||
width: 100%;
|
||||
padding: var(--sp-extra-tight) var(--sp-normal);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&__container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
&:hover {
|
||||
background-color: var(--bg-surface-hover);
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
&:focus {
|
||||
outline: none;
|
||||
background-color: var(--bg-surface-hover);
|
||||
}
|
||||
&:active {
|
||||
background-color: var(--bg-surface-active);
|
||||
}
|
||||
|
||||
&__text {
|
||||
margin-left: var(--sp-tight);
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@ import SettingTile from '../setting-tile/SettingTile';
|
|||
|
||||
import ChevronBottomIC from '../../../../public/res/ic/outlined/chevron-bottom.svg';
|
||||
|
||||
import { useForceUpdate } from '../../hooks/useForceUpdate';
|
||||
import { useRoomStateUpdate } from '../../hooks/useRoomStateUpdate';
|
||||
|
||||
const permissionsInfo = {
|
||||
users_default: {
|
||||
|
@ -155,23 +155,6 @@ const spacePermsGroups = {
|
|||
'Settings permissions': ['state_default', 'm.room.canonical_alias', 'm.room.power_levels'],
|
||||
};
|
||||
|
||||
function useRoomStateUpdate(roomId) {
|
||||
const [, forceUpdate] = useForceUpdate();
|
||||
const mx = initMatrix.matrixClient;
|
||||
|
||||
useEffect(() => {
|
||||
const handleStateEvent = (event) => {
|
||||
if (event.getRoomId() !== roomId) return;
|
||||
forceUpdate();
|
||||
};
|
||||
|
||||
mx.on('RoomState.events', handleStateEvent);
|
||||
return () => {
|
||||
mx.removeListener('RoomState.events', handleStateEvent);
|
||||
};
|
||||
}, [roomId]);
|
||||
}
|
||||
|
||||
function RoomPermissions({ roomId }) {
|
||||
useRoomStateUpdate(roomId);
|
||||
const mx = initMatrix.matrixClient;
|
||||
|
|
|
@ -23,6 +23,7 @@ import RoomVisibility from '../../molecules/room-visibility/RoomVisibility';
|
|||
import RoomAliases from '../../molecules/room-aliases/RoomAliases';
|
||||
import RoomHistoryVisibility from '../../molecules/room-history-visibility/RoomHistoryVisibility';
|
||||
import RoomEncryption from '../../molecules/room-encryption/RoomEncryption';
|
||||
import RoomIntegrations from '../../molecules/room-integrations/RoomIntegrations';
|
||||
import RoomPermissions from '../../molecules/room-permissions/RoomPermissions';
|
||||
import RoomMembers from '../../molecules/room-members/RoomMembers';
|
||||
import RoomEmojis from '../../molecules/room-emojis/RoomEmojis';
|
||||
|
@ -32,6 +33,7 @@ import SettingsIC from '../../../../public/res/ic/outlined/settings.svg';
|
|||
import EmojiIC from '../../../../public/res/ic/outlined/emoji.svg';
|
||||
import SearchIC from '../../../../public/res/ic/outlined/search.svg';
|
||||
import ShieldUserIC from '../../../../public/res/ic/outlined/shield-user.svg';
|
||||
import CategoryIC from '../../../../public/res/ic/outlined/category.svg';
|
||||
import LockIC from '../../../../public/res/ic/outlined/lock.svg';
|
||||
import AddUserIC from '../../../../public/res/ic/outlined/add-user.svg';
|
||||
import LeaveArrowIC from '../../../../public/res/ic/outlined/leave-arrow.svg';
|
||||
|
@ -45,6 +47,7 @@ const tabText = {
|
|||
SEARCH: 'Search',
|
||||
MEMBERS: 'Members',
|
||||
EMOJIS: 'Emojis',
|
||||
INTEGRATIONS: 'Integrations',
|
||||
PERMISSIONS: 'Permissions',
|
||||
SECURITY: 'Security',
|
||||
};
|
||||
|
@ -65,6 +68,10 @@ const tabItems = [{
|
|||
iconSrc: EmojiIC,
|
||||
text: tabText.EMOJIS,
|
||||
disabled: false,
|
||||
}, {
|
||||
iconSrc: CategoryIC,
|
||||
text: tabText.INTEGRATIONS,
|
||||
disabled: false,
|
||||
}, {
|
||||
iconSrc: ShieldUserIC,
|
||||
text: tabText.PERMISSIONS,
|
||||
|
@ -205,6 +212,7 @@ function RoomSettings({ roomId }) {
|
|||
{selectedTab.text === tabText.SEARCH && <RoomSearch roomId={roomId} />}
|
||||
{selectedTab.text === tabText.MEMBERS && <RoomMembers roomId={roomId} />}
|
||||
{selectedTab.text === tabText.EMOJIS && <RoomEmojis roomId={roomId} />}
|
||||
{selectedTab.text === tabText.INTEGRATIONS && <RoomIntegrations roomId={roomId} />}
|
||||
{selectedTab.text === tabText.PERMISSIONS && <RoomPermissions roomId={roomId} />}
|
||||
{selectedTab.text === tabText.SECURITY && <SecuritySettings roomId={roomId} />}
|
||||
</div>
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
padding: var(--sp-ultra-tight) var(--sp-extra-tight);
|
||||
border-radius: calc(var(--bo-radius) / 2);
|
||||
cursor: pointer;
|
||||
|
||||
@media (hover:hover) {
|
||||
|
||||
@media (hover: hover) {
|
||||
&:hover {
|
||||
background-color: var(--bg-surface-hover);
|
||||
box-shadow: var(--bs-surface-outline);
|
||||
|
@ -40,7 +40,7 @@
|
|||
margin: var(--sp-extra-loose);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
& .tabs {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
|
@ -54,7 +54,7 @@
|
|||
padding: 0 var(--sp-normal);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&__cards-wrapper {
|
||||
padding: 0 var(--sp-normal);
|
||||
@include dir.side(padding, var(--sp-normal), var(--sp-extra-tight));
|
||||
|
@ -74,8 +74,9 @@
|
|||
}
|
||||
|
||||
.room-settings .room-permissions__card,
|
||||
.room-settings .room-integrations__bridges,
|
||||
.room-settings .room-search__form,
|
||||
.room-settings .room-search__result-item ,
|
||||
.room-settings .room-search__result-item,
|
||||
.room-settings .room-members {
|
||||
@extend .room-settings__card;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue