import { memo, useMemo } from 'react'; import { Link } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { Comment, useCommunities } from '@bitsocialnet/bitsocial-react-hooks'; import styles from '../home.module.css'; import usePopularPosts from '../../../hooks/use-popular-posts'; import { useFeedStateString } from '../../../hooks/use-state-string'; import usePopularThreadsOptionsStore from '../../../stores/use-popular-threads-options-store'; import { getCommentMediaInfo } from '../../../lib/utils/media-utils'; import { CatalogPostMedia } from '../../../components/catalog-row'; import LoadingEllipsis from '../../../components/loading-ellipsis'; import BoxModal from '../box-modal'; import { DirectoryCommunity, findDirectoryByAddress } from '../../../hooks/use-directories'; import { useCommunityIdentifiers } from '../../../hooks/use-community-identifiers'; import { getBoardPath } from '../../../lib/utils/route-utils'; import { removeMarkdown } from '../../../lib/utils/post-utils'; interface PopularThreadProps { post: Comment; boardTitle: string; boardPath: string; } const ContentPreview = ({ content, maxLength = 99 }: { content: string; maxLength?: number }) => { const plainText = removeMarkdown(content).trim().replaceAll(' ', '').replace(/\n\n/g, '\n').replaceAll('\n\n', ''); const truncatedText = plainText.length > maxLength ? `${plainText.substring(0, maxLength).trim()}...` : plainText; return truncatedText; }; const PopularThreadCard = memo( ({ post, boardTitle, boardPath }: PopularThreadProps) => { const { cid, content, link, linkHeight, linkWidth, thumbnailUrl, title } = post || {}; const commentMediaInfo = getCommentMediaInfo(link, thumbnailUrl, linkWidth, linkHeight); return (
{boardTitle}
{title && ( <> {title.trim()} {content && ': '} )} {content && }
); }, (prevProps, nextProps) => prevProps.post?.cid === nextProps.post?.cid && prevProps.boardTitle === nextProps.boardTitle && prevProps.boardPath === nextProps.boardPath, ); const PopularThreadsBox = ({ directories, directoryAddresses }: { directories: DirectoryCommunity[]; directoryAddresses: string[] }) => { const { t } = useTranslation(); const { showWorksafeContentOnly, showNsfwContentOnly } = usePopularThreadsOptionsStore(); const getCommentCommunityAddress = (post: Comment) => post.communityAddress || post.subplebbitAddress; const directoryCommunities = useCommunityIdentifiers(directoryAddresses); const { communities } = useCommunities({ communities: directoryCommunities }); const { filteredBoardAddresses, filteredCommunities } = useMemo(() => { const filteredEntries = directoryAddresses.flatMap((address, index) => { const directoryEntry = findDirectoryByAddress(directories, address); if (showWorksafeContentOnly && directoryEntry?.nsfw) { return []; } if (showNsfwContentOnly && !directoryEntry?.nsfw) { return []; } return [{ address, community: communities[index] }]; }); return { filteredBoardAddresses: filteredEntries.map((entry) => entry.address), filteredCommunities: filteredEntries.map((entry) => entry.community), }; }, [directories, directoryAddresses, showNsfwContentOnly, showWorksafeContentOnly, communities]); const { popularPosts, isLoading } = usePopularPosts(filteredCommunities, filteredBoardAddresses); const loadingStateString = useFeedStateString(filteredBoardAddresses) || t('loading'); return (

{t('popular_threads')}

{isLoading ? ( ) : ( popularPosts.map((post: Comment) => { const communityAddress = getCommentCommunityAddress(post); const directoryEntry = findDirectoryByAddress(directories, communityAddress); const boardTitle = directoryEntry?.title?.replace(/^\/[^/]+\/\s*-\s*/, '') || ''; const boardPath = communityAddress ? getBoardPath(communityAddress, directories) : ''; return ; }) )}
); }; export default PopularThreadsBox;