Use the generated card in markets
This commit is contained in:
parent
7ef42c376c
commit
2bf651993b
|
@ -1,12 +1,35 @@
|
||||||
import Head from 'next/head'
|
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: {
|
export function SEO(props: {
|
||||||
title: string
|
title: string
|
||||||
description: string
|
description: string
|
||||||
url?: string
|
url?: string
|
||||||
children?: any[]
|
children?: any[]
|
||||||
|
openGraph?: OpenGraphProps
|
||||||
}) {
|
}) {
|
||||||
const { title, description, url, children } = props
|
const { title, description, url, children, openGraph } = props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Head>
|
<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}
|
{children}
|
||||||
</Head>
|
</Head>
|
||||||
)
|
)
|
||||||
|
|
|
@ -165,3 +165,24 @@ export function ContractDetails(props: { contract: Contract }) {
|
||||||
</Col>
|
</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(' ')}` : '')
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import {
|
||||||
} from '../../lib/firebase/contracts'
|
} from '../../lib/firebase/contracts'
|
||||||
import { SEO } from '../../components/SEO'
|
import { SEO } from '../../components/SEO'
|
||||||
import { Page } from '../../components/page'
|
import { Page } from '../../components/page'
|
||||||
|
import { contractTextDetails } from '../../components/contract-card'
|
||||||
|
|
||||||
export async function getStaticProps(props: { params: any }) {
|
export async function getStaticProps(props: { params: any }) {
|
||||||
const { username, contractSlug } = props.params
|
const { username, contractSlug } = props.params
|
||||||
|
@ -63,12 +64,23 @@ export default function ContractPage(props: {
|
||||||
? `Resolved ${resolution}. ${contract.description}`
|
? `Resolved ${resolution}. ${contract.description}`
|
||||||
: `${probPercent} chance. ${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 (
|
return (
|
||||||
<Page wide={allowTrade}>
|
<Page wide={allowTrade}>
|
||||||
<SEO
|
<SEO
|
||||||
title={question}
|
title={question}
|
||||||
description={description}
|
description={description}
|
||||||
url={`/${props.username}/${props.slug}`}
|
url={`/${props.username}/${props.slug}`}
|
||||||
|
openGraph={openGraphProps}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Col className="w-full md:flex-row justify-between mt-6">
|
<Col className="w-full md:flex-row justify-between mt-6">
|
||||||
|
|
|
@ -26,15 +26,17 @@ function MyApp({ Component, pageProps }: AppProps) {
|
||||||
key="description2"
|
key="description2"
|
||||||
/>
|
/>
|
||||||
<meta property="og:url" content="https://manifold.markets" key="url" />
|
<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 name="twitter:site" content="@manifoldmarkets" />
|
||||||
<meta
|
<meta
|
||||||
property="og:image"
|
property="og:image"
|
||||||
content="https://manifold.markets/logo-cover.png"
|
content="https://manifold.markets/logo-cover.png"
|
||||||
|
key="image1"
|
||||||
/>
|
/>
|
||||||
<meta
|
<meta
|
||||||
name="twitter:image"
|
name="twitter:image"
|
||||||
content="https://manifold.markets/logo-bg.png"
|
content="https://manifold.markets/logo-bg.png"
|
||||||
|
key="image2"
|
||||||
/>
|
/>
|
||||||
</Head>
|
</Head>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user