Listen for new folds on /folds
This commit is contained in:
parent
f66bc6af4d
commit
bc3e43802b
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user