Opengraph preview [WIP]

This commit is contained in:
Ian Philips 2022-07-26 12:38:16 -07:00
parent cecf696e1f
commit 8507e4e1e3
5 changed files with 83 additions and 58 deletions

View File

@ -6,6 +6,8 @@ export type Challenge = {
// The user that created the challenge.
creatorId: string
creatorUsername: string
creatorName: string
creatorAvatarUrl?: string
// Displayed to people claiming the challenge
message: string

View File

@ -0,0 +1,36 @@
import { Contract } from 'common/lib/contract'
import { getBinaryProbPercent } from 'web/lib/firebase/contracts'
import { richTextToString } from 'common/lib/util/parse'
import { contractTextDetails } from 'web/components/contract/contract-details'
export const getOpenGraphProps = (contract: Contract) => {
const {
resolution,
question,
creatorName,
creatorUsername,
outcomeType,
creatorAvatarUrl,
description: desc,
} = contract
const probPercent =
outcomeType === 'BINARY' ? getBinaryProbPercent(contract) : undefined
const stringDesc = typeof desc === 'string' ? desc : richTextToString(desc)
const description = resolution
? `Resolved ${resolution}. ${stringDesc}`
: probPercent
? `${probPercent} chance. ${stringDesc}`
: stringDesc
return {
question,
probability: probPercent,
metadata: contractTextDetails(contract),
creatorName,
creatorUsername,
creatorAvatarUrl,
description,
}
}

View File

@ -1,11 +1,11 @@
import {
collectionGroup,
doc,
orderBy,
query,
setDoc,
where,
} from 'firebase/firestore'
import { doc } from 'firebase/firestore'
import { Challenge } from 'common/challenge'
import { customAlphabet } from 'nanoid'
import { coll, listenForValue, listenForValues } from './utils'
@ -46,6 +46,8 @@ export async function createChallenge(data: {
slug,
creatorId: creator.id,
creatorUsername: creator.username,
creatorName: creator.name,
creatorAvatarUrl: creator.avatarUrl,
creatorAmount: amount,
contractSlug: contract.slug,
contractId: contract.id,

View File

@ -13,7 +13,6 @@ import { Spacer } from 'web/components/layout/spacer'
import { listUsers, User } from 'web/lib/firebase/users'
import {
Contract,
getBinaryProbPercent,
getContractFromSlug,
tradingAllowed,
} from 'web/lib/firebase/contracts'
@ -28,7 +27,6 @@ import { Leaderboard } from 'web/components/leaderboard'
import { resolvedPayout } from 'common/calculate'
import { formatMoney } from 'common/util/format'
import { ContractTabs } from 'web/components/contract/contract-tabs'
import { contractTextDetails } from 'web/components/contract/contract-details'
import { useWindowSize } from 'web/hooks/use-window-size'
import Confetti from 'react-confetti'
import { NumericBetPanel } from '../../components/numeric-bet-panel'
@ -43,8 +41,8 @@ import { AlertBox } from 'web/components/alert-box'
import { useTracking } from 'web/hooks/use-tracking'
import { CommentTipMap, useTipTxns } from 'web/hooks/use-tip-txns'
import { useLiquidity } from 'web/hooks/use-liquidity'
import { richTextToString } from 'common/util/parse'
import { useSaveReferral } from 'web/hooks/use-save-referral'
import { getOpenGraphProps } from 'web/components/contract/contract-card-preview'
export const getStaticProps = fromPropz(getStaticPropz)
export async function getStaticPropz(props: {
@ -383,35 +381,3 @@ function ContractTopTrades(props: {
</div>
)
}
const getOpenGraphProps = (contract: Contract) => {
const {
resolution,
question,
creatorName,
creatorUsername,
outcomeType,
creatorAvatarUrl,
description: desc,
} = contract
const probPercent =
outcomeType === 'BINARY' ? getBinaryProbPercent(contract) : undefined
const stringDesc = typeof desc === 'string' ? desc : richTextToString(desc)
const description = resolution
? `Resolved ${resolution}. ${stringDesc}`
: probPercent
? `${probPercent} chance. ${stringDesc}`
: stringDesc
return {
question,
probability: probPercent,
metadata: contractTextDetails(contract),
creatorName,
creatorUsername,
creatorAvatarUrl,
description,
}
}

View File

@ -12,7 +12,7 @@ import { Spacer } from 'web/components/layout/spacer'
import { Row } from 'web/components/layout/row'
import { Challenge } from 'common/challenge'
import { useChallenge } from 'web/lib/firebase/challenges'
import { getChallengeUrl, useChallenge } from 'web/lib/firebase/challenges'
import { getPortfolioHistory, getUserByUsername } from 'web/lib/firebase/users'
import { PortfolioMetrics, User } from 'common/user'
import { Page } from 'web/components/page'
@ -20,7 +20,7 @@ import { useUser, useUserById } from 'web/hooks/use-user'
import { AcceptChallengeButton } from 'web/components/challenges/accept-challenge-button'
import { Avatar } from 'web/components/avatar'
import { UserLink } from 'web/components/user-page'
import { useEffect, useState } from 'react'
import React, { useEffect, useState } from 'react'
import { BinaryOutcomeLabel } from 'web/components/outcome-label'
import { formatMoney } from 'common/util/format'
import { last } from 'lodash'
@ -33,6 +33,9 @@ import {
PseudoNumericResolutionOrExpectation,
} from 'web/components/contract/contract-card'
import { ContractProbGraph } from 'web/components/contract/contract-prob-graph'
import { SEO } from 'web/components/SEO'
import { getOpenGraphProps } from 'web/components/contract/contract-card-preview'
export const getStaticProps = fromPropz(getStaticPropz)
export async function getStaticPropz(props: {
params: { username: string; contractSlug: string; challengeSlug: string }
@ -88,23 +91,39 @@ export default function ChallengePage(props: {
)
}
if (challenge.acceptances.length >= challenge.maxUses)
return (
<ClosedChallengeContent
contract={contract}
challenge={challenge}
creator={user}
bets={bets}
/>
)
const ogCardProps = getOpenGraphProps(contract)
return (
<OpenChallengeContent
user={currentUser}
contract={contract}
challenge={challenge}
creator={user}
bets={bets}
/>
<Page>
{ogCardProps && (
<SEO
title={
challenge.creatorName.split(' ')[0] +
' challenges you to a duel on: ' +
contract.question
}
description={ogCardProps.description}
url={getChallengeUrl(challenge)}
ogCardProps={ogCardProps}
/>
)}
{challenge.acceptances.length >= challenge.maxUses ? (
<ClosedChallengeContent
contract={contract}
challenge={challenge}
creator={user}
bets={bets}
/>
) : (
<OpenChallengeContent
user={currentUser}
contract={contract}
challenge={challenge}
creator={user}
bets={bets}
/>
)}
</Page>
)
}
@ -204,7 +223,7 @@ function ClosedChallengeContent(props: {
</Col>
)
return (
<Page>
<>
{showConfetti && (
<Confetti
width={width ?? 500}
@ -264,7 +283,7 @@ function ClosedChallengeContent(props: {
<Spacer h={3} />
<ChallengeContract contract={contract} bets={bets} />
</Col>
</Page>
</>
)
}
@ -390,7 +409,7 @@ function OpenChallengeContent(props: {
)
}
return (
<Page>
<>
<Col
ref={setContainerRef}
style={{ height: remainingHeight }}
@ -437,6 +456,6 @@ function OpenChallengeContent(props: {
/>
</Row>
</Col>
</Page>
</>
)
}