feat: implement progress tracking for media file processing in timeline
This commit is contained in:
@ -69,6 +69,7 @@ export function Timeline() {
|
|||||||
} = usePlaybackStore();
|
} = usePlaybackStore();
|
||||||
const [isDragOver, setIsDragOver] = useState(false);
|
const [isDragOver, setIsDragOver] = useState(false);
|
||||||
const [isProcessing, setIsProcessing] = useState(false);
|
const [isProcessing, setIsProcessing] = useState(false);
|
||||||
|
const [progress, setProgress] = useState(0);
|
||||||
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);
|
||||||
@ -334,8 +335,12 @@ export function Timeline() {
|
|||||||
} else if (e.dataTransfer.files?.length > 0) {
|
} else if (e.dataTransfer.files?.length > 0) {
|
||||||
// Handle file drops by creating new tracks
|
// Handle file drops by creating new tracks
|
||||||
setIsProcessing(true);
|
setIsProcessing(true);
|
||||||
|
setProgress(0);
|
||||||
try {
|
try {
|
||||||
const processedItems = await processMediaFiles(e.dataTransfer.files);
|
const processedItems = await processMediaFiles(
|
||||||
|
e.dataTransfer.files,
|
||||||
|
(p) => setProgress(p)
|
||||||
|
);
|
||||||
for (const processedItem of processedItems) {
|
for (const processedItem of processedItems) {
|
||||||
addMediaItem(processedItem);
|
addMediaItem(processedItem);
|
||||||
const currentMediaItems = useMediaStore.getState().mediaItems;
|
const currentMediaItems = useMediaStore.getState().mediaItems;
|
||||||
@ -363,6 +368,7 @@ export function Timeline() {
|
|||||||
toast.error("Failed to process dropped files");
|
toast.error("Failed to process dropped files");
|
||||||
} finally {
|
} finally {
|
||||||
setIsProcessing(false);
|
setIsProcessing(false);
|
||||||
|
setProgress(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -594,10 +600,11 @@ export function Timeline() {
|
|||||||
<div className="w-px h-6 bg-border mx-1" />
|
<div className="w-px h-6 bg-border mx-1" />
|
||||||
|
|
||||||
{/* Time Display */}
|
{/* Time Display */}
|
||||||
<div className="text-xs text-muted-foreground font-mono px-2"
|
<div
|
||||||
style={{ minWidth: '18ch', textAlign: 'center' }}
|
className="text-xs text-muted-foreground font-mono px-2"
|
||||||
>
|
style={{ minWidth: "18ch", textAlign: "center" }}
|
||||||
{currentTime.toFixed(1)}s / {duration.toFixed(1)}s
|
>
|
||||||
|
{currentTime.toFixed(1)}s / {duration.toFixed(1)}s
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Test Clip Button - for debugging */}
|
{/* Test Clip Button - for debugging */}
|
||||||
@ -946,14 +953,12 @@ export function Timeline() {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{isDragOver && (
|
{isDragOver && (
|
||||||
<div
|
<div className="absolute inset-0 z-20 flex items-center justify-center pointer-events-none backdrop-blur-lg">
|
||||||
className="absolute left-0 right-0 border-2 border-dashed border-accent flex items-center justify-center text-muted-foreground"
|
<div>
|
||||||
style={{
|
{isProcessing
|
||||||
top: `${tracks.length * 60}px`,
|
? `Processing ${progress}%`
|
||||||
height: "60px",
|
: "Drop media here to add to timeline"}
|
||||||
}}
|
</div>
|
||||||
>
|
|
||||||
<div>Drop media here to add a new track</div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -1630,18 +1635,18 @@ function TimelineTrackContent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mediaItem.type === "audio") {
|
if (mediaItem.type === "audio") {
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-full flex items-center gap-2">
|
<div className="w-full h-full flex items-center gap-2">
|
||||||
<div className="flex-1 min-w-0">
|
<div className="flex-1 min-w-0">
|
||||||
<AudioWaveform
|
<AudioWaveform
|
||||||
audioUrl={mediaItem.url}
|
audioUrl={mediaItem.url}
|
||||||
height={24}
|
height={24}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
);
|
||||||
);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback for videos without thumbnails
|
// Fallback for videos without thumbnails
|
||||||
return (
|
return (
|
||||||
|
Reference in New Issue
Block a user