import React, { lazy, memo } from 'react' import { QueryClient, QueryClientProvider, useQuery } from 'react-query' import MobileLineageTree from './components/MobileLineageTree' import Dialog from './components/Dialog' import { useMobile } from './hooks/useMediaQuery' import useDynamicAPI from './hooks/useDynamicAPI' import useDynamicComponents from './hooks/useDynamicComponents' import useDynamicConfig from './hooks/useDynamicConfig' import { useInfoQuery, InfoContext } from './hooks/useDynamicInfo' import useDynamicLineages from './hooks/useDynamicLineages' import useLineageTree from './hooks/useLineageTree' import useQueryAsState from './hooks/useQueryAsState' import { setAliases } from './pango' const UI = memo(lazy(() => import('./components/UI'))) const DynamicUI = ({ aliases_url = 'https://raw.githubusercontent.com/cov-lineages/pango-designation/master/pango_designation/alias_key.json', api_url = './api', tiles_url = './tiles/Local_Authority_Districts__December_2019__Boundaries_UK_BUC.json', config_url = './data/config.json', confidence, avg, smoothing, useAPIImpl = useDynamicAPI, ...props }) => { const { darkMode } = props const getAliases = async () => { const response = await fetch(aliases_url) const aliases = await response.json() setAliases(aliases) } useQuery('aliases', getAliases, { suspense: true }) const getTiles = async () => { const response = await fetch(tiles_url) return response.json() } const { data: tiles } = useQuery('tiles', getTiles, { suspense: true }) const info = useInfoQuery(api_url) const fetchConfig = async () => { const response = await fetch(config_url) return response.json() } const { data: staticConfig } = useQuery('config', fetchConfig, { suspense: true }) const isMobile = useMobile() const { colourPalette, lineages, lineageToColourIndex, nextColourIndex, submit } = useDynamicLineages(staticConfig) const api = useAPIImpl({ api_url, lineages, info, confidence, avg, smoothing }) const config = useDynamicConfig({ colourPalette, lineages, lineageToColourIndex, staticConfig }) const [{ lineageView, lineageFilter, area, xMin, xMax }, updateQuery] = useQueryAsState({ lineageView: null, lineageFilter: 'all' }) const setLineageView = React.useCallback((bool, method) => updateQuery({ lineageView: bool ? '1' : undefined }, method), []) const setLineageFilter = React.useCallback(preset => updateQuery({ lineageFilter: preset === 'all' ? undefined : preset }), []) const showLineageView = React.useMemo(() => !!lineageView, [lineageView]) const mutationMode = React.useMemo(() => config.dynamic_mode.mutations, [config]) const queryParams = React.useMemo(() => ({ area, fromDate: xMin, toDate: xMax }), [area, xMin, xMax]) const lineageTree = useLineageTree({ api_url, colourPalette, lineageToColourIndex, mutationMode, preset: lineageFilter, queryParams, setPreset: setLineageFilter, showLineageView }) const injection = useDynamicComponents({ api_url, darkMode, info, isMobile, lineages, lineageToColourIndex, lineageTree, lineageView, nextColourIndex, queryParams, setLineageView, submit }) return ( <InfoContext.Provider value={info}> <UI {...props} api={api} config={config} injection={injection} lastModified={info.lastModified} lineages={lineages} tiles={tiles} /> { isMobile && <Dialog isOpen={!!lineageView} onClose={() => {}}> <div className='fixed inset-0 flex flex-col bg-white dark:bg-gray-700 pt-3'> { lineageView && <MobileLineageTree api_url={api_url} darkMode={darkMode} info={info} initialValues={lineageToColourIndex} lineageTree={lineageTree} onClose={values => { if (values !== lineageToColourIndex) { submit(values, { lineageView: undefined }) } else { setLineageView(false) } }} queryParams={queryParams} /> } </div> </Dialog> } </InfoContext.Provider> ) } const twentyFourHoursInMs = 1000 * 60 * 60 * 24 const DynamicCovInce = props => { const queryClient = React.useRef(new QueryClient({ defaultOptions: { queries: { refetchOnWindowFocus: false, refetchOnmount: false, refetchOnReconnect: false, staleTime: twentyFourHoursInMs * 100 } } })) return ( <QueryClientProvider client={queryClient.current}> <DynamicUI {...props} /> </QueryClientProvider> ) } export default DynamicCovInce