Add AnswerContract type to wrap FR, MCM, Bounty
This commit is contained in:
parent
49f60cdb80
commit
00717c90ef
|
@ -24,6 +24,7 @@ import {
|
|||
FreeResponseContract,
|
||||
PseudoNumericContract,
|
||||
MultipleChoiceContract,
|
||||
AnswerContract,
|
||||
} from './contract'
|
||||
import { floatingEqual } from './util/math'
|
||||
|
||||
|
@ -201,9 +202,7 @@ export function getContractBetNullMetrics() {
|
|||
}
|
||||
}
|
||||
|
||||
export function getTopAnswer(
|
||||
contract: FreeResponseContract | MultipleChoiceContract
|
||||
) {
|
||||
export function getTopAnswer(contract: AnswerContract) {
|
||||
const { answers } = contract
|
||||
const top = maxBy(
|
||||
answers?.map((answer) => ({
|
||||
|
|
|
@ -71,6 +71,10 @@ export type DPMContract = Contract & DPM
|
|||
export type CPMMContract = Contract & CPMM
|
||||
export type DPMBinaryContract = BinaryContract & DPM
|
||||
export type CPMMBinaryContract = BinaryContract & CPMM
|
||||
export type AnswerContract =
|
||||
| FreeResponseContract
|
||||
| MultipleChoiceContract
|
||||
| BountyContract
|
||||
|
||||
export type DPM = {
|
||||
mechanism: 'dpm-2'
|
||||
|
|
|
@ -15,6 +15,7 @@ import {
|
|||
getCpmmProbability,
|
||||
} from './calculate-cpmm'
|
||||
import {
|
||||
AnswerContract,
|
||||
CPMMBinaryContract,
|
||||
DPMBinaryContract,
|
||||
FreeResponseContract,
|
||||
|
@ -323,7 +324,7 @@ export const getNewBinaryDpmBetInfo = (
|
|||
export const getNewMultiBetInfo = (
|
||||
outcome: string,
|
||||
amount: number,
|
||||
contract: FreeResponseContract | MultipleChoiceContract,
|
||||
contract: AnswerContract,
|
||||
loanAmount: number
|
||||
) => {
|
||||
const { pool, totalShares, totalBets } = contract
|
||||
|
|
|
@ -3,6 +3,7 @@ import { sum, groupBy, sumBy, mapValues } from 'lodash'
|
|||
import { Bet, NumericBet } from './bet'
|
||||
import { deductDpmFees, getDpmProbability } from './calculate-dpm'
|
||||
import {
|
||||
AnswerContract,
|
||||
DPMContract,
|
||||
FreeResponseContract,
|
||||
MultipleChoiceContract,
|
||||
|
@ -184,7 +185,7 @@ export const getDpmMktPayouts = (
|
|||
|
||||
export const getPayoutsMultiOutcome = (
|
||||
resolutions: { [outcome: string]: number },
|
||||
contract: FreeResponseContract | MultipleChoiceContract,
|
||||
contract: AnswerContract,
|
||||
bets: Bet[]
|
||||
) => {
|
||||
const poolTotal = sum(Object.values(contract.pool))
|
||||
|
|
|
@ -36,7 +36,10 @@ export const createanswer = newEndpoint(opts, async (req, auth) => {
|
|||
if (!contractSnap.exists) throw new APIError(400, 'Invalid contract')
|
||||
const contract = contractSnap.data() as Contract
|
||||
|
||||
if (contract.outcomeType !== 'FREE_RESPONSE')
|
||||
if (
|
||||
contract.outcomeType !== 'FREE_RESPONSE' &&
|
||||
contract.outcomeType !== 'BOUNTY'
|
||||
)
|
||||
throw new APIError(400, 'Requires a free response contract')
|
||||
|
||||
const { closeTime, volume } = contract
|
||||
|
|
|
@ -3,6 +3,7 @@ import { z } from 'zod'
|
|||
import { difference, uniq, mapValues, groupBy, sumBy } from 'lodash'
|
||||
|
||||
import {
|
||||
AnswerContract,
|
||||
Contract,
|
||||
FreeResponseContract,
|
||||
MultipleChoiceContract,
|
||||
|
@ -295,10 +296,7 @@ function getResolutionParams(contract: Contract, body: string) {
|
|||
throw new APIError(500, `Invalid outcome type: ${outcomeType}`)
|
||||
}
|
||||
|
||||
function validateAnswer(
|
||||
contract: FreeResponseContract | MultipleChoiceContract,
|
||||
answer: number
|
||||
) {
|
||||
function validateAnswer(contract: AnswerContract, answer: number) {
|
||||
const validIds = contract.answers.map((a) => a.id)
|
||||
if (!validIds.includes(answer.toString())) {
|
||||
throw new APIError(400, `${answer} is not a valid answer ID`)
|
||||
|
|
|
@ -3,7 +3,7 @@ import { useEffect, useRef, useState } from 'react'
|
|||
import { XIcon } from '@heroicons/react/solid'
|
||||
|
||||
import { Answer } from 'common/answer'
|
||||
import { FreeResponseContract, MultipleChoiceContract } from 'common/contract'
|
||||
import { AnswerContract } from 'common/contract'
|
||||
import { BuyAmountInput } from '../amount-input'
|
||||
import { Col } from '../layout/col'
|
||||
import { APIError, placeBet } from 'web/lib/firebase/api'
|
||||
|
@ -30,7 +30,7 @@ import { AlertBox } from '../alert-box'
|
|||
|
||||
export function AnswerBetPanel(props: {
|
||||
answer: Answer
|
||||
contract: FreeResponseContract | MultipleChoiceContract
|
||||
contract: AnswerContract
|
||||
closePanel: () => void
|
||||
className?: string
|
||||
isModal?: boolean
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import clsx from 'clsx'
|
||||
|
||||
import { Answer } from 'common/answer'
|
||||
import { FreeResponseContract, MultipleChoiceContract } from 'common/contract'
|
||||
import { AnswerContract } from 'common/contract'
|
||||
import { Col } from '../layout/col'
|
||||
import { Row } from '../layout/row'
|
||||
import { Avatar } from '../avatar'
|
||||
|
@ -13,7 +13,7 @@ import { Linkify } from '../linkify'
|
|||
|
||||
export function AnswerItem(props: {
|
||||
answer: Answer
|
||||
contract: FreeResponseContract | MultipleChoiceContract
|
||||
contract: AnswerContract
|
||||
showChoice: 'radio' | 'checkbox' | undefined
|
||||
chosenProb: number | undefined
|
||||
totalChosenProb?: number
|
||||
|
|
|
@ -2,7 +2,7 @@ import clsx from 'clsx'
|
|||
import { sum } from 'lodash'
|
||||
import { useState } from 'react'
|
||||
|
||||
import { FreeResponseContract, MultipleChoiceContract } from 'common/contract'
|
||||
import { AnswerContract } from 'common/contract'
|
||||
import { Col } from '../layout/col'
|
||||
import { APIError, resolveMarket } from 'web/lib/firebase/api'
|
||||
import { Row } from '../layout/row'
|
||||
|
@ -11,7 +11,7 @@ import { ResolveConfirmationButton } from '../confirmation-button'
|
|||
import { removeUndefinedProps } from 'common/util/object'
|
||||
|
||||
export function AnswerResolvePanel(props: {
|
||||
contract: FreeResponseContract | MultipleChoiceContract
|
||||
contract: AnswerContract
|
||||
resolveOption: 'CHOOSE' | 'CHOOSE_MULTIPLE' | 'CANCEL' | undefined
|
||||
setResolveOption: (
|
||||
option: 'CHOOSE' | 'CHOOSE_MULTIPLE' | 'CANCEL' | undefined
|
||||
|
|
|
@ -5,14 +5,18 @@ import { groupBy, sortBy, sumBy } from 'lodash'
|
|||
import { memo } from 'react'
|
||||
|
||||
import { Bet } from 'common/bet'
|
||||
import { FreeResponseContract, MultipleChoiceContract } from 'common/contract'
|
||||
import {
|
||||
AnswerContract,
|
||||
FreeResponseContract,
|
||||
MultipleChoiceContract,
|
||||
} from 'common/contract'
|
||||
import { getOutcomeProbability } from 'common/calculate'
|
||||
import { useWindowSize } from 'web/hooks/use-window-size'
|
||||
|
||||
const NUM_LINES = 6
|
||||
|
||||
export const AnswersGraph = memo(function AnswersGraph(props: {
|
||||
contract: FreeResponseContract | MultipleChoiceContract
|
||||
contract: AnswerContract
|
||||
bets: Bet[]
|
||||
height?: number
|
||||
}) {
|
||||
|
@ -178,10 +182,7 @@ function formatTime(
|
|||
return d.format(format)
|
||||
}
|
||||
|
||||
const computeProbsByOutcome = (
|
||||
bets: Bet[],
|
||||
contract: FreeResponseContract | MultipleChoiceContract
|
||||
) => {
|
||||
const computeProbsByOutcome = (bets: Bet[], contract: AnswerContract) => {
|
||||
const { totalBets, outcomeType } = contract
|
||||
|
||||
const betsByOutcome = groupBy(bets, (bet) => bet.outcome)
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
import { sortBy, partition, sum, uniq } from 'lodash'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import { FreeResponseContract, MultipleChoiceContract } from 'common/contract'
|
||||
import {
|
||||
AnswerContract,
|
||||
BountyContract,
|
||||
FreeResponseContract,
|
||||
MultipleChoiceContract,
|
||||
} from 'common/contract'
|
||||
import { Col } from '../layout/col'
|
||||
import { useUser } from 'web/hooks/use-user'
|
||||
import { getDpmOutcomeProbability } from 'common/calculate-dpm'
|
||||
|
@ -25,9 +30,7 @@ import { UserLink } from 'web/components/user-page'
|
|||
import { Linkify } from 'web/components/linkify'
|
||||
import { BuyButton } from 'web/components/yes-no-selector'
|
||||
|
||||
export function AnswersPanel(props: {
|
||||
contract: FreeResponseContract | MultipleChoiceContract
|
||||
}) {
|
||||
export function AnswersPanel(props: { contract: AnswerContract }) {
|
||||
const { contract } = props
|
||||
const { creatorId, resolution, resolutions, totalBets, outcomeType } =
|
||||
contract
|
||||
|
@ -136,7 +139,7 @@ export function AnswersPanel(props: {
|
|||
<div className="pb-4 text-gray-500">No answers yet...</div>
|
||||
)}
|
||||
|
||||
{outcomeType === 'FREE_RESPONSE' &&
|
||||
{(outcomeType === 'FREE_RESPONSE' || outcomeType === 'BOUNTY') &&
|
||||
tradingAllowed(contract) &&
|
||||
(!resolveOption || resolveOption === 'CANCEL') && (
|
||||
<CreateAnswerPanel contract={contract} />
|
||||
|
@ -158,7 +161,7 @@ export function AnswersPanel(props: {
|
|||
}
|
||||
|
||||
function getAnswerItems(
|
||||
contract: FreeResponseContract | MultipleChoiceContract,
|
||||
contract: AnswerContract,
|
||||
answers: Answer[],
|
||||
user: User | undefined | null
|
||||
) {
|
||||
|
@ -184,7 +187,7 @@ function getAnswerItems(
|
|||
}
|
||||
|
||||
function OpenAnswer(props: {
|
||||
contract: FreeResponseContract | MultipleChoiceContract
|
||||
contract: AnswerContract
|
||||
answer: Answer
|
||||
items: ActivityItem[]
|
||||
type: string
|
||||
|
|
|
@ -3,7 +3,7 @@ import { useState } from 'react'
|
|||
import Textarea from 'react-expanding-textarea'
|
||||
import { findBestMatch } from 'string-similarity'
|
||||
|
||||
import { FreeResponseContract } from 'common/contract'
|
||||
import { BountyContract, FreeResponseContract } from 'common/contract'
|
||||
import { BuyAmountInput } from '../amount-input'
|
||||
import { Col } from '../layout/col'
|
||||
import { APIError, createAnswer } from 'web/lib/firebase/api'
|
||||
|
@ -26,7 +26,9 @@ import { MAX_ANSWER_LENGTH } from 'common/answer'
|
|||
import { withTracking } from 'web/lib/service/analytics'
|
||||
import { lowerCase } from 'lodash'
|
||||
|
||||
export function CreateAnswerPanel(props: { contract: FreeResponseContract }) {
|
||||
export function CreateAnswerPanel(props: {
|
||||
contract: FreeResponseContract | BountyContract
|
||||
}) {
|
||||
const { contract } = props
|
||||
const user = useUser()
|
||||
const [text, setText] = useState('')
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
import { contractPath, getBinaryProbPercent } from 'web/lib/firebase/contracts'
|
||||
import { Col } from '../layout/col'
|
||||
import {
|
||||
AnswerContract,
|
||||
BinaryContract,
|
||||
BountyContract,
|
||||
Contract,
|
||||
|
@ -232,7 +233,7 @@ export function BountyValue(props: {
|
|||
}
|
||||
|
||||
function FreeResponseTopAnswer(props: {
|
||||
contract: FreeResponseContract | MultipleChoiceContract
|
||||
contract: AnswerContract
|
||||
truncate: 'short' | 'long' | 'none'
|
||||
className?: string
|
||||
}) {
|
||||
|
|
|
@ -56,7 +56,8 @@ export function ContractTabs(props: {
|
|||
tips={tips}
|
||||
user={user}
|
||||
mode={
|
||||
contract.outcomeType === 'FREE_RESPONSE'
|
||||
contract.outcomeType === 'FREE_RESPONSE' ||
|
||||
contract.outcomeType === 'BOUNTY'
|
||||
? 'free-response-comment-answer-groups'
|
||||
: 'comments'
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import { Answer } from 'common/answer'
|
|||
import { getProbability } from 'common/calculate'
|
||||
import { getValueFromBucket } from 'common/calculate-dpm'
|
||||
import {
|
||||
AnswerContract,
|
||||
BinaryContract,
|
||||
BountyContract,
|
||||
Contract,
|
||||
|
@ -78,7 +79,7 @@ export function BinaryContractOutcomeLabel(props: {
|
|||
}
|
||||
|
||||
export function FreeResponseOutcomeLabel(props: {
|
||||
contract: FreeResponseContract | MultipleChoiceContract | BountyContract
|
||||
contract: AnswerContract
|
||||
resolution: string | 'CANCEL' | 'MKT'
|
||||
truncate: 'short' | 'long' | 'none'
|
||||
answerClassName?: string
|
||||
|
|
Loading…
Reference in New Issue
Block a user