From c88b59220e30488e00271fbc81bab375d056c25b Mon Sep 17 00:00:00 2001 From: ajvpot <553597+ajvpot@users.noreply.github.com> Date: Fri, 5 Sep 2025 23:59:53 +0200 Subject: [PATCH] Don't use suspense, just use a fallback component --- src/components/ConfigContext.tsx | 99 +++++++++++++------------------- 1 file changed, 39 insertions(+), 60 deletions(-) diff --git a/src/components/ConfigContext.tsx b/src/components/ConfigContext.tsx index 96a5eeb..f674e1a 100644 --- a/src/components/ConfigContext.tsx +++ b/src/components/ConfigContext.tsx @@ -1,5 +1,5 @@ "use client"; -import React, { createContext, useContext, useState, useEffect, useRef, useLayoutEffect, ReactNode, use, Suspense } from "react"; +import React, { createContext, useContext, useState, useEffect, useRef, useLayoutEffect, ReactNode } from "react"; import { getChannelIdFromKey } from "../lib/meshcore"; import { getRegionFriendlyNames } from "../lib/regions"; import Modal from "./Modal"; @@ -54,61 +54,53 @@ const PUBLIC_MESHCORE_KEY = { privateKey: "izOH6cXN6mrJ5e26oRXNcg==", }; -// Config loader that uses Suspense -let configPromise: Promise | null = null; - -function loadConfigFromStorage(): Promise { - if (configPromise) { - return configPromise; +function loadConfigFromStorage(): Config { + try { + const stored = localStorage.getItem("meshExplorerConfig"); + if (stored) { + const parsed = JSON.parse(stored); + return { ...DEFAULT_CONFIG, ...parsed }; + } + return DEFAULT_CONFIG; + } catch (error) { + console.warn("Failed to parse config from localStorage:", error); + return DEFAULT_CONFIG; } - - configPromise = new Promise((resolve) => { - // Use setTimeout to ensure this runs after the component mounts - setTimeout(() => { - try { - const stored = localStorage.getItem("meshExplorerConfig"); - if (stored) { - const parsed = JSON.parse(stored); - resolve({ ...DEFAULT_CONFIG, ...parsed }); - } else { - resolve(DEFAULT_CONFIG); - } - } catch (error) { - console.warn("Failed to parse config from localStorage:", error); - resolve(DEFAULT_CONFIG); - } - }, 0); - }); - - return configPromise; -} - -// Hook to get config with Suspense -function useConfigWithSuspense(): Config { - return use(loadConfigFromStorage()); } const ConfigContext = createContext(null); -// Internal component that uses the config with Suspense -function ConfigProviderInternal({ children }: { children: ReactNode }) { - const initialConfig = useConfigWithSuspense(); - const [config, setConfig] = useState(initialConfig); +// Loading component for Suspense fallback +function ConfigLoadingFallback() { + return ( +
+
+
+
Loading configuration...
+
+
+ ); +} + +// Main ConfigProvider that uses proper loading state +export function ConfigProvider({ children }: { children: ReactNode }) { + const [config, setConfig] = useState(null); const [open, setOpen] = useState(false); const [keyModalOpen, setKeyModalOpen] = useState(false); const configButtonRef = useRef(null); const firstRender = useRef(true); - // Update config when the initial config changes (should only happen once) + // Load config from localStorage on mount useEffect(() => { - setConfig(initialConfig); - }, [initialConfig]); + const loadedConfig = loadConfigFromStorage(); + setConfig(loadedConfig); + }, []); - // Save to localStorage + // Save to localStorage when config changes useEffect(() => { - if (!firstRender.current) { + if (config && !firstRender.current) { localStorage.setItem("meshExplorerConfig", JSON.stringify(config)); - } else { + } else if (config) { firstRender.current = false; } }, [config]); @@ -117,6 +109,11 @@ function ConfigProviderInternal({ children }: { children: ReactNode }) { const openConfig = () => setOpen(true); const closeConfig = () => setOpen(false); + // Show loading state while config is being loaded + if (!config) { + return ; + } + return ( {children} @@ -138,24 +135,6 @@ function ConfigProviderInternal({ children }: { children: ReactNode }) { ); } -// Loading component for Suspense fallback -function ConfigLoadingFallback() { - return ( -
-
Loading configuration...
-
- ); -} - -// Main ConfigProvider that wraps with Suspense -export function ConfigProvider({ children }: { children: ReactNode }) { - return ( - }> - {children} - - ); -} - export function useConfig() { return useContext(ConfigContext); }