New component to add arbitrary (but static) react embeds to posts programatically + midterms component (#1051)
This commit is contained in:
		
							parent
							
								
									4d214c01b4
								
							
						
					
					
						commit
						aaa09f49c0
					
				| 
						 | 
				
			
			@ -100,6 +100,7 @@ const stringParseExts = [
 | 
			
		|||
      '[embed]' + node.attrs.src ? `(${node.attrs.src})` : '',
 | 
			
		||||
  }),
 | 
			
		||||
  skippableComponent('gridCardsComponent'),
 | 
			
		||||
  skippableComponent('staticReactEmbedComponent'),
 | 
			
		||||
  TiptapTweet.extend({ renderText: () => '[tweet]' }),
 | 
			
		||||
  TiptapSpoiler.extend({ renderHTML: () => ['span', '[spoiler]', 0] }),
 | 
			
		||||
]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,6 +22,7 @@ import { linkClass } from './site-link'
 | 
			
		|||
import { DisplayMention } from './editor/mention'
 | 
			
		||||
import { DisplayContractMention } from './editor/contract-mention'
 | 
			
		||||
import GridComponent from './editor/tiptap-grid-cards'
 | 
			
		||||
import StaticReactEmbedComponent from './editor/tiptap-static-react-embed'
 | 
			
		||||
 | 
			
		||||
import Iframe from 'common/util/tiptap-iframe'
 | 
			
		||||
import TiptapTweet from './editor/tiptap-tweet'
 | 
			
		||||
