Compute fold follower count from cloud function.
This commit is contained in:
parent
e4377ee3a3
commit
ef8157025f
|
@ -15,4 +15,6 @@ export type Fold = {
|
||||||
// Default: creatorIds: undefined, excludedCreatorIds: []
|
// Default: creatorIds: undefined, excludedCreatorIds: []
|
||||||
creatorIds?: string[]
|
creatorIds?: string[]
|
||||||
excludedCreatorIds?: string[]
|
excludedCreatorIds?: string[]
|
||||||
|
|
||||||
|
followCount: number
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,10 +62,13 @@ export const createFold = functions.runWith({ minInstances: 1 }).https.onCall(
|
||||||
contractIds: [],
|
contractIds: [],
|
||||||
excludedContractIds: [],
|
excludedContractIds: [],
|
||||||
excludedCreatorIds: [],
|
excludedCreatorIds: [],
|
||||||
|
followCount: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
await foldRef.create(fold)
|
await foldRef.create(fold)
|
||||||
|
|
||||||
|
await foldRef.collection('followers').doc(userId).set({ userId })
|
||||||
|
|
||||||
return { status: 'success', fold }
|
return { status: 'success', fold }
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,6 +11,7 @@ export * from './sell-bet'
|
||||||
export * from './create-contract'
|
export * from './create-contract'
|
||||||
export * from './create-user'
|
export * from './create-user'
|
||||||
export * from './create-fold'
|
export * from './create-fold'
|
||||||
|
export * from './on-fold-follow'
|
||||||
export * from './unsubscribe'
|
export * from './unsubscribe'
|
||||||
export * from './update-contract-metrics'
|
export * from './update-contract-metrics'
|
||||||
export * from './update-user-metrics'
|
export * from './update-user-metrics'
|
||||||
|
|
17
functions/src/on-fold-follow.ts
Normal file
17
functions/src/on-fold-follow.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import * as functions from 'firebase-functions'
|
||||||
|
import * as admin from 'firebase-admin'
|
||||||
|
|
||||||
|
const firestore = admin.firestore()
|
||||||
|
|
||||||
|
export const onFoldFollow = functions.firestore
|
||||||
|
.document('folds/{foldId}/followers/{userId}')
|
||||||
|
.onWrite(async (change, context) => {
|
||||||
|
const { foldId } = context.params
|
||||||
|
|
||||||
|
const snapshot = await firestore
|
||||||
|
.collection(`folds/${foldId}/followers`)
|
||||||
|
.get()
|
||||||
|
const followCount = snapshot.size
|
||||||
|
|
||||||
|
await firestore.doc(`folds/${foldId}`).update({ followCount })
|
||||||
|
})
|
|
@ -41,7 +41,8 @@ export default function Folds(props: {
|
||||||
}) {
|
}) {
|
||||||
const [curatorsDict, setCuratorsDict] = useState(props.curatorsDict)
|
const [curatorsDict, setCuratorsDict] = useState(props.curatorsDict)
|
||||||
|
|
||||||
const folds = useFolds() ?? props.folds
|
let folds = useFolds() ?? props.folds
|
||||||
|
folds = _.sortBy(folds, (fold) => -1 * fold.followCount)
|
||||||
const user = useUser()
|
const user = useUser()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -74,31 +75,11 @@ export default function Folds(props: {
|
||||||
|
|
||||||
<Col className="gap-2">
|
<Col className="gap-2">
|
||||||
{folds.map((fold) => (
|
{folds.map((fold) => (
|
||||||
<Col
|
<FoldCard
|
||||||
key={fold.id}
|
key={fold.id}
|
||||||
className="bg-white p-4 rounded-xl gap-1 relative"
|
fold={fold}
|
||||||
>
|
curator={curatorsDict[fold.curatorId]}
|
||||||
<Link href={foldPath(fold)}>
|
/>
|
||||||
<a className="absolute left-0 right-0 top-0 bottom-0" />
|
|
||||||
</Link>
|
|
||||||
<Row className="justify-between items-center gap-2">
|
|
||||||
<SiteLink href={foldPath(fold)}>{fold.name}</SiteLink>
|
|
||||||
<FollowFoldButton className="z-10 mb-1" fold={fold} />
|
|
||||||
</Row>
|
|
||||||
<Row className="items-center gap-2 text-gray-500 text-sm">
|
|
||||||
<div>12 followers</div>
|
|
||||||
<div>•</div>
|
|
||||||
<Row>
|
|
||||||
<div className="mr-1">Curated by</div>
|
|
||||||
<UserLink
|
|
||||||
className="text-neutral"
|
|
||||||
name={curatorsDict[fold.curatorId]?.name ?? ''}
|
|
||||||
username={curatorsDict[fold.curatorId]?.username ?? ''}
|
|
||||||
/>
|
|
||||||
</Row>
|
|
||||||
</Row>
|
|
||||||
<div className="text-gray-500 text-sm">{fold.about}</div>
|
|
||||||
</Col>
|
|
||||||
))}
|
))}
|
||||||
</Col>
|
</Col>
|
||||||
</Col>
|
</Col>
|
||||||
|
@ -106,3 +87,34 @@ export default function Folds(props: {
|
||||||
</Page>
|
</Page>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function FoldCard(props: { fold: Fold; curator: User | undefined }) {
|
||||||
|
const { fold, curator } = props
|
||||||
|
return (
|
||||||
|
<Col
|
||||||
|
key={fold.id}
|
||||||
|
className="bg-white p-4 rounded-xl gap-1 shadow-md relative"
|
||||||
|
>
|
||||||
|
<Link href={foldPath(fold)}>
|
||||||
|
<a className="absolute left-0 right-0 top-0 bottom-0" />
|
||||||
|
</Link>
|
||||||
|
<Row className="justify-between items-center gap-2">
|
||||||
|
<SiteLink href={foldPath(fold)}>{fold.name}</SiteLink>
|
||||||
|
<FollowFoldButton className="z-10 mb-1" fold={fold} />
|
||||||
|
</Row>
|
||||||
|
<Row className="items-center gap-2 text-gray-500 text-sm">
|
||||||
|
<div>{fold.followCount} followers</div>
|
||||||
|
<div>•</div>
|
||||||
|
<Row>
|
||||||
|
<div className="mr-1">Curated by</div>
|
||||||
|
<UserLink
|
||||||
|
className="text-neutral"
|
||||||
|
name={curator?.name ?? ''}
|
||||||
|
username={curator?.username ?? ''}
|
||||||
|
/>
|
||||||
|
</Row>
|
||||||
|
</Row>
|
||||||
|
<div className="text-gray-500 text-sm">{fold.about}</div>
|
||||||
|
</Col>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user