diff --git a/web/components/challenges/create-challenge-modal.tsx b/web/components/challenges/create-challenge-modal.tsx index e93ec314..b1ac7704 100644 --- a/web/components/challenges/create-challenge-modal.tsx +++ b/web/components/challenges/create-challenge-modal.tsx @@ -11,7 +11,7 @@ import { User } from 'common/user' import { Modal } from 'web/components/layout/modal' import { Button } from '../button' import { createChallenge, getChallengeUrl } from 'web/lib/firebase/challenges' -import { BinaryContract } from 'common/contract' +import { BinaryContract, MAX_QUESTION_LENGTH } from 'common/contract' import { SiteLink } from 'web/components/site-link' import { formatMoney } from 'common/util/format' import { NoLabel, YesLabel } from '../outcome-label' @@ -19,24 +19,32 @@ import { QRCode } from '../qr-code' import { copyToClipboard } from 'web/lib/util/copy' import { AmountInput } from '../amount-input' import { getProbability } from 'common/calculate' +import { createMarket } from 'web/lib/firebase/api' +import { removeUndefinedProps } from 'common/util/object' +import { FIXED_ANTE } from 'common/antes' +import Textarea from 'react-expanding-textarea' +import { useTextEditor } from 'web/components/editor' +import { LoadingIndicator } from 'web/components/loading-indicator' import { track } from 'web/lib/service/analytics' type challengeInfo = { amount: number expiresTime: number | null - message: string outcome: 'YES' | 'NO' | number acceptorAmount: number + question: string } export function CreateChallengeModal(props: { user: User | null | undefined - contract: BinaryContract isOpen: boolean setOpen: (open: boolean) => void + contract?: BinaryContract }) { const { user, contract, isOpen, setOpen } = props const [challengeSlug, setChallengeSlug] = useState('') + const [loading, setLoading] = useState(false) + const { editor } = useTextEditor({ placeholder: '' }) return ( @@ -46,24 +54,42 @@ export function CreateChallengeModal(props: { { - const challenge = await createChallenge({ - creator: user, - creatorAmount: newChallenge.amount, - expiresTime: newChallenge.expiresTime, - message: newChallenge.message, - acceptorAmount: newChallenge.acceptorAmount, - outcome: newChallenge.outcome, - contract: contract, - }) - if (challenge) { - setChallengeSlug(getChallengeUrl(challenge)) - track('challenge created', { - creator: user.username, - amount: newChallenge.amount, - contractId: contract.id, + setLoading(true) + try { + const challengeContract = contract + ? contract + : await createMarket( + removeUndefinedProps({ + question: newChallenge.question, + outcomeType: 'BINARY', + initialProb: 50, + description: editor?.getJSON(), + ante: FIXED_ANTE, + closeTime: dayjs().add(30, 'day').valueOf(), + }) + ) + const challenge = await createChallenge({ + creator: user, + creatorAmount: newChallenge.amount, + expiresTime: newChallenge.expiresTime, + acceptorAmount: newChallenge.acceptorAmount, + outcome: newChallenge.outcome, + contract: challengeContract as BinaryContract, }) + if (challenge) { + setChallengeSlug(getChallengeUrl(challenge)) + track('challenge created', { + creator: user.username, + amount: newChallenge.amount, + contractId: challengeContract.id, + }) + } + } catch (e) { + console.error("couldn't create market/challenge:", e) } + setLoading(false) }} challengeSlug={challengeSlug} /> @@ -75,25 +101,24 @@ export function CreateChallengeModal(props: { function CreateChallengeForm(props: { user: User - contract: BinaryContract onCreate: (m: challengeInfo) => Promise challengeSlug: string + loading: boolean + contract?: BinaryContract }) { - const { user, onCreate, contract, challengeSlug } = props + const { user, onCreate, contract, challengeSlug, loading } = props const [isCreating, setIsCreating] = useState(false) const [finishedCreating, setFinishedCreating] = useState(false) const [error, setError] = useState('') const [editingAcceptorAmount, setEditingAcceptorAmount] = useState(false) const defaultExpire = 'week' - const defaultMessage = `${user.name} is challenging you to a bet! Do you think ${contract.question}` - const [challengeInfo, setChallengeInfo] = useState({ expiresTime: dayjs().add(2, defaultExpire).valueOf(), outcome: 'YES', amount: 100, acceptorAmount: 100, - message: defaultMessage, + question: contract ? contract.question : '', }) useEffect(() => { setError('') @@ -106,7 +131,15 @@ function CreateChallengeForm(props: { onSubmit={(e) => { e.preventDefault() if (user.balance < challengeInfo.amount) { - setError('You do not have enough mana to create this challenge') + setError("You don't have enough mana to create this challenge") + return + } + if (!contract && user.balance < FIXED_ANTE + challengeInfo.amount) { + setError( + `You don't have enough mana to create this challenge and market. You need ${formatMoney( + FIXED_ANTE + challengeInfo.amount + )}` + ) return } setIsCreating(true) @@ -118,7 +151,23 @@ function CreateChallengeForm(props: {
Challenge a friend to bet on{' '} - {contract.question} + {contract ? ( + {contract.question} + ) : ( +