투자관리 차트탭 기능 수정
This commit is contained in:
@@ -18,6 +18,8 @@
|
||||
import { useState, useEffect, useRef, useCallback } from 'react';
|
||||
import type { RefObject, MutableRefObject } from 'react';
|
||||
import type { ChartManager } from '../utils/ChartManager';
|
||||
import { toHistoryApiIso } from '../utils/analysisChartData';
|
||||
import { timeframeToCandleType } from '../utils/chartCandleType';
|
||||
import { fetchUpbitCandlesBeforeCached } from '../utils/requestCache';
|
||||
import type { OHLCVBar, Timeframe } from '../types';
|
||||
|
||||
@@ -38,6 +40,8 @@ interface UseHistoryLoaderOptions {
|
||||
timeframe: Timeframe;
|
||||
isUpbit: boolean;
|
||||
managerRef: RefObject<ChartManager | null>;
|
||||
/** 과거 캔들 prepend 완료 후 (추가된 봉 수, 전체 봉 수) */
|
||||
onBarsPrepended?: (addedCount: number, totalBars: number) => void;
|
||||
}
|
||||
|
||||
interface UseHistoryLoaderReturn {
|
||||
@@ -91,6 +95,7 @@ export function useHistoryLoader({
|
||||
timeframe,
|
||||
isUpbit,
|
||||
managerRef,
|
||||
onBarsPrepended,
|
||||
}: UseHistoryLoaderOptions): UseHistoryLoaderReturn {
|
||||
const [isLoadingMore, setIsLoadingMore] = useState(false);
|
||||
|
||||
@@ -103,6 +108,8 @@ export function useHistoryLoader({
|
||||
/** false 가 되면 더 이상 API 를 호출하지 않음 */
|
||||
const hasMoreRef = useRef(true);
|
||||
const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
const onPrependedRef = useRef(onBarsPrepended);
|
||||
onPrependedRef.current = onBarsPrepended;
|
||||
|
||||
// 심볼·타임프레임이 바뀌면 상태 초기화
|
||||
useEffect(() => {
|
||||
@@ -125,10 +132,15 @@ export function useHistoryLoader({
|
||||
const oldestTime = mgr.getOldestBarTime();
|
||||
if (oldestTime === null) return;
|
||||
|
||||
// Unix 타임스탬프(초) → ISO 8601 UTC ('Z' 없이 전달, 백엔드에서 처리)
|
||||
const beforeIso = new Date(oldestTime * 1000)
|
||||
.toISOString()
|
||||
.replace('.000Z', ''); // '2026-05-20T10:00:00'
|
||||
// exclusive to — 가장 오래된 봉 시각 그대로 쓰면 중복·0건이 될 수 있어 한 봉 이전으로
|
||||
const raw = mgr.getRawBars();
|
||||
let beforeSec = oldestTime;
|
||||
if (raw.length >= 2) {
|
||||
const step = Math.max(1, (raw[1].time as number) - (raw[0].time as number));
|
||||
beforeSec = oldestTime - step;
|
||||
}
|
||||
const beforeIso = toHistoryApiIso(beforeSec);
|
||||
const candleType = timeframeToCandleType(timeframe);
|
||||
|
||||
// ★ 락 설정: 이 시점부터 동일 타임스탬프 중복 요청 차단
|
||||
loadingRef.current = true;
|
||||
@@ -139,8 +151,8 @@ export function useHistoryLoader({
|
||||
|
||||
// ── 1. 백엔드 /api/candles/history 우선 시도 ──────────────────────────
|
||||
try {
|
||||
olderBars = await fetchHistoryFromBackend(symbol, timeframe, beforeIso, LOAD_BATCH);
|
||||
console.debug(`[HistoryLoader] 백엔드에서 ${olderBars.length}개 수신`);
|
||||
olderBars = await fetchHistoryFromBackend(symbol, candleType, beforeIso, LOAD_BATCH);
|
||||
console.debug(`[HistoryLoader] 백엔드에서 ${olderBars.length}개 수신 (${candleType})`);
|
||||
} catch (backendErr) {
|
||||
// ── 2. 백엔드 실패 시 업비트 REST 직접 폴백 ───────────────────────
|
||||
console.warn('[HistoryLoader] 백엔드 실패, 업비트 직접 폴백:', backendErr);
|
||||
@@ -153,7 +165,10 @@ export function useHistoryLoader({
|
||||
hasMoreRef.current = false; // 더 이상 데이터 없음
|
||||
} else {
|
||||
// ── 3. 차트 앞부분에 부드럽게 병합 (Prepend) ──────────────────────
|
||||
await mgr.prependBars(olderBars);
|
||||
const added = await mgr.prependBars(olderBars);
|
||||
if (added > 0) {
|
||||
onPrependedRef.current?.(added, mgr.getRawBarsLength());
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('[HistoryLoader] 과거 데이터 로드 실패:', e);
|
||||
|
||||
Reference in New Issue
Block a user