import { useEffect, useMemo, useRef, FormEvent } from 'react'; import { Link, useNavigate } from 'react-router-dom'; import { Trans, useTranslation } from 'react-i18next'; import styles from './home.module.css'; import { useDirectories, useDirectoryAddresses } from '../../hooks/use-directories'; 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'; import LoadingEllipsis from '../../components/loading-ellipsis'; import useDirectoryModalStore from '../../stores/use-directory-modal-store'; import DisclaimerModal from '../../components/disclaimer-modal'; import DirectoryModal from '../../components/directory-modal'; import { getBoardPath } from '../../lib/utils/route-utils'; import { isWebRuntime } from '../../lib/media-hosting/show-upload-controls'; import lowerCase from 'lodash/lowerCase'; // https://github.com/bitsocialnet/lists/blob/master/5chan-directories.json const SearchBar = () => { const searchInputRef = useRef(null); const { t } = useTranslation(); const navigate = useNavigate(); const directories = useDirectories(); const handleSearchSubmit = (e: FormEvent) => { e.preventDefault(); const searchInput = searchInputRef.current?.value; if (searchInput) { const boardPath = getBoardPath(searchInput, directories); navigate(`/${boardPath}`); } }; return (
); }; const InfoBox = () => { const { t } = useTranslation(); const isWeb = isWebRuntime(); return (

{t('what_is_5chan')}

, 2: , }} />

{isWeb ? ( , }} /> ) : ( t('app_p2p_info') )}
); }; interface StatValueProps { isLoaded: boolean; loadingLabel: string; value: number; } const StatValue = ({ isLoaded, loadingLabel, value }: StatValueProps) => (isLoaded ? <>{value} : ); const Stats = ({ directoryAddresses }: { directoryAddresses: string[] }) => { const { t } = useTranslation(); const communitiesStats = useCommunitiesStatsStore((state) => state.communityStats); const { totalPosts, currentUsers, boardsTracked, allDirectoryStatsLoaded } = useMemo(() => { let totalPosts = 0; let currentUsers = 0; let boardsTracked = 0; let allDirectoryStatsLoaded = directoryAddresses.length > 0; for (const address of directoryAddresses) { const stat = communitiesStats[address]; if (!stat || stat.allPostCount === undefined) { allDirectoryStatsLoaded = false; continue; } totalPosts += stat.allPostCount || 0; currentUsers += stat.weekActiveUserCount || 0; boardsTracked++; } return { totalPosts, currentUsers, boardsTracked, allDirectoryStatsLoaded }; }, [communitiesStats, directoryAddresses]); const loadingLabel = t('loading'); return ( <> {/* Render collectors to fetch stats for each community */} {directoryAddresses.map((address) => ( ))}

{t('stats')}

{t('total_posts')}
{t('current_users')}
{t('boards_tracked')}
); }; export const Footer = () => { const { t } = useTranslation(); return ( <>
); }; export const HomeLogo = () => { return (
); }; const Home = () => { const directories = useDirectories(); const directoryAddresses = useDirectoryAddresses(); const { closeDirectoryModal } = useDirectoryModalStore(); useEffect(() => { document.title = '5chan'; }, []); // Close directory modal when navigating away from home useEffect(() => { return () => { closeDirectoryModal(); }; }, [closeDirectoryModal]); return ( <>
); }; export default Home;