Remove group details cache, update group directly

This commit is contained in:
Ian Philips 2022-06-22 17:19:17 -05:00
parent e5e13cc598
commit 6a35d3bf2d
8 changed files with 60 additions and 51 deletions

View File

@ -1,6 +1,5 @@
import { Answer } from './answer'
import { Fees } from './fees'
import { GroupDetails } from 'common/group'
export type AnyMechanism = DPM | CPMM
export type AnyOutcomeType = Binary | FreeResponse | Numeric
@ -25,8 +24,6 @@ export type Contract<T extends AnyContractType = AnyContractType> = {
lowercaseTags: string[]
visibility: 'public' | 'unlisted'
groupDetails?: GroupDetails[] // Starting with one group per contract
createdTime: number // Milliseconds since epoch
lastUpdatedTime?: number // Updated on new bet or comment
lastBetTime?: number

View File

@ -13,9 +13,3 @@ export type Group = {
export const MAX_GROUP_NAME_LENGTH = 75
export const MAX_ABOUT_LENGTH = 140
export const MAX_ID_LENGTH = 60
export type GroupDetails = {
groupId: string
groupSlug: string
groupName: string
}

View File

@ -11,7 +11,6 @@ import {
import { User } from './user'
import { parseTags } from './util/parse'
import { removeUndefinedProps } from './util/object'
import { GroupDetails } from 'common/group'
export function getNewContract(
id: string,
@ -28,8 +27,7 @@ export function getNewContract(
// used for numeric markets
bucketCount: number,
min: number,
max: number,
groupDetails?: GroupDetails
max: number
) {
const tags = parseTags(
`${question} ${description} ${extraTags.map((tag) => `#${tag}`).join(' ')}`
@ -71,7 +69,6 @@ export function getNewContract(
liquidityFee: 0,
platformFee: 0,
},
groupDetails: groupDetails ? [groupDetails] : undefined,
})
return contract as Contract

View File

@ -77,19 +77,6 @@ export const createmarket = newEndpoint(['POST'], async (req, auth) => {
}
const user = userDoc.data() as User
let group = null
if (groupId) {
const groupDoc = await firestore.collection('groups').doc(groupId).get()
if (!groupDoc.exists) {
throw new APIError(400, 'No group exists with the given group ID.')
}
group = groupDoc.data() as Group
if (!group.memberIds.includes(user.id)) {
throw new APIError(400, 'User is not a member of the group.')
}
}
const userContractsCreatedTodaySnapshot = await firestore
.collection(`contracts`)
.where('creatorId', '==', auth.uid)
@ -104,6 +91,30 @@ export const createmarket = newEndpoint(['POST'], async (req, auth) => {
if (ante > user.balance && !isFree)
throw new APIError(400, `Balance must be at least ${ante}.`)
const slug = await getSlug(question)
const contractRef = firestore.collection('contracts').doc()
let group = null
if (groupId) {
const groupDocRef = await firestore.collection('groups').doc(groupId)
const groupDoc = await groupDocRef.get()
if (!groupDoc.exists) {
throw new APIError(400, 'No group exists with the given group ID.')
}
group = groupDoc.data() as Group
if (!group.memberIds.includes(user.id)) {
throw new APIError(
400,
'User must be a member of the group to add markets to it.'
)
}
if (!group.contractIds.includes(contractRef.id))
await groupDocRef.update({
contractIds: [...group.contractIds, contractRef.id],
})
}
console.log(
'creating contract for',
user.username,
@ -113,8 +124,6 @@ export const createmarket = newEndpoint(['POST'], async (req, auth) => {
ante || 0
)
const slug = await getSlug(question)
const contractRef = firestore.collection('contracts').doc()
const contract = getNewContract(
contractRef.id,
slug,
@ -128,14 +137,7 @@ export const createmarket = newEndpoint(['POST'], async (req, auth) => {
tags ?? [],
NUMERIC_BUCKET_COUNT,
min ?? 0,
max ?? 0,
group
? {
groupId: group.id,
groupName: group.name,
groupSlug: group.slug,
}
: undefined
max ?? 0
)
if (!isFree && ante) await chargeUser(user.id, ante, true)

View File

@ -28,6 +28,7 @@ import { UserFollowButton } from '../follow-button'
import { groupPath } from 'web/lib/firebase/groups'
import { SiteLink } from 'web/components/site-link'
import { DAY_MS } from 'common/util/time'
import { useGroupsWithContract } from 'web/hooks/use-group'
export function MiscDetails(props: {
contract: Contract
@ -110,10 +111,10 @@ export function ContractDetails(props: {
disabled?: boolean
}) {
const { contract, bets, isCreator, disabled } = props
const { closeTime, creatorName, creatorUsername, creatorId, groupDetails } =
contract
const { closeTime, creatorName, creatorUsername, creatorId } = contract
const { volumeLabel, resolvedDate } = contractMetrics(contract)
// Find a group that this contract id is in
const groups = useGroupsWithContract(contract.id)
return (
<Row className="flex-1 flex-wrap items-center gap-x-4 gap-y-2 text-sm text-gray-500">
<Row className="items-center gap-2">
@ -134,11 +135,12 @@ export function ContractDetails(props: {
)}
{!disabled && <UserFollowButton userId={creatorId} small />}
</Row>
{groupDetails && (
{/*// TODO: we can add contracts to multiple groups but only show the first it was added to*/}
{groups && groups.length > 0 && (
<Row className={'line-clamp-1 mt-1 max-w-[200px]'}>
<SiteLink href={`${groupPath(groupDetails[0].groupSlug)}`}>
<SiteLink href={`${groupPath(groups[0].slug)}`}>
<UserGroupIcon className="mx-1 mb-1 inline h-5 w-5" />
<span>{groupDetails[0].groupName}</span>
<span>{groups[0].name}</span>
</SiteLink>
</Row>
)}

View File

@ -2,6 +2,7 @@ import { useEffect, useState } from 'react'
import { Group } from 'common/group'
import { User } from 'common/user'
import {
getGroupsWithContractId,
listenForGroup,
listenForGroups,
listenForMemberGroups,
@ -76,3 +77,13 @@ export function useMembers(group: Group) {
}, [group])
return members
}
export const useGroupsWithContract = (contractId: string | undefined) => {
const [groups, setGroups] = useState<Group[] | null | undefined>()
useEffect(() => {
if (contractId) getGroupsWithContractId(contractId, setGroups)
}, [contractId])
return groups
}

View File

@ -1,7 +1,9 @@
import {
collection,
collectionGroup,
deleteDoc,
doc,
orderBy,
query,
updateDoc,
where,
@ -82,3 +84,15 @@ export function listenForMemberGroups(
setGroups(sorted)
})
}
export async function getGroupsWithContractId(
contractId: string,
setGroups: (groups: Group[]) => void
) {
const q = query(
groupCollection,
where('contractIds', 'array-contains', contractId)
)
const groups = await getValues<Group>(q)
setGroups(groups)
}

View File

@ -451,15 +451,7 @@ function AddContractButton(props: { group: Group; user: User }) {
useEffect(() => {
return listenForUserContracts(user.id, (contracts) => {
setContracts(
contracts.filter(
(c) =>
!group.contractIds.includes(c.id) &&
// TODO: It'll be easy to allow questions to be in multiple groups as long as we
// have the on-update-group function update the newly added contract's groupDetails (via contractIds)
!c.groupDetails
)
)
setContracts(contracts.filter((c) => !group.contractIds.includes(c.id)))
})
}, [group.contractIds, user.id])