Map fixes (#1011)
* usa map: fix sizing * useSetIframeBackbroundColor * preload contracts * seo
This commit is contained in:
		
							parent
							
								
									a53fb49ec3
								
							
						
					
					
						commit
						f8ec306ee9
					
				|  | @ -3,12 +3,9 @@ import Router from 'next/router' | |||
| import { useEffect, useState } from 'react' | ||||
| 
 | ||||
| import { getProbability } from 'common/calculate' | ||||
| import { Contract, CPMMBinaryContract } from 'common/contract' | ||||
| import { CPMMBinaryContract } from 'common/contract' | ||||
| import { Customize, USAMap } from './usa-map' | ||||
| import { | ||||
|   getContractFromSlug, | ||||
|   listenForContract, | ||||
| } from 'web/lib/firebase/contracts' | ||||
| import { listenForContract } from 'web/lib/firebase/contracts' | ||||
| import { interpolateColor } from 'common/util/color' | ||||
| 
 | ||||
| export interface StateElectionMarket { | ||||
|  | @ -18,10 +15,14 @@ export interface StateElectionMarket { | |||
|   state: string | ||||
| } | ||||
| 
 | ||||
| export function StateElectionMap(props: { markets: StateElectionMarket[] }) { | ||||
| export function StateElectionMap(props: { | ||||
|   markets: StateElectionMarket[] | ||||
|   contracts: CPMMBinaryContract[] | ||||
| }) { | ||||
|   const { markets } = props | ||||
|   const [contracts, setContracts] = useState(props.contracts) | ||||
|   useUpdateContracts(contracts, setContracts) | ||||
| 
 | ||||
|   const contracts = useContracts(markets.map((m) => m.slug)) | ||||
|   const probs = contracts.map((c) => | ||||
|     c ? getProbability(c as CPMMBinaryContract) : 0.5 | ||||
|   ) | ||||
|  | @ -50,29 +51,23 @@ const probToColor = (prob: number, isWinRepublican: boolean) => { | |||
|   return interpolateColor('#ebe4ec', color, Math.abs(p - 0.5) * 2) | ||||
| } | ||||
| 
 | ||||
| const useContracts = (slugs: string[]) => { | ||||
|   const [contracts, setContracts] = useState<(Contract | undefined)[]>( | ||||
|     slugs.map(() => undefined) | ||||
|   ) | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     Promise.all(slugs.map((slug) => getContractFromSlug(slug))).then( | ||||
|       (contracts) => setContracts(contracts) | ||||
|     ) | ||||
|   }, [slugs]) | ||||
| 
 | ||||
| const useUpdateContracts = ( | ||||
|   contracts: CPMMBinaryContract[], | ||||
|   setContracts: (newContracts: CPMMBinaryContract[]) => void | ||||
| ) => { | ||||
|   useEffect(() => { | ||||
|     if (contracts.some((c) => c === undefined)) return | ||||
| 
 | ||||
|     // listen to contract updates
 | ||||
|     const unsubs = (contracts as Contract[]).map((c, i) => | ||||
|     const unsubs = contracts.map((c, i) => | ||||
|       listenForContract( | ||||
|         c.id, | ||||
|         (newC) => newC && setContracts(setAt(contracts, i, newC)) | ||||
|         (newC) => | ||||
|           newC && setContracts(setAt(contracts, i, newC as CPMMBinaryContract)) | ||||
|       ) | ||||
|     ) | ||||
|     return () => unsubs.forEach((u) => u()) | ||||
|   }, [contracts]) | ||||
|   }, [contracts, setContracts]) | ||||
| 
 | ||||
|   return contracts | ||||
| } | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| // https://github.com/jb-1980/usa-map-react
 | ||||
| // MIT License
 | ||||
| 
 | ||||
| import clsx from 'clsx' | ||||
| import { DATA } from './data' | ||||
| import { USAState } from './usa-state' | ||||
| 
 | ||||
|  | @ -65,40 +66,38 @@ export const USAMap = ({ | |||
|   const stateClickHandler = (state: string) => customize?.[state]?.clickHandler | ||||
| 
 | ||||
|   return ( | ||||
|     <div className="flex w-full"> | ||||
|       <svg | ||||
|         className={className} | ||||
|         xmlns="http://www.w3.org/2000/svg" | ||||
|         viewBox="0 0 959 593" | ||||
|       > | ||||
|         <title>{title}</title> | ||||
|         <g className="outlines"> | ||||
|           {States({ | ||||
|             hideStateTitle, | ||||
|             fillStateColor, | ||||
|             stateClickHandler, | ||||
|           })} | ||||
|           <g className="DC state"> | ||||
|             <path | ||||
|               className="DC1" | ||||
|               fill={fillStateColor('DC1')} | ||||
|               d="M801.8,253.8 l-1.1-1.6 -1-0.8 1.1-1.6 2.2,1.5z" | ||||
|             /> | ||||
|             <circle | ||||
|               className="DC2" | ||||
|               onClick={onClick} | ||||
|               data-name={'DC'} | ||||
|               fill={fillStateColor('DC2')} | ||||
|               stroke="#FFFFFF" | ||||
|               strokeWidth="1.5" | ||||
|               cx="801.3" | ||||
|               cy="251.8" | ||||
|               r="5" | ||||
|               opacity="1" | ||||
|             /> | ||||
|           </g> | ||||
|     <svg | ||||
|       className={clsx('flex h-96 w-full sm:h-full', className)} | ||||
|       xmlns="http://www.w3.org/2000/svg" | ||||
|       viewBox="0 0 959 593" | ||||
|     > | ||||
|       <title>{title}</title> | ||||
|       <g className="outlines"> | ||||
|         {States({ | ||||
|           hideStateTitle, | ||||
|           fillStateColor, | ||||
|           stateClickHandler, | ||||
|         })} | ||||
|         <g className="DC state"> | ||||
|           <path | ||||
|             className="DC1" | ||||
|             fill={fillStateColor('DC1')} | ||||
|             d="M801.8,253.8 l-1.1-1.6 -1-0.8 1.1-1.6 2.2,1.5z" | ||||
|           /> | ||||
|           <circle | ||||
|             className="DC2" | ||||
|             onClick={onClick} | ||||
|             data-name={'DC'} | ||||
|             fill={fillStateColor('DC2')} | ||||
|             stroke="#FFFFFF" | ||||
|             strokeWidth="1.5" | ||||
|             cx="801.3" | ||||
|             cy="251.8" | ||||
|             r="5" | ||||
|             opacity="1" | ||||
|           /> | ||||
|         </g> | ||||
|       </svg> | ||||
|     </div> | ||||
|       </g> | ||||
|     </svg> | ||||
|   ) | ||||
| } | ||||
|  |  | |||
|  | @ -1,11 +1,15 @@ | |||
| import { CPMMBinaryContract } from 'common/contract' | ||||
| import { useEffect } from 'react' | ||||
| import { Col } from 'web/components/layout/col' | ||||
| import { Spacer } from 'web/components/layout/spacer' | ||||
| import { Page } from 'web/components/page' | ||||
| import { SEO } from 'web/components/SEO' | ||||
| import { Title } from 'web/components/title' | ||||
| import { | ||||
|   StateElectionMarket, | ||||
|   StateElectionMap, | ||||
| } from 'web/components/usa-map/state-election-map' | ||||
| import { getContractFromSlug } from 'web/lib/firebase/contracts' | ||||
| 
 | ||||
| const senateMidterms: StateElectionMarket[] = [ | ||||
|   { | ||||
|  | @ -175,27 +179,60 @@ const governorMidterms: StateElectionMarket[] = [ | |||
|   }, | ||||
| ] | ||||
| 
 | ||||
| const App = () => { | ||||
| export async function getStaticProps() { | ||||
|   const senateContracts = await Promise.all( | ||||
|     senateMidterms.map((m) => getContractFromSlug(m.slug)) | ||||
|   ) | ||||
| 
 | ||||
|   const governorContracts = await Promise.all( | ||||
|     governorMidterms.map((m) => getContractFromSlug(m.slug)) | ||||
|   ) | ||||
| 
 | ||||
|   return { | ||||
|     props: { senateContracts, governorContracts }, | ||||
|     revalidate: 60, // regenerate after a minute
 | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const App = (props: { | ||||
|   senateContracts: CPMMBinaryContract[] | ||||
|   governorContracts: CPMMBinaryContract[] | ||||
| }) => { | ||||
|   useSetIframeBackbroundColor() | ||||
|   const { senateContracts, governorContracts } = props | ||||
| 
 | ||||
|   return ( | ||||
|     <Page className=""> | ||||
|       <Col className="items-center justify-center"> | ||||
|         <Title text="2022 US Midterm Elections" className="mt-2" /> | ||||
|         <SEO | ||||
|           title="2022 US Midterm Elections" | ||||
|           description="Bet on the midterm elections using prediction markets. See Manifold's state-by-state breakdown of senate and governor races." | ||||
|         /> | ||||
|         <div className="mt-2 text-2xl">Senate</div> | ||||
|         <StateElectionMap markets={senateMidterms} /> | ||||
|         <StateElectionMap | ||||
|           markets={senateMidterms} | ||||
|           contracts={senateContracts} | ||||
|         /> | ||||
|         <iframe | ||||
|           src="https://manifold.markets/TomShlomi/will-the-gop-control-the-us-senate" | ||||
|           frameBorder="0" | ||||
|           className="mt-8 flex h-96 w-full" | ||||
|         ></iframe> | ||||
|         <Spacer h={8} /> | ||||
| 
 | ||||
|         <div className="mt-8 text-2xl">Governors</div> | ||||
|         <StateElectionMap markets={governorMidterms} /> | ||||
|         <StateElectionMap | ||||
|           markets={governorMidterms} | ||||
|           contracts={governorContracts} | ||||
|         /> | ||||
|         <iframe | ||||
|           src="https://manifold.markets/ManifoldMarkets/democrats-go-down-at-least-one-gove" | ||||
|           frameBorder="0" | ||||
|           className="mt-8 flex h-96 w-full" | ||||
|         ></iframe> | ||||
|         <Spacer h={8} /> | ||||
| 
 | ||||
|         <div className="mt-8 text-2xl">House</div> | ||||
|         <iframe | ||||
|           src="https://manifold.markets/BoltonBailey/will-democrats-maintain-control-of" | ||||
|  | @ -203,6 +240,7 @@ const App = () => { | |||
|           className="mt-8 flex h-96 w-full" | ||||
|         ></iframe> | ||||
|         <Spacer h={8} /> | ||||
| 
 | ||||
|         <div className="mt-8 text-2xl">Related markets</div> | ||||
|         <iframe | ||||
|           src="https://manifold.markets/BoltonBailey/balance-of-power-in-us-congress-aft" | ||||
|  | @ -232,4 +270,13 @@ const App = () => { | |||
|   ) | ||||
| } | ||||
| 
 | ||||
| const useSetIframeBackbroundColor = () => { | ||||
|   useEffect(() => { | ||||
|     if (window.location.host !== 'manifold.markets') return | ||||
|     for (let i = 0; i < self.frames.length; i++) { | ||||
|       self.frames[i].document.body.style.backgroundColor = '#f9fafb' | ||||
|     } | ||||
|   }, []) | ||||
| } | ||||
| 
 | ||||
| export default App | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user