diff --git a/web/src/components/VideoGenerationPage.tsx b/web/src/components/VideoGenerationPage.tsx index b99080f..26f6b24 100644 --- a/web/src/components/VideoGenerationPage.tsx +++ b/web/src/components/VideoGenerationPage.tsx @@ -20,7 +20,7 @@ export function VideoGenerationPage() { const regenerate = useGenerationStore((s) => s.regenerate); const removeTask = useGenerationStore((s) => s.removeTask); const scrollRef = useRef(null); - const prevCountRef = useRef(tasks.length); + const prevLastIdRef = useRef(null); const initialLoadRef = useRef(true); const savedScrollTop = useGenerationStore((s) => s.savedScrollTop); const saveScrollPosition = useGenerationStore((s) => s.saveScrollPosition); @@ -36,9 +36,14 @@ export function VideoGenerationPage() { loadTasks(); }, [loadTasks]); - // Restore scroll position after initial load, or scroll to bottom for new tasks + // Restore scroll position after initial load, or scroll to bottom ONLY when a new task + // is appended at the tail. 通过比较末尾 task 的 id 来判断 —— 头部加载历史(prepend)、 + // 任务状态更新(如轮询完成)、删除某条都不会改变末尾 id,因此不会触发滚动, + // 避免用户往上翻时被突然拽回底部。 useEffect(() => { if (tasks.length === 0) return; + const currentLastId = tasks[tasks.length - 1]?.id ?? null; + if (initialLoadRef.current) { initialLoadRef.current = false; // Use requestAnimationFrame to ensure DOM has rendered @@ -50,15 +55,16 @@ export function VideoGenerationPage() { scrollRef.current.scrollTop = scrollRef.current.scrollHeight; } }); - prevCountRef.current = tasks.length; + prevLastIdRef.current = currentLastId; return; } - if (tasks.length > prevCountRef.current && scrollRef.current) { + + if (currentLastId !== prevLastIdRef.current && scrollRef.current) { scrollRef.current.scrollTo({ top: scrollRef.current.scrollHeight, behavior: 'smooth' }); } - prevCountRef.current = tasks.length; + prevLastIdRef.current = currentLastId; // eslint-disable-next-line react-hooks/exhaustive-deps - }, [tasks.length]); + }, [tasks]); // Save scroll position + auto-load older tasks when scrolled near top const handleScroll = useCallback(() => {