Add discover tab of users based on markets you have bet on

This commit is contained in:
James Grugett 2022-06-07 23:42:42 -05:00
parent ac763de16b
commit ad6594f0bc
3 changed files with 59 additions and 2 deletions

View File

@ -3,11 +3,12 @@ import { PencilIcon } from '@heroicons/react/outline'
import { User } from 'common/user'
import { useEffect, useState } from 'react'
import { useFollowers, useFollows } from 'web/hooks/use-follows'
import { prefetchUsers } from 'web/hooks/use-user'
import { prefetchUsers, useUser } from 'web/hooks/use-user'
import { FollowList } from './follow-list'
import { Col } from './layout/col'
import { Modal } from './layout/modal'
import { Tabs } from './layout/tabs'
import { useDiscoverUsers } from 'web/hooks/use-users'
export function FollowingButton(props: { user: User }) {
const { user } = props
@ -114,6 +115,13 @@ function FollowingFollowersDialog(props: {
prefetchUsers([...followingIds, ...followerIds])
}, [followingIds, followerIds])
const currentUser = useUser()
const discoverUserIds = useDiscoverUsers()
useEffect(() => {
prefetchUsers(discoverUserIds)
}, [discoverUserIds])
return (
<Modal open={isOpen} setOpen={setIsOpen}>
<Col className="rounded bg-white p-6">
@ -129,6 +137,14 @@ function FollowingFollowersDialog(props: {
title: 'Followers',
content: <FollowList userIds={followerIds} />,
},
...(currentUser
? [
{
title: 'Discover',
content: <FollowList userIds={discoverUserIds} />,
},
]
: []),
]}
defaultIndex={defaultTab === 'following' ? 0 : 1}
/>

View File

@ -5,6 +5,10 @@ import {
listenForAllUsers,
listenForPrivateUsers,
} from 'web/lib/firebase/users'
import { useUser } from './use-user'
import { groupBy, sortBy, difference } from 'lodash'
import { getContractsOfUserBets } from 'web/lib/firebase/bets'
import { useFollows } from './use-follows'
export const useUsers = () => {
const [users, setUsers] = useState<User[]>([])
@ -37,3 +41,29 @@ export const usePrivateUsers = () => {
return users
}
export const useDiscoverUsers = () => {
const user = useUser()
const [discoverUserIds, setDiscoverUserIds] = useState<string[]>([])
useEffect(() => {
if (user)
getContractsOfUserBets(user.id).then((contracts) => {
const creatorCounts = Object.entries(
groupBy(contracts, 'creatorId')
).map(([id, contracts]) => [id, contracts.length] as const)
const topCreatorIds = sortBy(creatorCounts, ([_, i]) => i)
.map(([id]) => id)
.reverse()
setDiscoverUserIds(topCreatorIds)
})
}, [user])
const followedUserIds = useFollows(user?.id)
const nonSuggestions = [user?.id ?? '', ...(followedUserIds ?? [])]
return difference(discoverUserIds, nonSuggestions).slice(0, 50)
}

View File

@ -5,12 +5,14 @@ import {
where,
orderBy,
} from 'firebase/firestore'
import { range } from 'lodash'
import { range, uniq } from 'lodash'
import { db } from './init'
import { Bet } from 'common/bet'
import { Contract } from 'common/contract'
import { getValues, listenForValues } from './utils'
import { getContractFromId } from './contracts'
import { filterDefined } from 'common/util/array'
export type { Bet }
function getBetsCollection(contractId: string) {
@ -76,6 +78,15 @@ export async function getUserBets(
.catch((reason) => reason)
}
export async function getContractsOfUserBets(userId: string) {
const bets: Bet[] = await getUserBets(userId, { includeRedemptions: false })
const contractIds = uniq(bets.map((bet) => bet.contractId))
const contracts = await Promise.all(
contractIds.map((contractId) => getContractFromId(contractId))
)
return filterDefined(contracts)
}
export function listenForUserBets(
userId: string,
setBets: (bets: Bet[]) => void,