;
}) {
const [isVisible, setIsVisible] = useState(false);
useEffect(() => {
let timer: any;
if (users.length > 0 && !loading) {
timer = setTimeout(() => {
setIsVisible(true);
}, 50);
} else if (users.length === 0) {
setIsVisible(false);
}
return () => clearTimeout(timer);
}, [users.length, loading]);
const renderUserList = () => {
if (users.length === 0) {
if (loading) {
return ;
}
return ;
}
const listContainerClass = `${classes['read-receipt-info__user-list-container']} ${
isVisible ? classes['read-receipt-info__user-list-container--visible'] : ''
}`;
return (
{users.map(user => )}
{loading && }
{!hasMore && }
);
};
return (
{renderUserList()}
);
}
function ReadReceiptInfo(props: IReadReceiptInfoProps) {
const {
open,
message,
readCount = 0,
unreadCount = 0,
className,
onClose,
style,
} = props;
const { t } = useUIKit();
const [activeTab, setActiveTab] = useState<'read' | 'unread'>('read');
const [readLoading, setReadLoading] = useState(false);
const [unreadLoading, setUnreadLoading] = useState(false);
const [loadMoreLoading, setLoadMoreLoading] = useState(false);
const readListRef = useRef(null);
const unreadListRef = useRef(null);
const {
readMemberList,
unreadMemberList,
hasMoreReadMembers,
hasMoreUnreadMembers,
loadReadMembers,
loadUnreadMembers,
loadMoreMembers,
} = useMessageActionStore(message);
const loadReadUsers = useCallback(async () => {
setReadLoading(true);
try {
await loadReadMembers(100);
} catch (error) {
console.error('Failed to load read users:', error);
} finally {
setReadLoading(false);
}
}, [loadReadMembers]);
const loadUnreadUsers = useCallback(async () => {
setUnreadLoading(true);
try {
await loadUnreadMembers(50);
} catch (error) {
console.error('Failed to load unread users:', error);
} finally {
setUnreadLoading(false);
}
}, [loadUnreadMembers]);
// Handle scroll to load more
const handleScroll = useCallback((event: React.UIEvent) => {
const { currentTarget } = event;
const { scrollTop, scrollHeight, clientHeight } = currentTarget;
if (scrollHeight - scrollTop - clientHeight >= 50) {
return;
}
if (loadMoreLoading) {
return;
}
const shouldLoad
= (activeTab === 'read' && hasMoreReadMembers && !readLoading)
|| (activeTab === 'unread' && hasMoreUnreadMembers && !unreadLoading);
if (!shouldLoad) {
return;
}
setLoadMoreLoading(true);
loadMoreMembers(activeTab === 'read')
.finally(() => {
setLoadMoreLoading(false);
});
}, [activeTab, readLoading, unreadLoading, hasMoreReadMembers, hasMoreUnreadMembers, loadMoreLoading, loadMoreMembers]);
// Load data when modal opens
useEffect(() => {
if (open) {
loadReadUsers();
loadUnreadUsers();
}
}, [open, loadReadUsers, loadUnreadUsers]);
// Refresh when counts change
useEffect(() => {
if (!open || !message?.msgID) {
return;
}
if (readLoading || unreadLoading) {
return;
}
if (activeTab === 'read') {
loadReadUsers();
} else {
loadUnreadUsers();
}
}, [readCount, unreadCount]);
return (
);
}
export {
ReadReceiptInfo,
};