import React, { useEffect } from 'react';
import { useMeasure } from 'react-use';
import { FixedSizeList } from 'react-window';
import { HMSPeer, selectIsLargeRoom, useHMSStore, usePaginatedParticipants } from '@100mslive/react-sdk';
import { AddIcon, ChevronRightIcon, CrossIcon } from '@100mslive/react-icons';
import { Accordion } from '../../../Accordion';
import { Button } from '../../../Button';
import { HorizontalDivider } from '../../../Divider';
import { Flex } from '../../../Layout';
import { Text } from '../../../Text';
import { Participant } from './ParticipantList';
import { RoleOptions } from './RoleOptions';
import { useGroupOnStageActions } from '../hooks/useGroupOnStageActions';
// @ts-ignore: No implicit Any
import { getFormattedCount } from '../../common/utils';
export const ROW_HEIGHT = 50;
const ITER_TIMER = 5000;
export interface ItemData {
peerList: HMSPeer[];
isHandRaisedAccordion?: boolean;
isConnected: boolean;
}
export function itemKey(index: number, data: ItemData) {
return data.peerList[index]?.id;
}
export const VirtualizedParticipantItem = React.memo(
({ index, data, style }: { index: number; data: ItemData; style: React.CSSProperties }) => {
return (
);
},
);
export const RoleAccordion = ({
peerList = [],
roleName,
isConnected,
filter,
isHandRaisedAccordion = false,
offStageRoles,
onActive,
}: ItemData & {
roleName: string;
isHandRaisedAccordion?: boolean;
filter?: { search?: string };
offStageRoles: string[];
onActive?: (role: string) => void;
}) => {
const [ref, { width }] = useMeasure();
const isLargeRoom = useHMSStore(selectIsLargeRoom);
const { peers, total, loadPeers } = usePaginatedParticipants({ role: roleName, limit: 10 });
const isOffStageRole = roleName && offStageRoles.includes(roleName);
let peersInAccordion = peerList;
// for large rooms, peer list would be empty
if (isOffStageRole && isLargeRoom) {
peersInAccordion = peers;
if (filter?.search) {
peersInAccordion = peersInAccordion.filter(peer => peer.name.toLowerCase().includes(filter.search || ''));
}
}
const { bringAllToStage, bring_to_stage_label, canBringToStage, lowerAllHands } = useGroupOnStageActions({
peers: peersInAccordion,
});
useEffect(() => {
if (!isOffStageRole || !isLargeRoom) {
return;
}
loadPeers();
const interval = setInterval(() => {
loadPeers();
}, ITER_TIMER);
return () => clearInterval(interval);
}, [isOffStageRole, isLargeRoom]); //eslint-disable-line
if (peersInAccordion.length === 0 || (isHandRaisedAccordion && filter?.search)) {
return null;
}
const height = ROW_HEIGHT * peersInAccordion.length;
const hasNext = total > peersInAccordion.length && !filter?.search;
return (
{roleName} {`(${getFormattedCount(isLargeRoom && isOffStageRole ? total : peerList.length)})`}
{
try {
const aHandRaisedAt = JSON.parse(a.metadata || '{}').handRaisedAt;
const bHandRaisedAt = JSON.parse(b.metadata || '{}').handRaisedAt;
return aHandRaisedAt - bHandRaisedAt;
} catch (err) {
return 0;
}
})
: peersInAccordion,
isConnected,
isHandRaisedAccordion,
}}
itemKey={itemKey}
itemCount={peersInAccordion.length}
width={width}
height={height}
>
{VirtualizedParticipantItem}
{offStageRoles?.includes(roleName) && hasNext ? (
onActive?.(roleName)}
>
View All
) : null}
{isHandRaisedAccordion && canBringToStage && (
<>
>
)}
);
};