From 798dfc424ff48823a19b4e978b1a7f67070d09af Mon Sep 17 00:00:00 2001 From: "plebeius.eth" Date: Sun, 5 May 2024 15:28:11 +0200 Subject: [PATCH] feat(home): add custom hook for stats functionality --- src/views/home/home.module.css | 4 -- src/views/home/home.tsx | 107 ++++++++++++++++++++++++++++----- 2 files changed, 93 insertions(+), 18 deletions(-) diff --git a/src/views/home/home.module.css b/src/views/home/home.module.css index 16538986..c3031163 100644 --- a/src/views/home/home.module.css +++ b/src/views/home/home.module.css @@ -181,10 +181,6 @@ text-align: center; } -.popularThreads .loading { - text-align: left !important; -} - .popularThread { vertical-align: top; display: inline-block; diff --git a/src/views/home/home.tsx b/src/views/home/home.tsx index 01889a1d..8b3bc562 100644 --- a/src/views/home/home.tsx +++ b/src/views/home/home.tsx @@ -9,6 +9,10 @@ import { getCommentMediaInfo, getHasThumbnail } from '../../lib/utils/media-util import { CatalogPostMedia } from '../../components/catalog-row'; import LoadingEllipsis from '../../components/loading-ellipsis'; +// for temporary hook to fetch subplebbit stats +import { useMemo } from 'react'; +import { create } from 'zustand'; + const isValidAddress = (address: string): boolean => { if (address.includes('/') || address.includes('\\') || address.includes(' ')) { return false; @@ -256,9 +260,7 @@ const PopularThreads = ({ subplebbits }: { subplebbits: any }) => {
{popularPosts.length < 8 ? ( - - - + ) : ( popularPosts.map((post: any) => ( @@ -269,28 +271,105 @@ const PopularThreads = ({ subplebbits }: { subplebbits: any }) => { ); }; +// temporary hook to fetch subplebbit stats +// Assuming useSubplebbitsStats and its Zustand store are defined as shown previously +function useSubplebbitsStats(options: any) { + const { subplebbitAddresses, accountName } = options || {}; + const account = useAccount({ accountName }); + const { subplebbits } = useSubplebbits({ subplebbitAddresses }); + + const { setSubplebbitStats, subplebbitsStats } = useSubplebbitsStatsStore(); + + useEffect(() => { + if (!subplebbitAddresses || subplebbitAddresses.length === 0 || !account) { + return; + } + + subplebbits.forEach((subplebbit) => { + if (subplebbit && subplebbit.statsCid && !subplebbitsStats[subplebbit.address]) { + // Only fetch stats if they haven't been fetched yet + account.plebbit + .fetchCid(subplebbit.statsCid) + .then((fetchedStats: any) => { + setSubplebbitStats(subplebbit.address, JSON.parse(fetchedStats)); + }) + .catch((error: any) => { + console.error('Fetching subplebbit stats failed', { subplebbitAddress: subplebbit.address, error }); + }); + } + }); + }, [subplebbitAddresses?.toString(), account?.id, subplebbits]); + + return useMemo(() => { + return subplebbitAddresses.reduce((acc: any, address: any) => { + acc[address] = subplebbitsStats[address] || { loading: true }; + return acc; + }, {}); + }, [subplebbitsStats, subplebbitAddresses?.toString()]); +} + +export type SubplebbitsStatsState = { + subplebbitsStats: { [subplebbitAddress: string]: any }; + setSubplebbitStats: Function; +}; + +const useSubplebbitsStatsStore = create((set) => ({ + subplebbitsStats: {}, + setSubplebbitStats: (subplebbitAddress: string, subplebbitStats: any) => + set((state) => ({ + subplebbitsStats: { ...state.subplebbitsStats, [subplebbitAddress]: subplebbitStats }, + })), +})); + const Stats = ({ multisub, subplebbitAddresses }: { multisub: any; subplebbitAddresses: string[] }) => { const { t } = useTranslation(); - // const { totalPosts, currentUsers, boardsTracked } = useSubplebbitStats(subplebbitAddresses); + const stats = useSubplebbitsStats({ subplebbitAddresses }); + + const allStatsLoaded = useMemo(() => { + return subplebbitAddresses.every((address) => stats[address]); + }, [stats, subplebbitAddresses]); + + const { totalPosts, currentUsers } = useMemo(() => { + let totalPosts = 0; + let currentUsers = 0; + + if (allStatsLoaded) { + Object.values(stats).forEach((stat: any) => { + totalPosts += stat.allPostCount || 0; + currentUsers += stat.weekActiveUserCount || 0; + }); + } + + return { totalPosts, currentUsers }; + }, [stats, allStatsLoaded]); + + const boardsTracked = Object.values(stats).filter((stat: any) => stat && !stat.loading).length; + const enoughStats = boardsTracked > multisub.length / 2; return (

{t('stats')}

-
+
{/*

{t('stats_info')}

*/} -
- Total Posts: x,xxx,xxx -
-
- Current Users: xxx,xxx -
-
- Boards Tracked: {multisub.length} -
+ {enoughStats ? ( + <> +
+ Total Posts: {totalPosts} +
+
+ Current Users: {currentUsers} +
+
+ Boards Tracked: {boardsTracked} +
+ + ) : ( + + )}
);