import React, { useState } from 'react';
import { Room } from 'matrix-js-sdk';
import {
Icon,
Icons,
Modal,
Overlay,
OverlayBackdrop,
OverlayCenter,
Text,
color,
config,
} from 'folds';
import FocusTrap from 'focus-trap-react';
import { useSetting } from '../../state/hooks/settings';
import { settingsAtom } from '../../state/settings';
import { getMemberName } from '../../utils/room';
import { UserAvatar } from '../user-avatar';
import { StackedAvatar } from '../stacked-avatar';
import { EventReaders } from '../event-readers';
import { stopPropagation } from '../../utils/keyboard';
import { useModalStyle } from '../../hooks/useModalStyle';
import { useMemberAvatar } from '../../hooks/useMemberAvatar';
import { useRoomMembersChange } from '../../hooks/useRoomMemberChange';
import { MobileTouchTarget } from '../../styles/mobile.css';
import * as css from './ReadReceiptAvatars.css';
const MAX_DISPLAY = 5;
function ReceiptStackedAvatar({ room, userId }: { room: Room; userId: string }) {
const { name, avatarUrl } = useMemberAvatar(room, userId);
return (
}
/>
);
}
export function ReadReceiptAvatars({
room,
eventId,
userIds,
}: {
room: Room;
eventId: string;
userIds: string[];
}) {
const [open, setOpen] = useState(false);
const [lotusTerminal] = useSetting(settingsAtom, 'lotusTerminal');
const modalStyle = useModalStyle(360);
// The tooltip names below are read from room member state at render time.
// Re-render on a member-state change of any displayed reader so a display-name
// update shows live (each avatar handles its own via useMemberAvatar). Uses the
// shared member-change store — one global listener for the whole app (PERF-3).
useRoomMembersChange(room.roomId, userIds);
if (userIds.length === 0) return null;
const displayed = userIds.slice(0, MAX_DISPLAY);
const extra = userIds.length - MAX_DISPLAY;
const tooltipNames =
userIds
.slice(0, 5)
.map((id) => getMemberName(room, id))
.join(', ') + (extra > 0 ? ` +${extra} more` : '');
return (
<>
}>
setOpen(false),
clickOutsideDeactivates: true,
escapeDeactivates: stopPropagation,
}}
>
setOpen(false)} />
>
);
}