{tracks.length === 0 ? "Drop media to start editing" : "No clip at current time"}
@@ -44,8 +44,26 @@ export function PreviewPanel() {
);
}
- // Calculate the relative time within the clip (accounting for trim)
- const relativeTime = Math.max(0, currentTime - activeClip.startTime + activeClip.trimStart);
+ // Handle test clips without media items
+ if (!activeMediaItem && activeClip.mediaId === "test") {
+ return (
+
+
+
🎬
+
{activeClip.name}
+
Test clip for playback
+
+
+ );
+ }
+
+ if (!activeMediaItem) {
+ return (
+
+ Media not found
+
+ );
+ }
if (activeMediaItem.type === "video") {
return (
@@ -53,7 +71,10 @@ export function PreviewPanel() {
src={activeMediaItem.url}
poster={activeMediaItem.thumbnailUrl}
className="w-full h-full"
- startTime={relativeTime}
+ clipStartTime={activeClip.startTime}
+ trimStart={activeClip.trimStart}
+ trimEnd={activeClip.trimEnd}
+ clipDuration={activeClip.duration}
key={`${activeClip.id}-${activeClip.trimStart}-${activeClip.trimEnd}`}
/>
);
diff --git a/apps/web/src/components/editor/timeline.tsx b/apps/web/src/components/editor/timeline.tsx
index d1bb3aa..1d2df66 100644
--- a/apps/web/src/components/editor/timeline.tsx
+++ b/apps/web/src/components/editor/timeline.tsx
@@ -13,6 +13,8 @@ import {
MoreVertical,
Volume2,
VolumeX,
+ Pause,
+ Play,
} from "lucide-react";
import {
Tooltip,
@@ -31,10 +33,10 @@ export function Timeline() {
// Timeline shows all tracks (video, audio, effects) and their clips.
// You can drag media here to add it to your project.
// Clips can be trimmed, deleted, and moved.
- const { tracks, addTrack, addClipToTrack, removeTrack, toggleTrackMute, removeClipFromTrack, moveClipToTrack } =
+ const { tracks, addTrack, addClipToTrack, removeTrack, toggleTrackMute, removeClipFromTrack, moveClipToTrack, getTotalDuration } =
useTimelineStore();
const { mediaItems, addMediaItem } = useMediaStore();
- const { currentTime, duration, seek } = usePlaybackStore();
+ const { currentTime, duration, seek, setDuration, isPlaying, play, pause, toggle } = usePlaybackStore();
const [isDragOver, setIsDragOver] = useState(false);
const [isProcessing, setIsProcessing] = useState(false);
const [zoomLevel, setZoomLevel] = useState(1);
@@ -50,6 +52,12 @@ export function Timeline() {
y: number;
} | null>(null);
+ // Update timeline duration when tracks change
+ useEffect(() => {
+ const totalDuration = getTotalDuration();
+ setDuration(Math.max(totalDuration, 10)); // Minimum 10 seconds for empty timeline
+ }, [tracks, setDuration, getTotalDuration]);
+
// Close context menu on click elsewhere
useEffect(() => {
const handleClick = () => setContextMenu(null);
@@ -208,6 +216,59 @@ export function Timeline() {
{/* Toolbar */}