import React, { createContext, useCallback, useRef, useContext, useEffect } from 'react';
|
|
const STORAGE_KEY = 'rsf_tab_dialog_state';
|
|
// 按路径存储弹窗状态
|
const TabDialogStateContext = createContext(null);
|
|
// 规范化路径为「资源列表」路径
|
export const getDialogStatePath = (pathnameOrLocation) => {
|
const pathname = typeof pathnameOrLocation === 'object' && pathnameOrLocation?.pathname != null
|
? pathnameOrLocation.pathname
|
: String(pathnameOrLocation || '');
|
if (!pathname || pathname === '/') return pathname || '/';
|
const segments = pathname.replace(/^\//, '').split('/').filter(Boolean);
|
const first = segments[0];
|
return first ? `/${first}` : pathname;
|
};
|
|
const readFromStorage = () => {
|
try {
|
const raw = typeof window !== 'undefined' ? window.localStorage.getItem(STORAGE_KEY) : null;
|
if (raw) {
|
const parsed = JSON.parse(raw);
|
return typeof parsed === 'object' && parsed !== null ? parsed : {};
|
}
|
} catch (_) {}
|
return {};
|
};
|
|
const writeToStorage = (data) => {
|
try {
|
if (typeof window !== 'undefined') {
|
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(data));
|
}
|
} catch (_) {}
|
};
|
|
export const TabDialogStateProvider = ({ children }) => {
|
const storeRef = useRef({});
|
|
useEffect(() => {
|
storeRef.current = readFromStorage();
|
}, []);
|
|
const getDialogState = useCallback((path) => {
|
const fromRef = storeRef.current[path];
|
if (fromRef !== undefined) return fromRef;
|
const fromStorage = readFromStorage()[path];
|
if (fromStorage !== undefined) {
|
storeRef.current[path] = fromStorage;
|
return fromStorage;
|
}
|
return undefined;
|
}, []);
|
|
const setDialogState = useCallback((path, state) => {
|
storeRef.current[path] = state;
|
const all = readFromStorage();
|
all[path] = state;
|
writeToStorage(all);
|
}, []);
|
|
const value = { getDialogState, setDialogState };
|
return (
|
<TabDialogStateContext.Provider value={value}>
|
{children}
|
</TabDialogStateContext.Provider>
|
);
|
};
|
|
export const useTabDialogState = () => {
|
const ctx = useContext(TabDialogStateContext);
|
if (!ctx) return null;
|
return ctx;
|
};
|