Listen for new folds on /folds

This commit is contained in:
jahooma 2022-01-23 23:47:20 -06:00
parent f66bc6af4d
commit bc3e43802b
3 changed files with 57 additions and 15 deletions

View File

@ -1,6 +1,6 @@
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { Fold } from '../../common/fold' import { Fold } from '../../common/fold'
import { listenForFold } from '../lib/firebase/folds' import { listenForFold, listenForFolds } from '../lib/firebase/folds'
export const useFold = (foldId: string) => { export const useFold = (foldId: string) => {
const [fold, setFold] = useState<Fold | null | undefined>() const [fold, setFold] = useState<Fold | null | undefined>()
@ -11,3 +11,13 @@ export const useFold = (foldId: string) => {
return fold return fold
} }
export const useFolds = () => {
const [folds, setFolds] = useState<Fold[] | undefined>()
useEffect(() => {
return listenForFolds(setFolds)
}, [])
return folds
}

View File

@ -2,7 +2,7 @@ import { collection, doc, query, updateDoc, where } from 'firebase/firestore'
import { Fold } from '../../../common/fold' import { Fold } from '../../../common/fold'
import { Contract, contractCollection } from './contracts' import { Contract, contractCollection } from './contracts'
import { db } from './init' import { db } from './init'
import { getValues, listenForValue } from './utils' import { getValues, listenForValue, listenForValues } from './utils'
const foldCollection = collection(db, 'folds') const foldCollection = collection(db, 'folds')
@ -21,6 +21,10 @@ export async function listAllFolds() {
return getValues<Fold>(foldCollection) return getValues<Fold>(foldCollection)
} }
export function listenForFolds(setFolds: (folds: Fold[]) => void) {
return listenForValues(foldCollection, setFolds)
}
export async function getFoldBySlug(slug: string) { export async function getFoldBySlug(slug: string) {
const q = query(foldCollection, where('slug', '==', slug)) const q = query(foldCollection, where('slug', '==', slug))
const folds = await getValues<Fold>(q) const folds = await getValues<Fold>(q)

View File

@ -1,7 +1,7 @@
import clsx from 'clsx' import clsx from 'clsx'
import _ from 'lodash' import _ from 'lodash'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { useState } from 'react' import { useEffect, useState } from 'react'
import { Fold } from '../../common/fold' import { Fold } from '../../common/fold'
import { parseWordsAsTags } from '../../common/util/parse' import { parseWordsAsTags } from '../../common/util/parse'
import { ConfirmationButton } from '../components/confirmation-button' import { ConfirmationButton } from '../components/confirmation-button'
@ -13,6 +13,7 @@ import { SiteLink } from '../components/site-link'
import { TagsList } from '../components/tags-list' import { TagsList } from '../components/tags-list'
import { Title } from '../components/title' import { Title } from '../components/title'
import { UserLink } from '../components/user-page' import { UserLink } from '../components/user-page'
import { useFolds } from '../hooks/use-fold'
import { useUser } from '../hooks/use-user' import { useUser } from '../hooks/use-user'
import { createFold } from '../lib/firebase/api-call' import { createFold } from '../lib/firebase/api-call'
import { foldPath, listAllFolds } from '../lib/firebase/folds' import { foldPath, listAllFolds } from '../lib/firebase/folds'
@ -25,22 +26,44 @@ export async function getStaticProps() {
const curators = await Promise.all( const curators = await Promise.all(
folds.map((fold) => getUser(fold.curatorId)) folds.map((fold) => getUser(fold.curatorId))
) )
const curatorsDict = _.fromPairs(
curators.map((curator) => [curator.id, curator])
)
return { return {
props: { props: {
folds, folds,
curators, curatorsDict,
}, },
revalidate: 60, // regenerate after a minute revalidate: 60, // regenerate after a minute
} }
} }
export default function Folds(props: { folds: Fold[]; curators: User[] }) { export default function Folds(props: {
const { folds, curators } = props folds: Fold[]
curatorsDict: _.Dictionary<User>
}) {
const [curatorsDict, setCuratorsDict] = useState(props.curatorsDict)
const folds = useFolds() ?? props.folds
const user = useUser() const user = useUser()
useEffect(() => {
// Load User object for curator of new Folds.
const newFolds = folds.filter(({ curatorId }) => !curatorsDict[curatorId])
if (newFolds.length > 0) {
Promise.all(newFolds.map(({ curatorId }) => getUser(curatorId))).then(
(newUsers) => {
const newUsersDict = _.fromPairs(
newUsers.map((user) => [user.id, user])
)
setCuratorsDict({ ...curatorsDict, ...newUsersDict })
}
)
}
})
return ( return (
<Page> <Page>
<Col className="items-center"> <Col className="items-center">
@ -51,7 +74,7 @@ export default function Folds(props: { folds: Fold[]; curators: User[] }) {
</Row> </Row>
<Col className="gap-4"> <Col className="gap-4">
{folds.map((fold, index) => ( {folds.map((fold) => (
<Row key={fold.id} className="items-center gap-2"> <Row key={fold.id} className="items-center gap-2">
<SiteLink href={foldPath(fold)}>{fold.name}</SiteLink> <SiteLink href={foldPath(fold)}>{fold.name}</SiteLink>
<div /> <div />
@ -61,8 +84,8 @@ export default function Folds(props: { folds: Fold[]; curators: User[] }) {
<div className="text-sm text-gray-500 mr-1">Curated by</div> <div className="text-sm text-gray-500 mr-1">Curated by</div>
<UserLink <UserLink
className="text-sm text-neutral" className="text-sm text-neutral"
name={curators[index].name} name={curatorsDict[fold.curatorId]?.name ?? ''}
username={curators[index].username} username={curatorsDict[fold.curatorId]?.username ?? ''}
/> />
</Row> </Row>
</Row> </Row>
@ -94,10 +117,15 @@ function CreateFoldButton() {
tags: parseWordsAsTags(tags), tags: parseWordsAsTags(tags),
}).then((r) => r.data || {}) }).then((r) => r.data || {})
if (result.fold) await router.push(foldPath(result.fold)) if (result.fold) {
else console.log(result.status, result.message) await router.push(foldPath(result.fold)).catch((e) => {
console.log(e)
setIsSubmitting(false) setIsSubmitting(false)
})
} else {
console.log(result.status, result.message)
setIsSubmitting(false)
}
} }
return ( return (
@ -125,7 +153,7 @@ function CreateFoldButton() {
<Spacer h={4} /> <Spacer h={4} />
<form> <div>
<div className="form-control w-full"> <div className="form-control w-full">
<label className="label"> <label className="label">
<span className="mb-1">Fold name</span> <span className="mb-1">Fold name</span>
@ -167,7 +195,7 @@ function CreateFoldButton() {
/> />
</> </>
)} )}
</form> </div>
</ConfirmationButton> </ConfirmationButton>
) )
} }