diff --git a/web/components/follow-fold-button.tsx b/web/components/follow-fold-button.tsx index f394aae9..6649aad8 100644 --- a/web/components/follow-fold-button.tsx +++ b/web/components/follow-fold-button.tsx @@ -1,6 +1,6 @@ import clsx from 'clsx' import { Fold } from '../../common/fold' -import { useFollowingFold } from '../hooks/use-fold' +import { useFollowedFolds } from '../hooks/use-fold' import { useUser } from '../hooks/use-user' import { followFold, unfollowFold } from '../lib/firebase/folds' @@ -8,7 +8,11 @@ export function FollowFoldButton(props: { fold: Fold; className?: string }) { const { fold, className } = props const user = useUser() - const following = useFollowingFold(fold, user) + + const followedFoldIds = useFollowedFolds(user) + const following = followedFoldIds + ? followedFoldIds.includes(fold.id) + : undefined const onFollow = () => { if (user) followFold(fold.id, user.id) diff --git a/web/hooks/use-active-contracts.ts b/web/hooks/use-active-contracts.ts index 67bb8574..0bd099e2 100644 --- a/web/hooks/use-active-contracts.ts +++ b/web/hooks/use-active-contracts.ts @@ -1,4 +1,5 @@ import _ from 'lodash' +import { useRef } from 'react' import { Fold } from '../../common/fold' import { User } from '../../common/user' @@ -50,8 +51,11 @@ export const useActiveContracts = ( ) ) - const followedFoldSlugs = - followedFoldIds === undefined ? undefined : followedFolds.map((f) => f.slug) + // Save the initial followed fold slugs. + const followedFoldSlugsRef = useRef() + if (followedFoldIds && !followedFoldSlugsRef.current) + followedFoldSlugsRef.current = followedFolds.map((f) => f.slug) + const initialFollowedFoldSlugs = followedFoldSlugsRef.current const tagSet = new Set( _.flatten(followedFolds.map((fold) => fold.lowercaseTags)) @@ -97,5 +101,10 @@ export const useActiveContracts = ( (contract) => commentsByContract[contract.id] ?? [] ) - return { activeContracts, activeBets, activeComments, followedFoldSlugs } + return { + activeContracts, + activeBets, + activeComments, + initialFollowedFoldSlugs, + } } diff --git a/web/hooks/use-fold.ts b/web/hooks/use-fold.ts index 2bbe6e23..683b364a 100644 --- a/web/hooks/use-fold.ts +++ b/web/hooks/use-fold.ts @@ -2,11 +2,11 @@ import { useEffect, useState } from 'react' import { Fold } from '../../common/fold' import { User } from '../../common/user' import { - getFollowedFolds, listenForFold, listenForFolds, listenForFoldsWithTags, listenForFollow, + listenForFollowedFolds, } from '../lib/firebase/folds' export const useFold = (foldId: string | undefined) => { @@ -62,7 +62,7 @@ export const useFollowedFolds = (user: User | null | undefined) => { setFollowedFoldIds(JSON.parse(followedFoldJson)) } - getFollowedFolds(user.id).then((foldIds) => { + return listenForFollowedFolds(user.id, (foldIds) => { setFollowedFoldIds(foldIds) localStorage.setItem(key, JSON.stringify(foldIds)) }) diff --git a/web/lib/firebase/folds.ts b/web/lib/firebase/folds.ts index d1170565..7ca4e912 100644 --- a/web/lib/firebase/folds.ts +++ b/web/lib/firebase/folds.ts @@ -4,6 +4,7 @@ import { deleteDoc, doc, getDocs, + onSnapshot, query, setDoc, updateDoc, @@ -201,3 +202,20 @@ export async function getFollowedFolds(userId: string) { ) return foldIds } + +export function listenForFollowedFolds( + userId: string, + setFoldIds: (foldIds: string[]) => void +) { + return onSnapshot( + query(collectionGroup(db, 'followers'), where('userId', '==', userId)), + (snapshot) => { + if (snapshot.metadata.fromCache) return + + const foldIds = snapshot.docs.map( + (doc) => doc.ref.parent.parent?.id as string + ) + setFoldIds(foldIds) + } + ) +} diff --git a/web/pages/home.tsx b/web/pages/home.tsx index ffadaf2a..4a91fd59 100644 --- a/web/pages/home.tsx +++ b/web/pages/home.tsx @@ -37,8 +37,12 @@ const Home = (props: { }) => { const user = useUser() - const { activeContracts, activeBets, activeComments, followedFoldSlugs } = - useActiveContracts(props, user) + const { + activeContracts, + activeBets, + activeComments, + initialFollowedFoldSlugs, + } = useActiveContracts(props, user) if (user === null) { Router.replace('/') @@ -52,11 +56,11 @@ const Home = (props: { - {followedFoldSlugs !== undefined && - followedFoldSlugs.length === 0 && ( + {initialFollowedFoldSlugs !== undefined && + initialFollowedFoldSlugs.length === 0 && ( )}