Add embedded ContractGrid to Posts (#822)

* Add embedded market grids

* Hacky way to set height

I haven't figured out a way yet to get the height of the actual iframe's content, so I did some bad estimate for now to unblock shipping the feature, while I continue investigating.
This commit is contained in:
FRC 2022-09-01 17:47:45 +01:00 committed by GitHub
parent 7310cf3d4a
commit 96be4e8992
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 72 additions and 10 deletions

View File

@ -35,7 +35,7 @@ export default Node.create<IframeOptions>({
HTMLAttributes: {
class: 'iframe-wrapper' + ' ' + wrapperClasses,
// Tailwind JIT doesn't seem to pick up `pb-[20rem]`, so we hack this in:
style: 'padding-bottom: 20rem;',
style: 'padding-bottom: 20rem; ',
},
}
},
@ -48,6 +48,9 @@ export default Node.create<IframeOptions>({
frameborder: {
default: 0,
},
height: {
default: 0,
},
allowfullscreen: {
default: this.options.allowFullscreen,
parseHTML: () => this.options.allowFullscreen,
@ -60,6 +63,11 @@ export default Node.create<IframeOptions>({
},
renderHTML({ HTMLAttributes }) {
this.options.HTMLAttributes.style =
this.options.HTMLAttributes.style +
' height: ' +
HTMLAttributes.height +
';'
return [
'div',
this.options.HTMLAttributes,

View File

@ -27,6 +27,7 @@ export function ContractsGrid(props: {
}
highlightOptions?: ContractHighlightOptions
trackingPostfix?: string
breakpointColumns?: { [key: string]: number }
}) {
const {
contracts,
@ -67,7 +68,7 @@ export function ContractsGrid(props: {
<Col className="gap-8">
<Masonry
// Show only 1 column on tailwind's md breakpoint (768px)
breakpointCols={{ default: 2, 768: 1 }}
breakpointCols={props.breakpointColumns ?? { default: 2, 768: 1 }}
className="-ml-4 flex w-auto"
columnClassName="pl-4 bg-clip-padding"
>

View File

@ -7,7 +7,7 @@ import { Col } from '../layout/col'
import { Modal } from '../layout/modal'
import { Row } from '../layout/row'
import { LoadingIndicator } from '../loading-indicator'
import { embedCode } from '../share-embed-button'
import { embedContractCode, embedContractGridCode } from '../share-embed-button'
import { insertContent } from './utils'
export function MarketModal(props: {
@ -28,7 +28,11 @@ export function MarketModal(props: {
async function doneAddingContracts() {
setLoading(true)
insertContent(editor, ...contracts.map(embedCode))
if (contracts.length == 1) {
insertContent(editor, embedContractCode(contracts[0]))
} else if (contracts.length > 1) {
insertContent(editor, embedContractGridCode(contracts))
}
setLoading(false)
setOpen(false)
setContracts([])
@ -42,9 +46,14 @@ export function MarketModal(props: {
{!loading && (
<Row className="grow justify-end gap-4">
{contracts.length > 0 && (
{contracts.length == 1 && (
<Button onClick={doneAddingContracts} color={'indigo'}>
Embed {contracts.length} question
Embed 1 question
</Button>
)}
{contracts.length > 1 && (
<Button onClick={doneAddingContracts} color={'indigo'}>
Embed grid of {contracts.length} question
{contracts.length > 1 && 's'}
</Button>
)}

View File

@ -9,11 +9,18 @@ import { DOMAIN } from 'common/envs/constants'
import { copyToClipboard } from 'web/lib/util/copy'
import { track } from 'web/lib/service/analytics'
export function embedCode(contract: Contract) {
export function embedContractCode(contract: Contract) {
const title = contract.question
const src = `https://${DOMAIN}/embed${contractPath(contract)}`
return `<iframe src="${src}" title="${title}" frameborder="0"></iframe>`
}
return `<iframe width="560" height="405" src="${src}" title="${title}" frameborder="0"></iframe>`
export function embedContractGridCode(contracts: Contract[]) {
const height = (contracts.length - (contracts.length % 2)) * 100 + 'px'
const src = `http://${DOMAIN}/embed/grid/${contracts
.map((c) => c.slug)
.join('/')}`
return `<iframe height="${height}" src="${src}" title="Grid of contracts" frameborder="0"></iframe>`
}
export function ShareEmbedButton(props: { contract: Contract }) {
@ -26,7 +33,7 @@ export function ShareEmbedButton(props: { contract: Contract }) {
as="div"
className="relative z-10 flex-shrink-0"
onMouseUp={() => {
copyToClipboard(embedCode(contract))
copyToClipboard(embedContractCode(contract))
toast.success('Embed code copied!', {
icon: codeIcon,
})

View File

@ -41,7 +41,7 @@ export default function CreatePost() {
return (
<Page>
<div className="mx-auto w-full max-w-2xl">
<div className="mx-auto w-full max-w-3xl">
<div className="rounded-lg px-6 py-4 sm:py-0">
<Title className="!mt-0" text="Create a post" />
<form>

View File

@ -0,0 +1,37 @@
import React from 'react'
import { Contract, getContractFromSlug } from 'web/lib/firebase/contracts'
import { ContractsGrid } from 'web/components/contract/contracts-grid'
export async function getStaticProps(props: { params: { slugs: string[] } }) {
const { slugs } = props.params
const contracts = (await Promise.all(
slugs.map((slug) =>
getContractFromSlug(slug) != null ? getContractFromSlug(slug) : []
)
)) as Contract[]
return {
props: {
contracts,
},
revalidate: 60, // regenerate after a minute
}
}
export async function getStaticPaths() {
return { paths: [], fallback: 'blocking' }
}
export default function ContractGridPage(props: { contracts: Contract[] }) {
const { contracts } = props
return (
<>
<ContractsGrid
contracts={contracts}
breakpointColumns={{ default: 2, 650: 1 }}
/>
</>
)
}