Pull out quick bet display component
This commit is contained in:
		
							parent
							
								
									a204380f57
								
							
						
					
					
						commit
						8e746ce0cb
					
				|  | @ -25,7 +25,7 @@ import { | |||
| import { getOutcomeProbability, getTopAnswer } from 'common/calculate' | ||||
| import { AvatarDetails, MiscDetails } from './contract-details' | ||||
| import { getExpectedValue, getValueFromBucket } from 'common/calculate-dpm' | ||||
| import { QuickBet, QuickOutcomeView, ProbBar, getColor } from './quick-bet' | ||||
| import { QuickBet, ProbBar, getColor } from './quick-bet' | ||||
| import { useContractWithPreload } from 'web/hooks/use-contract' | ||||
| 
 | ||||
| export function ContractCard(props: { | ||||
|  | @ -90,7 +90,28 @@ export function ContractCard(props: { | |||
|             <QuickBet contract={contract} /> | ||||
|           ) : ( | ||||
|             <Col className="m-auto pl-2"> | ||||
|               <QuickOutcomeView contract={contract} /> | ||||
|               {outcomeType === 'BINARY' && ( | ||||
|                 <BinaryResolutionOrChance | ||||
|                   className="items-center" | ||||
|                   contract={contract} | ||||
|                 /> | ||||
|               )} | ||||
| 
 | ||||
|               {outcomeType === 'NUMERIC' && ( | ||||
|                 <NumericResolutionOrExpectation | ||||
|                   className="items-center" | ||||
|                   contract={contract as NumericContract} | ||||
|                 /> | ||||
|               )} | ||||
| 
 | ||||
|               {outcomeType === 'FREE_RESPONSE' && ( | ||||
|                 <FreeResponseResolutionOrChance | ||||
|                   className="self-end text-gray-600" | ||||
|                   contract={contract as FullContract<DPM, FreeResponse>} | ||||
|                   truncate="long" | ||||
|                 /> | ||||
|               )} | ||||
|               <ProbBar contract={contract} /> | ||||
|             </Col> | ||||
|           )} | ||||
|         </Row> | ||||
|  | @ -103,10 +124,8 @@ export function BinaryResolutionOrChance(props: { | |||
|   contract: FullContract<DPM | CPMM, Binary> | ||||
|   large?: boolean | ||||
|   className?: string | ||||
|   hideText?: boolean | ||||
|   override?: string | ||||
| }) { | ||||
|   const { contract, large, className, hideText, override } = props | ||||
|   const { contract, large, className } = props | ||||
|   const { resolution } = contract | ||||
|   const textColor = `text-${getColor(contract)}` | ||||
| 
 | ||||
|  | @ -127,13 +146,11 @@ export function BinaryResolutionOrChance(props: { | |||
|       ) : ( | ||||
|         <> | ||||
|           <div className={clsx(textColor, 'transition-all')}> | ||||
|             {override ?? getBinaryProbPercent(contract)} | ||||
|             {getBinaryProbPercent(contract)} | ||||
|           </div> | ||||
|           <div className={clsx(textColor, large ? 'text-xl' : 'text-base')}> | ||||
|             chance | ||||
|           </div> | ||||
|           {!hideText && ( | ||||
|             <div className={clsx(textColor, large ? 'text-xl' : 'text-base')}> | ||||
|               chance | ||||
|             </div> | ||||
|           )} | ||||
|         </> | ||||
|       )} | ||||
|     </Col> | ||||
|  | @ -162,10 +179,8 @@ export function FreeResponseResolutionOrChance(props: { | |||
|   contract: FreeResponseContract | ||||
|   truncate: 'short' | 'long' | 'none' | ||||
|   className?: string | ||||
|   hideText?: boolean | ||||
|   override?: string | ||||
| }) { | ||||
|   const { contract, truncate, className, hideText, override } = props | ||||
|   const { contract, truncate, className } = props | ||||
|   const { resolution } = contract | ||||
| 
 | ||||
|   const topAnswer = getTopAnswer(contract) | ||||
|  | @ -188,10 +203,9 @@ export function FreeResponseResolutionOrChance(props: { | |||
|           <Row className="items-center gap-6"> | ||||
|             <Col className={clsx('text-3xl', textColor)}> | ||||
|               <div> | ||||
|                 {override ?? | ||||
|                   formatPercent(getOutcomeProbability(contract, topAnswer.id))} | ||||
|                 {formatPercent(getOutcomeProbability(contract, topAnswer.id))} | ||||
|               </div> | ||||
|               {!hideText && <div className="text-base">chance</div>} | ||||
|               <div className="text-base">chance</div> | ||||
|             </Col> | ||||
|           </Row> | ||||
|         ) | ||||
|  | @ -203,10 +217,8 @@ export function FreeResponseResolutionOrChance(props: { | |||
| export function NumericResolutionOrExpectation(props: { | ||||
|   contract: NumericContract | ||||
|   className?: string | ||||
|   hideText?: boolean | ||||
|   override?: string | ||||
| }) { | ||||
|   const { contract, className, hideText, override } = props | ||||
|   const { contract, className } = props | ||||
|   const { resolution } = contract | ||||
|   const textColor = `text-${getColor(contract)}` | ||||
| 
 | ||||
|  | @ -223,11 +235,9 @@ export function NumericResolutionOrExpectation(props: { | |||
|       ) : ( | ||||
|         <> | ||||
|           <div className={clsx('text-3xl', textColor)}> | ||||
|             {override ?? formatLargeNumber(getExpectedValue(contract))} | ||||
|             {formatLargeNumber(getExpectedValue(contract))} | ||||
|           </div> | ||||
|           {!hideText && ( | ||||
|             <div className={clsx('text-base', textColor)}>expected</div> | ||||
|           )} | ||||
|           <div className={clsx('text-base', textColor)}>expected</div> | ||||
|         </> | ||||
|       )} | ||||
|     </Col> | ||||
|  |  | |||
|  | @ -13,14 +13,19 @@ import { | |||
|   Binary, | ||||
|   NumericContract, | ||||
|   FreeResponse, | ||||
|   FreeResponseContract, | ||||
| } from 'common/contract' | ||||
| import { formatMoney, formatPercent } from 'common/util/format' | ||||
| import { | ||||
|   formatLargeNumber, | ||||
|   formatMoney, | ||||
|   formatPercent, | ||||
| } from 'common/util/format' | ||||
| import { useState } from 'react' | ||||
| import toast from 'react-hot-toast' | ||||
| import { useUser } from 'web/hooks/use-user' | ||||
| import { useUserContractBets } from 'web/hooks/use-user-bets' | ||||
| import { placeBet } from 'web/lib/firebase/api-call' | ||||
| import { getBinaryProb } from 'web/lib/firebase/contracts' | ||||
| import { getBinaryProb, getBinaryProbPercent } from 'web/lib/firebase/contracts' | ||||
| import TriangleDownFillIcon from 'web/lib/icons/triangle-down-fill-icon' | ||||
| import TriangleFillIcon from 'web/lib/icons/triangle-fill-icon' | ||||
| import { Col } from '../layout/col' | ||||
|  | @ -71,7 +76,7 @@ export function QuickBet(props: { contract: Contract }) { | |||
|     // Catch any errors from hovering on an invalid option
 | ||||
|   } | ||||
| 
 | ||||
|   const color = getColor(contract) | ||||
|   const color = getColor(contract, previewProb) | ||||
| 
 | ||||
|   async function placeQuickBet(direction: 'UP' | 'DOWN') { | ||||
|     const betPromise = async () => { | ||||
|  | @ -170,8 +175,7 @@ export function QuickBet(props: { contract: Contract }) { | |||
| 
 | ||||
| export function ProbBar(props: { contract: Contract; previewProb?: number }) { | ||||
|   const { contract, previewProb } = props | ||||
|   // TODO: Switch preview color as it changes from green to red
 | ||||
|   const color = getColor(contract) | ||||
|   const color = getColor(contract, previewProb) | ||||
|   const prob = previewProb ?? getProb(contract) | ||||
|   return ( | ||||
|     <> | ||||
|  | @ -195,47 +199,40 @@ export function ProbBar(props: { contract: Contract; previewProb?: number }) { | |||
|   ) | ||||
| } | ||||
| 
 | ||||
| // TODO: just directly code in the outcomes for quick bet, rather than relying on
 | ||||
| // code resuse. Too many differences anyways
 | ||||
| export function QuickOutcomeView(props: { | ||||
| function QuickOutcomeView(props: { | ||||
|   contract: Contract | ||||
|   previewProb?: number | ||||
|   caption?: 'chance' | 'expected' | ||||
| }) { | ||||
|   const { contract, previewProb } = props | ||||
|   const { contract, previewProb, caption } = props | ||||
|   const { outcomeType } = contract | ||||
|   // If there's a preview probability,
 | ||||
|   const override = | ||||
|     previewProb === undefined ? undefined : formatPercent(previewProb) | ||||
|   const textColor = `text-${getColor(contract, previewProb)}` | ||||
| 
 | ||||
|   let display: string | undefined | ||||
|   switch (outcomeType) { | ||||
|     case 'BINARY': | ||||
|       display = getBinaryProbPercent(contract) | ||||
|       break | ||||
|     case 'NUMERIC': | ||||
|       display = formatLargeNumber(getExpectedValue(contract as NumericContract)) | ||||
|       break | ||||
|     case 'FREE_RESPONSE': | ||||
|       const topAnswer = getTopAnswer(contract as FreeResponseContract) | ||||
|       display = | ||||
|         topAnswer && | ||||
|         formatPercent(getOutcomeProbability(contract, topAnswer.id)) | ||||
|       break | ||||
|   } | ||||
| 
 | ||||
|   return ( | ||||
|     <> | ||||
|       {outcomeType === 'BINARY' && ( | ||||
|         <BinaryResolutionOrChance | ||||
|           className="items-center" | ||||
|           contract={contract} | ||||
|           hideText | ||||
|           override={override} | ||||
|         /> | ||||
|       )} | ||||
| 
 | ||||
|       {outcomeType === 'NUMERIC' && ( | ||||
|         <NumericResolutionOrExpectation | ||||
|           className="items-center" | ||||
|           contract={contract as NumericContract} | ||||
|           hideText | ||||
|           override={override} | ||||
|         /> | ||||
|       )} | ||||
| 
 | ||||
|       {outcomeType === 'FREE_RESPONSE' && ( | ||||
|         <FreeResponseResolutionOrChance | ||||
|           className="self-end text-gray-600" | ||||
|           contract={contract as FullContract<DPM, FreeResponse>} | ||||
|           truncate="long" | ||||
|           hideText | ||||
|           override={override} | ||||
|         /> | ||||
|       )} | ||||
|     <Col className={clsx('items-center text-3xl', textColor)}> | ||||
|       {override ?? display} | ||||
|       {caption && <div className="text-base">{caption}</div>} | ||||
|       <ProbBar contract={contract} previewProb={previewProb} /> | ||||
|     </> | ||||
|     </Col> | ||||
|   ) | ||||
| } | ||||
| 
 | ||||
|  | @ -260,7 +257,7 @@ function getNumericScale(contract: NumericContract) { | |||
|   return (ev - min) / (max - min) | ||||
| } | ||||
| 
 | ||||
| export function getColor(contract: Contract) { | ||||
| export function getColor(contract: Contract, previewProb?: number) { | ||||
|   // TODO: Not sure why eg green-400 doesn't work here; try upgrading Tailwind
 | ||||
|   // TODO: Try injecting a gradient here
 | ||||
|   // return 'primary'
 | ||||
|  | @ -278,9 +275,6 @@ export function getColor(contract: Contract) { | |||
|   } | ||||
| 
 | ||||
|   const marketClosed = (contract.closeTime || Infinity) < Date.now() | ||||
|   return marketClosed | ||||
|     ? 'gray-400' | ||||
|     : getProb(contract) >= 0.5 | ||||
|     ? 'primary' | ||||
|     : 'red-400' | ||||
|   const prob = previewProb ?? getProb(contract) | ||||
|   return marketClosed ? 'gray-400' : prob >= 0.5 ? 'primary' : 'red-400' | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user