가상매매 시간봉 제거
This commit is contained in:
@@ -54,6 +54,8 @@ import { migrateLocalStorageToUiPreferences } from '../utils/uiPreferencesMigrat
|
||||
// 전역 캐시 — 여러 컴포넌트에서 공유하여 중복 요청 방지
|
||||
let _cache: AppSettingsDto | null = null;
|
||||
let _loadPromise: Promise<AppSettingsDto> | null = null;
|
||||
/** invalidate 이후 완료된 로드만 캐시에 반영 */
|
||||
let _loadGeneration = 0;
|
||||
type AppSettingsListener = () => void;
|
||||
const _listeners = new Set<AppSettingsListener>();
|
||||
|
||||
@@ -74,20 +76,31 @@ export function subscribeAppSettings(listener: AppSettingsListener): () => void
|
||||
function ensureLoaded(): Promise<AppSettingsDto> {
|
||||
if (_cache !== null) return Promise.resolve(_cache);
|
||||
if (_loadPromise) return _loadPromise;
|
||||
const generation = _loadGeneration;
|
||||
_loadPromise = loadAppSettings().then(async data => {
|
||||
if (generation !== _loadGeneration) {
|
||||
_loadPromise = null;
|
||||
return _cache ?? {};
|
||||
}
|
||||
_cache = data ?? {};
|
||||
const migrated = migrateLocalStorageToUiPreferences(_cache);
|
||||
if (migrated?.changed) {
|
||||
try {
|
||||
const saved = await saveAppSettings({ uiPreferences: migrated.uiPreferences });
|
||||
_cache = { ..._cache, ...saved, uiPreferences: migrated.uiPreferences };
|
||||
if (generation === _loadGeneration) {
|
||||
_cache = { ..._cache, ...saved, uiPreferences: migrated.uiPreferences };
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('[useAppSettings] uiPreferences 마이그레이션 저장 실패:', e);
|
||||
_cache = { ..._cache, uiPreferences: migrated.uiPreferences };
|
||||
if (generation === _loadGeneration) {
|
||||
_cache = { ..._cache, uiPreferences: migrated.uiPreferences };
|
||||
}
|
||||
}
|
||||
}
|
||||
_loadPromise = null;
|
||||
notifyAppSettingsListeners();
|
||||
if (generation === _loadGeneration) {
|
||||
notifyAppSettingsListeners();
|
||||
}
|
||||
return _cache;
|
||||
});
|
||||
return _loadPromise;
|
||||
@@ -96,6 +109,7 @@ function ensureLoaded(): Promise<AppSettingsDto> {
|
||||
export function invalidateAppSettingsCache() {
|
||||
_cache = null;
|
||||
_loadPromise = null;
|
||||
_loadGeneration += 1;
|
||||
}
|
||||
|
||||
/** 서버에서 app-settings 재로드 후 캐시 갱신 (모바일 ↻ 동기화 등) */
|
||||
@@ -167,13 +181,32 @@ export function resolveAppDefaults(s: AppSettingsDto) {
|
||||
/** sessionKey 변경 시(로그인/로그아웃) 설정을 DB에서 다시 로드 */
|
||||
export function useAppSettings(sessionKey = 0) {
|
||||
const [settings, setSettings] = useState<AppSettingsDto>(_cache ?? {});
|
||||
const [isLoaded, setIsLoaded] = useState(false);
|
||||
const [isLoaded, setIsLoaded] = useState(_cache !== null);
|
||||
const mountedRef = useRef(true);
|
||||
const prevSessionKeyRef = useRef(sessionKey);
|
||||
|
||||
useEffect(() => {
|
||||
mountedRef.current = true;
|
||||
setIsLoaded(false);
|
||||
invalidateAppSettingsCache();
|
||||
const sessionChanged = prevSessionKeyRef.current !== sessionKey;
|
||||
prevSessionKeyRef.current = sessionKey;
|
||||
|
||||
if (sessionChanged) {
|
||||
if (_cache !== null) {
|
||||
setSettings(_cache);
|
||||
setDisplayTimezone(normalizeTimezone(_cache.displayTimezone ?? DEFAULT_DISPLAY_TIMEZONE));
|
||||
setIsLoaded(true);
|
||||
} else {
|
||||
setIsLoaded(false);
|
||||
invalidateAppSettingsCache();
|
||||
}
|
||||
} else if (_cache !== null) {
|
||||
setSettings(_cache);
|
||||
setDisplayTimezone(normalizeTimezone(_cache.displayTimezone ?? DEFAULT_DISPLAY_TIMEZONE));
|
||||
setIsLoaded(true);
|
||||
} else {
|
||||
setIsLoaded(false);
|
||||
}
|
||||
|
||||
ensureLoaded().then(data => {
|
||||
if (mountedRef.current) {
|
||||
setSettings(data);
|
||||
|
||||
Reference in New Issue
Block a user