fix: prettier format
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 1m12s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 2m17s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 2m9s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m0s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m27s
AI Code Review / AI Code Review (pull_request) Failing after 1m53s
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m17s
CI/CD Pipeline / PR Build API Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 4m59s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m28s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Failing after 2m45s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 3m4s
CI/CD Pipeline / Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Build Production API Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been cancelled
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been cancelled
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Has been cancelled
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 1m12s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 2m17s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 2m9s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m0s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m27s
AI Code Review / AI Code Review (pull_request) Failing after 1m53s
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m17s
CI/CD Pipeline / PR Build API Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 4m59s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m28s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Failing after 2m45s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 3m4s
CI/CD Pipeline / Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Build Production API Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been cancelled
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been cancelled
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Has been cancelled
This commit is contained in:
@@ -1,75 +1,71 @@
|
||||
import { useState, useCallback, useEffect, useRef } from "react";
|
||||
import { useState, useCallback, useEffect, useRef } from "react"
|
||||
|
||||
interface UsePlayheadDragOptions {
|
||||
/** 当前播放时间(秒) */
|
||||
currentTime: number;
|
||||
currentTime: number
|
||||
/** 缩放:每秒像素数 */
|
||||
pps: number;
|
||||
pps: number
|
||||
/** 总时长(秒) */
|
||||
totalDuration: number;
|
||||
totalDuration: number
|
||||
/** 播放头跳转回调 */
|
||||
onSeek?: (time: number) => void;
|
||||
onSeek?: (time: number) => void
|
||||
}
|
||||
|
||||
/**
|
||||
* 播放头拖拽 Hook
|
||||
* 封装播放头的 mousedown/mousemove/mouseup 拖拽逻辑
|
||||
*/
|
||||
export const usePlayheadDrag = ({
|
||||
pps,
|
||||
totalDuration,
|
||||
onSeek,
|
||||
}: UsePlayheadDragOptions) => {
|
||||
const [playheadDragging, setPlayheadDragging] = useState(false);
|
||||
const trackRef = useRef<HTMLDivElement>(null);
|
||||
export const usePlayheadDrag = ({ pps, totalDuration, onSeek }: UsePlayheadDragOptions) => {
|
||||
const [playheadDragging, setPlayheadDragging] = useState(false)
|
||||
const trackRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
/* ── 播放头拖拽全局 mousemove/mouseup ── */
|
||||
useEffect(() => {
|
||||
if (!playheadDragging) return;
|
||||
if (!playheadDragging) return
|
||||
|
||||
const handleMouseMove = (e: MouseEvent) => {
|
||||
const trackEl = trackRef.current;
|
||||
if (!trackEl) return;
|
||||
const rect = trackEl.getBoundingClientRect();
|
||||
const x = e.clientX - rect.left + trackEl.scrollLeft;
|
||||
const time = Math.max(0, Math.min(x / pps, totalDuration));
|
||||
onSeek?.(Math.round(time * 10) / 10);
|
||||
};
|
||||
const trackEl = trackRef.current
|
||||
if (!trackEl) return
|
||||
const rect = trackEl.getBoundingClientRect()
|
||||
const x = e.clientX - rect.left + trackEl.scrollLeft
|
||||
const time = Math.max(0, Math.min(x / pps, totalDuration))
|
||||
onSeek?.(Math.round(time * 10) / 10)
|
||||
}
|
||||
|
||||
const handleMouseUp = () => {
|
||||
setPlayheadDragging(false);
|
||||
};
|
||||
setPlayheadDragging(false)
|
||||
}
|
||||
|
||||
document.addEventListener("mousemove", handleMouseMove);
|
||||
document.addEventListener("mouseup", handleMouseUp);
|
||||
document.addEventListener("mousemove", handleMouseMove)
|
||||
document.addEventListener("mouseup", handleMouseUp)
|
||||
return () => {
|
||||
document.removeEventListener("mousemove", handleMouseMove);
|
||||
document.removeEventListener("mouseup", handleMouseUp);
|
||||
};
|
||||
}, [playheadDragging, pps, totalDuration, onSeek]);
|
||||
document.removeEventListener("mousemove", handleMouseMove)
|
||||
document.removeEventListener("mouseup", handleMouseUp)
|
||||
}
|
||||
}, [playheadDragging, pps, totalDuration, onSeek])
|
||||
|
||||
/* ── 播放头拖拽开始 ── */
|
||||
const handlePlayheadMouseDown = useCallback((e: React.MouseEvent) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setPlayheadDragging(true);
|
||||
}, []);
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
setPlayheadDragging(true)
|
||||
}, [])
|
||||
|
||||
/* ── 标尺点击跳转播放头 ── */
|
||||
const handleRulerClick = useCallback(
|
||||
(e: React.MouseEvent<HTMLDivElement>) => {
|
||||
const rect = e.currentTarget.getBoundingClientRect();
|
||||
const x = e.clientX - rect.left;
|
||||
const time = Math.max(0, Math.min(x / pps, totalDuration));
|
||||
onSeek?.(Math.round(time * 10) / 10);
|
||||
const rect = e.currentTarget.getBoundingClientRect()
|
||||
const x = e.clientX - rect.left
|
||||
const time = Math.max(0, Math.min(x / pps, totalDuration))
|
||||
onSeek?.(Math.round(time * 10) / 10)
|
||||
},
|
||||
[pps, totalDuration, onSeek],
|
||||
);
|
||||
)
|
||||
|
||||
return {
|
||||
trackRef,
|
||||
playheadDragging,
|
||||
handlePlayheadMouseDown,
|
||||
handleRulerClick,
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user