mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-11-04 22:40:29 +03:00
show mutual rooms in spaces, rooms and direct messages categories
This commit is contained in:
parent
1b63b59fdc
commit
65600b2a1c
1 changed files with 114 additions and 60 deletions
|
|
@ -1,7 +1,8 @@
|
||||||
import React, { MouseEventHandler, useState } from 'react';
|
import React, { MouseEventHandler, useMemo, useState } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import FocusTrap from 'focus-trap-react';
|
import FocusTrap from 'focus-trap-react';
|
||||||
import { isKeyHotkey } from 'is-hotkey';
|
import { isKeyHotkey } from 'is-hotkey';
|
||||||
|
import { Room } from 'matrix-js-sdk';
|
||||||
import {
|
import {
|
||||||
PopOut,
|
PopOut,
|
||||||
Menu,
|
Menu,
|
||||||
|
|
@ -134,6 +135,12 @@ export function ServerChip({ server }: { server: string }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MutualRoomsData = {
|
||||||
|
rooms: Room[];
|
||||||
|
spaces: Room[];
|
||||||
|
directs: Room[];
|
||||||
|
};
|
||||||
|
|
||||||
export function MutualRoomsChip({ userId }: { userId: string }) {
|
export function MutualRoomsChip({ userId }: { userId: string }) {
|
||||||
const mx = useMatrixClient();
|
const mx = useMatrixClient();
|
||||||
const mutualRoomSupported = useMutualRoomsSupport();
|
const mutualRoomSupported = useMutualRoomsSupport();
|
||||||
|
|
@ -154,6 +161,33 @@ export function MutualRoomsChip({ userId }: { userId: string }) {
|
||||||
|
|
||||||
const close = () => setCords(undefined);
|
const close = () => setCords(undefined);
|
||||||
|
|
||||||
|
const mutual: MutualRoomsData = useMemo(() => {
|
||||||
|
const data: MutualRoomsData = {
|
||||||
|
rooms: [],
|
||||||
|
spaces: [],
|
||||||
|
directs: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
if (mutualRoomsState.status === AsyncStatus.Success) {
|
||||||
|
const mutualRooms = mutualRoomsState.data
|
||||||
|
.sort(factoryRoomIdByAtoZ(mx))
|
||||||
|
.map(getRoom)
|
||||||
|
.filter((room) => !!room);
|
||||||
|
mutualRooms.forEach((room) => {
|
||||||
|
if (room.isSpaceRoom()) {
|
||||||
|
data.spaces.push(room);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (directs.includes(room.roomId)) {
|
||||||
|
data.directs.push(room);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
data.rooms.push(room);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}, [mutualRoomsState, getRoom, directs, mx]);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
userId === mx.getSafeUserId() ||
|
userId === mx.getSafeUserId() ||
|
||||||
!mutualRoomSupported ||
|
!mutualRoomSupported ||
|
||||||
|
|
@ -162,6 +196,56 @@ export function MutualRoomsChip({ userId }: { userId: string }) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const renderItem = (room: Room) => {
|
||||||
|
const { roomId } = room;
|
||||||
|
const dm = directs.includes(roomId);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MenuItem
|
||||||
|
key={roomId}
|
||||||
|
variant="Surface"
|
||||||
|
fill="None"
|
||||||
|
size="300"
|
||||||
|
radii="300"
|
||||||
|
style={{ paddingLeft: config.space.S100 }}
|
||||||
|
onClick={() => {
|
||||||
|
if (room.isSpaceRoom()) {
|
||||||
|
navigateSpace(roomId);
|
||||||
|
} else {
|
||||||
|
navigateRoom(roomId);
|
||||||
|
}
|
||||||
|
closeUserRoomProfile();
|
||||||
|
}}
|
||||||
|
before={
|
||||||
|
<Avatar size="200" radii={dm ? '400' : '300'}>
|
||||||
|
{dm || room.isSpaceRoom() ? (
|
||||||
|
<RoomAvatar
|
||||||
|
roomId={room.roomId}
|
||||||
|
src={
|
||||||
|
dm
|
||||||
|
? getDirectRoomAvatarUrl(mx, room, 96, useAuthentication)
|
||||||
|
: getRoomAvatarUrl(mx, room, 96, useAuthentication)
|
||||||
|
}
|
||||||
|
alt={room.name}
|
||||||
|
renderFallback={() => (
|
||||||
|
<Text as="span" size="H6">
|
||||||
|
{nameInitials(room.name)}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<RoomIcon size="100" joinRule={room.getJoinRule()} />
|
||||||
|
)}
|
||||||
|
</Avatar>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text size="B300" truncate>
|
||||||
|
{room.name}
|
||||||
|
</Text>
|
||||||
|
</MenuItem>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PopOut
|
<PopOut
|
||||||
anchor={cords}
|
anchor={cords}
|
||||||
|
|
@ -191,65 +275,33 @@ export function MutualRoomsChip({ userId }: { userId: string }) {
|
||||||
<Scroll size="300" hideTrack>
|
<Scroll size="300" hideTrack>
|
||||||
<Box
|
<Box
|
||||||
direction="Column"
|
direction="Column"
|
||||||
gap="100"
|
gap="400"
|
||||||
style={{
|
style={{ padding: config.space.S200, paddingRight: 0 }}
|
||||||
padding: config.space.S200,
|
|
||||||
paddingRight: 0,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{mutualRoomsState.data
|
{mutual.spaces.length > 0 && (
|
||||||
.sort(factoryRoomIdByAtoZ(mx))
|
<Box direction="Column" gap="100">
|
||||||
.map((roomId) => getRoom(roomId))
|
<Text style={{ paddingLeft: config.space.S100 }} size="L400">
|
||||||
.map((room) => {
|
Spaces
|
||||||
if (!room) return null;
|
</Text>
|
||||||
const { roomId } = room;
|
{mutual.spaces.map(renderItem)}
|
||||||
const dm = directs.includes(roomId);
|
</Box>
|
||||||
|
)}
|
||||||
return (
|
{mutual.rooms.length > 0 && (
|
||||||
<MenuItem
|
<Box direction="Column" gap="100">
|
||||||
key={roomId}
|
<Text style={{ paddingLeft: config.space.S100 }} size="L400">
|
||||||
variant="Surface"
|
Rooms
|
||||||
fill="None"
|
</Text>
|
||||||
size="300"
|
{mutual.rooms.map(renderItem)}
|
||||||
radii="300"
|
</Box>
|
||||||
style={{ paddingLeft: config.space.S100 }}
|
)}
|
||||||
onClick={() => {
|
{mutual.directs.length > 0 && (
|
||||||
if (room.isSpaceRoom()) {
|
<Box direction="Column" gap="100">
|
||||||
navigateSpace(roomId);
|
<Text style={{ paddingLeft: config.space.S100 }} size="L400">
|
||||||
} else {
|
Direct Messages
|
||||||
navigateRoom(roomId);
|
</Text>
|
||||||
}
|
{mutual.directs.map(renderItem)}
|
||||||
closeUserRoomProfile();
|
</Box>
|
||||||
}}
|
)}
|
||||||
before={
|
|
||||||
<Avatar size="200" radii={dm ? '400' : '300'}>
|
|
||||||
{dm || room.isSpaceRoom() ? (
|
|
||||||
<RoomAvatar
|
|
||||||
roomId={room.roomId}
|
|
||||||
src={
|
|
||||||
dm
|
|
||||||
? getDirectRoomAvatarUrl(mx, room, 96, useAuthentication)
|
|
||||||
: getRoomAvatarUrl(mx, room, 96, useAuthentication)
|
|
||||||
}
|
|
||||||
alt={room.name}
|
|
||||||
renderFallback={() => (
|
|
||||||
<Text as="span" size="H6">
|
|
||||||
{nameInitials(room.name)}
|
|
||||||
</Text>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<RoomIcon size="100" joinRule={room.getJoinRule()} />
|
|
||||||
)}
|
|
||||||
</Avatar>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Text size="B300" truncate>
|
|
||||||
{room.name}
|
|
||||||
</Text>
|
|
||||||
</MenuItem>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Box>
|
</Box>
|
||||||
</Scroll>
|
</Scroll>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
@ -262,7 +314,9 @@ export function MutualRoomsChip({ userId }: { userId: string }) {
|
||||||
variant="SurfaceVariant"
|
variant="SurfaceVariant"
|
||||||
radii="Pill"
|
radii="Pill"
|
||||||
before={mutualRoomsState.status === AsyncStatus.Loading && <Spinner size="50" />}
|
before={mutualRoomsState.status === AsyncStatus.Loading && <Spinner size="50" />}
|
||||||
disabled={mutualRoomsState.status !== AsyncStatus.Success}
|
disabled={
|
||||||
|
mutualRoomsState.status !== AsyncStatus.Success || mutualRoomsState.data.length === 0
|
||||||
|
}
|
||||||
onClick={open}
|
onClick={open}
|
||||||
aria-pressed={!!cords}
|
aria-pressed={!!cords}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue