fix: permissions and room icon resolution (#2)
* Initialize call state upon room creation for call rooms, remove subsequent useless permission * handle case of missing call permissions * use call icon for room item summary when room is call room * replace previous icon src resolution function with a more robust approach * replace usages of previous icon resolution function with new implementation * fix room name not updating for a while when changed * set up framework for room power level overrides upon room creation * override join call permission to all members upon room creation * fix broken usages of RoomIcon * remove unneeded import * remove unnecessary logic * format with prettier
This commit is contained in:
parent
9554b31c7d
commit
efb3e115db
15 changed files with 190 additions and 100 deletions
|
|
@ -11,6 +11,7 @@ import { CreateRoomKind } from './CreateRoomKindSelector';
|
|||
import { RoomType, StateEvent } from '../../../types/matrix/room';
|
||||
import { getViaServers } from '../../plugins/via-servers';
|
||||
import { getMxIdServer } from '../../utils/matrix';
|
||||
import { IPowerLevels } from '../../hooks/usePowerLevels';
|
||||
|
||||
export const createRoomCreationContent = (
|
||||
type: RoomType | undefined,
|
||||
|
|
@ -82,6 +83,44 @@ export const createRoomEncryptionState = () => ({
|
|||
},
|
||||
});
|
||||
|
||||
export const createRoomCallState = () => ({
|
||||
type: 'org.matrix.msc3401.call',
|
||||
state_key: '',
|
||||
content: {},
|
||||
});
|
||||
|
||||
export const createPowerLevelContentOverrides = (
|
||||
base: IPowerLevels,
|
||||
overrides: Partial<IPowerLevels>
|
||||
): IPowerLevels => ({
|
||||
...base,
|
||||
...overrides,
|
||||
...(base.events || overrides.events
|
||||
? {
|
||||
events: {
|
||||
...base.events,
|
||||
...overrides.events,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
...(base.users || overrides.users
|
||||
? {
|
||||
users: {
|
||||
...base.users,
|
||||
...overrides.users,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
...(base.notifications || overrides.notifications
|
||||
? {
|
||||
notifications: {
|
||||
...base.notifications,
|
||||
...overrides.notifications,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
export type CreateRoomData = {
|
||||
version: string;
|
||||
type?: RoomType;
|
||||
|
|
@ -94,6 +133,7 @@ export type CreateRoomData = {
|
|||
knock: boolean;
|
||||
allowFederation: boolean;
|
||||
additionalCreators?: string[];
|
||||
powerLevelContentOverrides?: IPowerLevels;
|
||||
};
|
||||
export const createRoom = async (mx: MatrixClient, data: CreateRoomData): Promise<string> => {
|
||||
const initialState: ICreateRoomStateEvent[] = [];
|
||||
|
|
@ -106,6 +146,10 @@ export const createRoom = async (mx: MatrixClient, data: CreateRoomData): Promis
|
|||
initialState.push(createRoomParentState(data.parent));
|
||||
}
|
||||
|
||||
if (data.type === RoomType.Call) {
|
||||
initialState.push(createRoomCallState());
|
||||
}
|
||||
|
||||
initialState.push(createRoomJoinRulesState(data.kind, data.parent, data.knock));
|
||||
|
||||
const options: ICreateRoomOpts = {
|
||||
|
|
@ -136,5 +180,15 @@ export const createRoom = async (mx: MatrixClient, data: CreateRoomData): Promis
|
|||
);
|
||||
}
|
||||
|
||||
if (data.powerLevelContentOverrides) {
|
||||
const roomPowers = await mx.getStateEvent(result.room_id, StateEvent.RoomPowerLevels, '');
|
||||
const updatedPowers = createPowerLevelContentOverrides(
|
||||
roomPowers,
|
||||
data.powerLevelContentOverrides
|
||||
);
|
||||
|
||||
await mx.sendStateEvent(result.room_id, StateEvent.RoomPowerLevels as any, updatedPowers, '');
|
||||
}
|
||||
|
||||
return result.room_id;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ export function RoomMentionAutocomplete({
|
|||
)}
|
||||
/>
|
||||
) : (
|
||||
<RoomIcon size="100" joinRule={room.getJoinRule()} space={room.isSpaceRoom()} />
|
||||
<RoomIcon size="100" joinRule={room.getJoinRule()} roomType={room.getType()} />
|
||||
)}
|
||||
</Avatar>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { JoinRule } from 'matrix-js-sdk';
|
|||
import { AvatarFallback, AvatarImage, Icon, Icons, color } from 'folds';
|
||||
import React, { ComponentProps, ReactEventHandler, ReactNode, forwardRef, useState } from 'react';
|
||||
import * as css from './RoomAvatar.css';
|
||||
import { joinRuleToIconSrc } from '../../utils/room';
|
||||
import { getRoomIconSrc } from '../../utils/room';
|
||||
import colorMXID from '../../../util/colorMXID';
|
||||
|
||||
type RoomAvatarProps = {
|
||||
|
|
@ -44,14 +44,10 @@ export function RoomAvatar({ roomId, src, alt, renderFallback }: RoomAvatarProps
|
|||
export const RoomIcon = forwardRef<
|
||||
SVGSVGElement,
|
||||
Omit<ComponentProps<typeof Icon>, 'src'> & {
|
||||
joinRule: JoinRule;
|
||||
space?: boolean;
|
||||
call?: boolean;
|
||||
joinRule?: JoinRule;
|
||||
roomType?: string;
|
||||
locked?: boolean;
|
||||
}
|
||||
>(({ joinRule, space, call, ...props }, ref) => (
|
||||
<Icon
|
||||
src={joinRuleToIconSrc(Icons, joinRule, space || false, call || false) ?? Icons.Hash}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
>(({ joinRule, roomType, locked, ...props }, ref) => (
|
||||
<Icon src={getRoomIconSrc(Icons, roomType, joinRule, locked)} {...props} ref={ref} />
|
||||
));
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Room } from 'matrix-js-sdk';
|
||||
import { EventType, Room } from 'matrix-js-sdk';
|
||||
import React, {
|
||||
useContext,
|
||||
useCallback,
|
||||
|
|
@ -21,6 +21,10 @@ import { useRoomNavigate } from '../../hooks/useRoomNavigate';
|
|||
import { getMemberDisplayName } from '../../utils/room';
|
||||
import { getMxIdLocalPart } from '../../utils/matrix';
|
||||
import * as css from './CallView.css';
|
||||
import { useRoomPermissions } from '../../hooks/useRoomPermissions';
|
||||
import { useRoomCreators } from '../../hooks/useRoomCreators';
|
||||
import { usePowerLevelsContext } from '../../hooks/usePowerLevels';
|
||||
import { useRoomName } from '../../hooks/useRoomMeta';
|
||||
|
||||
type OriginalStyles = {
|
||||
position?: string;
|
||||
|
|
@ -57,6 +61,13 @@ export function CallView({ room }: { room: Room }) {
|
|||
|
||||
const [visibleCallNames, setVisibleCallNames] = useState('');
|
||||
|
||||
const powerLevels = usePowerLevelsContext();
|
||||
const creators = useRoomCreators(room);
|
||||
|
||||
const roomName = useRoomName(room);
|
||||
const permissions = useRoomPermissions(creators, powerLevels);
|
||||
const canJoin = permissions.event(EventType.GroupCallMemberPrefix, mx.getSafeUserId());
|
||||
|
||||
const {
|
||||
isActiveCallReady,
|
||||
activeCallRoomId,
|
||||
|
|
@ -160,6 +171,8 @@ export function CallView({ room }: { room: Room }) {
|
|||
]);
|
||||
|
||||
const handleJoinVCClick: MouseEventHandler<HTMLElement> = (evt) => {
|
||||
if (!canJoin) return;
|
||||
|
||||
if (isMobile) {
|
||||
evt.stopPropagation();
|
||||
setViewedCallRoomId(room.roomId);
|
||||
|
|
@ -210,11 +223,7 @@ export function CallView({ room }: { room: Room }) {
|
|||
>
|
||||
<CallViewUserGrid>
|
||||
{callMembers.slice(0, 6).map((callMember) => (
|
||||
<CallViewUser
|
||||
key={callMember.membershipID}
|
||||
room={room}
|
||||
callMembership={callMember}
|
||||
/>
|
||||
<CallViewUser key={callMember.membershipID} room={room} callMembership={callMember} />
|
||||
))}
|
||||
</CallViewUserGrid>
|
||||
|
||||
|
|
@ -231,21 +240,25 @@ export function CallView({ room }: { room: Room }) {
|
|||
paddingBottom: config.space.S300,
|
||||
}}
|
||||
>
|
||||
{room.name}
|
||||
{roomName}
|
||||
</Text>
|
||||
<Text size="T200">
|
||||
{visibleCallNames !== '' ? visibleCallNames : 'No one'}{' '}
|
||||
{memberDisplayNames.length > 1 ? 'are' : 'is'} currently in voice
|
||||
</Text>
|
||||
</Box>
|
||||
<Button variant="Secondary" disabled={isActiveCallRoom} onClick={handleJoinVCClick}>
|
||||
<Button
|
||||
variant="Secondary"
|
||||
disabled={!canJoin || isActiveCallRoom}
|
||||
onClick={handleJoinVCClick}
|
||||
>
|
||||
{isActiveCallRoom ? (
|
||||
<Box justifyContent="Center" alignItems="Center" gap="200">
|
||||
<Spinner />
|
||||
<Text size="B500">{activeCallRoomId === room.roomId ? `Joining` : 'Join Voice'}</Text>
|
||||
</Box>
|
||||
) : (
|
||||
<Text size="B500">Join Voice</Text>
|
||||
<Text size="B500">{canJoin ? 'Join Voice' : 'Channel Locked'}</Text>
|
||||
)}
|
||||
</Button>
|
||||
</Box>
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ export function RoomProfileEdit({
|
|||
alt={name}
|
||||
renderFallback={() => (
|
||||
<RoomIcon
|
||||
space={room.isSpaceRoom()}
|
||||
roomType={room.getType()}
|
||||
size="400"
|
||||
joinRule={joinRule?.join_rule ?? JoinRule.Invite}
|
||||
filled
|
||||
|
|
@ -342,7 +342,7 @@ export function RoomProfile({ permissions }: RoomProfileProps) {
|
|||
alt={name}
|
||||
renderFallback={() => (
|
||||
<RoomIcon
|
||||
space={room.isSpaceRoom()}
|
||||
roomType={room.getType()}
|
||||
size="400"
|
||||
joinRule={joinRule?.join_rule ?? JoinRule.Invite}
|
||||
filled
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@ import {
|
|||
RoomVersionSelector,
|
||||
useAdditionalCreators,
|
||||
} from '../../components/create-room';
|
||||
import { RoomType } from '../../../types/matrix/room';
|
||||
import { RoomType, StateEvent } from '../../../types/matrix/room';
|
||||
import { IPowerLevels } from '../../hooks/usePowerLevels';
|
||||
|
||||
const getCreateRoomKindToIcon = (kind: CreateRoomKind) => {
|
||||
if (kind === CreateRoomKind.Private) return Icons.HashLock;
|
||||
|
|
@ -118,9 +119,18 @@ export function CreateRoomForm({ defaultKind, space, onCreate }: CreateRoomFormP
|
|||
roomKnock = knock;
|
||||
}
|
||||
|
||||
let roomType;
|
||||
const powerOverrides: IPowerLevels = {
|
||||
events: {},
|
||||
};
|
||||
if (callRoom) {
|
||||
roomType = RoomType.Call;
|
||||
powerOverrides.events![StateEvent.GroupCallMemberPrefix] = 0;
|
||||
}
|
||||
|
||||
create({
|
||||
version: selectedRoomVersion,
|
||||
type: callRoom ? RoomType.Call : undefined,
|
||||
type: roomType,
|
||||
parent: space,
|
||||
kind,
|
||||
name: roomName,
|
||||
|
|
@ -130,6 +140,7 @@ export function CreateRoomForm({ defaultKind, space, onCreate }: CreateRoomFormP
|
|||
knock: roomKnock,
|
||||
allowFederation: federation,
|
||||
additionalCreators: allowAdditionalCreators ? additionalCreators : undefined,
|
||||
powerLevelContentOverrides: powerOverrides,
|
||||
}).then((roomId) => {
|
||||
if (alive()) {
|
||||
onCreate?.(roomId);
|
||||
|
|
@ -183,12 +194,7 @@ export function CreateRoomForm({ defaultKind, space, onCreate }: CreateRoomFormP
|
|||
title="Call Room"
|
||||
description="Enable this to create a room optimized for voice calls."
|
||||
after={
|
||||
<Switch
|
||||
variant="Primary"
|
||||
value={callRoom}
|
||||
onChange={setCallRoom}
|
||||
disabled={disabled}
|
||||
/>
|
||||
<Switch variant="Primary" value={callRoom} onChange={setCallRoom} disabled={disabled} />
|
||||
}
|
||||
/>
|
||||
</SequenceCard>
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import { LocalRoomSummaryLoader } from '../../components/RoomSummaryLoader';
|
|||
import { UseStateProvider } from '../../components/UseStateProvider';
|
||||
import { RoomTopicViewer } from '../../components/room-topic-viewer';
|
||||
import { onEnterOrSpace, stopPropagation } from '../../utils/keyboard';
|
||||
import { Membership } from '../../../types/matrix/room';
|
||||
import { Membership, RoomType } from '../../../types/matrix/room';
|
||||
import * as css from './RoomItem.css';
|
||||
import * as styleCss from './style.css';
|
||||
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
|
||||
|
|
@ -175,6 +175,7 @@ function RoomProfileError({ roomId, suggested, inaccessibleRoom, via }: RoomProf
|
|||
|
||||
type RoomProfileProps = {
|
||||
roomId: string;
|
||||
roomType?: string;
|
||||
name: string;
|
||||
topic?: string;
|
||||
avatarUrl?: string;
|
||||
|
|
@ -185,6 +186,7 @@ type RoomProfileProps = {
|
|||
};
|
||||
function RoomProfile({
|
||||
roomId,
|
||||
roomType,
|
||||
name,
|
||||
topic,
|
||||
avatarUrl,
|
||||
|
|
@ -200,9 +202,7 @@ function RoomProfile({
|
|||
roomId={roomId}
|
||||
src={avatarUrl}
|
||||
alt={name}
|
||||
renderFallback={() => (
|
||||
<RoomIcon size="300" joinRule={joinRule ?? JoinRule.Restricted} filled />
|
||||
)}
|
||||
renderFallback={() => <RoomIcon size="300" joinRule={joinRule} roomType={roomType} />}
|
||||
/>
|
||||
</Avatar>
|
||||
<Box grow="Yes" direction="Column">
|
||||
|
|
@ -338,6 +338,7 @@ export const RoomItemCard = as<'div', RoomItemCardProps>(
|
|||
{(localSummary) => (
|
||||
<RoomProfile
|
||||
roomId={roomId}
|
||||
roomType={localSummary.roomType}
|
||||
name={localSummary.name}
|
||||
topic={localSummary.topic}
|
||||
avatarUrl={
|
||||
|
|
@ -396,6 +397,7 @@ export const RoomItemCard = as<'div', RoomItemCardProps>(
|
|||
{summary && (
|
||||
<RoomProfile
|
||||
roomId={roomId}
|
||||
roomType={summary.room_type}
|
||||
name={summary.name || summary.canonical_alias || roomId}
|
||||
topic={summary.topic}
|
||||
avatarUrl={
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import { SearchOrderBy } from 'matrix-js-sdk';
|
|||
import FocusTrap from 'focus-trap-react';
|
||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
import { joinRuleToIconSrc } from '../../utils/room';
|
||||
import { getRoomIconSrc } from '../../utils/room';
|
||||
import { factoryRoomIdByAtoZ } from '../../utils/sort';
|
||||
import {
|
||||
SearchItemStrGetter,
|
||||
|
|
@ -274,9 +274,7 @@ function SelectRoomButton({ roomList, selectedRooms, onChange }: SelectRoomButto
|
|||
before={
|
||||
<Icon
|
||||
size="50"
|
||||
src={
|
||||
joinRuleToIconSrc(Icons, room.getJoinRule(), false) ?? Icons.Hash
|
||||
}
|
||||
src={getRoomIconSrc(Icons, room.getType(), room.getJoinRule())}
|
||||
/>
|
||||
}
|
||||
>
|
||||
|
|
@ -392,10 +390,7 @@ export function SearchFilters({
|
|||
onClick={() => onSelectedRoomsChange(selectedRooms.filter((rId) => rId !== roomId))}
|
||||
radii="Pill"
|
||||
before={
|
||||
<Icon
|
||||
size="50"
|
||||
src={joinRuleToIconSrc(Icons, room.getJoinRule(), false) ?? Icons.Hash}
|
||||
/>
|
||||
<Icon size="50" src={getRoomIconSrc(Icons, room.getType(), room.getJoinRule())} />
|
||||
}
|
||||
after={<Icon size="50" src={Icons.Cross} />}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React, { MouseEventHandler, forwardRef, useState, MouseEvent } from 'react';
|
||||
import { Room } from 'matrix-js-sdk';
|
||||
import { EventType, Room } from 'matrix-js-sdk';
|
||||
import {
|
||||
Avatar,
|
||||
Box,
|
||||
|
|
@ -21,7 +21,7 @@ import {
|
|||
} from 'folds';
|
||||
import { useFocusWithin, useHover } from 'react-aria';
|
||||
import FocusTrap from 'focus-trap-react';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { NavButton, NavItem, NavItemContent, NavItemOptions } from '../../components/nav';
|
||||
import { UnreadBadge, UnreadBadgeCenter } from '../../components/unread-badge';
|
||||
import { RoomAvatar, RoomIcon } from '../../components/room-avatar';
|
||||
|
|
@ -59,6 +59,7 @@ import { useCallMembers } from '../../hooks/useCallMemberships';
|
|||
import { useRoomNavigate } from '../../hooks/useRoomNavigate';
|
||||
import { ScreenSize, useScreenSizeContext } from '../../hooks/useScreenSize';
|
||||
import { RoomNavUser } from './RoomNavUser';
|
||||
import { useRoomName } from '../../hooks/useRoomMeta';
|
||||
|
||||
type RoomNavItemMenuProps = {
|
||||
room: Room;
|
||||
|
|
@ -241,6 +242,10 @@ export function RoomNavItem({
|
|||
const { focusWithinProps } = useFocusWithin({ onFocusWithinChange: setHover });
|
||||
const [menuAnchor, setMenuAnchor] = useState<RectCords>();
|
||||
const unread = useRoomUnread(room.roomId, roomToUnreadAtom);
|
||||
const typingMember = useRoomTypingMember(room.roomId).filter(
|
||||
(receipt) => receipt.userId !== mx.getUserId()
|
||||
);
|
||||
|
||||
const {
|
||||
isActiveCallReady,
|
||||
activeCallRoomId,
|
||||
|
|
@ -250,14 +255,20 @@ export function RoomNavItem({
|
|||
toggleChat,
|
||||
hangUp,
|
||||
} = useCallState();
|
||||
const typingMember = useRoomTypingMember(room.roomId).filter(
|
||||
(receipt) => receipt.userId !== mx.getUserId()
|
||||
);
|
||||
|
||||
const isActiveCall = isActiveCallReady && activeCallRoomId === room.roomId;
|
||||
const callMemberships = useCallMembers(mx, room.roomId);
|
||||
|
||||
const powerLevels = usePowerLevels(room);
|
||||
const creators = useRoomCreators(room);
|
||||
const roomName = useRoomName(room);
|
||||
|
||||
const permissions = useRoomPermissions(creators, powerLevels);
|
||||
const canJoinCall = permissions.event(EventType.GroupCallMemberPrefix, mx.getSafeUserId());
|
||||
|
||||
const { navigateRoom } = useRoomNavigate();
|
||||
const navigate = useNavigate();
|
||||
const { roomIdOrAlias: viewedRoomId } = useParams();
|
||||
|
||||
const screenSize = useScreenSizeContext();
|
||||
const isMobile = screenSize === ScreenSize.Mobile;
|
||||
|
||||
|
|
@ -278,10 +289,7 @@ export function RoomNavItem({
|
|||
const handleNavItemClick: MouseEventHandler<HTMLElement> = (evt) => {
|
||||
if (room.isCallRoom()) {
|
||||
if (!isMobile) {
|
||||
if (!isActiveCall) {
|
||||
if (mx.getRoom(viewedRoomId)?.isCallRoom()) {
|
||||
navigateRoom(room.roomId);
|
||||
}
|
||||
if (!isActiveCall && canJoinCall) {
|
||||
hangUp();
|
||||
setActiveCallRoomId(room.roomId);
|
||||
} else {
|
||||
|
|
@ -307,7 +315,7 @@ export function RoomNavItem({
|
|||
|
||||
const optionsVisible = hover || !!menuAnchor;
|
||||
const ariaLabel = [
|
||||
room.name,
|
||||
roomName,
|
||||
room.isCallRoom()
|
||||
? [
|
||||
'Call Room',
|
||||
|
|
@ -345,10 +353,10 @@ export function RoomNavItem({
|
|||
? getDirectRoomAvatarUrl(mx, room, 96, useAuthentication)
|
||||
: getRoomAvatarUrl(mx, room, 96, useAuthentication)
|
||||
}
|
||||
alt={room.name}
|
||||
alt={roomName}
|
||||
renderFallback={() => (
|
||||
<Text as="span" size="H6">
|
||||
{nameInitials(room.name)}
|
||||
{nameInitials(roomName)}
|
||||
</Text>
|
||||
)}
|
||||
/>
|
||||
|
|
@ -360,7 +368,8 @@ export function RoomNavItem({
|
|||
filled={selected || isActiveCall}
|
||||
size="100"
|
||||
joinRule={room.getJoinRule()}
|
||||
call={room.isCallRoom()}
|
||||
roomType={room.getType()}
|
||||
locked={room.isCallRoom() && !canJoinCall}
|
||||
/>
|
||||
)}
|
||||
</Avatar>
|
||||
|
|
@ -371,7 +380,7 @@ export function RoomNavItem({
|
|||
size="Inherit"
|
||||
truncate
|
||||
>
|
||||
{room.name}
|
||||
{roomName}
|
||||
</Text>
|
||||
</Box>
|
||||
{!optionsVisible && !unread && !selected && typingMember.length > 0 && (
|
||||
|
|
|
|||
|
|
@ -49,13 +49,6 @@ export const usePermissionGroups = (): PermissionGroup[] => {
|
|||
const callSettingsGroup: PermissionGroup = {
|
||||
name: 'Calls',
|
||||
items: [
|
||||
{
|
||||
location: {
|
||||
state: true,
|
||||
key: StateEvent.GroupCallPrefix,
|
||||
},
|
||||
name: 'Start Call',
|
||||
},
|
||||
{
|
||||
location: {
|
||||
state: true,
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import {
|
|||
Spinner,
|
||||
} from 'folds';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { JoinRule, Room } from 'matrix-js-sdk';
|
||||
import { Room } from 'matrix-js-sdk';
|
||||
|
||||
import { useStateEvent } from '../../hooks/useStateEvent';
|
||||
import { PageHeader } from '../../components/page';
|
||||
|
|
@ -321,11 +321,7 @@ export function RoomViewHeader() {
|
|||
src={avatarUrl}
|
||||
alt={name}
|
||||
renderFallback={() => (
|
||||
<RoomIcon
|
||||
size="200"
|
||||
joinRule={room.getJoinRule() ?? JoinRule.Restricted}
|
||||
filled
|
||||
/>
|
||||
<RoomIcon size="200" joinRule={room.getJoinRule()} roomType={room.getType()} />
|
||||
)}
|
||||
/>
|
||||
</Avatar>
|
||||
|
|
|
|||
|
|
@ -373,7 +373,7 @@ export function Search({ requestClose }: SearchProps) {
|
|||
<RoomIcon
|
||||
size="100"
|
||||
joinRule={room.getJoinRule()}
|
||||
space={room.isSpaceRoom()}
|
||||
roomType={room.getType()}
|
||||
/>
|
||||
)}
|
||||
</Avatar>
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ export function SpaceSettings({ initialPage, requestClose }: SpaceSettingsProps)
|
|||
alt={roomName}
|
||||
renderFallback={() => (
|
||||
<RoomIcon
|
||||
space
|
||||
roomType={room.getType()}
|
||||
size="50"
|
||||
joinRule={joinRuleContent?.join_rule ?? JoinRule.Invite}
|
||||
filled
|
||||
|
|
|
|||
|
|
@ -50,16 +50,8 @@ export function PersistentCallContainer({ children }: PersistentCallContainerPro
|
|||
themeKind: ThemeKind | null
|
||||
) => {
|
||||
if (mx?.getUserId()) {
|
||||
if (
|
||||
(activeCallRoomId !== viewedCallRoomId && isActiveCallReady) ||
|
||||
(activeCallRoomId && !isActiveCallReady) ||
|
||||
(!activeCallRoomId && viewedCallRoomId && !isActiveCallReady)
|
||||
) {
|
||||
const roomIdToSet = (skipLobby ? activeCallRoomId : viewedCallRoomId) ?? '';
|
||||
|
||||
if (roomIdToSet === '') {
|
||||
return;
|
||||
}
|
||||
if (activeCallRoomId && !isActiveCallReady) {
|
||||
const roomIdToSet = activeCallRoomId;
|
||||
|
||||
const widgetId = `element-call-${roomIdToSet}-${Date.now()}`;
|
||||
const newUrl = getWidgetUrl(
|
||||
|
|
@ -125,7 +117,6 @@ export function PersistentCallContainer({ children }: PersistentCallContainerPro
|
|||
[
|
||||
mx,
|
||||
activeCallRoomId,
|
||||
viewedCallRoomId,
|
||||
isActiveCallReady,
|
||||
clientConfig.elementCallUrl,
|
||||
activeClientWidget,
|
||||
|
|
|
|||
|
|
@ -257,25 +257,60 @@ export const getUnreadInfos = (mx: MatrixClient): UnreadInfo[] => {
|
|||
return unreadInfos;
|
||||
};
|
||||
|
||||
export const joinRuleToIconSrc = (
|
||||
export const getRoomIconSrc = (
|
||||
icons: Record<IconName, IconSrc>,
|
||||
joinRule: JoinRule,
|
||||
space: boolean,
|
||||
call: boolean
|
||||
): IconSrc | undefined => {
|
||||
if (joinRule === JoinRule.Restricted) {
|
||||
return space ? icons.Space : call ? icons.VolumeHigh : icons.Hash;
|
||||
roomType?: string,
|
||||
joinRule?: JoinRule,
|
||||
locked?: boolean
|
||||
): IconSrc => {
|
||||
type RoomIcons = {
|
||||
base: IconSrc;
|
||||
locked: IconSrc;
|
||||
public: IconSrc;
|
||||
};
|
||||
|
||||
const roomTypeIcons: Record<string, RoomIcons> = {
|
||||
[RoomType.Call]: {
|
||||
base: icons.VolumeHigh,
|
||||
locked: icons.Lock,
|
||||
public: icons.VolumeHigh,
|
||||
},
|
||||
[RoomType.Space]: {
|
||||
base: icons.Space,
|
||||
locked: icons.SpaceLock,
|
||||
public: icons.SpaceGlobe,
|
||||
},
|
||||
default: {
|
||||
base: icons.Hash,
|
||||
locked: icons.HashLock,
|
||||
public: icons.HashGlobe,
|
||||
},
|
||||
};
|
||||
|
||||
const roomIcons = roomTypeIcons[roomType ?? 'default'] ?? roomTypeIcons.default;
|
||||
|
||||
let roomIcon = roomIcons.base;
|
||||
|
||||
if (locked) {
|
||||
roomIcon = roomIcons.locked;
|
||||
} else {
|
||||
switch (joinRule) {
|
||||
case JoinRule.Invite:
|
||||
case JoinRule.Knock:
|
||||
roomIcon = roomIcons.locked;
|
||||
break;
|
||||
case JoinRule.Restricted:
|
||||
roomIcon = roomIcons.base;
|
||||
break;
|
||||
case JoinRule.Public:
|
||||
roomIcon = roomIcons.public;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (joinRule === JoinRule.Knock) {
|
||||
return space ? icons.SpaceLock : call ? icons.VolumeHigh : icons.HashLock;
|
||||
}
|
||||
if (joinRule === JoinRule.Invite) {
|
||||
return space ? icons.SpaceLock : call ? icons.VolumeHigh : icons.HashLock;
|
||||
}
|
||||
if (joinRule === JoinRule.Public) {
|
||||
return space ? icons.SpaceGlobe : call ? icons.VolumeHigh : icons.HashGlobe;
|
||||
}
|
||||
return undefined;
|
||||
|
||||
return roomIcon;
|
||||
};
|
||||
|
||||
export const getRoomAvatarUrl = (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue