Show resolution time in market cards when appropriate (#565)

* Show resolution time in market cards when appropriate

* Rebase and fix contract-search-firestore
This commit is contained in:
Ben Congdon 2022-06-23 10:12:57 -07:00 committed by GitHub
parent 4a1a907b37
commit cdd8af241b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 45 additions and 19 deletions

View File

@ -238,12 +238,18 @@ export function ContractSearchInner(props: {
if (isInitialLoad && contracts.length === 0) return <></> if (isInitialLoad && contracts.length === 0) return <></>
const showTime = index.endsWith('close-date')
? 'close-date'
: index.endsWith('resolve-date')
? 'resolve-date'
: undefined
return ( return (
<ContractsGrid <ContractsGrid
contracts={contracts} contracts={contracts}
loadMore={showMore} loadMore={showMore}
hasMore={!isLastPage} hasMore={!isLastPage}
showCloseTime={index.endsWith('close-date')} showTime={showTime}
onContractClick={onContractClick} onContractClick={onContractClick}
/> />
) )

View File

@ -17,7 +17,7 @@ import {
FreeResponseOutcomeLabel, FreeResponseOutcomeLabel,
} from '../outcome-label' } from '../outcome-label'
import { getOutcomeProbability, getTopAnswer } from 'common/calculate' import { getOutcomeProbability, getTopAnswer } from 'common/calculate'
import { AvatarDetails, MiscDetails } from './contract-details' import { AvatarDetails, MiscDetails, ShowTime } from './contract-details'
import { getExpectedValue, getValueFromBucket } from 'common/calculate-dpm' import { getExpectedValue, getValueFromBucket } from 'common/calculate-dpm'
import { QuickBet, ProbBar, getColor } from './quick-bet' import { QuickBet, ProbBar, getColor } from './quick-bet'
import { useContractWithPreload } from 'web/hooks/use-contract' import { useContractWithPreload } from 'web/hooks/use-contract'
@ -28,13 +28,12 @@ import { trackCallback } from 'web/lib/service/analytics'
export function ContractCard(props: { export function ContractCard(props: {
contract: Contract contract: Contract
showHotVolume?: boolean showHotVolume?: boolean
showCloseTime?: boolean showTime?: ShowTime
className?: string className?: string
onClick?: () => void onClick?: () => void
hideQuickBet?: boolean hideQuickBet?: boolean
}) { }) {
const { showHotVolume, showCloseTime, className, onClick, hideQuickBet } = const { showHotVolume, showTime, className, onClick, hideQuickBet } = props
props
const contract = useContractWithPreload(props.contract) ?? props.contract const contract = useContractWithPreload(props.contract) ?? props.contract
const { question, outcomeType } = contract const { question, outcomeType } = contract
const { resolution } = contract const { resolution } = contract
@ -118,7 +117,7 @@ export function ContractCard(props: {
<MiscDetails <MiscDetails
contract={contract} contract={contract}
showHotVolume={showHotVolume} showHotVolume={showHotVolume}
showCloseTime={showCloseTime} showTime={showTime}
/> />
</Col> </Col>
{showQuickBet ? ( {showQuickBet ? (

View File

@ -30,14 +30,23 @@ import { SiteLink } from 'web/components/site-link'
import { DAY_MS } from 'common/util/time' import { DAY_MS } from 'common/util/time'
import { useGroupsWithContract } from 'web/hooks/use-group' import { useGroupsWithContract } from 'web/hooks/use-group'
export type ShowTime = 'resolve-date' | 'close-date'
export function MiscDetails(props: { export function MiscDetails(props: {
contract: Contract contract: Contract
showHotVolume?: boolean showHotVolume?: boolean
showCloseTime?: boolean showTime?: ShowTime
}) { }) {
const { contract, showHotVolume, showCloseTime } = props const { contract, showHotVolume, showTime } = props
const { volume, volume24Hours, closeTime, tags, isResolved, createdTime } = const {
contract volume,
volume24Hours,
closeTime,
tags,
isResolved,
createdTime,
resolutionTime,
} = contract
// Show at most one category that this contract is tagged by // Show at most one category that this contract is tagged by
const categories = CATEGORY_LIST.filter((category) => const categories = CATEGORY_LIST.filter((category) =>
tags.map((t) => t.toLowerCase()).includes(category) tags.map((t) => t.toLowerCase()).includes(category)
@ -50,12 +59,18 @@ export function MiscDetails(props: {
<Row className="gap-0.5"> <Row className="gap-0.5">
<TrendingUpIcon className="h-5 w-5" /> {formatMoney(volume24Hours)} <TrendingUpIcon className="h-5 w-5" /> {formatMoney(volume24Hours)}
</Row> </Row>
) : showCloseTime ? ( ) : showTime === 'close-date' ? (
<Row className="gap-0.5"> <Row className="gap-0.5">
<ClockIcon className="h-5 w-5" /> <ClockIcon className="h-5 w-5" />
{(closeTime || 0) < Date.now() ? 'Closed' : 'Closes'}{' '} {(closeTime || 0) < Date.now() ? 'Closed' : 'Closes'}{' '}
{fromNow(closeTime || 0)} {fromNow(closeTime || 0)}
</Row> </Row>
) : showTime === 'resolve-date' && resolutionTime !== undefined ? (
<Row className="gap-0.5">
<ClockIcon className="h-5 w-5" />
{'Resolved '}
{fromNow(resolutionTime || 0)}
</Row>
) : volume > 0 || !isNew ? ( ) : volume > 0 || !isNew ? (
<Row>{contractPool(contract)} pool</Row> <Row>{contractPool(contract)} pool</Row>
) : ( ) : (
@ -88,9 +103,9 @@ export function AvatarDetails(props: { contract: Contract }) {
export function AbbrContractDetails(props: { export function AbbrContractDetails(props: {
contract: Contract contract: Contract
showHotVolume?: boolean showHotVolume?: boolean
showCloseTime?: boolean showTime?: ShowTime
}) { }) {
const { contract, showHotVolume, showCloseTime } = props const { contract, showHotVolume, showTime } = props
return ( return (
<Row className="items-center justify-between"> <Row className="items-center justify-between">
<AvatarDetails contract={contract} /> <AvatarDetails contract={contract} />
@ -98,7 +113,7 @@ export function AbbrContractDetails(props: {
<MiscDetails <MiscDetails
contract={contract} contract={contract}
showHotVolume={showHotVolume} showHotVolume={showHotVolume}
showCloseTime={showCloseTime} showTime={showTime}
/> />
</Row> </Row>
) )

View File

@ -3,6 +3,7 @@ import { User } from '../../lib/firebase/users'
import { Col } from '../layout/col' import { Col } from '../layout/col'
import { SiteLink } from '../site-link' import { SiteLink } from '../site-link'
import { ContractCard } from './contract-card' import { ContractCard } from './contract-card'
import { ShowTime } from './contract-details'
import { ContractSearch } from '../contract-search' import { ContractSearch } from '../contract-search'
import { useIsVisible } from 'web/hooks/use-is-visible' import { useIsVisible } from 'web/hooks/use-is-visible'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
@ -12,14 +13,14 @@ export function ContractsGrid(props: {
contracts: Contract[] contracts: Contract[]
loadMore: () => void loadMore: () => void
hasMore: boolean hasMore: boolean
showCloseTime?: boolean showTime?: ShowTime
onContractClick?: (contract: Contract) => void onContractClick?: (contract: Contract) => void
overrideGridClassName?: string overrideGridClassName?: string
hideQuickBet?: boolean hideQuickBet?: boolean
}) { }) {
const { const {
contracts, contracts,
showCloseTime, showTime,
hasMore, hasMore,
loadMore, loadMore,
onContractClick, onContractClick,
@ -60,7 +61,7 @@ export function ContractsGrid(props: {
<ContractCard <ContractCard
contract={contract} contract={contract}
key={contract.id} key={contract.id}
showCloseTime={showCloseTime} showTime={showTime}
onClick={ onClick={
onContractClick ? () => onContractClick(contract) : undefined onContractClick ? () => onContractClick(contract) : undefined
} }

View File

@ -62,6 +62,12 @@ export default function ContractSearchFirestore(props: {
matches = sortBy(matches, ({ volume24Hours }) => -1 * volume24Hours) matches = sortBy(matches, ({ volume24Hours }) => -1 * volume24Hours)
} }
const showTime = ['close-date', 'closed'].includes(sort)
? 'close-date'
: sort === 'resolve-date'
? 'resolve-date'
: undefined
return ( return (
<div> <div>
{/* Show a search input next to a sort dropdown */} {/* Show a search input next to a sort dropdown */}
@ -85,7 +91,6 @@ export default function ContractSearchFirestore(props: {
<option value="close-date">Closing soon</option> <option value="close-date">Closing soon</option>
</select> </select>
</div> </div>
{contracts === undefined ? ( {contracts === undefined ? (
<LoadingIndicator /> <LoadingIndicator />
) : ( ) : (
@ -93,7 +98,7 @@ export default function ContractSearchFirestore(props: {
contracts={matches} contracts={matches}
loadMore={() => {}} loadMore={() => {}}
hasMore={false} hasMore={false}
showCloseTime={['close-date', 'closed'].includes(sort)} showTime={showTime}
/> />
)} )}
</div> </div>