Bet embed (#204)

* Add bet buttons to embed

- Make only title link to market
- Prevent avatar / username from being clicked on

* refactor: remove extra elem, de-indent

* adjust embed info row styles

* make bet panel smaller

* make sell panel smaller
This commit is contained in:
Sinclair Chen 2022-05-17 10:31:19 -07:00 committed by GitHub
parent d458d8a299
commit f8601af45c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 90 additions and 64 deletions

View File

@ -151,8 +151,7 @@ export function BetPanelSwitcher(props: {
<Col <Col
className={clsx( className={clsx(
'rounded-b-md bg-white px-8 py-6', 'rounded-b-md bg-white px-8 py-6',
!sharesOutcome && 'rounded-t-md', !sharesOutcome && 'rounded-t-md'
className
)} )}
> >
<Title <Title

View File

@ -15,8 +15,9 @@ export default function BetRow(props: {
contract: FullContract<DPM | CPMM, Binary> contract: FullContract<DPM | CPMM, Binary>
className?: string className?: string
btnClassName?: string btnClassName?: string
betPanelClassName?: string
}) { }) {
const { className, btnClassName, contract } = props const { className, btnClassName, betPanelClassName, contract } = props
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const [betChoice, setBetChoice] = useState<'YES' | 'NO' | undefined>( const [betChoice, setBetChoice] = useState<'YES' | 'NO' | undefined>(
undefined undefined
@ -31,7 +32,7 @@ export default function BetRow(props: {
return ( return (
<> <>
<YesNoSelector <YesNoSelector
className={clsx('mt-2 justify-end', className)} className={clsx('justify-end', className)}
btnClassName={clsx('btn-sm w-24', btnClassName)} btnClassName={clsx('btn-sm w-24', btnClassName)}
onSelect={(choice) => { onSelect={(choice) => {
setOpen(true) setOpen(true)
@ -40,6 +41,7 @@ export default function BetRow(props: {
replaceNoButton={ replaceNoButton={
yesFloorShares > 0 ? ( yesFloorShares > 0 ? (
<SellButton <SellButton
panelClassName={betPanelClassName}
contract={contract} contract={contract}
user={user} user={user}
sharesOutcome={'YES'} sharesOutcome={'YES'}
@ -50,6 +52,7 @@ export default function BetRow(props: {
replaceYesButton={ replaceYesButton={
noFloorShares > 0 ? ( noFloorShares > 0 ? (
<SellButton <SellButton
panelClassName={betPanelClassName}
contract={contract} contract={contract}
user={user} user={user}
sharesOutcome={'NO'} sharesOutcome={'NO'}
@ -60,6 +63,7 @@ export default function BetRow(props: {
/> />
<Modal open={open} setOpen={setOpen}> <Modal open={open} setOpen={setOpen}>
<BetPanelSwitcher <BetPanelSwitcher
className={betPanelClassName}
contract={contract} contract={contract}
title={contract.question} title={contract.question}
selected={betChoice} selected={betChoice}

View File

@ -93,26 +93,30 @@ export function ContractDetails(props: {
contract: Contract contract: Contract
bets: Bet[] bets: Bet[]
isCreator?: boolean isCreator?: boolean
hideShareButtons?: boolean disabled?: boolean
}) { }) {
const { contract, bets, isCreator, hideShareButtons } = props const { contract, bets, isCreator, disabled } = props
const { closeTime, creatorName, creatorUsername } = contract const { closeTime, creatorName, creatorUsername } = contract
const { volumeLabel, createdDate, resolvedDate } = contractMetrics(contract) const { volumeLabel, createdDate, resolvedDate } = contractMetrics(contract)
return ( return (
<Col className="gap-2 text-sm text-gray-500 sm:flex-row sm:flex-wrap"> <Row className="flex-1 flex-wrap items-center gap-x-4 gap-y-2 text-sm text-gray-500">
<Row className="flex-1 flex-wrap items-center gap-x-4 gap-y-3">
<Row className="items-center gap-2"> <Row className="items-center gap-2">
<Avatar <Avatar
username={creatorUsername} username={creatorUsername}
avatarUrl={contract.creatorAvatarUrl} avatarUrl={contract.creatorAvatarUrl}
noLink={disabled}
size={6} size={6}
/> />
{disabled ? (
creatorName
) : (
<UserLink <UserLink
className="whitespace-nowrap" className="whitespace-nowrap"
name={creatorName} name={creatorName}
username={creatorUsername} username={creatorUsername}
/> />
)}
</Row> </Row>
{(!!closeTime || !!resolvedDate) && ( {(!!closeTime || !!resolvedDate) && (
@ -154,11 +158,8 @@ export function ContractDetails(props: {
<div className="whitespace-nowrap">{volumeLabel}</div> <div className="whitespace-nowrap">{volumeLabel}</div>
</Row> </Row>
{!hideShareButtons && ( {!disabled && <ContractInfoDialog contract={contract} bets={bets} />}
<ContractInfoDialog contract={contract} bets={bets} />
)}
</Row> </Row>
</Col>
) )
} }

View File

@ -11,8 +11,9 @@ export function SellButton(props: {
user: User | null | undefined user: User | null | undefined
sharesOutcome: 'YES' | 'NO' | undefined sharesOutcome: 'YES' | 'NO' | undefined
shares: number shares: number
panelClassName?: string
}) { }) {
const { contract, user, sharesOutcome, shares } = props const { contract, user, sharesOutcome, shares, panelClassName } = props
const userBets = useUserContractBets(user?.id, contract.id) const userBets = useUserContractBets(user?.id, contract.id)
const [showSellModal, setShowSellModal] = useState(false) const [showSellModal, setShowSellModal] = useState(false)
const { mechanism } = contract const { mechanism } = contract
@ -24,7 +25,7 @@ export function SellButton(props: {
className={clsx( className={clsx(
'btn-sm w-24 gap-1', 'btn-sm w-24 gap-1',
// from the yes-no-selector: // from the yes-no-selector:
'flex inline-flex flex-row items-center justify-center rounded-3xl border-2 p-2', 'inline-flex items-center justify-center rounded-3xl border-2 p-2',
sharesOutcome === 'NO' sharesOutcome === 'NO'
? 'hover:bg-primary-focus border-primary hover:border-primary-focus text-primary hover:text-white' ? 'hover:bg-primary-focus border-primary hover:border-primary-focus text-primary hover:text-white'
: 'border-red-400 text-red-500 hover:border-red-500 hover:bg-red-500 hover:text-white' : 'border-red-400 text-red-500 hover:border-red-500 hover:bg-red-500 hover:text-white'
@ -38,6 +39,7 @@ export function SellButton(props: {
</div> </div>
{showSellModal && ( {showSellModal && (
<SellSharesModal <SellSharesModal
className={panelClassName}
contract={contract as FullContract<CPMM, Binary>} contract={contract as FullContract<CPMM, Binary>}
user={user} user={user}
userBets={userBets ?? []} userBets={userBets ?? []}

View File

@ -7,8 +7,10 @@ import { Title } from './title'
import { formatWithCommas } from 'common/util/format' import { formatWithCommas } from 'common/util/format'
import { OutcomeLabel } from './outcome-label' import { OutcomeLabel } from './outcome-label'
import { SellPanel } from './bet-panel' import { SellPanel } from './bet-panel'
import clsx from 'clsx'
export function SellSharesModal(props: { export function SellSharesModal(props: {
className?: string
contract: FullContract<CPMM, Binary> contract: FullContract<CPMM, Binary>
userBets: Bet[] userBets: Bet[]
shares: number shares: number
@ -16,11 +18,19 @@ export function SellSharesModal(props: {
user: User user: User
setOpen: (open: boolean) => void setOpen: (open: boolean) => void
}) { }) {
const { contract, shares, sharesOutcome, userBets, user, setOpen } = props const {
className,
contract,
shares,
sharesOutcome,
userBets,
user,
setOpen,
} = props
return ( return (
<Modal open={true} setOpen={setOpen}> <Modal open={true} setOpen={setOpen}>
<Col className="rounded-md bg-white px-8 py-6"> <Col className={clsx('rounded-md bg-white px-8 py-6', className)}>
<Title className="!mt-0" text={'Sell shares'} /> <Title className="!mt-0" text={'Sell shares'} />
<div className="mb-6"> <div className="mb-6">

View File

@ -1,7 +1,14 @@
import { Bet } from 'common/bet' import { Bet } from 'common/bet'
import { Contract, DPM, FreeResponse, FullContract } from 'common/contract' import {
BinaryContract,
Contract,
DPM,
FreeResponse,
FullContract,
} from 'common/contract'
import { DOMAIN } from 'common/envs/constants' import { DOMAIN } from 'common/envs/constants'
import { AnswersGraph } from 'web/components/answers/answers-graph' import { AnswersGraph } from 'web/components/answers/answers-graph'
import BetRow from 'web/components/bet-row'
import { import {
BinaryResolutionOrChance, BinaryResolutionOrChance,
FreeResponseResolutionOrChance, FreeResponseResolutionOrChance,
@ -92,13 +99,8 @@ function ContractEmbed(props: { contract: Contract; bets: Bet[] }) {
return ( return (
<Col className="w-full flex-1 bg-white"> <Col className="w-full flex-1 bg-white">
<div className="relative flex flex-col pt-2" ref={setElem}> <div className="relative flex flex-col pt-2" ref={setElem}>
<SiteLink
className="absolute top-0 left-0 z-20 h-full w-full"
href={href}
/>
<div className="px-3 text-xl text-indigo-700 md:text-2xl"> <div className="px-3 text-xl text-indigo-700 md:text-2xl">
<Linkify text={question} /> <SiteLink href={href}>{question}</SiteLink>
</div> </div>
<Spacer h={3} /> <Spacer h={3} />
@ -108,10 +110,18 @@ function ContractEmbed(props: { contract: Contract; bets: Bet[] }) {
contract={contract} contract={contract}
bets={bets} bets={bets}
isCreator={false} isCreator={false}
hideShareButtons disabled
/> />
{isBinary && <BinaryResolutionOrChance contract={contract} />} {isBinary && (
<Row className="items-center gap-4">
<BetRow
contract={contract as BinaryContract}
betPanelClassName="scale-75"
/>
<BinaryResolutionOrChance contract={contract} />
</Row>
)}
{outcomeType === 'FREE_RESPONSE' && resolution && ( {outcomeType === 'FREE_RESPONSE' && resolution && (
<FreeResponseResolutionOrChance <FreeResponseResolutionOrChance