Use the generated card in markets

This commit is contained in:
Austin Chen 2022-01-10 01:43:51 -05:00
parent 7ef42c376c
commit 2bf651993b
4 changed files with 76 additions and 2 deletions

View File

@ -1,12 +1,35 @@
import Head from 'next/head'
export type OpenGraphProps = {
question: string
probability: string
metadata: string
creatorName: string
creatorUsername: string
creatorAvatarUrl: string
}
function buildCardUrl(props: OpenGraphProps) {
// URL encode each of the props, then add them as query params
return (
`https://manifold-og-image.vercel.app/m.png` +
`?question=${encodeURIComponent(props.question)}` +
`&probability=${encodeURIComponent(props.probability)}` +
`&metadata=${encodeURIComponent(props.metadata)}` +
`&creatorName=${encodeURIComponent(props.creatorName)}` +
`&creatorUsername=${encodeURIComponent(props.creatorUsername)}` +
`&creatorAvatarUrl=${encodeURIComponent(props.creatorAvatarUrl)}`
)
}
export function SEO(props: {
title: string
description: string
url?: string
children?: any[]
openGraph?: OpenGraphProps
}) {
const { title, description, url, children } = props
const { title, description, url, children, openGraph } = props
return (
<Head>
@ -34,6 +57,22 @@ export function SEO(props: {
/>
)}
{openGraph && (
<>
<meta
property="og:image"
content={buildCardUrl(openGraph)}
key="image1"
/>
<meta name="twitter:card" content="summary_large_image" key="card" />
<meta
name="twitter:image"
content={buildCardUrl(openGraph)}
key="image2"
/>
</>
)}
{children}
</Head>
)

View File

@ -165,3 +165,24 @@ export function ContractDetails(props: { contract: Contract }) {
</Col>
)
}
// String version of the above, to send to the OpenGraph image generator
export function contractTextDetails(contract: Contract) {
const { question, description, closeTime } = contract
const { truePool, createdDate, resolvedDate } = compute(contract)
const tags = parseTags(`${question} ${description}`).map((tag) => `#${tag}`)
return (
`${contract.creatorUsername}${
resolvedDate ? `${createdDate} - ${resolvedDate}` : createdDate
}` +
(closeTime
? `${closeTime > Date.now() ? 'Closes' : 'Closed'} ${dayjs(
closeTime
).format('MMM D, h:mma')}`
: '') +
`${formatMoney(truePool)} pool` +
(tags.length > 0 ? `${tags.join(' ')}` : '')
)
}

View File

@ -18,6 +18,7 @@ import {
} from '../../lib/firebase/contracts'
import { SEO } from '../../components/SEO'
import { Page } from '../../components/page'
import { contractTextDetails } from '../../components/contract-card'
export async function getStaticProps(props: { params: any }) {
const { username, contractSlug } = props.params
@ -63,12 +64,23 @@ export default function ContractPage(props: {
? `Resolved ${resolution}. ${contract.description}`
: `${probPercent} chance. ${contract.description}`
const openGraphProps = {
question,
probability: probPercent,
metadata: contractTextDetails(contract),
creatorName: contract.creatorName,
creatorUsername: contract.creatorUsername,
// TODO: replace with actual avatar url
creatorAvatarUrl: `https://avatars.dicebear.com/v2/identicon/${contract.creatorUsername}.svg`,
}
return (
<Page wide={allowTrade}>
<SEO
title={question}
description={description}
url={`/${props.username}/${props.slug}`}
openGraph={openGraphProps}
/>
<Col className="w-full md:flex-row justify-between mt-6">

View File

@ -26,15 +26,17 @@ function MyApp({ Component, pageProps }: AppProps) {
key="description2"
/>
<meta property="og:url" content="https://manifold.markets" key="url" />
<meta name="twitter:card" content="summary" />
<meta name="twitter:card" content="summary" key="card" />
<meta name="twitter:site" content="@manifoldmarkets" />
<meta
property="og:image"
content="https://manifold.markets/logo-cover.png"
key="image1"
/>
<meta
name="twitter:image"
content="https://manifold.markets/logo-bg.png"
key="image2"
/>
</Head>