From d924f25fc786829893e0cfeb060e2853445f0f5e Mon Sep 17 00:00:00 2001 From: ct Date: Mon, 16 Jun 2025 14:45:39 +0800 Subject: [PATCH] Revert "Update" This reverts commit 8ab96e5d009735c33a53b73b826ad3434f149224. --- .../editor/partials/canvas/video-editor.jsx | 135 +++--------------- 1 file changed, 19 insertions(+), 116 deletions(-) diff --git a/resources/js/modules/editor/partials/canvas/video-editor.jsx b/resources/js/modules/editor/partials/canvas/video-editor.jsx index 4354ad7..01fd660 100644 --- a/resources/js/modules/editor/partials/canvas/video-editor.jsx +++ b/resources/js/modules/editor/partials/canvas/video-editor.jsx @@ -1,9 +1,9 @@ -// Updated video-editor.jsx to use selected meme and background +// TODO: I moved the sample timeline data to a dedicated file, and delayed the loading to 1 sec with useEffect. as such, alot of the ogics are broken. I need to make sure the delayed timeline should work like normal import { useMitt } from '@/plugins/MittContext'; -import useMediaStore from '@/stores/MediaStore'; // Add this import import useVideoEditorStore from '@/stores/VideoEditorStore'; import { useCallback, useEffect, useRef, useState } from 'react'; +import sampleTimelineElements from './sample-timeline-data'; import useVideoExport from './video-export'; import VideoPreview from './video-preview'; @@ -23,9 +23,6 @@ const VideoEditor = ({ width, height }) => { const lastUpdateRef = useRef(0); const emitter = useMitt(); - // Add MediaStore to get selected items - const { selectedMeme, selectedBackground } = useMediaStore(); - const [currentTime, setCurrentTime] = useState(0); const [isPlaying, setIsPlaying] = useState(false); const [videoElements, setVideoElements] = useState({}); @@ -47,56 +44,10 @@ const VideoEditor = ({ width, height }) => { timelineElementsRef.current = timelineElements; }, [timelineElements]); - // ✅ NEW: Create timeline from selected items - const createTimelineFromSelections = useCallback(() => { - const elements = []; - - // If we have a selected meme, use its duration, otherwise default to 5 seconds - const memeDuration = selectedMeme?.duration ? parseFloat(selectedMeme.duration) : 5; - - // Add background video if selected (base layer) - if (selectedBackground) { - elements.push({ - id: `bg_${selectedBackground.ids}`, - type: 'video', - source_webm: selectedBackground.media_url, // Assuming it's webm - source_mov: selectedBackground.media_url, // You might need different URLs - poster: selectedBackground.media_url, - name: 'Background', - startTime: 0, - layer: 0, - inPoint: 0, - duration: memeDuration, // Match meme duration - x: 0, - y: 0, - width: dimensions.width, - height: dimensions.height, - }); - } - - // Add meme video if selected (overlay layer) - if (selectedMeme) { - elements.push({ - id: `meme_${selectedMeme.ids}`, - type: 'video', - source_webm: selectedMeme.webm_url, - source_mov: selectedMeme.mov_url, - poster: selectedMeme.webp_url, - name: selectedMeme.name, - startTime: 0, - layer: 1, - inPoint: 0, - duration: memeDuration, - x: 0, // Offset slightly for overlay effect - y: 0, - width: dimensions.width - 100, - height: dimensions.height - 100, - }); - } - - showConsoleLogs && console.log('Created timeline from selections:', elements); - return elements; - }, [selectedMeme, selectedBackground, dimensions]); + // ✅ FIX 1: Use useEffect to automatically setup videos when timeline loads + useEffect(() => { + initTimeline(); + }, []); const timelineUpdateResolverRef = useRef(null); @@ -109,29 +60,20 @@ const VideoEditor = ({ width, height }) => { // Add this useEffect to resolve the promise when timeline updates useEffect(() => { - if (timelineUpdateResolverRef.current && timelineElements.length >= 0) { - // Changed from > 0 to >= 0 + if (timelineUpdateResolverRef.current && timelineElements.length > 0) { timelineUpdateResolverRef.current(); timelineUpdateResolverRef.current = null; } }, [timelineElements]); - // ✅ UPDATED: Use selections instead of sample data - const initTimeline = useCallback(() => { + const initTimeline = () => { cleanupVideos(videoElements); + setTimelineElementsAsync(sampleTimelineElements).then(() => { + showConsoleLogs && console.log('Loaded sample timeline'); - const newElements = createTimelineFromSelections(); - setTimelineElementsAsync(newElements).then(() => { - showConsoleLogs && console.log('Loaded timeline from selections'); setupVideos(); }); - }, [createTimelineFromSelections, videoElements]); - - // ✅ NEW: Watch for changes in selected items and update timeline - useEffect(() => { - initTimeline(); - }, [selectedMeme, selectedBackground]); // Re-run when selections change - + }; // ✅ FIX 3: Auto-update status when videos load useEffect(() => { setupVideoStatus(); @@ -141,8 +83,7 @@ const VideoEditor = ({ width, height }) => { setVideoIsPlaying(isPlaying); }, [isPlaying, setVideoIsPlaying]); - // ✅ UPDATED: Calculate duration from actual timeline - const totalDuration = timelineElements.length > 0 ? Math.max(...timelineElements.map((el) => el.startTime + el.duration)) : 5; // Default fallback + const totalDuration = Math.max(...timelineElements.map((el) => el.startTime + el.duration)); // Use the FFmpeg hook const { isExporting, exportProgress, exportStatus, ffmpegCommand, copyFFmpegCommand, exportVideo } = useVideoExport({ @@ -194,13 +135,6 @@ const VideoEditor = ({ width, height }) => { posterImg.crossOrigin = 'anonymous'; posterImg.src = element.poster; - // Fixed section from setupVideos function in video-editor.jsx - // Replace this entire posterImg.onload section in your setupVideos function - - // Replace this entire posterImg.onload section in your setupVideos function - - // Replace this entire posterImg.onload section in your setupVideos function - posterImg.onload = () => { console.log('Poster loaded for:', element.id); @@ -209,51 +143,21 @@ const VideoEditor = ({ width, height }) => { const posterWidth = posterImg.naturalWidth; const posterHeight = posterImg.naturalHeight; - // ✅ UPDATED: Check if this element is the selectedBackground using store data - const isBackgroundElement = selectedBackground && element.id.includes(selectedBackground.ids); + let scaledWidth = posterWidth; + let scaledHeight = posterHeight; - let scaledWidth, scaledHeight, centeredX, centeredY; - - if (isBackgroundElement) { - // Background should maintain aspect ratio and cover the entire canvas - // Calculate scale to cover entire canvas (like CSS object-fit: cover) + if (posterWidth > maxWidth || posterHeight > maxHeight) { const scaleX = maxWidth / posterWidth; const scaleY = maxHeight / posterHeight; - const scale = Math.max(scaleX, scaleY); // Use larger scale to cover + const scale = Math.min(scaleX, scaleY); scaledWidth = posterWidth * scale; scaledHeight = posterHeight * scale; - - // Center the background - centeredX = (maxWidth - scaledWidth) / 2; - centeredY = (maxHeight - scaledHeight) / 2; - } else { - // Meme overlay: start with original size, apply constraints, then 70% and bottom positioning - scaledWidth = posterWidth; - scaledHeight = posterHeight; - - // Apply size constraints (keep original logic for memes) - if (posterWidth > maxWidth || posterHeight > maxHeight) { - const scaleX = maxWidth / posterWidth; - const scaleY = maxHeight / posterHeight; - const scale = Math.min(scaleX, scaleY); - - scaledWidth = posterWidth * scale; - scaledHeight = posterHeight * scale; - } - - // Apply 70% size reduction - scaledWidth = scaledWidth * 0.7; - scaledHeight = scaledHeight * 0.7; - - // Center horizontally - centeredX = (maxWidth - scaledWidth) / 2; - - // Position at bottom with some padding - const bottomPadding = 40; // 40px from bottom - centeredY = maxHeight - scaledHeight - bottomPadding; } + const centeredX = (maxWidth - scaledWidth) / 2; + const centeredY = (maxHeight - scaledHeight) / 2; + setTimelineElements((prev) => prev.map((el) => { if (el.id === element.id && el.type === 'video') { @@ -311,7 +215,6 @@ const VideoEditor = ({ width, height }) => { setVideoElements(videoEls); }; - // Rest of the component remains the same... const cleanupVideos = (videosToCleanup) => { if (!videosToCleanup) return;