diff --git a/src/App.tsx b/src/App.tsx index 31387bea..563d4247 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -50,6 +50,7 @@ const App = () => { const { denied, permission } = useDevicePermissions({ continueToApp }); const initializedGlobalState = useInitializeGlobalStateReducer(); const [, dispatch] = initializedGlobalState; + const [apiError, setApiError] = useState(false); useFetchDevices({ dispatch, @@ -101,12 +102,22 @@ const App = () => { /> )} - {permission && !denied && ( + {apiError && ( + + + + )} + {permission && !denied && !apiError && ( <> } + element={ + setApiError(true)} /> + } errorElement={} /> { - const [{ joinProductionOptions }] = useGlobalState(); +export const LandingPage = ({ setApiError }: { setApiError: () => void }) => { + const [{ joinProductionOptions, apiError }] = useGlobalState(); + + useEffect(() => { + if (apiError) { + setApiError(); + } + }, [apiError, setApiError]); useNavigateToProduction(joinProductionOptions); diff --git a/src/components/landing-page/use-fetch-production-list.ts b/src/components/landing-page/use-fetch-production-list.ts index 65d22559..8dd9dbbf 100644 --- a/src/components/landing-page/use-fetch-production-list.ts +++ b/src/components/landing-page/use-fetch-production-list.ts @@ -45,6 +45,9 @@ export const useFetchProductionList = (filter?: GetProductionListFilter) => { setError(null); }) .catch((e) => { + dispatch({ + type: "API_NOT_AVAILABLE", + }); setError( e instanceof Error ? e diff --git a/src/global-state/global-state-actions.ts b/src/global-state/global-state-actions.ts index bd8af653..1dec8986 100644 --- a/src/global-state/global-state-actions.ts +++ b/src/global-state/global-state-actions.ts @@ -3,6 +3,7 @@ import { TJoinProductionOptions } from "../components/production-line/types.ts"; export type TGlobalStateAction = | TPublishError | TProductionCreated + | TApiNotAvailable | TProductionListFetched | TUpdateDevicesAction | TUpdateJoinProductionOptions @@ -25,6 +26,10 @@ export type TProductionCreated = { type: "PRODUCTION_UPDATED"; }; +export type TApiNotAvailable = { + type: "API_NOT_AVAILABLE"; +}; + export type TProductionListFetched = { type: "PRODUCTION_LIST_FETCHED"; }; diff --git a/src/global-state/global-state-reducer.ts b/src/global-state/global-state-reducer.ts index ebc0d0d1..1294cbb8 100644 --- a/src/global-state/global-state-reducer.ts +++ b/src/global-state/global-state-reducer.ts @@ -12,6 +12,7 @@ const initialGlobalState: TGlobalState = { dominantSpeaker: null, audioLevelAboveThreshold: false, selectedProductionId: null, + apiError: false, }; const globalReducer: Reducer = ( @@ -31,6 +32,11 @@ const globalReducer: Reducer = ( ...state, reloadProductionList: true, }; + case "API_NOT_AVAILABLE": + return { + ...state, + apiError: new Error("API not available"), + }; case "PRODUCTION_LIST_FETCHED": return { ...state, diff --git a/src/global-state/types.ts b/src/global-state/types.ts index a48011b5..d2ff2e98 100644 --- a/src/global-state/types.ts +++ b/src/global-state/types.ts @@ -13,4 +13,5 @@ export type TGlobalState = { dominantSpeaker: string | null; audioLevelAboveThreshold: boolean; selectedProductionId: string | null; + apiError: Error | false; };