diff --git a/src/GlobalStates/GlobalStore.ts b/src/GlobalStates/GlobalStore.ts index 7b1e169c..bea8ab47 100644 --- a/src/GlobalStates/GlobalStore.ts +++ b/src/GlobalStates/GlobalStore.ts @@ -31,6 +31,7 @@ type StoreState = { plotDim: number; flipY:boolean; initStore:string; + storeFromURL: boolean; variable: string; variables: string[]; openVariables: boolean; @@ -65,6 +66,7 @@ type StoreState = { setPlotDim: (plotDim: number) => void; setFlipY: (flipY:boolean) => void; setInitStore: (initStore:string) => void; + setStoreFromURL: (storeFromURL: boolean) => void; setVariable: (variable: string) => void; setVariables: (variables: string[]) => void; setOpenVariables: (openVariables: boolean) => void; @@ -98,6 +100,7 @@ export const useGlobalStore = create((set, get) => ({ plotDim: 0, flipY: false, initStore: ESDC, + storeFromURL: false, variable: 'Default', variables: [], openVariables: false, @@ -152,6 +155,7 @@ export const useGlobalStore = create((set, get) => ({ setPlotDim: (plotDim) => set({ plotDim }), setFlipY: (flipY) => set({ flipY }), setInitStore: (initStore) => set({ initStore }), + setStoreFromURL: (storeFromURL) => set({ storeFromURL }), setVariable: (variable) => set({ variable }), setVariables: (variables) => set({ variables }), setOpenVariables: (openVariables) => set({ openVariables }), diff --git a/src/components/LandingHome.tsx b/src/components/LandingHome.tsx index f56c19cb..923b2a2a 100644 --- a/src/components/LandingHome.tsx +++ b/src/components/LandingHome.tsx @@ -25,16 +25,18 @@ async function sendPing() { export function LandingHome() { const { - initStore, timeSeries, variable, plotOn, - setZMeta, setVariables, setTitleDescription, + initStore, timeSeries, variable, storeFromURL, + setZMeta, setVariables, setTitleDescription, setOpenVariables, setStoreFromURL, } = useGlobalStore(useShallow(state => ({ initStore: state.initStore, timeSeries: state.timeSeries, variable: state.variable, - plotOn: state.plotOn, + storeFromURL: state.storeFromURL, setZMeta: state.setZMeta, setVariables: state.setVariables, setTitleDescription: state.setTitleDescription, + setOpenVariables: state.setOpenVariables, + setStoreFromURL: state.setStoreFromURL, }))) const { currentStore, fetchKey, @@ -49,27 +51,27 @@ export function LandingHome() { setUseNC: state.setUseNC }))) - function resetSlices() { - setZSlice([0, null]) - setYSlice([0, null]) - setXSlice([0, null]) - } - useEffect(() => { - resetSlices(); + void fetchKey; + setZSlice([0, null]); + setYSlice([0, null]); + setXSlice([0, null]); if (initStore.startsWith('local:')) { const path = initStore.replace('local:', ''); - if (!NETCDF_EXT_REGEX.test(path)) return; // TODO: handled zarr + if (!NETCDF_EXT_REGEX.test(path)) return; const filename = path.split('/').pop() ?? 'file.nc'; fetch(`/file?path=${encodeURIComponent(path)}`) .then(res => { if (!res.ok) throw new Error(`HTTP ${res.status}`); return res.blob(); }) - .then(blob => { - loadNetCDF(blob, filename); - useGlobalStore.setState({openVariables: true}) - return + .then(async blob => { + await loadNetCDF(blob, filename); + if (storeFromURL) { + setOpenVariables(true); + setStoreFromURL(false); + } + return; }) .catch(e => useGlobalStore.getState().setStatus(`Failed to load: ${e instanceof Error ? e.message : String(e)}`)); return; @@ -86,23 +88,40 @@ export function LandingHome() { // Clear after use useZarrStore.getState().setIcechunkOptions(null); useZarrStore.getState().setFetchOptions(null); - }, [initStore, fetchKey, setCurrentStore]) + }, [initStore, fetchKey, setCurrentStore, setUseNC, setZSlice, setYSlice, setXSlice, storeFromURL, setOpenVariables, setStoreFromURL]); useEffect(() => { + const { initStore } = useGlobalStore.getState(); + if (initStore.startsWith('local')) return; + let isMounted = true; + const activeStore = currentStore; - GetTitleDescription(currentStore).then((result) => { - if (isMounted) setTitleDescription(result); + GetTitleDescription(activeStore).then((result) => { + if (isMounted && currentStore === activeStore) setTitleDescription(result); }); - const fullmetadata = GetZarrMetadata(currentStore); + const fullmetadata = GetZarrMetadata(activeStore); const variables = GetVariableNames(fullmetadata); - fullmetadata.then(e => setZMeta(e)) - variables.then(e => setVariables(e)) + fullmetadata.then((e) => { + if (isMounted && currentStore === activeStore) setZMeta(e); + }); + variables.then((e) => { + if (isMounted && currentStore === activeStore) { + setVariables(e); + const { storeFromURL } = useGlobalStore.getState(); + if (storeFromURL) { + setOpenVariables(true); + setStoreFromURL(false); + } + } + }); - return () => { isMounted = false; }; - }, [currentStore, setZMeta, setVariables, setTitleDescription]) + return () => { + isMounted = false; + }; + }, [currentStore, setZMeta, setVariables, setTitleDescription, setOpenVariables, setStoreFromURL]); useEffect(()=>{ if (process.env.NODE_ENV !== "development") { diff --git a/src/components/StoreInitializer.tsx b/src/components/StoreInitializer.tsx index 7e0e650e..199308a4 100644 --- a/src/components/StoreInitializer.tsx +++ b/src/components/StoreInitializer.tsx @@ -9,6 +9,7 @@ import { isRemoteStore } from '@/utils/isRemoteStore'; function StoreInitializerInner() { const searchParams = useSearchParams(); const setInitStore = useGlobalStore(s => s.setInitStore); + const setStoreFromURL = useGlobalStore(s => s.setStoreFromURL); const { setUseNC, setFetchNC } = useZarrStore(useShallow(s => ({ setUseNC: s.setUseNC, setFetchNC: s.setFetchNC, @@ -16,13 +17,20 @@ function StoreInitializerInner() { useEffect(() => { const store = searchParams.get("store"); - if (!store) return; + if (!store) { + setStoreFromURL(false); + return; + } const isNC = searchParams.get("format") === "nc"; setUseNC(isNC); setFetchNC(isNC); - setInitStore(isRemoteStore(store) ? store : `local:${store}`); - }, []); + const initValue = isRemoteStore(store) ? store : `local:${store}`; + setInitStore(initValue); + // mark that a store was provided in the URL; LandingHome will open variables once + // the custom store is actually loaded. + setStoreFromURL(true); + }, [searchParams, setUseNC, setFetchNC, setInitStore, setStoreFromURL]); return null; }