manifold/web/hooks/use-group.ts
James Grugett 54c227cf6c
Updates to experimental home (#858)
* Line clamp question in prob change table

* Tweaks

* Expand option for daily movers

* Snap scrolling for carousel

* Add arrows to section headers

* Remove carousel from experimental/home

* React querify fetching your groups

* Edit home is its own page

* Add daily profit and balance

* Merge branch 'main' into new-home

* Make experimental search by your followed groups/creators

* Just submit, allow xs on pills

* Weigh in

* Use next/future/image component to optimize avatar images

* Inga/challenge icon (#857)

* changed challenge icon to custom icon
* fixed tip button alignment

* weighing in and trading "weigh in" for "trade"

Co-authored-by: Ian Philips <iansphilips@gmail.com>
Co-authored-by: Austin Chen <akrolsmir@gmail.com>
Co-authored-by: ingawei <46611122+ingawei@users.noreply.github.com>
Co-authored-by: mantikoros <sgrugett@gmail.com>
2022-09-08 01:36:34 -05:00

126 lines
3.2 KiB
TypeScript

import { useEffect, useState } from 'react'
import { Group } from 'common/group'
import { User } from 'common/user'
import {
getMemberGroups,
GroupMemberDoc,
groupMembers,
listenForGroup,
listenForGroupContractDocs,
listenForGroups,
listenForMemberGroupIds,
listenForOpenGroups,
listGroups,
} from 'web/lib/firebase/groups'
import { getUser } from 'web/lib/firebase/users'
import { filterDefined } from 'common/util/array'
import { Contract } from 'common/contract'
import { uniq } from 'lodash'
import { listenForValues } from 'web/lib/firebase/utils'
import { useQuery } from 'react-query'
export const useGroup = (groupId: string | undefined) => {
const [group, setGroup] = useState<Group | null | undefined>()
useEffect(() => {
if (groupId) return listenForGroup(groupId, setGroup)
}, [groupId])
return group
}
export const useGroups = () => {
const [groups, setGroups] = useState<Group[] | undefined>()
useEffect(() => {
return listenForGroups(setGroups)
}, [])
return groups
}
export const useOpenGroups = () => {
const [groups, setGroups] = useState<Group[]>([])
useEffect(() => {
return listenForOpenGroups(setGroups)
}, [])
return groups
}
export const useMemberGroups = (userId: string | null | undefined) => {
const result = useQuery(['member-groups', userId ?? ''], () =>
getMemberGroups(userId ?? '')
)
return result.data
}
// Note: We cache member group ids in localstorage to speed up the initial load
export const useMemberGroupIds = (user: User | null | undefined) => {
const [memberGroupIds, setMemberGroupIds] = useState<string[] | undefined>(
undefined
)
useEffect(() => {
if (user) {
return listenForMemberGroupIds(user.id, (groupIds) => {
setMemberGroupIds(groupIds)
})
}
}, [user])
return memberGroupIds
}
export function useMembers(groupId: string | undefined) {
const [members, setMembers] = useState<User[]>([])
useEffect(() => {
if (groupId)
listenForValues<GroupMemberDoc>(groupMembers(groupId), (memDocs) => {
const memberIds = memDocs.map((memDoc) => memDoc.userId)
Promise.all(memberIds.map((id) => getUser(id))).then((users) => {
setMembers(users)
})
})
}, [groupId])
return members
}
export function useMemberIds(groupId: string | null) {
const [memberIds, setMemberIds] = useState<string[]>([])
useEffect(() => {
if (groupId)
return listenForValues<GroupMemberDoc>(groupMembers(groupId), (docs) => {
setMemberIds(docs.map((doc) => doc.userId))
})
}, [groupId])
return memberIds
}
export const useGroupsWithContract = (contract: Contract) => {
const [groups, setGroups] = useState<Group[]>([])
useEffect(() => {
if (contract.groupSlugs)
listGroups(uniq(contract.groupSlugs)).then((groups) =>
setGroups(filterDefined(groups))
)
}, [contract.groupSlugs])
return groups
}
export function useGroupContractIds(groupId: string) {
const [contractIds, setContractIds] = useState<string[]>([])
useEffect(() => {
if (groupId)
return listenForGroupContractDocs(groupId, (docs) =>
setContractIds(docs.map((doc) => doc.contractId))
)
}, [groupId])
return contractIds
}