diff --git a/src/geographic-selection-provider.tsx b/src/geographic-selection-provider.tsx index 9bd4f37..75bb62c 100644 --- a/src/geographic-selection-provider.tsx +++ b/src/geographic-selection-provider.tsx @@ -7,18 +7,24 @@ interface GeographicPageProps { setHoveredConcept: React.Dispatch>; presentNations: string[]; setPresentNations: React.Dispatch>; + quizSelectedCountries: string[]; + setQuizSelectedCountries: React.Dispatch>; } -const GeographicPageContext = createContext< - GeographicPageProps | undefined ->(undefined); +const GeographicPageContext = createContext( + undefined +); export const GeographicPageProvider: React.FC<{ children: React.ReactNode; }> = ({ children }) => { + const [selectedCountry, setSelectedCountry] = useState(null); const [hoveredConcept, setHoveredConcept] = useState(null); const [presentNations, setPresentNations] = useState([]); + const [quizSelectedCountries, setQuizSelectedCountries] = useState( + [] + ); return ( {children} @@ -44,4 +52,4 @@ export const useGeographicPageContext = () => { ); } return context; -}; \ No newline at end of file +}; diff --git a/src/geographic-selection.tsx b/src/geographic-selection.tsx index e44e02d..1040a54 100644 --- a/src/geographic-selection.tsx +++ b/src/geographic-selection.tsx @@ -118,36 +118,35 @@ export const InnerGeographicSelection: React.FC<{ return (
-
- - -
-
-
- -
-
- -
+
+ + +
+
+
+ +
+
+
- - {selectedCountry && - (() => { - const { timePeriod, ...notes } = - countryNotes[selectedCountry] || - generalNotes[selectedCountry]; - return ( - setSelectedCountry(null)}> - - - ); - })()}
+ + {selectedCountry && + (() => { + const { timePeriod, ...notes } = + countryNotes[selectedCountry] || generalNotes[selectedCountry]; + return ( + setSelectedCountry(null)}> + + + ); + })()} +
); @@ -242,8 +241,12 @@ const MapHandler: React.FC<{ const mapRef = useRef(null); const [canScrollRight, setCanScrollRight] = useState(false); const [canScrollLeft, setCanScrollLeft] = useState(false); - const { hoveredConcept, setPresentNations, setSelectedCountry } = - useGeographicPageContext(); + const { + hoveredConcept, + setPresentNations, + setSelectedCountry, + quizSelectedCountries, + } = useGeographicPageContext(); useEffect(() => { const svgEl = mapRef.current; @@ -294,20 +297,26 @@ const MapHandler: React.FC<{ const countryStyles = useMemo(() => { const styles: Record = {}; nations.forEach((nation) => { + const quizSelected = quizSelectedCountries.includes(nation); const isHighlighted = - hoveredConcept && - generalNotes[hoveredConcept]?.applicableCountries.includes(nation); + quizSelected || + (hoveredConcept && + generalNotes[hoveredConcept]?.applicableCountries.includes(nation)); styles[`[data-country="${nation}"]`] = { - fill: countryColors[nation], + fill: (!quizSelected) ? countryColors[nation] : (quizSelectedCountries[0] === nation) ? "blue" : "red", cursor: "pointer", - opacity: isHighlighted ? 1 : hoveredConcept ? 0.3 : 1, + opacity: isHighlighted + ? 1 + : hoveredConcept || quizSelectedCountries.length > 0 + ? 0.3 + : 1, stroke: isHighlighted ? "#333" : "none", strokeWidth: isHighlighted ? ".5px" : "0", transition: "opacity 0.2s ease, stroke 0.2s ease", }; }); return styles; - }, [countryColors, hoveredConcept]); + }, [countryColors, hoveredConcept, quizSelectedCountries]); const handleCountryClick = (event: React.MouseEvent) => { const target = event.target as SVGElement; @@ -391,17 +400,19 @@ const MapHandler: React.FC<{ ); }; +const animWaitTimeMs = 200; + const Quiz: React.FC = () => { const [quizOpen, setQuizOpen] = useState(false); const [chosenCountries, setChosenCountries] = useState<[string, string]>([ "", "", ]); - const { presentNations } = useGeographicPageContext(); + const { presentNations, setQuizSelectedCountries } = + useGeographicPageContext(); const maxTries = 20; - const pickCountries = () => { - if (!quizOpen) return; + const pickCountries = async () => { let numTries = 0; let country1: string; let notes1: { [section: string]: string[] }; @@ -435,27 +446,54 @@ const Quiz: React.FC = () => { }) ); setChosenCountries([country1, country2]); + for (let i = 0; i < 8; i++) { + setQuizSelectedCountries([ + presentNations[Math.floor(Math.random() * presentNations.length)], + ]); + await new Promise((resolve) => setTimeout(resolve, animWaitTimeMs)); + } + setQuizSelectedCountries([country1]); + await new Promise((resolve) => setTimeout(resolve, 1000 + animWaitTimeMs)); + for (let i = 0; i < 8; i++) { + setQuizSelectedCountries([ + country1, + presentNations[Math.floor(Math.random() * presentNations.length)], + ]); + await new Promise((resolve) => setTimeout(resolve, animWaitTimeMs)); + } + setQuizSelectedCountries([country1, country2]); + await new Promise((resolve) => setTimeout(resolve, 1000)); + setQuizOpen(true); }; - useEffect(() => { - pickCountries(); - }, [quizOpen]); - return ( <> {!quizOpen && ( )} {quizOpen && ( - setQuizOpen(false)} opaqueness={0.75}> + { + setQuizOpen(false); + setQuizSelectedCountries([]); + }} + opaqueness={0.75} + >

Find similarities & differences

- +