| 
						 | 
				
			
			@ -81,6 +82,7 @@ export const editorExtensions = (simple = false): Extensions => [
 | 
			
		|||
  DisplayMention,
 | 
			
		||||
  DisplayContractMention,
 | 
			
		||||
  GridComponent,
 | 
			
		||||
  StaticReactEmbedComponent,
 | 
			
		||||
  Iframe,
 | 
			
		||||
  TiptapTweet,
 | 
			
		||||
  TiptapSpoiler.configure({
 | 
			
		||||
| 
						 | 
				
			
			@ -363,6 +365,7 @@ export function RichContent(props: {
 | 
			
		|||
      DisplayMention,
 | 
			
		||||
      DisplayContractMention,
 | 
			
		||||
      GridComponent,
 | 
			
		||||
      StaticReactEmbedComponent,
 | 
			
		||||
      Iframe,
 | 
			
		||||
      TiptapTweet,
 | 
			
		||||
      TiptapSpoiler.configure({
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										44
									
								
								web/components/editor/tiptap-static-react-embed.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								web/components/editor/tiptap-static-react-embed.tsx
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
import { mergeAttributes, Node } from '@tiptap/core'
 | 
			
		||||
import React from 'react'
 | 
			
		||||
import { NodeViewWrapper, ReactNodeViewRenderer } from '@tiptap/react'
 | 
			
		||||
import { StaticReactEmbed } from '../static-react-embed'
 | 
			
		||||
 | 
			
		||||
export default Node.create({
 | 
			
		||||
  name: 'staticReactEmbedComponent',
 | 
			
		||||
 | 
			
		||||
  group: 'block',
 | 
			
		||||
 | 
			
		||||
  atom: true,
 | 
			
		||||
 | 
			
		||||
  addAttributes() {
 | 
			
		||||
    return {
 | 
			
		||||
      embedName: '',
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  parseHTML() {
 | 
			
		||||
    return [
 | 
			
		||||
      {
 | 
			
		||||
        tag: 'static-react-embed-component',
 | 
			
		||||
      },
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  renderHTML({ HTMLAttributes }) {
 | 
			
		||||
    return ['static-react-embed-component', mergeAttributes(HTMLAttributes)]
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  addNodeView() {
 | 
			
		||||
    return ReactNodeViewRenderer(StaticReactEmbedComponent)
 | 
			
		||||
  },
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
export function StaticReactEmbedComponent(props: any) {
 | 
			
		||||
  const embedName = props.node.attrs.embedName
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <NodeViewWrapper className="static-react-embed-component">
 | 
			
		||||
      <StaticReactEmbed embedName={embedName} />
 | 
			
		||||
    </NodeViewWrapper>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										212
									
								
								web/components/midterms-maps.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										212
									
								
								web/components/midterms-maps.tsx
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,212 @@
 | 
			
		|||
import { useEffect } from 'react'
 | 
			
		||||
import { getContractFromSlug } from 'web/lib/firebase/contracts'
 | 
			
		||||
import {
 | 
			
		||||
  StateElectionMap,
 | 
			
		||||
  StateElectionMarket,
 | 
			
		||||
} from './usa-map/state-election-map'
 | 
			
		||||
import { useState } from 'react'
 | 
			
		||||
import { LoadingIndicator } from './loading-indicator'
 | 
			
		||||
import { CPMMBinaryContract } from 'common/contract'
 | 
			
		||||
 | 
			
		||||
export function MidtermsMaps(props: { mapType: string }) {
 | 
			
		||||
  const { mapType } = props
 | 
			
		||||
  const [contracts, setContracts] = useState<CPMMBinaryContract[] | null>(null)
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    const getContracts = async () => {
 | 
			
		||||
      if (props.mapType === 'senate') {
 | 
			
		||||
        const senateContracts = await Promise.all(
 | 
			
		||||
          senateMidterms.map((m) =>
 | 
			
		||||
            getContractFromSlug(m.slug).then((c) => c ?? null)
 | 
			
		||||
          )
 | 
			
		||||
        )
 | 
			
		||||
        setContracts(senateContracts as CPMMBinaryContract[])
 | 
			
		||||
      } else if (props.mapType === 'governor') {
 | 
			
		||||
        const governorContracts = await Promise.all(
 | 
			
		||||
          governorMidterms.map((m) =>
 | 
			
		||||
            getContractFromSlug(m.slug).then((c) => c ?? null)
 | 
			
		||||
          )
 | 
			
		||||
        )
 | 
			
		||||
        setContracts(governorContracts as CPMMBinaryContract[])
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    getContracts()
 | 
			
		||||
  }, [props.mapType, setContracts])
 | 
			
		||||
 | 
			
		||||
  return contracts ? (
 | 
			
		||||
    <StateElectionMap
 | 
			
		||||
      markets={mapType == 'senate' ? senateMidterms : governorMidterms}
 | 
			
		||||
      contracts={contracts}
 | 
			
		||||
    />
 | 
			
		||||
  ) : (
 | 
			
		||||
    <LoadingIndicator />
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const senateMidterms: StateElectionMarket[] = [
 | 
			
		||||
  {
 | 
			
		||||
    state: 'AZ',
 | 
			
		||||
    creatorUsername: 'BTE',
 | 
			
		||||
    slug: 'will-blake-masters-win-the-arizona',
 | 
			
		||||
    isWinRepublican: true,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'OH',
 | 
			
		||||
    creatorUsername: 'BTE',
 | 
			
		||||
    slug: 'will-jd-vance-win-the-ohio-senate-s',
 | 
			
		||||
    isWinRepublican: true,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'WI',
 | 
			
		||||
    creatorUsername: 'BTE',
 | 
			
		||||
    slug: 'will-ron-johnson-be-reelected-in-th',
 | 
			
		||||
    isWinRepublican: true,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'FL',
 | 
			
		||||
    creatorUsername: 'BTE',
 | 
			
		||||
    slug: 'will-marco-rubio-be-reelected-to-th',
 | 
			
		||||
    isWinRepublican: true,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'PA',
 | 
			
		||||
    creatorUsername: 'MattP',
 | 
			
		||||
    slug: 'will-dr-oz-be-elected-to-the-us-sen',
 | 
			
		||||
    isWinRepublican: true,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'GA',
 | 
			
		||||
    creatorUsername: 'NcyRocks',
 | 
			
		||||
    slug: 'will-a-democrat-win-the-2022-us-sen-3d2432ba6d79',
 | 
			
		||||
    isWinRepublican: false,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'NV',
 | 
			
		||||
    creatorUsername: 'NcyRocks',
 | 
			
		||||
    slug: 'will-a-democrat-win-the-2022-us-sen',
 | 
			
		||||
    isWinRepublican: false,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'NC',
 | 
			
		||||
    creatorUsername: 'NcyRocks',
 | 
			
		||||
    slug: 'will-a-democrat-win-the-2022-us-sen-6f1a901e1fcf',
 | 
			
		||||
    isWinRepublican: false,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'NH',
 | 
			
		||||
    creatorUsername: 'NcyRocks',
 | 
			
		||||
    slug: 'will-a-democrat-win-the-2022-us-sen-23194a72f1b7',
 | 
			
		||||
    isWinRepublican: false,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'UT',
 | 
			
		||||
    creatorUsername: 'SG',
 | 
			
		||||
    slug: 'will-mike-lee-win-the-2022-utah-sen',
 | 
			
		||||
    isWinRepublican: true,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'CO',
 | 
			
		||||
    creatorUsername: 'SG',
 | 
			
		||||
    slug: 'will-michael-bennet-win-the-2022-co',
 | 
			
		||||
    isWinRepublican: false,
 | 
			
		||||
  },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
const governorMidterms: StateElectionMarket[] = [
 | 
			
		||||
  {
 | 
			
		||||
    state: 'TX',
 | 
			
		||||
    creatorUsername: 'LarsDoucet',
 | 
			
		||||
    slug: 'republicans-will-win-the-2022-texas',
 | 
			
		||||
    isWinRepublican: true,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'GA',
 | 
			
		||||
    creatorUsername: 'MattP',
 | 
			
		||||
    slug: 'will-stacey-abrams-win-the-2022-geo',
 | 
			
		||||
    isWinRepublican: false,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'FL',
 | 
			
		||||
    creatorUsername: 'Tetraspace',
 | 
			
		||||
    slug: 'if-charlie-crist-is-the-democratic',
 | 
			
		||||
    isWinRepublican: false,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'PA',
 | 
			
		||||
    creatorUsername: 'JonathanMast',
 | 
			
		||||
    slug: 'will-josh-shapiro-win-the-2022-penn',
 | 
			
		||||
    isWinRepublican: false,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'PA',
 | 
			
		||||
    creatorUsername: 'JonathanMast',
 | 
			
		||||
    slug: 'will-josh-shapiro-win-the-2022-penn',
 | 
			
		||||
    isWinRepublican: false,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'CO',
 | 
			
		||||
    creatorUsername: 'ScottLawrence',
 | 
			
		||||
    slug: 'will-jared-polis-be-reelected-as-co',
 | 
			
		||||
    isWinRepublican: false,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'OR',
 | 
			
		||||
    creatorUsername: 'Tetraspace',
 | 
			
		||||
    slug: 'if-tina-kotek-is-the-2022-democrati',
 | 
			
		||||
    isWinRepublican: false,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'MD',
 | 
			
		||||
    creatorUsername: 'Tetraspace',
 | 
			
		||||
    slug: 'if-wes-moore-is-the-2022-democratic',
 | 
			
		||||
    isWinRepublican: false,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'AK',
 | 
			
		||||
    creatorUsername: 'SG',
 | 
			
		||||
    slug: 'will-a-republican-win-the-2022-alas',
 | 
			
		||||
    isWinRepublican: true,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'AZ',
 | 
			
		||||
    creatorUsername: 'SG',
 | 
			
		||||
    slug: 'will-a-republican-win-the-2022-ariz',
 | 
			
		||||
    isWinRepublican: true,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'AZ',
 | 
			
		||||
    creatorUsername: 'SG',
 | 
			
		||||
    slug: 'will-a-republican-win-the-2022-ariz',
 | 
			
		||||
    isWinRepublican: true,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'WI',
 | 
			
		||||
    creatorUsername: 'SG',
 | 
			
		||||
    slug: 'will-a-democrat-win-the-2022-wiscon',
 | 
			
		||||
    isWinRepublican: false,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'NV',
 | 
			
		||||
    creatorUsername: 'SG',
 | 
			
		||||
    slug: 'will-a-democrat-win-the-2022-nevada',
 | 
			
		||||
    isWinRepublican: false,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'KS',
 | 
			
		||||
    creatorUsername: 'SG',
 | 
			
		||||
    slug: 'will-a-democrat-win-the-2022-kansas',
 | 
			
		||||
    isWinRepublican: false,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'NV',
 | 
			
		||||
    creatorUsername: 'SG',
 | 
			
		||||
    slug: 'will-a-democrat-win-the-2022-new-me',
 | 
			
		||||
    isWinRepublican: false,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    state: 'ME',
 | 
			
		||||
    creatorUsername: 'SG',
 | 
			
		||||
    slug: 'will-a-democrat-win-the-2022-maine',
 | 
			
		||||
    isWinRepublican: false,
 | 
			
		||||
  },
 | 
			
		||||
]
 | 
			
		||||
							
								
								
									
										20
									
								
								web/components/static-react-embed.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								web/components/static-react-embed.tsx
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
import { useState, useEffect } from 'react'
 | 
			
		||||
import { MidtermsMaps } from './midterms-maps'
 | 
			
		||||
 | 
			
		||||
export function StaticReactEmbed(props: { embedName: string }) {
 | 
			
		||||
  const { embedName } = props
 | 
			
		||||
  const [embed, setEmbed] = useState<JSX.Element | null>(null)
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    const governorMidtermsMap = <MidtermsMaps mapType="governor" />
 | 
			
		||||
    const senateMidtermsMap = <MidtermsMaps mapType="senate" />
 | 
			
		||||
 | 
			
		||||
    if (embedName === 'governor-midterms-map') {
 | 
			
		||||
      setEmbed(governorMidtermsMap)
 | 
			
		||||
    } else if (embedName === 'senate-midterms-map') {
 | 
			
		||||
      setEmbed(senateMidtermsMap)
 | 
			
		||||
    }
 | 
			
		||||
  }, [embedName, setEmbed])
 | 
			
		||||
 | 
			
		||||
  return <div>{embed}</div>
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user