From 96be4e89925525d472d1e0f20cbc581e0ad62137 Mon Sep 17 00:00:00 2001 From: FRC Date: Thu, 1 Sep 2022 17:47:45 +0100 Subject: [PATCH] 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. --- common/util/tiptap-iframe.ts | 10 +++++- web/components/contract/contracts-grid.tsx | 3 +- web/components/editor/market-modal.tsx | 17 +++++++--- web/components/share-embed-button.tsx | 13 ++++++-- web/pages/create-post.tsx | 2 +- web/pages/embed/grid/[...slugs]/index.tsx | 37 ++++++++++++++++++++++ 6 files changed, 72 insertions(+), 10 deletions(-) create mode 100644 web/pages/embed/grid/[...slugs]/index.tsx diff --git a/common/util/tiptap-iframe.ts b/common/util/tiptap-iframe.ts index 5af63d2f..9e260821 100644 --- a/common/util/tiptap-iframe.ts +++ b/common/util/tiptap-iframe.ts @@ -35,7 +35,7 @@ export default Node.create({ 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({ frameborder: { default: 0, }, + height: { + default: 0, + }, allowfullscreen: { default: this.options.allowFullscreen, parseHTML: () => this.options.allowFullscreen, @@ -60,6 +63,11 @@ export default Node.create({ }, renderHTML({ HTMLAttributes }) { + this.options.HTMLAttributes.style = + this.options.HTMLAttributes.style + + ' height: ' + + HTMLAttributes.height + + ';' return [ 'div', this.options.HTMLAttributes, diff --git a/web/components/contract/contracts-grid.tsx b/web/components/contract/contracts-grid.tsx index 2f804644..3a09a167 100644 --- a/web/components/contract/contracts-grid.tsx +++ b/web/components/contract/contracts-grid.tsx @@ -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: { diff --git a/web/components/editor/market-modal.tsx b/web/components/editor/market-modal.tsx index a81953de..31c437b1 100644 --- a/web/components/editor/market-modal.tsx +++ b/web/components/editor/market-modal.tsx @@ -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 && ( - {contracts.length > 0 && ( + {contracts.length == 1 && ( + )} + {contracts.length > 1 && ( + )} diff --git a/web/components/share-embed-button.tsx b/web/components/share-embed-button.tsx index cfbe78f0..a42ffc34 100644 --- a/web/components/share-embed-button.tsx +++ b/web/components/share-embed-button.tsx @@ -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 `` +} - return `` +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 `` } 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, }) diff --git a/web/pages/create-post.tsx b/web/pages/create-post.tsx index f88f56a5..01147cc0 100644 --- a/web/pages/create-post.tsx +++ b/web/pages/create-post.tsx @@ -41,7 +41,7 @@ export default function CreatePost() { return ( -
+
<form> diff --git a/web/pages/embed/grid/[...slugs]/index.tsx b/web/pages/embed/grid/[...slugs]/index.tsx new file mode 100644 index 00000000..7500665f --- /dev/null +++ b/web/pages/embed/grid/[...slugs]/index.tsx @@ -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 }} + /> + </> + ) +}