New implementation of market card embeddings (#1025)
* Grids of cards now implemented by rendering component instead of iframe * Sinclair's nit
This commit is contained in:
parent
59cdc9f776
commit
3fc53112b9
|
@ -22,6 +22,8 @@ import { FileUploadButton } from './file-upload-button'
|
|||
import { linkClass } from './site-link'
|
||||
import { DisplayMention } from './editor/mention'
|
||||
import { DisplayContractMention } from './editor/contract-mention'
|
||||
import GridComponent from './editor/tiptap-grid-cards'
|
||||
|
||||
import Iframe from 'common/util/tiptap-iframe'
|
||||
import TiptapTweet from './editor/tiptap-tweet'
|
||||
import { EmbedModal } from './editor/embed-modal'
|
||||
|
@ -78,6 +80,7 @@ export const editorExtensions = (simple = false): Extensions => [
|
|||
DisplayLink,
|
||||
DisplayMention,
|
||||
DisplayContractMention,
|
||||
GridComponent,
|
||||
Iframe,
|
||||
TiptapTweet,
|
||||
TiptapSpoiler.configure({
|
||||
|
@ -355,6 +358,7 @@ export function RichContent(props: {
|
|||
DisplayLink.configure({ openOnClick: false }), // stop link opening twice (browser still opens)
|
||||
DisplayMention,
|
||||
DisplayContractMention,
|
||||
GridComponent,
|
||||
Iframe,
|
||||
TiptapTweet,
|
||||
TiptapSpoiler.configure({
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Editor } from '@tiptap/react'
|
||||
import { Contract } from 'common/contract'
|
||||
import { SelectMarketsModal } from '../contract-select-modal'
|
||||
import { embedContractCode, embedContractGridCode } from '../share-embed-button'
|
||||
import { embedContractCode } from '../share-embed-button'
|
||||
import { insertContent } from './utils'
|
||||
|
||||
export function MarketModal(props: {
|
||||
|
@ -15,7 +15,10 @@ export function MarketModal(props: {
|
|||
if (contracts.length == 1) {
|
||||
insertContent(editor, embedContractCode(contracts[0]))
|
||||
} else if (contracts.length > 1) {
|
||||
insertContent(editor, embedContractGridCode(contracts))
|
||||
insertContent(
|
||||
editor,
|
||||
`<grid-cards-component contractIds="${contracts.map((c) => c.id)}" />`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
55
web/components/editor/tiptap-grid-cards.tsx
Normal file
55
web/components/editor/tiptap-grid-cards.tsx
Normal file
|
@ -0,0 +1,55 @@
|
|||
import { mergeAttributes, Node } from '@tiptap/core'
|
||||
import React from 'react'
|
||||
import { NodeViewWrapper, ReactNodeViewRenderer } from '@tiptap/react'
|
||||
import { ContractsGrid } from '../contract/contracts-grid'
|
||||
|
||||
import { useContractsFromIds } from 'web/hooks/use-contract'
|
||||
import { LoadingIndicator } from '../loading-indicator'
|
||||
|
||||
export default Node.create({
|
||||
name: 'gridCardsComponent',
|
||||
|
||||
group: 'block',
|
||||
|
||||
atom: true,
|
||||
|
||||
addAttributes() {
|
||||
return {
|
||||
contractIds: [],
|
||||
}
|
||||
},
|
||||
|
||||
parseHTML() {
|
||||
return [
|
||||
{
|
||||
tag: 'grid-cards-component',
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
renderHTML({ HTMLAttributes }) {
|
||||
return ['grid-cards-component', mergeAttributes(HTMLAttributes)]
|
||||
},
|
||||
|
||||
addNodeView() {
|
||||
return ReactNodeViewRenderer(GridComponent)
|
||||
},
|
||||
})
|
||||
|
||||
export function GridComponent(props: any) {
|
||||
const contractIds = props.node.attrs.contractIds
|
||||
const contracts = useContractsFromIds(contractIds.split(','))
|
||||
|
||||
return (
|
||||
<NodeViewWrapper className="grid-cards-component">
|
||||
{contracts ? (
|
||||
<ContractsGrid
|
||||
contracts={contracts}
|
||||
breakpointColumns={{ default: 2, 650: 1 }}
|
||||
/>
|
||||
) : (
|
||||
<LoadingIndicator />
|
||||
)}
|
||||
</NodeViewWrapper>
|
||||
)
|
||||
}
|
|
@ -3,10 +3,12 @@ import { useFirestoreDocumentData } from '@react-query-firebase/firestore'
|
|||
import {
|
||||
Contract,
|
||||
contracts,
|
||||
getContractFromId,
|
||||
listenForContract,
|
||||
} from 'web/lib/firebase/contracts'
|
||||
import { useStateCheckEquality } from './use-state-check-equality'
|
||||
import { doc, DocumentData } from 'firebase/firestore'
|
||||
import { useQuery } from 'react-query'
|
||||
|
||||
export const useContract = (contractId: string) => {
|
||||
const result = useFirestoreDocumentData<DocumentData, Contract>(
|
||||
|
@ -18,6 +20,17 @@ export const useContract = (contractId: string) => {
|
|||
return result.isLoading ? undefined : result.data
|
||||
}
|
||||
|
||||
export const useContractsFromIds = (contractIds: string[]) => {
|
||||
const contractResult = useQuery(['contracts', contractIds], () =>
|
||||
Promise.all(contractIds.map(getContractFromId))
|
||||
)
|
||||
const contracts = contractResult.data?.filter(
|
||||
(contract): contract is Contract => !!contract
|
||||
)
|
||||
|
||||
return contractResult.isLoading ? undefined : contracts
|
||||
}
|
||||
|
||||
export const useContractWithPreload = (
|
||||
initial: Contract | null | undefined
|
||||
) => {
|
||||
|
|
Loading…
Reference in New Issue
Block a user