fix: latest trades on top + fixed height container so page never jumps

This commit is contained in:
root 2026-02-27 13:01:47 +00:00
parent 1db9e55259
commit 04d3219a1c

View File

@ -1,6 +1,6 @@
"use client"; "use client";
import { useEffect, useState, useRef, useCallback } from "react"; import { useEffect, useState, useCallback } from "react";
import { authFetch } from "@/lib/auth"; import { authFetch } from "@/lib/auth";
import { useAuth } from "@/lib/auth"; import { useAuth } from "@/lib/auth";
import Link from "next/link"; import Link from "next/link";
@ -56,29 +56,25 @@ function timeStr(ms: number) {
function LiveTrades({ symbol }: { symbol: Symbol }) { function LiveTrades({ symbol }: { symbol: Symbol }) {
const [trades, setTrades] = useState<TradeRow[]>([]); const [trades, setTrades] = useState<TradeRow[]>([]);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const containerRef = useRef<HTMLDivElement>(null);
const lastAggId = useRef<number>(0);
useEffect(() => { useEffect(() => {
let running = true; let running = true;
// 重置
setTrades([]); setTrades([]);
setLoading(true); setLoading(true);
lastAggId.current = 0;
const fetch = async () => { const fetch = async () => {
try { try {
const res = await authFetch(`/api/trades/latest?symbol=${symbol}&limit=30`); const res = await authFetch(`/api/trades/latest?symbol=${symbol}&limit=40`);
if (!res.ok) return; if (!res.ok) return;
const data = await res.json(); const data = await res.json();
if (!running) return; if (!running) return;
const incoming: TradeRow[] = (data.data || []).reverse(); // 改为时间升序 const incoming: TradeRow[] = data.data || [];
setTrades(prev => { setTrades(prev => {
const existingIds = new Set(prev.map((t: TradeRow) => t.agg_id)); const existingIds = new Set(prev.map((t: TradeRow) => t.agg_id));
const newOnes = incoming.filter((t: TradeRow) => !existingIds.has(t.agg_id)); const newOnes = incoming.filter((t: TradeRow) => !existingIds.has(t.agg_id));
if (newOnes.length === 0) return prev; if (newOnes.length === 0) return prev;
// 追加到末尾保持时间升序最多保留120条 // 最新在顶部最多保留50条
return [...prev, ...newOnes].slice(-120); return [...newOnes, ...prev].slice(0, 50);
}); });
setLoading(false); setLoading(false);
} catch {} } catch {}
@ -103,7 +99,8 @@ function LiveTrades({ symbol }: { symbol: Symbol }) {
<span className="text-red-500 font-medium"> </span>= <span className="text-red-500 font-medium"> </span>=
</p> </p>
</div> </div>
<div ref={containerRef} className="overflow-y-auto flex-1" style={{ height: 420 }}> {/* 固定高度容器,内部自己滚动,不影响页面 */}
<div className="overflow-y-auto" style={{ height: 420 }}>
{loading ? ( {loading ? (
<div className="flex items-center justify-center h-24 text-slate-400 text-sm">...</div> <div className="flex items-center justify-center h-24 text-slate-400 text-sm">...</div>
) : ( ) : (