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:
parent
7310cf3d4a
commit
96be4e8992
|
@ -48,6 +48,9 @@ export default Node.create<IframeOptions>({
|
||||||
frameborder: {
|
frameborder: {
|
||||||
default: 0,
|
default: 0,
|
||||||
},
|
},
|
||||||
|
height: {
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
allowfullscreen: {
|
allowfullscreen: {
|
||||||
default: this.options.allowFullscreen,
|
default: this.options.allowFullscreen,
|
||||||
parseHTML: () => this.options.allowFullscreen,
|
parseHTML: () => this.options.allowFullscreen,
|
||||||
|
@ -60,6 +63,11 @@ export default Node.create<IframeOptions>({
|
||||||
},
|
},
|
||||||
|
|
||||||
renderHTML({ HTMLAttributes }) {
|
renderHTML({ HTMLAttributes }) {
|
||||||
|
this.options.HTMLAttributes.style =
|
||||||
|
this.options.HTMLAttributes.style +
|
||||||
|
' height: ' +
|
||||||
|
HTMLAttributes.height +
|
||||||
|
';'
|
||||||
return [
|
return [
|
||||||
'div',
|
'div',
|
||||||
this.options.HTMLAttributes,
|
this.options.HTMLAttributes,
|
||||||
|
|
|
@ -27,6 +27,7 @@ export function ContractsGrid(props: {
|
||||||
}
|
}
|
||||||
highlightOptions?: ContractHighlightOptions
|
highlightOptions?: ContractHighlightOptions
|
||||||
trackingPostfix?: string
|
trackingPostfix?: string
|
||||||
|
breakpointColumns?: { [key: string]: number }
|
||||||
}) {
|
}) {
|
||||||
const {
|
const {
|
||||||
contracts,
|
contracts,
|
||||||
|
@ -67,7 +68,7 @@ export function ContractsGrid(props: {
|
||||||
<Col className="gap-8">
|
<Col className="gap-8">
|
||||||
<Masonry
|
<Masonry
|
||||||
// Show only 1 column on tailwind's md breakpoint (768px)
|
// 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"
|
className="-ml-4 flex w-auto"
|
||||||
columnClassName="pl-4 bg-clip-padding"
|
columnClassName="pl-4 bg-clip-padding"
|
||||||
>
|
>
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { Col } from '../layout/col'
|
||||||
import { Modal } from '../layout/modal'
|
import { Modal } from '../layout/modal'
|
||||||
import { Row } from '../layout/row'
|
import { Row } from '../layout/row'
|
||||||
import { LoadingIndicator } from '../loading-indicator'
|
import { LoadingIndicator } from '../loading-indicator'
|
||||||
import { embedCode } from '../share-embed-button'
|
import { embedContractCode, embedContractGridCode } from '../share-embed-button'
|
||||||
import { insertContent } from './utils'
|
import { insertContent } from './utils'
|
||||||
|
|
||||||
export function MarketModal(props: {
|
export function MarketModal(props: {
|
||||||
|
@ -28,7 +28,11 @@ export function MarketModal(props: {
|
||||||
|
|
||||||
async function doneAddingContracts() {
|
async function doneAddingContracts() {
|
||||||
setLoading(true)
|
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)
|
setLoading(false)
|
||||||
setOpen(false)
|
setOpen(false)
|
||||||
setContracts([])
|
setContracts([])
|
||||||
|
@ -42,9 +46,14 @@ export function MarketModal(props: {
|
||||||
|
|
||||||
{!loading && (
|
{!loading && (
|
||||||
<Row className="grow justify-end gap-4">
|
<Row className="grow justify-end gap-4">
|
||||||
{contracts.length > 0 && (
|
{contracts.length == 1 && (
|
||||||
<Button onClick={doneAddingContracts} color={'indigo'}>
|
<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'}
|
{contracts.length > 1 && 's'}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -9,11 +9,18 @@ import { DOMAIN } from 'common/envs/constants'
|
||||||
import { copyToClipboard } from 'web/lib/util/copy'
|
import { copyToClipboard } from 'web/lib/util/copy'
|
||||||
import { track } from 'web/lib/service/analytics'
|
import { track } from 'web/lib/service/analytics'
|
||||||
|
|
||||||
export function embedCode(contract: Contract) {
|
export function embedContractCode(contract: Contract) {
|
||||||
const title = contract.question
|
const title = contract.question
|
||||||
const src = `https://${DOMAIN}/embed${contractPath(contract)}`
|
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 }) {
|
export function ShareEmbedButton(props: { contract: Contract }) {
|
||||||
|
@ -26,7 +33,7 @@ export function ShareEmbedButton(props: { contract: Contract }) {
|
||||||
as="div"
|
as="div"
|
||||||
className="relative z-10 flex-shrink-0"
|
className="relative z-10 flex-shrink-0"
|
||||||
onMouseUp={() => {
|
onMouseUp={() => {
|
||||||
copyToClipboard(embedCode(contract))
|
copyToClipboard(embedContractCode(contract))
|
||||||
toast.success('Embed code copied!', {
|
toast.success('Embed code copied!', {
|
||||||
icon: codeIcon,
|
icon: codeIcon,
|
||||||
})
|
})
|
||||||
|
|
|
@ -41,7 +41,7 @@ export default function CreatePost() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page>
|
<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">
|
<div className="rounded-lg px-6 py-4 sm:py-0">
|
||||||
<Title className="!mt-0" text="Create a post" />
|
<Title className="!mt-0" text="Create a post" />
|
||||||
<form>
|
<form>
|
||||||
|
|
37
web/pages/embed/grid/[...slugs]/index.tsx
Normal file
37
web/pages/embed/grid/[...slugs]/index.tsx
Normal 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 }}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user