설정 db 저장

This commit is contained in:
Macbook
2026-06-23 01:09:42 +09:00
parent 32be015b49
commit 2d465cfc26
14 changed files with 192 additions and 37 deletions
+23 -9
View File
@@ -7,7 +7,7 @@
* - defaultSymbol : 기본 종목 (DEFAULT_STATE.symbol)
* - defaultTimeframe : 기본 타임프레임 (DEFAULT_STATE.timeframe)
* - defaultChartType : 기본 차트 타입
* - (테마는 DB 미사용 — localStorage, see localThemeStorage)
* - defaultTheme : 기본 테마 (로그인 시 DB 공유, 게스트는 localStorage)
* - defaultLogScale : 기본 로그 스케일
* - defaultLayoutId : 기본 레이아웃 ID
* - mainChartStyle : 캔들 색상 (DEFAULT_MAIN_CHART_STYLE)
@@ -20,7 +20,7 @@
* // 기본 심볼 사용
* const symbol = settings.defaultSymbol ?? 'KRW-BTC';
*
* // 테마 변경 시 saveLocalTheme() (App.tsx)
* // 테마 변경 시 saveAppDef({ defaultTheme }) + saveLocalTheme() (App.tsx)
* ```
*/
@@ -65,7 +65,7 @@ import {
} from '../types/chartPaneSeparator';
import { migrateLocalStorageToUiPreferences } from '../utils/uiPreferencesMigrate';
import { reconcilePendingUiPreferencesOnLoad } from '../utils/uiPreferencesDb';
import { loadLocalTheme } from '../utils/localThemeStorage';
import { loadLocalTheme, resolveThemeForSession } from '../utils/localThemeStorage';
// 전역 캐시 — 여러 컴포넌트에서 공유하여 중복 요청 방지
let _cache: AppSettingsDto | null = null;
@@ -127,6 +127,21 @@ function ensureLoaded(): Promise<AppSettingsDto> {
}
}
}
if (hasRegisteredUser() && _cache) {
const local = loadLocalTheme();
const dbTheme = _cache.defaultTheme;
const dbIsDefault = !dbTheme || dbTheme === 'dark';
if (dbIsDefault && local !== 'dark') {
try {
const saved = await saveAppSettings({ defaultTheme: local });
if (generation === _loadGeneration && saved) {
_cache = { ..._cache, ...saved, defaultTheme: local };
}
} catch (e) {
console.warn('[useAppSettings] 테마 localStorage→DB 이전 실패:', e);
}
}
}
if (hasRegisteredUser()) {
try {
await loadStrategies();
@@ -161,11 +176,12 @@ export function reloadAppSettingsCache(): Promise<AppSettingsDto> {
/** DB 또는 fallback 기본값 접근 헬퍼 */
export function resolveAppDefaults(s: AppSettingsDto) {
const accountTheme = resolveThemeForSession(s.defaultTheme, hasRegisteredUser());
return {
symbol: (s.defaultSymbol ?? 'KRW-BTC') as string,
timeframe: (s.defaultTimeframe ?? '1D') as Timeframe,
chartType: (s.defaultChartType ?? 'candlestick') as ChartType,
theme: loadLocalTheme(),
theme: accountTheme,
logScale: s.defaultLogScale ?? false,
layoutId: s.defaultLayoutId ?? '1',
mainChartStyle:(s.mainChartStyle as unknown as MainChartStyle | null) ?? DEFAULT_MAIN_CHART_STYLE,
@@ -184,7 +200,7 @@ export function resolveAppDefaults(s: AppSettingsDto) {
),
chartPaneSeparator: resolveChartPaneSeparatorOptions(
s.chartPaneSeparator as Partial<ChartPaneSeparatorOptions> | null | undefined,
loadLocalTheme(),
accountTheme,
),
tradeAlertPopup: s.tradeAlertPopup ?? true,
tradeAlertSoundEnabled: s.tradeAlertSoundEnabled ?? true,
@@ -288,9 +304,7 @@ export function useAppSettings(sessionKey = 0) {
* 낙관적 업데이트 — DB 저장 실패해도 UI 는 즉시 반영.
*/
const save = useCallback((patch: AppSettingsDto) => {
const { defaultTheme: _omitTheme, ...patchWithoutTheme } = patch;
const apiPatch = 'defaultTheme' in patch ? patchWithoutTheme : patch;
const merged = { ...(_cache ?? {}), ...apiPatch };
const merged = { ...(_cache ?? {}), ...patch };
_cache = merged;
notifyAppSettingsListeners();
setSettings(merged);
@@ -303,7 +317,7 @@ export function useAppSettings(sessionKey = 0) {
if (patch.tradeAlertTimeFormat != null) {
setTradeAlertTimeFormat(normalizeChartTimeFormat(patch.tradeAlertTimeFormat));
}
saveAppSettings(apiPatch).then(updated => {
saveAppSettings(patch).then(updated => {
if (updated) {
_cache = { ...(_cache ?? {}), ...updated };
notifyAppSettingsListeners();