Add basic bridge show support

This commit is contained in:
ginnyTheCat 2022-08-03 15:27:26 +02:00
parent 29ddcfa1f9
commit 18907f06c7
No known key found for this signature in database
GPG key ID: 6B7EF3FED72A0D97
6 changed files with 149 additions and 24 deletions

View 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]);
}

View 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;

View 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);
}
}

View file

@ -15,7 +15,7 @@ import SettingTile from '../setting-tile/SettingTile';
import ChevronBottomIC from '../../../../public/res/ic/outlined/chevron-bottom.svg'; import ChevronBottomIC from '../../../../public/res/ic/outlined/chevron-bottom.svg';
import { useForceUpdate } from '../../hooks/useForceUpdate'; import { useRoomStateUpdate } from '../../hooks/useRoomStateUpdate';
const permissionsInfo = { const permissionsInfo = {
users_default: { users_default: {
@ -155,23 +155,6 @@ const spacePermsGroups = {
'Settings permissions': ['state_default', 'm.room.canonical_alias', 'm.room.power_levels'], '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 }) { function RoomPermissions({ roomId }) {
useRoomStateUpdate(roomId); useRoomStateUpdate(roomId);
const mx = initMatrix.matrixClient; const mx = initMatrix.matrixClient;

View file

@ -23,6 +23,7 @@ import RoomVisibility from '../../molecules/room-visibility/RoomVisibility';
import RoomAliases from '../../molecules/room-aliases/RoomAliases'; import RoomAliases from '../../molecules/room-aliases/RoomAliases';
import RoomHistoryVisibility from '../../molecules/room-history-visibility/RoomHistoryVisibility'; import RoomHistoryVisibility from '../../molecules/room-history-visibility/RoomHistoryVisibility';
import RoomEncryption from '../../molecules/room-encryption/RoomEncryption'; import RoomEncryption from '../../molecules/room-encryption/RoomEncryption';
import RoomIntegrations from '../../molecules/room-integrations/RoomIntegrations';
import RoomPermissions from '../../molecules/room-permissions/RoomPermissions'; import RoomPermissions from '../../molecules/room-permissions/RoomPermissions';
import RoomMembers from '../../molecules/room-members/RoomMembers'; import RoomMembers from '../../molecules/room-members/RoomMembers';
import RoomEmojis from '../../molecules/room-emojis/RoomEmojis'; 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 EmojiIC from '../../../../public/res/ic/outlined/emoji.svg';
import SearchIC from '../../../../public/res/ic/outlined/search.svg'; import SearchIC from '../../../../public/res/ic/outlined/search.svg';
import ShieldUserIC from '../../../../public/res/ic/outlined/shield-user.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 LockIC from '../../../../public/res/ic/outlined/lock.svg';
import AddUserIC from '../../../../public/res/ic/outlined/add-user.svg'; import AddUserIC from '../../../../public/res/ic/outlined/add-user.svg';
import LeaveArrowIC from '../../../../public/res/ic/outlined/leave-arrow.svg'; import LeaveArrowIC from '../../../../public/res/ic/outlined/leave-arrow.svg';
@ -45,6 +47,7 @@ const tabText = {
SEARCH: 'Search', SEARCH: 'Search',
MEMBERS: 'Members', MEMBERS: 'Members',
EMOJIS: 'Emojis', EMOJIS: 'Emojis',
INTEGRATIONS: 'Integrations',
PERMISSIONS: 'Permissions', PERMISSIONS: 'Permissions',
SECURITY: 'Security', SECURITY: 'Security',
}; };
@ -65,6 +68,10 @@ const tabItems = [{
iconSrc: EmojiIC, iconSrc: EmojiIC,
text: tabText.EMOJIS, text: tabText.EMOJIS,
disabled: false, disabled: false,
}, {
iconSrc: CategoryIC,
text: tabText.INTEGRATIONS,
disabled: false,
}, { }, {
iconSrc: ShieldUserIC, iconSrc: ShieldUserIC,
text: tabText.PERMISSIONS, text: tabText.PERMISSIONS,
@ -205,6 +212,7 @@ function RoomSettings({ roomId }) {
{selectedTab.text === tabText.SEARCH && <RoomSearch roomId={roomId} />} {selectedTab.text === tabText.SEARCH && <RoomSearch roomId={roomId} />}
{selectedTab.text === tabText.MEMBERS && <RoomMembers roomId={roomId} />} {selectedTab.text === tabText.MEMBERS && <RoomMembers roomId={roomId} />}
{selectedTab.text === tabText.EMOJIS && <RoomEmojis 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.PERMISSIONS && <RoomPermissions roomId={roomId} />}
{selectedTab.text === tabText.SECURITY && <SecuritySettings roomId={roomId} />} {selectedTab.text === tabText.SECURITY && <SecuritySettings roomId={roomId} />}
</div> </div>

View file

@ -18,8 +18,8 @@
padding: var(--sp-ultra-tight) var(--sp-extra-tight); padding: var(--sp-ultra-tight) var(--sp-extra-tight);
border-radius: calc(var(--bo-radius) / 2); border-radius: calc(var(--bo-radius) / 2);
cursor: pointer; cursor: pointer;
@media (hover:hover) { @media (hover: hover) {
&:hover { &:hover {
background-color: var(--bg-surface-hover); background-color: var(--bg-surface-hover);
box-shadow: var(--bs-surface-outline); box-shadow: var(--bs-surface-outline);
@ -40,7 +40,7 @@
margin: var(--sp-extra-loose); margin: var(--sp-extra-loose);
} }
} }
& .tabs { & .tabs {
position: sticky; position: sticky;
top: 0; top: 0;
@ -54,7 +54,7 @@
padding: 0 var(--sp-normal); padding: 0 var(--sp-normal);
} }
} }
&__cards-wrapper { &__cards-wrapper {
padding: 0 var(--sp-normal); padding: 0 var(--sp-normal);
@include dir.side(padding, var(--sp-normal), var(--sp-extra-tight)); @include dir.side(padding, var(--sp-normal), var(--sp-extra-tight));
@ -74,8 +74,9 @@
} }
.room-settings .room-permissions__card, .room-settings .room-permissions__card,
.room-settings .room-integrations__bridges,
.room-settings .room-search__form, .room-settings .room-search__form,
.room-settings .room-search__result-item , .room-settings .room-search__result-item,
.room-settings .room-members { .room-settings .room-members {
@extend .room-settings__card; @extend .room-settings__card;
} }