Skip to content

Commit a78fe1d

Browse files
committed
fix
1 parent 7f828ff commit a78fe1d

File tree

5 files changed

+64
-36
lines changed

5 files changed

+64
-36
lines changed

app/coins/[id]/page.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ const CoinDetails = async ({ params }: { params: Promise<{ id: string }> }) => {
2424
const { id } = await params;
2525
const coinData = await getCoinDetails(id);
2626
const topGainersLosers = await getTopGainersLosers();
27-
const coinOHLCData = await getCoinOHLC(id, 1, 'usd', 'hourly', 'full');
2827
const pool = await fetchPools(id);
28+
// Fetch initial OHLC data for 1 day (matches initialPeriod='daily')
29+
const coinOHLCData = await getCoinOHLC(id, 1, 'usd', 'hourly', 'full');
2930

3031
const coinDetails = [
3132
{
@@ -64,10 +65,10 @@ const CoinDetails = async ({ params }: { params: Promise<{ id: string }> }) => {
6465
<main className='coin-details-main'>
6566
<section className='size-full xl:col-span-2'>
6667
<LiveDataWrapper
67-
coinOHLCData={coinOHLCData}
6868
coinId={id}
6969
pool={pool}
7070
coin={coinData}
71+
coinOHLCData={coinOHLCData}
7172
>
7273
{/* Exchange Listings - pass it as a child of a client component
7374
// so it will be render server side */}

components/CandlestickChart.tsx

Lines changed: 56 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,38 +23,53 @@ export default function CandlestickChart({
2323
children,
2424
liveOhlcv = null,
2525
mode = 'historical',
26+
initialPeriod = 'daily',
2627
}: CandlestickChartProps) {
2728
const chartContainerRef = useRef<HTMLDivElement | null>(null);
2829
const chartRef = useRef<IChartApi | null>(null);
2930
const candleSeriesRef = useRef<ISeriesApi<'Candlestick'> | null>(null);
30-
const [period, setPeriod] = useState<Period>('daily');
31+
32+
const [period, setPeriod] = useState<Period>(initialPeriod);
3133
const [ohlcData, setOhlcData] = useState<OHLCData[]>(data ?? []);
3234
const [loading, setLoading] = useState(false);
35+
const prevOhlcDataLength = useRef<number>(data?.length ?? 0);
3336

34-
console.log('==== Candlestick Chart Live OHLCV:', liveOhlcv);
37+
console.log('=====liveOhlcv', liveOhlcv);
3538

36-
// Fetch historical data
39+
// Fetch OHLC data when period changes
3740
const fetchOHLCData = async (selectedPeriod: Period) => {
3841
setLoading(true);
3942
try {
4043
const config = PERIOD_CONFIG[selectedPeriod];
44+
console.log('==== Fetching OHLC:', {
45+
period: selectedPeriod,
46+
days: config.days,
47+
interval: config.interval,
48+
coinId,
49+
});
4150
const newData = await getCoinOHLC(
4251
coinId,
4352
config.days,
4453
'usd',
4554
config.interval,
4655
'full'
4756
);
57+
console.log('==== OHLC Fetched:', {
58+
period: selectedPeriod,
59+
dataPoints: newData?.length,
60+
});
4861
setOhlcData(newData ?? []);
4962
} catch (err) {
50-
console.error(err);
63+
console.error('Failed to fetch OHLC data:', err);
5164
} finally {
5265
setLoading(false);
5366
}
5467
};
5568

5669
const handlePeriodChange = (newPeriod: Period) => {
57-
if (mode === 'live' || newPeriod === period) return;
70+
if (newPeriod === period) return;
71+
72+
console.log('==== Period Change:', { from: period, to: newPeriod, mode });
5873
setPeriod(newPeriod);
5974
fetchOHLCData(newPeriod);
6075
};
@@ -95,6 +110,12 @@ export default function CandlestickChart({
95110
useEffect(() => {
96111
if (!candleSeriesRef.current) return;
97112

113+
console.log('==== Chart Update Effect Triggered:', {
114+
ohlcDataPoints: ohlcData.length,
115+
hasLiveOhlcv: !!liveOhlcv,
116+
liveOhlcv,
117+
});
118+
98119
// Convert timestamps from milliseconds to seconds
99120
const convertedToSeconds = ohlcData.map(
100121
(item) =>
@@ -108,6 +129,7 @@ export default function CandlestickChart({
108129
);
109130

110131
let merged: OHLCData[];
132+
let action = 'none';
111133

112134
if (liveOhlcv) {
113135
const liveTimestamp = liveOhlcv[0];
@@ -119,10 +141,19 @@ export default function CandlestickChart({
119141
if (lastHistoricalCandle && lastHistoricalCandle[0] === liveTimestamp) {
120142
// Update the last candle with live data
121143
merged = [...convertedToSeconds.slice(0, -1), liveOhlcv];
144+
action = 'updated';
122145
} else {
123146
// Append new live candle
124147
merged = [...convertedToSeconds, liveOhlcv];
148+
action = 'appended';
125149
}
150+
151+
console.log('==== Live OHLCV Merge:', {
152+
action,
153+
liveTimestamp,
154+
liveTime: new Date(liveTimestamp * 1000).toISOString(),
155+
lastHistoricalTimestamp: lastHistoricalCandle?.[0],
156+
});
126157
} else {
127158
merged = convertedToSeconds;
128159
}
@@ -134,34 +165,34 @@ export default function CandlestickChart({
134165

135166
candleSeriesRef.current.setData(converted);
136167

137-
// Only fit content on initial load or period change, not on live updates
138-
if (!liveOhlcv || mode === 'historical') {
168+
// Fit content when ohlcData changes (period change), not on live updates
169+
const dataChanged = prevOhlcDataLength.current !== ohlcData.length;
170+
if (dataChanged || mode === 'historical') {
139171
chartRef.current?.timeScale().fitContent();
172+
prevOhlcDataLength.current = ohlcData.length;
140173
}
141174
}, [ohlcData, liveOhlcv, period, mode]);
142175

143176
return (
144177
<div className='candlestick-container'>
145178
<div className='candlestick-header'>
146179
<div className='flex-1'>{children}</div>
147-
{mode === 'historical' && (
148-
<div className='candlestick-button-group'>
149-
{PERIOD_BUTTONS.map(({ value, label }) => (
150-
<button
151-
key={value}
152-
className={
153-
period === value
154-
? 'candlestick-period-button-active'
155-
: 'candlestick-period-button'
156-
}
157-
onClick={() => handlePeriodChange(value)}
158-
disabled={loading}
159-
>
160-
{label}
161-
</button>
162-
))}
163-
</div>
164-
)}
180+
<div className='candlestick-button-group'>
181+
{PERIOD_BUTTONS.map(({ value, label }) => (
182+
<button
183+
key={value}
184+
className={
185+
period === value
186+
? 'candlestick-period-button-active'
187+
: 'candlestick-period-button'
188+
}
189+
onClick={() => handlePeriodChange(value)}
190+
disabled={loading}
191+
>
192+
{label}
193+
</button>
194+
))}
195+
</div>
165196
</div>
166197
<div
167198
ref={chartContainerRef}

components/LiveDataWrapper.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,8 @@ export default function LiveDataWrapper({
2424
const { price, trades, ohlcv } = useCoinGeckoWebSocket({
2525
coinId,
2626
poolId: pool.id,
27-
coinOHLCData,
2827
});
2928

30-
// console.log('==== LiveDataWrapper coinOHLCData:', coinOHLCData);
31-
// console.log('==== LiveDataWrapper OHLCV:', ohlcv);
32-
3329
return (
3430
<section className='size-full xl:col-span-2'>
3531
<CoinHeader
@@ -53,6 +49,7 @@ export default function LiveDataWrapper({
5349
liveOhlcv={ohlcv}
5450
coinId={coinId}
5551
mode='live'
52+
initialPeriod='daily'
5653
/>
5754
</div>
5855

hooks/useCoinGeckoWebSocket.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ const WS_BASE = `${process.env.NEXT_PUBLIC_COINGECKO_WEBSOCKET_URL}?x_cg_pro_api
66
export function useCoinGeckoWebSocket({
77
coinId,
88
poolId,
9-
coinOHLCData,
109
}: UseCoinGeckoWebSocketProps): UseCoinGeckoWebSocketReturn {
1110
const wsRef = useRef<WebSocket | null>(null);
1211
const subscribed = useRef<Set<string>>(new Set());
@@ -163,7 +162,7 @@ export function useCoinGeckoWebSocket({
163162
return () => {
164163
active = false;
165164
};
166-
}, [coinId, poolId, isWsReady, coinOHLCData, subscribe, unsubscribeAll]);
165+
}, [coinId, poolId, isWsReady, subscribe, unsubscribeAll]);
167166

168167
return {
169168
price,

types.d.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
type OHLCData = [number, number, number, number, number];
22

33
interface CandlestickChartProps {
4-
data: OHLCData[];
4+
data?: OHLCData[];
55
liveOhlcv?: OHLCData | null;
66
coinId: string;
77
height?: number;
88
children?: React.ReactNode;
99
mode?: 'historical' | 'live';
10+
initialPeriod?: Period;
1011
}
1112

1213
interface ConverterProps {
@@ -225,7 +226,7 @@ interface LiveDataProps {
225226
network: string;
226227
};
227228
coin: CoinDetailsData;
228-
coinOHLCData: OHLCData[];
229+
coinOHLCData?: OHLCData[];
229230
children?: React.ReactNode;
230231
}
231232

@@ -249,7 +250,6 @@ interface Category {
249250
interface UseCoinGeckoWebSocketProps {
250251
coinId: string;
251252
poolId: string;
252-
coinOHLCData: OHLCData[];
253253
}
254254

255255
interface UseCoinGeckoWebSocketReturn {

0 commit comments

Comments
 (0)