From 481a3ffc06b853930bb780fbe23444b81e38019e Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Wed, 29 Jul 2026 13:45:52 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20useRowProgress=20=E9=99=A4=E9=9B=B6?= =?UTF-8?q?=E4=BF=9D=E6=8A=A4=20+=20=E7=BB=84=E4=BB=B6=E5=8D=B8=E8=BD=BD?= =?UTF-8?q?=E6=B8=85=E7=90=86=20+=20=E8=A1=A5=E5=85=85smoke=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E5=BC=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../voice-material-row/useRowProgress.ts | 36 ++++++++++++++++--- .../test/pages/voice-materials/smoke.test.tsx | 2 ++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/apps/web/src/pages/voice-materials/components/voice-material-row/useRowProgress.ts b/apps/web/src/pages/voice-materials/components/voice-material-row/useRowProgress.ts index 3fc8e5e9b..d758b87c1 100755 --- a/apps/web/src/pages/voice-materials/components/voice-material-row/useRowProgress.ts +++ b/apps/web/src/pages/voice-materials/components/voice-material-row/useRowProgress.ts @@ -1,4 +1,4 @@ -import { useRef, useCallback } from "react" +import { useRef, useCallback, useEffect } from "react" interface UseRowProgressOptions { duration: number @@ -7,6 +7,22 @@ interface UseRowProgressOptions { export function useRowProgress({ duration, onSeek }: UseRowProgressOptions) { const progressRef = useRef(null) + const listenersRef = useRef<{ move: ((e: MouseEvent) => void) | null; up: (() => void) | null }>({ + move: null, + up: null, + }) + + const cleanupListeners = useCallback(() => { + const { move, up } = listenersRef.current + if (move) { + document.removeEventListener("mousemove", move) + listenersRef.current.move = null + } + if (up) { + document.removeEventListener("mouseup", up) + listenersRef.current.up = null + } + }, []) const handleMouseDown = useCallback( (e: React.MouseEvent) => { @@ -16,6 +32,7 @@ export function useRowProgress({ duration, onSeek }: UseRowProgressOptions) { const doSeek = (ev: MouseEvent) => { if (!progressRef.current) return const rect = progressRef.current.getBoundingClientRect() + if (rect.width <= 0) return const percent = Math.max(0, Math.min(1, (ev.clientX - rect.left) / rect.width)) onSeek(percent * duration) } @@ -24,15 +41,26 @@ export function useRowProgress({ duration, onSeek }: UseRowProgressOptions) { const handleMove = (ev: MouseEvent) => doSeek(ev) const handleUp = () => { - document.removeEventListener("mousemove", handleMove) - document.removeEventListener("mouseup", handleUp) + cleanupListeners() } + // 先清理旧的,再添加新的 + cleanupListeners() + listenersRef.current.move = handleMove + listenersRef.current.up = handleUp + document.addEventListener("mousemove", handleMove) document.addEventListener("mouseup", handleUp) }, - [duration, onSeek], + [duration, onSeek, cleanupListeners], ) + // 组件卸载时清理事件监听器 + useEffect(() => { + return () => { + cleanupListeners() + } + }, [cleanupListeners]) + return { progressRef, handleMouseDown } } diff --git a/apps/web/src/test/pages/voice-materials/smoke.test.tsx b/apps/web/src/test/pages/voice-materials/smoke.test.tsx index 379d72ed9..946a442db 100755 --- a/apps/web/src/test/pages/voice-materials/smoke.test.tsx +++ b/apps/web/src/test/pages/voice-materials/smoke.test.tsx @@ -20,6 +20,8 @@ import "@/pages/voice-materials/components/voice-material-card/CardActions" import "@/pages/voice-materials/components/voice-material-card/BatchCheckbox" import "@/pages/voice-materials/components/voice-material-card/types" import "@/pages/voice-materials/components/VoiceMaterialRow" +import "@/pages/voice-materials/components/voice-material-row/useRowProgress" +import "@/pages/voice-materials/components/voice-material-row/TagDisplay" import "@/pages/voice-materials/components/Toolbar" import "@/pages/voice-materials/components/TagFilterBar" import "@/pages/voice-materials/components/BatchBar" -- 2.54.0