import { Avatar, Box, ListItem, ListItemAvatar, ListItemButton, ListItemText, Popover, Typography, useTheme, } from '@mui/material'; import { useRef, useState } from 'react'; import { AutoSizer, CellMeasurer, CellMeasurerCache, List, } from 'react-virtualized'; import { LoadingButton } from '@mui/lab'; import { getFee } from '../../background'; import { getBaseApiReact } from '../../App'; import { useTranslation } from 'react-i18next'; const cache = new CellMeasurerCache({ fixedWidth: true, defaultHeight: 50, }); const ListOfMembers = ({ members, groupId, setInfoSnack, setOpenSnack, isAdmin, isOwner, show, }) => { const [popoverAnchor, setPopoverAnchor] = useState(null); // Track which list item the popover is anchored to const [openPopoverIndex, setOpenPopoverIndex] = useState(null); // Track which list item has the popover open const [isLoadingKick, setIsLoadingKick] = useState(false); const [isLoadingBan, setIsLoadingBan] = useState(false); const [isLoadingMakeAdmin, setIsLoadingMakeAdmin] = useState(false); const [isLoadingRemoveAdmin, setIsLoadingRemoveAdmin] = useState(false); const theme = useTheme(); const { t } = useTranslation(['core', 'group']); const listRef = useRef(null); const handlePopoverOpen = (event, index) => { setPopoverAnchor(event.currentTarget); setOpenPopoverIndex(index); }; const handlePopoverClose = () => { setPopoverAnchor(null); setOpenPopoverIndex(null); }; const handleKick = async (address) => { try { const fee = await getFee('GROUP_KICK'); await show({ message: t('core:question.perform_transaction', { action: 'GROUP_KICK', postProcess: 'capitalizeFirst', }), publishFee: fee.fee + ' QORT', }); setIsLoadingKick(true); new Promise((res, rej) => { window .sendMessage('kickFromGroup', { groupId, qortalAddress: address, }) .then((response) => { if (!response?.error) { setInfoSnack({ type: 'success', message: t('group:message.success.group_kick', { postProcess: 'capitalizeFirst', }), }); setOpenSnack(true); handlePopoverClose(); res(response); return; } setInfoSnack({ type: 'error', message: response?.error, }); setOpenSnack(true); rej(response.error); }) .catch((error) => { setInfoSnack({ type: 'error', message: error.message || t('core:message.error.generic', { postProcess: 'capitalizeFirst', }), }); setOpenSnack(true); rej(error); }); }); } catch (error) { console.log(error); } finally { setIsLoadingKick(false); } }; const handleBan = async (address) => { try { const fee = await getFee('GROUP_BAN'); await show({ message: t('core:question.perform_transaction', { action: 'GROUP_BAN', postProcess: 'capitalizeFirst', }), publishFee: fee.fee + ' QORT', }); setIsLoadingBan(true); await new Promise((res, rej) => { window .sendMessage('banFromGroup', { groupId, qortalAddress: address, rBanTime: 0, }) .then((response) => { if (!response?.error) { setInfoSnack({ type: 'success', message: t('group:message.success.group_ban', { postProcess: 'capitalizeFirst', }), }); setOpenSnack(true); handlePopoverClose(); res(response); return; } setInfoSnack({ type: 'error', message: response?.error, }); setOpenSnack(true); rej(response.error); }) .catch((error) => { setInfoSnack({ type: 'error', message: error.message || t('core:message.error.generic', { postProcess: 'capitalizeFirst', }), }); setOpenSnack(true); rej(error); }); }); } catch (error) { console.log(error); } finally { setIsLoadingBan(false); } }; const makeAdmin = async (address) => { try { const fee = await getFee('ADD_GROUP_ADMIN'); await show({ message: t('core:question.perform_transaction', { action: 'ADD_GROUP_ADMIN', postProcess: 'capitalizeFirst', }), publishFee: fee.fee + ' QORT', }); setIsLoadingMakeAdmin(true); await new Promise((res, rej) => { window .sendMessage('makeAdmin', { groupId, qortalAddress: address, }) .then((response) => { if (!response?.error) { setInfoSnack({ type: 'success', message: t('group:message.success.group_member_admin', { postProcess: 'capitalizeFirst', }), }); setOpenSnack(true); handlePopoverClose(); res(response); return; } setInfoSnack({ type: 'error', message: response?.error, }); setOpenSnack(true); rej(response.error); }) .catch((error) => { setInfoSnack({ type: 'error', message: error.message || t('core:message.error.generic', { postProcess: 'capitalizeFirst', }), }); setOpenSnack(true); rej(error); }); }); } catch (error) { console.log(error); } finally { setIsLoadingMakeAdmin(false); } }; const removeAdmin = async (address) => { try { const fee = await getFee('REMOVE_GROUP_ADMIN'); await show({ message: t('core:question.perform_transaction', { action: 'REMOVE_GROUP_ADMIN', postProcess: 'capitalizeFirst', }), publishFee: fee.fee + ' QORT', }); setIsLoadingRemoveAdmin(true); await new Promise((res, rej) => { window .sendMessage('removeAdmin', { groupId, qortalAddress: address, }) .then((response) => { if (!response?.error) { setInfoSnack({ type: 'success', message: t('group:message.success.group_remove_member', { postProcess: 'capitalizeFirst', }), }); setOpenSnack(true); handlePopoverClose(); res(response); return; } setInfoSnack({ type: 'error', message: response?.error, }); setOpenSnack(true); rej(response.error); }) .catch((error) => { setInfoSnack({ type: 'error', message: error.message || t('core:message.error.generic', { postProcess: 'capitalizeFirst', }), }); setOpenSnack(true); rej(error); }); }); } catch (error) { console.log(error); } finally { setIsLoadingRemoveAdmin(false); } }; const rowRenderer = ({ index, key, parent, style }) => { const member = members[index]; return ( {({ measure }) => (
{isOwner && ( <> handleKick(member?.member)} > {t('group:action.kick_member', { postProcess: 'capitalizeFirst', })} handleBan(member?.member)} > {t('group:action.ban', { postProcess: 'capitalizeFirst', })} makeAdmin(member?.member)} > {t('group:action.make_admin', { postProcess: 'capitalizeFirst', })} removeAdmin(member?.member)} > {t('group:action.remove_admin', { postProcess: 'capitalizeFirst', })} )} handlePopoverOpen(event, index)} > {member?.isAdmin && ( {t('core:admin', { postProcess: 'capitalizeFirst', })} )}
)}
); }; return (

{t('core:list.member', { postProcess: 'capitalizeFirst', })}

{({ height, width }) => ( )}
); }; export default ListOfMembers;