diff --git a/src/components/FileUpload.tsx b/src/components/FileUpload.tsx index f9f2127e..5c788b6e 100644 --- a/src/components/FileUpload.tsx +++ b/src/components/FileUpload.tsx @@ -9,6 +9,7 @@ import { MAX_FILE_SIZE, WARNING_FILE_SIZE } from "@/lib/types"; interface Props { onFileSelect: (file: File) => void; + onClear: () => void; currentFile: File | null; fileError: string; duration: number; @@ -16,6 +17,7 @@ interface Props { export default function FileUpload({ onFileSelect, + onClear, currentFile, fileError, duration, @@ -125,6 +127,13 @@ export default function FileUpload({ if (file) handleFile(file); }; + const handleClear = () => { + setError(""); + setWarning(""); + if (inputRef.current) inputRef.current.value = ""; + onClear(); + }; + // ── File info (shown after upload) ─────────────────── const FileInfo = () => (
@@ -158,14 +167,28 @@ export default function FileUpload({
- +
+ + + +

diff --git a/src/components/VideoEditor.tsx b/src/components/VideoEditor.tsx index 1e4e9f0d..b95481b5 100644 --- a/src/components/VideoEditor.tsx +++ b/src/components/VideoEditor.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState, useRef, useEffect, useMemo } from "react"; +import { useState, useRef, useEffect, useMemo, useCallback } from "react"; import { useVideoEditor } from "@/hooks/useVideoEditor"; import { TextOverlay } from "@/lib/types"; import FileUpload from "./FileUpload"; @@ -239,6 +239,22 @@ export default function VideoEditor() { setOpenSections((prev) => ({ ...prev, [key]: !prev[key] })); const downloadRef = useRef(null); + const handleClearUpload = useCallback(() => { + if (status === "loading-engine" || status === "exporting") { + cancelExport(); + } + reset(); + setSelectedTextId(null); + setOpenSections({ + resize: true, + trim: false, + rotation: false, + text: false, + audio: false, + export: false, + }); + }, [reset, cancelExport, status]); + /** * Updates a text overlay property and syncs with recipe. */ @@ -370,7 +386,13 @@ export default function VideoEditor() {

- + {!file && (
diff --git a/src/hooks/useVideoEditor.ts b/src/hooks/useVideoEditor.ts index a86c35f2..38cc6b86 100644 --- a/src/hooks/useVideoEditor.ts +++ b/src/hooks/useVideoEditor.ts @@ -640,18 +640,49 @@ export function useVideoEditor() { const reset = useCallback(() => { + exportCancelledRef.current = true; + exportAbortControllerRef.current?.abort(); + exportAbortControllerRef.current = null; + terminateFFmpeg(); + if (result?.blobUrl) URL.revokeObjectURL(result.blobUrl); + setFile(null); setVideoMetadata(null); setDuration(0); - setRecipe(DEFAULT_RECIPE); + setCurrentTime(0); + setFileError(""); + setRecipe({ + ...DEFAULT_RECIPE, + soundOnCompletion: + typeof window !== "undefined" && + localStorage.getItem("soundOnCompletion") === "true", + }); setStatus("idle"); setProgress(0); setResult(null); setError(null); setExportStartedAt(null); + + setMusicFile(null); + setMusicVolume(70); + setOriginalAudioVolume(40); + setLoopMusic(false); + setOverlayFile(null); + setOverlayPosition("bottom-right"); + setOverlaySize(150); + setOverlayOpacity(100); + + const video = videoRef.current; + if (video) { + video.pause(); + video.removeAttribute("src"); + video.load(); + } + try { localStorage.removeItem(STORAGE_KEY); + localStorage.removeItem("reframe-settings"); } catch { // ignore }