Listen for contract updates in folds feed

This commit is contained in:
James Grugett 2022-01-30 22:12:12 -06:00
parent 9d2b99f237
commit 00b7f3505f
4 changed files with 48 additions and 16 deletions

View File

@ -5,6 +5,7 @@ import {
listenForContracts, listenForContracts,
listenForHotContracts, listenForHotContracts,
} from '../lib/firebase/contracts' } from '../lib/firebase/contracts'
import { listenForTaggedContracts } from '../lib/firebase/folds'
export const useContracts = () => { export const useContracts = () => {
const [contracts, setContracts] = useState<Contract[] | undefined>() const [contracts, setContracts] = useState<Contract[] | undefined>()
@ -16,6 +17,21 @@ export const useContracts = () => {
return contracts return contracts
} }
export const useTaggedContracts = (tags: string[] | undefined) => {
const [contracts, setContracts] = useState<Contract[] | undefined>(
tags && tags.length === 0 ? [] : undefined
)
const tagsKey = tags?.map((tag) => tag.toLowerCase()).join(',') ?? ''
useEffect(() => {
if (!tags || tags.length === 0) return
return listenForTaggedContracts(tags, setContracts)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [tagsKey])
return contracts
}
export const useHotContracts = () => { export const useHotContracts = () => {
const [hotContracts, setHotContracts] = useState<Contract[] | undefined>() const [hotContracts, setHotContracts] = useState<Contract[] | undefined>()

View File

@ -45,6 +45,17 @@ export async function getFoldBySlug(slug: string) {
return folds.length === 0 ? null : folds[0] return folds.length === 0 ? null : folds[0]
} }
function contractsByTagsQuery(tags: string[]) {
return query(
contractCollection,
where(
'lowercaseTags',
'array-contains-any',
tags.map((tag) => tag.toLowerCase())
)
)
}
export async function getFoldContracts(fold: Fold) { export async function getFoldContracts(fold: Fold) {
const { const {
tags, tags,
@ -56,18 +67,7 @@ export async function getFoldContracts(fold: Fold) {
const [tagsContracts, includedContracts] = await Promise.all([ const [tagsContracts, includedContracts] = await Promise.all([
// TODO: if tags.length > 10, execute multiple parallel queries // TODO: if tags.length > 10, execute multiple parallel queries
tags.length > 0 tags.length > 0 ? getValues<Contract>(contractsByTagsQuery(tags)) : [],
? getValues<Contract>(
query(
contractCollection,
where(
'lowercaseTags',
'array-contains-any',
tags.map((tag) => tag.toLowerCase())
)
)
)
: [],
// TODO: if contractIds.length > 10, execute multiple parallel queries // TODO: if contractIds.length > 10, execute multiple parallel queries
contractIds.length > 0 contractIds.length > 0
@ -97,6 +97,13 @@ export async function getFoldContracts(fold: Fold) {
return [...approvedContracts, ...includedContracts] return [...approvedContracts, ...includedContracts]
} }
export function listenForTaggedContracts(
tags: string[],
setContracts: (contracts: Contract[]) => void
) {
return listenForValues<Contract>(contractsByTagsQuery(tags), setContracts)
}
export function listenForFold( export function listenForFold(
foldId: string, foldId: string,
setFold: (fold: Fold | null) => void setFold: (fold: Fold | null) => void

View File

@ -2,8 +2,8 @@ import { getFirestore } from '@firebase/firestore'
import { initializeApp, getApps, getApp } from 'firebase/app' import { initializeApp, getApps, getApp } from 'firebase/app'
// TODO: Reenable this when we have a way to set the Firebase db in dev // TODO: Reenable this when we have a way to set the Firebase db in dev
// export const isProd = process.env.NODE_ENV === 'production' export const isProd = process.env.NODE_ENV === 'production'
export const isProd = true // export const isProd = true
const firebaseConfig = isProd const firebaseConfig = isProd
? { ? {

View File

@ -34,6 +34,7 @@ import Custom404 from '../../404'
import { FollowFoldButton } from '../../../components/follow-fold-button' import { FollowFoldButton } from '../../../components/follow-fold-button'
import FeedCreate from '../../../components/feed-create' import FeedCreate from '../../../components/feed-create'
import { SEO } from '../../../components/SEO' import { SEO } from '../../../components/SEO'
import { useTaggedContracts } from '../../../hooks/use-contracts'
export async function getStaticProps(props: { params: { slugs: string[] } }) { export async function getStaticProps(props: { params: { slugs: string[] } }) {
const { slugs } = props.params const { slugs } = props.params
@ -133,8 +134,6 @@ export default function FoldPage(props: {
}) { }) {
const { const {
curator, curator,
contracts,
activeContracts,
activeContractBets, activeContractBets,
activeContractComments, activeContractComments,
topTraders, topTraders,
@ -157,6 +156,16 @@ export default function FoldPage(props: {
const user = useUser() const user = useUser()
const isCurator = user && fold && user.id === fold.curatorId const isCurator = user && fold && user.id === fold.curatorId
const taggedContracts = useTaggedContracts(fold?.tags) ?? props.contracts
const contractsMap = _.fromPairs(
taggedContracts.map((contract) => [contract.id, contract])
)
const contracts = props.contracts.map((contract) => contractsMap[contract.id])
const activeContracts = props.activeContracts.map(
(contract) => contractsMap[contract.id]
)
if (fold === null || !foldSubpages.includes(page) || slugs[2]) { if (fold === null || !foldSubpages.includes(page) || slugs[2]) {
return <Custom404 /> return <Custom404 />
} }