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: {
|
||||
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,
|
||||
|
|
|
@ -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"
|
||||
>
|
||||
|
|
|
@ -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>
|
||||
)}
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
|
|
|
@ -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>
|
||||
|
|
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