manifold/web/lib/firebase/bets.ts
2022-01-03 18:12:13 -08:00

96 lines
2.1 KiB
TypeScript

import {
collection,
collectionGroup,
query,
onSnapshot,
where,
doc,
updateDoc,
} from 'firebase/firestore'
import { db } from './init'
import { User } from './users'
export type Bet = {
id: string
userId: string
contractId: string
amount: number // bet size; negative if SELL bet
outcome: 'YES' | 'NO'
shares: number // dynamic parimutuel pool weight; negative if SELL bet
probBefore: number
probAfter: number
sale?: {
amount: number // amount user makes from sale
betId: string // id of bet being sold
// TODO: add sale time?
}
isSold?: boolean // true if this BUY bet has been sold
createdTime: number
// Currently, comments are created after the bet, not atomically with the bet.
comment?: {
text: string
createdTime: number
// Denormalized, for rendering comments
userName?: string
userUsername?: string
userAvatarUrl?: string
}
}
function getBetsCollection(contractId: string) {
return collection(db, 'contracts', contractId, 'bets')
}
export function listenForBets(
contractId: string,
setBets: (bets: Bet[]) => void
) {
return onSnapshot(getBetsCollection(contractId), (snap) => {
const bets = snap.docs.map((doc) => doc.data() as Bet)
bets.sort((bet1, bet2) => bet1.createdTime - bet2.createdTime)
setBets(bets)
})
}
export function listenForUserBets(
userId: string,
setBets: (bets: Bet[]) => void
) {
const userQuery = query(
collectionGroup(db, 'bets'),
where('userId', '==', userId)
)
return onSnapshot(userQuery, (snap) => {
const bets = snap.docs.map((doc) => doc.data() as Bet)
bets.sort((bet1, bet2) => bet1.createdTime - bet2.createdTime)
setBets(bets)
})
}
export async function createComment(
contractId: string,
betId: string,
text: string,
commenter: User
) {
const betRef = doc(getBetsCollection(contractId), betId)
return await updateDoc(betRef, {
comment: {
text: text,
createdTime: Date.now(),
userName: commenter.name,
userUsername: commenter.username,
userAvatarUrl: commenter.avatarUrl,
},
})
}