This commit is contained in:
		
						commit
						d9a6b6c431
					
				|  | @ -22,6 +22,8 @@ import { FileUploadButton } from './file-upload-button' | ||||||
| import { linkClass } from './site-link' | import { linkClass } from './site-link' | ||||||
| import { DisplayMention } from './editor/mention' | import { DisplayMention } from './editor/mention' | ||||||
| import { DisplayContractMention } from './editor/contract-mention' | import { DisplayContractMention } from './editor/contract-mention' | ||||||
|  | import GridComponent from './editor/tiptap-grid-cards' | ||||||
|  | 
 | ||||||
| import Iframe from 'common/util/tiptap-iframe' | import Iframe from 'common/util/tiptap-iframe' | ||||||
| import TiptapTweet from './editor/tiptap-tweet' | import TiptapTweet from './editor/tiptap-tweet' | ||||||
| import { EmbedModal } from './editor/embed-modal' | import { EmbedModal } from './editor/embed-modal' | ||||||
|  | @ -78,6 +80,7 @@ export const editorExtensions = (simple = false): Extensions => [ | ||||||
|   DisplayLink, |   DisplayLink, | ||||||
|   DisplayMention, |   DisplayMention, | ||||||
|   DisplayContractMention, |   DisplayContractMention, | ||||||
|  |   GridComponent, | ||||||
|   Iframe, |   Iframe, | ||||||
|   TiptapTweet, |   TiptapTweet, | ||||||
|   TiptapSpoiler.configure({ |   TiptapSpoiler.configure({ | ||||||
|  | @ -355,6 +358,7 @@ export function RichContent(props: { | ||||||
|       DisplayLink.configure({ openOnClick: false }), // stop link opening twice (browser still opens)
 |       DisplayLink.configure({ openOnClick: false }), // stop link opening twice (browser still opens)
 | ||||||
|       DisplayMention, |       DisplayMention, | ||||||
|       DisplayContractMention, |       DisplayContractMention, | ||||||
|  |       GridComponent, | ||||||
|       Iframe, |       Iframe, | ||||||
|       TiptapTweet, |       TiptapTweet, | ||||||
|       TiptapSpoiler.configure({ |       TiptapSpoiler.configure({ | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| import { Editor } from '@tiptap/react' | import { Editor } from '@tiptap/react' | ||||||
| import { Contract } from 'common/contract' | import { Contract } from 'common/contract' | ||||||
| import { SelectMarketsModal } from '../contract-select-modal' | import { SelectMarketsModal } from '../contract-select-modal' | ||||||
| import { embedContractCode, embedContractGridCode } from '../share-embed-button' | import { embedContractCode } from '../share-embed-button' | ||||||
| import { insertContent } from './utils' | import { insertContent } from './utils' | ||||||
| 
 | 
 | ||||||
| export function MarketModal(props: { | export function MarketModal(props: { | ||||||
|  | @ -15,7 +15,10 @@ export function MarketModal(props: { | ||||||
|     if (contracts.length == 1) { |     if (contracts.length == 1) { | ||||||
|       insertContent(editor, embedContractCode(contracts[0])) |       insertContent(editor, embedContractCode(contracts[0])) | ||||||
|     } else if (contracts.length > 1) { |     } 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 { | import { | ||||||
|   Contract, |   Contract, | ||||||
|   contracts, |   contracts, | ||||||
|  |   getContractFromId, | ||||||
|   listenForContract, |   listenForContract, | ||||||
| } from 'web/lib/firebase/contracts' | } from 'web/lib/firebase/contracts' | ||||||
| import { useStateCheckEquality } from './use-state-check-equality' | import { useStateCheckEquality } from './use-state-check-equality' | ||||||
| import { doc, DocumentData } from 'firebase/firestore' | import { doc, DocumentData } from 'firebase/firestore' | ||||||
|  | import { useQuery } from 'react-query' | ||||||
| 
 | 
 | ||||||
| export const useContract = (contractId: string) => { | export const useContract = (contractId: string) => { | ||||||
|   const result = useFirestoreDocumentData<DocumentData, Contract>( |   const result = useFirestoreDocumentData<DocumentData, Contract>( | ||||||
|  | @ -18,6 +20,17 @@ export const useContract = (contractId: string) => { | ||||||
|   return result.isLoading ? undefined : result.data |   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 = ( | export const useContractWithPreload = ( | ||||||
|   initial: Contract | null | undefined |   initial: Contract | null | undefined | ||||||
| ) => { | ) => { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user