mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-11-04 22:40:29 +03:00
Some checks failed
Deploy to Netlify (dev) / Deploy to Netlify (push) Has been cancelled
* WIP - new profile view * render common rooms in user profile * add presence component * WIP - room user profile * temp hide profile button * show mutual rooms in spaces, rooms and direct messages categories * add message button * add option to change user powers in profile * improve ban info and option to unban * add share user button in user profile * add option to block user in user profile * improve blocked user alert body * add moderation tool in user profile * open profile view on left side in member drawer * open new user profile in all places
113 lines
3.6 KiB
TypeScript
113 lines
3.6 KiB
TypeScript
import React from 'react';
|
|
import classNames from 'classnames';
|
|
import {
|
|
Avatar,
|
|
Box,
|
|
Header,
|
|
Icon,
|
|
IconButton,
|
|
Icons,
|
|
MenuItem,
|
|
Scroll,
|
|
Text,
|
|
as,
|
|
config,
|
|
} from 'folds';
|
|
import { Room } from 'matrix-js-sdk';
|
|
import { useRoomEventReaders } from '../../hooks/useRoomEventReaders';
|
|
import { getMemberDisplayName } from '../../utils/room';
|
|
import { getMxIdLocalPart } from '../../utils/matrix';
|
|
import * as css from './EventReaders.css';
|
|
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
|
import { UserAvatar } from '../user-avatar';
|
|
import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
|
|
import { useOpenUserRoomProfile } from '../../state/hooks/userRoomProfile';
|
|
import { useSpaceOptionally } from '../../hooks/useSpace';
|
|
|
|
export type EventReadersProps = {
|
|
room: Room;
|
|
eventId: string;
|
|
requestClose: () => void;
|
|
};
|
|
export const EventReaders = as<'div', EventReadersProps>(
|
|
({ className, room, eventId, requestClose, ...props }, ref) => {
|
|
const mx = useMatrixClient();
|
|
const useAuthentication = useMediaAuthentication();
|
|
const latestEventReaders = useRoomEventReaders(room, eventId);
|
|
const openProfile = useOpenUserRoomProfile();
|
|
const space = useSpaceOptionally();
|
|
|
|
const getName = (userId: string) =>
|
|
getMemberDisplayName(room, userId) ?? getMxIdLocalPart(userId) ?? userId;
|
|
|
|
return (
|
|
<Box
|
|
className={classNames(css.EventReaders, className)}
|
|
direction="Column"
|
|
{...props}
|
|
ref={ref}
|
|
>
|
|
<Header className={css.Header} variant="Surface" size="600">
|
|
<Box grow="Yes">
|
|
<Text size="H3">Seen by</Text>
|
|
</Box>
|
|
<IconButton size="300" onClick={requestClose}>
|
|
<Icon src={Icons.Cross} />
|
|
</IconButton>
|
|
</Header>
|
|
<Box grow="Yes">
|
|
<Scroll visibility="Hover" hideTrack size="300">
|
|
<Box className={css.Content} direction="Column">
|
|
{latestEventReaders.map((readerId) => {
|
|
const name = getName(readerId);
|
|
const avatarMxcUrl = room.getMember(readerId)?.getMxcAvatarUrl();
|
|
const avatarUrl = avatarMxcUrl
|
|
? mx.mxcUrlToHttp(
|
|
avatarMxcUrl,
|
|
100,
|
|
100,
|
|
'crop',
|
|
undefined,
|
|
false,
|
|
useAuthentication
|
|
)
|
|
: undefined;
|
|
|
|
return (
|
|
<MenuItem
|
|
key={readerId}
|
|
style={{ padding: `0 ${config.space.S200}` }}
|
|
radii="400"
|
|
onClick={(event) => {
|
|
openProfile(
|
|
room.roomId,
|
|
space?.roomId,
|
|
readerId,
|
|
event.currentTarget.getBoundingClientRect(),
|
|
'Bottom'
|
|
);
|
|
}}
|
|
before={
|
|
<Avatar size="200">
|
|
<UserAvatar
|
|
userId={readerId}
|
|
src={avatarUrl ?? undefined}
|
|
alt={name}
|
|
renderFallback={() => <Icon size="50" src={Icons.User} filled />}
|
|
/>
|
|
</Avatar>
|
|
}
|
|
>
|
|
<Text size="T400" truncate>
|
|
{name}
|
|
</Text>
|
|
</MenuItem>
|
|
);
|
|
})}
|
|
</Box>
|
|
</Scroll>
|
|
</Box>
|
|
</Box>
|
|
);
|
|
}
|
|
);
|