11import { ErrorComponentProps , Outlet , ErrorComponent , createFileRoute , Link } from '@tanstack/react-router' ;
2- import { DEFAULT_LANG , mapConfigQueryOptions } from '../config' ;
3- import { useSuspenseQuery } from '@tanstack/react-query' ;
2+ import { DEFAULT_LANG , mapConfigQueryOptions , storeConfigQueryOptions } from '../config' ;
43import { Fragment , useEffect } from 'react' ;
54import { AxiosError } from 'axios' ;
6- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' ;
7- import { faSpinner } from '@fortawesome/free-solid-svg-icons' ;
85import { useAppStore } from '../hooks/app' ;
96import { useUIActions , useUIStore } from '../hooks/ui' ;
107import { Head } from '../components/Head' ;
118import { useTranslation } from 'react-i18next' ;
129import { Header } from '../components/Header' ;
1310import { Footer } from '../components/HomeFooter' ;
1411
12+ class MapNotFoundError extends Error { }
13+
1514export const Route = createFileRoute ( '/$mapId' ) ( {
1615 component : RootComponent ,
17- loader : ( { params : { mapId } , context : { queryClient } } ) => {
18- return queryClient . ensureQueryData (
19- mapConfigQueryOptions ( `${ useUIStore . getState ( ) . defaultConfig } /${ mapId } /config.json` ) ,
20- ) ;
16+ loader : async ( { params : { mapId } , context : { queryClient } } ) => {
17+ const config = useUIStore . getState ( ) . defaultConfig ;
18+ const storeResponse = await queryClient . fetchQuery ( storeConfigQueryOptions ( config ) ) ;
19+ const map = storeResponse . data . maps . find ( m => m . id === mapId ) ;
20+ if ( map ) {
21+ const configResponse = await queryClient . fetchQuery ( mapConfigQueryOptions ( map . url ) ) ;
22+ return configResponse . data ;
23+ }
24+ throw new MapNotFoundError ( mapId ) ;
2125 } ,
2226 errorComponent : ConfigErrorComponent ,
2327} ) ;
2428
2529function ConfigErrorComponent ( { error } : ErrorComponentProps ) {
26- if ( error instanceof AxiosError ) {
30+ if ( error instanceof AxiosError || MapNotFoundError ) {
2731 return (
2832 < div className = "min-h-screen bg-base-100 flex flex-col" >
2933 < Header icon = "" />
@@ -56,20 +60,15 @@ function ConfigErrorComponent({ error }: ErrorComponentProps) {
5660}
5761
5862function RootComponent ( ) {
59- const defaultConfigPath = useUIStore ( state => state . defaultConfig ) ;
60- const ready = useUIStore ( state => state . ready ) ;
61- const { mapId } = Route . useParams ( ) ;
62- const { isLoading, data : config } = useSuspenseQuery (
63- mapConfigQueryOptions ( `${ defaultConfigPath } /${ mapId } /config.json` ) ,
64- ) ;
63+ const config = Route . useLoaderData ( ) ;
6564 const uiActions = useUIActions ( ) ;
6665 const { i18n } = useTranslation ( ) ;
6766
6867 useEffect ( ( ) => {
69- useAppStore . setState ( ( ) => config . data ) ;
68+ useAppStore . setState ( ( ) => config ) ;
7069 if ( i18n ?. changeLanguage ) {
7170 i18n
72- . changeLanguage ( config . data . config . language ?? DEFAULT_LANG )
71+ . changeLanguage ( config . config . language ?? DEFAULT_LANG )
7372 . then ( ( ) => uiActions . setReady ( true ) )
7473 . catch ( console . error ) ;
7574 } else {
@@ -79,15 +78,7 @@ function RootComponent() {
7978 return ( ) => {
8079 uiActions . setReady ( false ) ;
8180 } ;
82- } , [ uiActions , config . data , i18n ] ) ;
83-
84- if ( isLoading || ! ready ) {
85- return (
86- < div className = "flex justify-center items-center w-screen h-screen bg-primary/20" >
87- < FontAwesomeIcon icon = { faSpinner } spin />
88- </ div >
89- ) ;
90- }
81+ } , [ uiActions , config , i18n ] ) ;
9182
9283 return (
9384 < Fragment >
0 commit comments