From 096a9e773ac58c0cdb4d35860b8daee128f39fdf Mon Sep 17 00:00:00 2001 From: mantikoros Date: Sat, 19 Feb 2022 18:02:40 -0600 Subject: [PATCH] refactor /home logic to useActiveContracts --- web/hooks/use-active-contracts.ts | 99 +++++++++++++++++++++++++++++ web/pages/home.tsx | 100 ++++++------------------------ 2 files changed, 118 insertions(+), 81 deletions(-) create mode 100644 web/hooks/use-active-contracts.ts diff --git a/web/hooks/use-active-contracts.ts b/web/hooks/use-active-contracts.ts new file mode 100644 index 00000000..d9bdb576 --- /dev/null +++ b/web/hooks/use-active-contracts.ts @@ -0,0 +1,99 @@ +import _ from 'lodash' + +import { Fold } from '../../common/fold' +import { User } from '../../common/user' +import { filterDefined } from '../../common/util/array' +import { Bet, getRecentBets } from '../lib/firebase/bets' +import { Comment, getRecentComments } from '../lib/firebase/comments' +import { Contract, listAllContracts } from '../lib/firebase/contracts' +import { listAllFolds } from '../lib/firebase/folds' +import { findActiveContracts } from '../pages/activity' +import { useUpdatedContracts } from './use-contracts' +import { useFollowedFolds } from './use-fold' +import { useUserBetContracts } from './use-user-bets' + +// used in static props +export const getAllContractInfo = async () => { + let [contracts, folds] = await Promise.all([ + listAllContracts().catch((_) => []), + listAllFolds().catch(() => []), + ]) + + const [recentBets, recentComments] = await Promise.all([ + getRecentBets(), + getRecentComments(), + ]) + + return { contracts, recentBets, recentComments, folds } +} + +export const useActiveContracts = ( + props: { + contracts: Contract[] + folds: Fold[] + recentBets: Bet[] + recentComments: Comment[] + }, + user: User | undefined | null +) => { + const contracts = useUpdatedContracts(props.contracts) + + const followedFoldIds = useFollowedFolds(user) + + const followedFolds = filterDefined( + (followedFoldIds ?? []).map((id) => + props.folds.find((fold) => fold.id === id) + ) + ) + + const followedFoldSlugs = + followedFoldIds === undefined ? undefined : followedFolds.map((f) => f.slug) + + const tagSet = new Set( + _.flatten(followedFolds.map((fold) => fold.lowercaseTags)) + ) + + const yourBetContractIds = useUserBetContracts(user?.id) + const yourBetContracts = yourBetContractIds + ? new Set(yourBetContractIds) + : undefined + + // Show no contracts before your info is loaded. + let feedContracts: Contract[] = [] + if (yourBetContracts && followedFoldIds) { + // Show all contracts if no folds are followed. + if (followedFoldIds.length === 0) feedContracts = contracts + else + feedContracts = contracts.filter( + (contract) => + contract.lowercaseTags.some((tag) => tagSet.has(tag)) || + yourBetContracts.has(contract.id) + ) + } + + const { recentComments, recentBets } = props + + const activeContracts = findActiveContracts( + feedContracts, + recentComments, + recentBets, + 365 + ) + + const betsByContract = _.groupBy(recentBets, (bet) => bet.contractId) + + const activeBets = activeContracts.map( + (contract) => betsByContract[contract.id] ?? [] + ) + + const commentsByContract = _.groupBy( + recentComments, + (comment) => comment.contractId + ) + + const activeComments = activeContracts.map( + (contract) => commentsByContract[contract.id] ?? [] + ) + + return { activeContracts, activeBets, activeComments, followedFoldSlugs } +} diff --git a/web/pages/home.tsx b/web/pages/home.tsx index 4cd19c94..ffadaf2a 100644 --- a/web/pages/home.tsx +++ b/web/pages/home.tsx @@ -1,46 +1,30 @@ import React from 'react' import Router from 'next/router' -import _ from 'lodash' -import { Contract, listAllContracts } from '../lib/firebase/contracts' +import { Contract } from '../lib/firebase/contracts' import { Page } from '../components/page' -import { ActivityFeed, findActiveContracts } from './activity' -import { Comment, getRecentComments } from '../lib/firebase/comments' -import { Bet, getRecentBets } from '../lib/firebase/bets' +import { ActivityFeed } from './activity' +import { Comment } from '../lib/firebase/comments' +import { Bet } from '../lib/firebase/bets' import FeedCreate from '../components/feed-create' import { Spacer } from '../components/layout/spacer' import { Col } from '../components/layout/col' import { useUser } from '../hooks/use-user' -import { useUpdatedContracts } from '../hooks/use-contracts' -import { listAllFolds } from '../lib/firebase/folds' import { Fold } from '../../common/fold' -import { filterDefined } from '../../common/util/array' -import { useUserBetContracts } from '../hooks/use-user-bets' import { LoadingIndicator } from '../components/loading-indicator' import { Row } from '../components/layout/row' import { SparklesIcon } from '@heroicons/react/solid' -import { useFollowedFolds } from '../hooks/use-fold' import { FastFoldFollowing } from '../components/fast-fold-following' +import { + getAllContractInfo, + useActiveContracts, +} from '../hooks/use-active-contracts' export async function getStaticProps() { - let [contracts, folds] = await Promise.all([ - listAllContracts().catch((_) => []), - listAllFolds().catch(() => []), - ]) - - const [recentBets, recentComments] = await Promise.all([ - getRecentBets(), - getRecentComments(), - ]) + const contractInfo = await getAllContractInfo() return { - props: { - contracts, - recentBets, - recentComments, - folds, - }, - + props: contractInfo, revalidate: 60, // regenerate after a minute } } @@ -51,57 +35,10 @@ const Home = (props: { recentBets: Bet[] recentComments: Comment[] }) => { - const { folds, recentBets, recentComments } = props - const user = useUser() - const contracts = useUpdatedContracts(props.contracts) - - const followedFoldIds = useFollowedFolds(user) - const followedFolds = filterDefined( - (followedFoldIds ?? []).map((id) => folds.find((fold) => fold.id === id)) - ) - const tagSet = new Set( - _.flatten(followedFolds.map((fold) => fold.lowercaseTags)) - ) - - const yourBetContractIds = useUserBetContracts(user?.id) - const yourBetContracts = yourBetContractIds - ? new Set(yourBetContractIds) - : undefined - - // Show no contracts before your info is loaded. - let feedContracts: Contract[] = [] - if (yourBetContracts && followedFoldIds) { - // Show all contracts if no folds are followed. - if (followedFoldIds.length === 0) feedContracts = contracts - else - feedContracts = contracts.filter( - (contract) => - contract.lowercaseTags.some((tag) => tagSet.has(tag)) || - yourBetContracts.has(contract.id) - ) - } - - const activeContracts = findActiveContracts( - feedContracts, - recentComments, - recentBets, - 365 - ) - - const betsByContract = _.groupBy(recentBets, (bet) => bet.contractId) - const activeBets = activeContracts.map( - (contract) => betsByContract[contract.id] ?? [] - ) - - const commentsByContract = _.groupBy( - recentComments, - (comment) => comment.contractId - ) - const activeComments = activeContracts.map( - (contract) => commentsByContract[contract.id] ?? [] - ) + const { activeContracts, activeBets, activeComments, followedFoldSlugs } = + useActiveContracts(props, user) if (user === null) { Router.replace('/') @@ -115,12 +52,13 @@ const Home = (props: { - {followedFoldIds !== undefined && followedFolds.length === 0 && ( - f.slug)} - /> - )} + {followedFoldSlugs !== undefined && + followedFoldSlugs.length === 0 && ( + + )}