mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
refactor: migrate 5chan to the community hooks API (#1073)
* refactor(community-api): migrate 5chan to community hooks * fix(review): address PR feedback * fix(review): preserve legacy board context fallbacks * fix(review): address latest bot feedback * fix(review): use communityAddress in edit menu privileges
This commit is contained in:
@@ -13,8 +13,8 @@ const testState = vi.hoisted(() => ({
|
||||
directories: [] as Array<{ address: string; title?: string }>,
|
||||
directoryAddresses: [] as string[],
|
||||
navigateMock: vi.fn(),
|
||||
subplebbits: {} as Record<string, unknown>,
|
||||
subplebbitsStats: {} as Record<string, { allPostCount?: number; weekActiveUserCount?: number }>,
|
||||
communities: {} as Record<string, unknown>,
|
||||
communityStats: {} as Record<string, { allPostCount?: number; weekActiveUserCount?: number }>,
|
||||
}));
|
||||
|
||||
vi.mock('react-i18next', () => ({
|
||||
@@ -33,7 +33,7 @@ vi.mock('react-router-dom', async () => {
|
||||
});
|
||||
|
||||
vi.mock('@bitsocialnet/bitsocial-react-hooks', () => ({
|
||||
useSubplebbits: () => ({ subplebbits: testState.subplebbits }),
|
||||
useCommunities: () => ({ communities: testState.communities }),
|
||||
}));
|
||||
|
||||
vi.mock('../../../hooks/use-directories', () => ({
|
||||
@@ -41,11 +41,10 @@ vi.mock('../../../hooks/use-directories', () => ({
|
||||
useDirectoryAddresses: () => testState.directoryAddresses,
|
||||
}));
|
||||
|
||||
vi.mock('../../../hooks/use-subplebbits-stats', () => ({
|
||||
SubplebbitStatsCollector: ({ subplebbitAddress }: { subplebbitAddress: string }) =>
|
||||
createElement('div', { 'data-testid': 'stats-collector', 'data-address': subplebbitAddress }),
|
||||
useSubplebbitsStatsStore: (selector: (state: { subplebbitsStats: typeof testState.subplebbitsStats }) => unknown) =>
|
||||
selector({ subplebbitsStats: testState.subplebbitsStats }),
|
||||
vi.mock('../../../hooks/use-communities-stats', () => ({
|
||||
CommunityStatsCollector: ({ communityAddress }: { communityAddress: string }) =>
|
||||
createElement('div', { 'data-testid': 'stats-collector', 'data-address': communityAddress }),
|
||||
useCommunitiesStatsStore: (selector: (state: { communityStats: typeof testState.communityStats }) => unknown) => selector({ communityStats: testState.communityStats }),
|
||||
}));
|
||||
|
||||
vi.mock('../../../stores/use-directory-modal-store', () => ({
|
||||
@@ -59,8 +58,8 @@ vi.mock('../boards-list', () => ({
|
||||
}));
|
||||
|
||||
vi.mock('../popular-threads-box', () => ({
|
||||
default: ({ directories, subplebbits }: { directories: unknown[]; subplebbits: Record<string, unknown> }) =>
|
||||
createElement('div', { 'data-testid': 'popular-threads-box' }, `popular:${directories.length}:${Object.keys(subplebbits).length}`),
|
||||
default: ({ directories, communities }: { directories: unknown[]; communities: Record<string, unknown> }) =>
|
||||
createElement('div', { 'data-testid': 'popular-threads-box' }, `popular:${directories.length}:${Object.keys(communities).length}`),
|
||||
}));
|
||||
|
||||
vi.mock('../../../components/site-legal-meta', () => ({
|
||||
@@ -95,11 +94,11 @@ describe('Home', () => {
|
||||
{ address: 'tech-posting.eth', title: '/g/ - Technology' },
|
||||
];
|
||||
testState.directoryAddresses = ['music-posting.eth', 'tech-posting.eth'];
|
||||
testState.subplebbits = {
|
||||
testState.communities = {
|
||||
'music-posting.eth': { address: 'music-posting.eth' },
|
||||
'tech-posting.eth': { address: 'tech-posting.eth' },
|
||||
};
|
||||
testState.subplebbitsStats = {
|
||||
testState.communityStats = {
|
||||
'music-posting.eth': { allPostCount: 5, weekActiveUserCount: 2 },
|
||||
'tech-posting.eth': { allPostCount: 7, weekActiveUserCount: 5 },
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useAccountSubplebbitAddresses } from '../../../hooks/use-account-subplebbit-addresses';
|
||||
import { useAccountCommunityAddresses } from '../../../hooks/use-account-community-addresses';
|
||||
import { useDirectoriesState, useDirectories, DirectoryCommunity } from '../../../hooks/use-directories';
|
||||
import { getBoardPath } from '../../../lib/utils/route-utils';
|
||||
import useDisclaimerModalStore from '../../../stores/use-disclaimer-modal-store';
|
||||
@@ -64,7 +64,7 @@ const BoardsList = ({ multisub }: { multisub: DirectoryCommunity[] }) => {
|
||||
const { useCatalogLinks, boardFilter } = useBoardsFilterStore();
|
||||
const directories = useDirectories();
|
||||
|
||||
const accountSubplebbitAddresses = useAccountSubplebbitAddresses();
|
||||
const accountCommunityAddresses = useAccountCommunityAddresses();
|
||||
|
||||
const handleLinkClick = (e: React.MouseEvent<HTMLAnchorElement>, address: string) => {
|
||||
e.preventDefault();
|
||||
@@ -598,7 +598,7 @@ const BoardsList = ({ multisub }: { multisub: DirectoryCommunity[] }) => {
|
||||
<li>
|
||||
<Link to='/subs'>Subscriptions</Link>
|
||||
</li>
|
||||
{accountSubplebbitAddresses.length > 0 && (
|
||||
{accountCommunityAddresses.length > 0 && (
|
||||
<li>
|
||||
<Link to='/mod'>{t('boards_you_moderate_nav')}</Link>
|
||||
</li>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { useEffect, useMemo, useRef, FormEvent } from 'react';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { Trans, useTranslation } from 'react-i18next';
|
||||
import { useSubplebbits } from '@bitsocialnet/bitsocial-react-hooks';
|
||||
import { useCommunities } from '@bitsocialnet/bitsocial-react-hooks';
|
||||
import styles from './home.module.css';
|
||||
import { useDirectories, useDirectoryAddresses } from '../../hooks/use-directories';
|
||||
import { SubplebbitStatsCollector, useSubplebbitsStatsStore } from '../../hooks/use-subplebbits-stats';
|
||||
import { CommunityStatsCollector, useCommunitiesStatsStore } from '../../hooks/use-communities-stats';
|
||||
import PopularThreadsBox from './popular-threads-box';
|
||||
import BoardsList from './boards-list';
|
||||
import SiteLegalMeta from '../../components/site-legal-meta';
|
||||
@@ -81,7 +81,7 @@ const InfoBox = () => {
|
||||
|
||||
const Stats = ({ directoryAddresses }: { directoryAddresses: string[] }) => {
|
||||
const { t } = useTranslation();
|
||||
const subplebbitsStats = useSubplebbitsStatsStore((state) => state.subplebbitsStats);
|
||||
const communitiesStats = useCommunitiesStatsStore((state) => state.communityStats);
|
||||
|
||||
const { totalPosts, currentUsers, boardsTracked } = useMemo(() => {
|
||||
let totalPosts = 0;
|
||||
@@ -89,7 +89,7 @@ const Stats = ({ directoryAddresses }: { directoryAddresses: string[] }) => {
|
||||
let boardsTracked = 0;
|
||||
|
||||
directoryAddresses.forEach((address) => {
|
||||
const stat = subplebbitsStats[address];
|
||||
const stat = communitiesStats[address];
|
||||
if (stat) {
|
||||
totalPosts += stat.allPostCount || 0;
|
||||
currentUsers += stat.weekActiveUserCount || 0;
|
||||
@@ -98,13 +98,13 @@ const Stats = ({ directoryAddresses }: { directoryAddresses: string[] }) => {
|
||||
});
|
||||
|
||||
return { totalPosts, currentUsers, boardsTracked };
|
||||
}, [subplebbitsStats, directoryAddresses]);
|
||||
}, [communitiesStats, directoryAddresses]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Render collectors to fetch stats for each subplebbit */}
|
||||
{/* Render collectors to fetch stats for each community */}
|
||||
{directoryAddresses.map((address) => (
|
||||
<SubplebbitStatsCollector key={address} subplebbitAddress={address} />
|
||||
<CommunityStatsCollector key={address} communityAddress={address} />
|
||||
))}
|
||||
<div className={styles.box}>
|
||||
<div className={`${styles.boxBar} ${styles.color2ColorBar}`}>
|
||||
@@ -183,7 +183,7 @@ export const HomeLogo = () => {
|
||||
const Home = () => {
|
||||
const directories = useDirectories();
|
||||
const directoryAddresses = useDirectoryAddresses();
|
||||
const { subplebbits } = useSubplebbits({ subplebbitAddresses: directoryAddresses });
|
||||
const { communities } = useCommunities({ communityAddresses: directoryAddresses });
|
||||
const { closeDirectoryModal } = useDirectoryModalStore();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -206,7 +206,7 @@ const Home = () => {
|
||||
<SearchBar />
|
||||
<InfoBox />
|
||||
<BoardsList multisub={directories} />
|
||||
<PopularThreadsBox directories={directories} directoryAddresses={directoryAddresses} subplebbits={subplebbits} />
|
||||
<PopularThreadsBox directories={directories} directoryAddresses={directoryAddresses} communities={communities} />
|
||||
<Stats directoryAddresses={directoryAddresses} />
|
||||
<Footer />
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { memo, useMemo } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Comment, Subplebbit } from '@bitsocialnet/bitsocial-react-hooks';
|
||||
import { Comment, Community } 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';
|
||||
@@ -58,16 +58,17 @@ const PopularThreadCard = memo(
|
||||
const PopularThreadsBox = ({
|
||||
directories,
|
||||
directoryAddresses,
|
||||
subplebbits,
|
||||
communities,
|
||||
}: {
|
||||
directories: DirectoryCommunity[];
|
||||
directoryAddresses: string[];
|
||||
subplebbits: Array<Subplebbit | undefined>;
|
||||
communities: Array<Community | undefined>;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { showWorksafeContentOnly, showNsfwContentOnly } = usePopularThreadsOptionsStore();
|
||||
const getCommentCommunityAddress = (post: Comment) => post.communityAddress || post.subplebbitAddress;
|
||||
|
||||
const { filteredBoardAddresses, filteredSubplebbits } = useMemo(() => {
|
||||
const { filteredBoardAddresses, filteredCommunities } = useMemo(() => {
|
||||
const filteredEntries = directoryAddresses.flatMap((address, index) => {
|
||||
const directoryEntry = findDirectoryByAddress(directories, address);
|
||||
if (showWorksafeContentOnly && directoryEntry?.nsfw) {
|
||||
@@ -77,16 +78,16 @@ const PopularThreadsBox = ({
|
||||
return [];
|
||||
}
|
||||
|
||||
return [{ address, subplebbit: subplebbits[index] }];
|
||||
return [{ address, community: communities[index] }];
|
||||
});
|
||||
|
||||
return {
|
||||
filteredBoardAddresses: filteredEntries.map((entry) => entry.address),
|
||||
filteredSubplebbits: filteredEntries.map((entry) => entry.subplebbit),
|
||||
filteredCommunities: filteredEntries.map((entry) => entry.community),
|
||||
};
|
||||
}, [directories, directoryAddresses, showNsfwContentOnly, showWorksafeContentOnly, subplebbits]);
|
||||
}, [directories, directoryAddresses, showNsfwContentOnly, showWorksafeContentOnly, communities]);
|
||||
|
||||
const { popularPosts, isLoading } = usePopularPosts(filteredSubplebbits, filteredBoardAddresses);
|
||||
const { popularPosts, isLoading } = usePopularPosts(filteredCommunities, filteredBoardAddresses);
|
||||
const loadingStateString = useFeedStateString(filteredBoardAddresses) || t('loading');
|
||||
|
||||
return (
|
||||
@@ -100,9 +101,10 @@ const PopularThreadsBox = ({
|
||||
<LoadingEllipsis string={loadingStateString} />
|
||||
) : (
|
||||
popularPosts.map((post: Comment) => {
|
||||
const directoryEntry = findDirectoryByAddress(directories, post.subplebbitAddress);
|
||||
const communityAddress = getCommentCommunityAddress(post);
|
||||
const directoryEntry = findDirectoryByAddress(directories, communityAddress);
|
||||
const boardTitle = directoryEntry?.title?.replace(/^\/[^/]+\/\s*-\s*/, '') || '';
|
||||
const boardPath = post.subplebbitAddress ? getBoardPath(post.subplebbitAddress, directories) : '';
|
||||
const boardPath = communityAddress ? getBoardPath(communityAddress, directories) : '';
|
||||
return <PopularThreadCard key={post.cid} post={post} boardTitle={boardTitle} boardPath={boardPath} />;
|
||||
})
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user