Merge pull request #41 from GeorgeCaoJ/main

fix: support context menu on track name and fix bugs of zooming in timeline track content
This commit is contained in:
iza
2025-06-24 12:34:19 +03:00
committed by GitHub

View File

@ -49,6 +49,7 @@ export function Timeline() {
const [zoomLevel, setZoomLevel] = useState(1); const [zoomLevel, setZoomLevel] = useState(1);
const dragCounterRef = useRef(0); const dragCounterRef = useRef(0);
const timelineRef = useRef<HTMLDivElement>(null); const timelineRef = useRef<HTMLDivElement>(null);
const [isInTimeline, setIsInTimeline] = useState(false);
// Unified context menu state // Unified context menu state
const [contextMenu, setContextMenu] = useState<{ const [contextMenu, setContextMenu] = useState<{
@ -477,10 +478,30 @@ export function Timeline() {
toast.success("Deleted selected clip(s)"); toast.success("Deleted selected clip(s)");
}; };
// Prevent explorer zooming in/out when in timeline
useEffect(() => {
const preventZoom = (e: WheelEvent) => {
// if (isInTimeline && (e.ctrlKey || e.metaKey)) {
if (isInTimeline && (e.ctrlKey || e.metaKey) && timelineRef.current?.contains(e.target as Node)) {
e.preventDefault();
}
};
document.addEventListener('wheel', preventZoom, { passive: false });
return () => {
document.removeEventListener('wheel', preventZoom);
};
}, [isInTimeline]);
return ( return (
<div <div
className={`h-full flex flex-col transition-colors duration-200 relative ${isDragOver ? "bg-accent/30 border-accent" : ""}`} className={`h-full flex flex-col transition-colors duration-200 relative ${isDragOver ? "bg-accent/30 border-accent" : ""}`}
{...dragProps} {...dragProps}
onMouseEnter={() => setIsInTimeline(true)}
onMouseLeave={() => setIsInTimeline(false)}
onWheel={handleWheel}
> >
{/* Show overlay when dragging media over the timeline */} {/* Show overlay when dragging media over the timeline */}
{isDragOver && ( {isDragOver && (
@ -758,25 +779,35 @@ export function Timeline() {
<div <div
key={track.id} key={track.id}
className="h-[60px] flex items-center px-3 border-b border-muted/30 bg-background group" className="h-[60px] flex items-center px-3 border-b border-muted/30 bg-background group"
onContextMenu={(e) => {
e.preventDefault();
setContextMenu({
type: 'track',
trackId: track.id,
x: e.clientX,
y: e.clientY,
});
}}
> >
<div className="flex items-center gap-2 flex-1 min-w-0"> <div className="flex items-center flex-1 min-w-0">
<div <div
className={`w-3 h-3 rounded-full flex-shrink-0 ${track.type === "video" className={`w-3 h-3 rounded-full flex-shrink-0 ${
? "bg-blue-500" track.type === "video"
: track.type === "audio" ? "bg-blue-500"
: track.type === "audio"
? "bg-green-500" ? "bg-green-500"
: "bg-purple-500" : "bg-purple-500"
}`} }`}
/> />
<span className="text-sm font-medium truncate"> <span className="ml-2 text-sm font-medium truncate">
{track.name} {track.name}
</span> </span>
{track.muted && (
<span className="ml-2 text-xs text-red-500 font-semibold">
Muted
</span>
)}
</div> </div>
{track.muted && (
<span className="ml-2 text-xs text-red-500 font-semibold flex-shrink-0">
Muted
</span>
)}
</div> </div>
))} ))}
</div> </div>
@ -795,7 +826,6 @@ export function Timeline() {
}} }}
onClick={handleTimelineAreaClick} onClick={handleTimelineAreaClick}
onMouseDown={handleTimelineMouseDown} onMouseDown={handleTimelineMouseDown}
onWheel={handleWheel}
> >
{tracks.length === 0 ? ( {tracks.length === 0 ? (
<div className="absolute inset-0 flex items-center justify-center"> <div className="absolute inset-0 flex items-center justify-center">