From 034a64a744ebafcf44738c4892396346174322ed Mon Sep 17 00:00:00 2001 From: srinidhi-2006-bit Date: Thu, 21 May 2026 09:49:18 +0530 Subject: [PATCH 1/2] feat: add dismissible privacy banner --- src/app/page.tsx | 6 ++-- src/components/PrivacyBanner.tsx | 59 ++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 src/components/PrivacyBanner.tsx diff --git a/src/app/page.tsx b/src/app/page.tsx index 0455049e..e3428153 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,5 +1,6 @@ import VideoEditor from "@/components/VideoEditor"; -import Footer from "@/components/Footer"; +import Footer from "@/components/Footer"; +import PrivacyBanner from "@/components/PrivacyBanner"; export default function Home() { return ( @@ -13,6 +14,7 @@ export default function Home() {
+
@@ -20,4 +22,4 @@ export default function Home() { ); } - + diff --git a/src/components/PrivacyBanner.tsx b/src/components/PrivacyBanner.tsx new file mode 100644 index 00000000..e7dd86c9 --- /dev/null +++ b/src/components/PrivacyBanner.tsx @@ -0,0 +1,59 @@ +"use client"; + +import { useEffect, useState } from "react"; + +const STORAGE_KEY = "reframe-privacy-banner-dismissed"; + +export default function PrivacyBanner() { + const [visible, setVisible] = useState(false); + + useEffect(() => { + const dismissedAt = localStorage.getItem(STORAGE_KEY); + + if (!dismissedAt) { + setVisible(true); + return; + } + + const sevenDays = 7 * 24 * 60 * 60 * 1000; + const expired = Date.now() - Number(dismissedAt) > sevenDays; + + if (expired) { + localStorage.removeItem(STORAGE_KEY); + setVisible(true); + } + }, []); + + const handleClose = () => { + localStorage.setItem(STORAGE_KEY, Date.now().toString()); + setVisible(false); + }; + + if (!visible) return null; + + return ( +
+
+
+

+ Your videos never leave your device. +

+ +

+ Processing is done entirely in your browser using FFmpeg.wasm. + No server, no upload, no account required. +

+
+ + +
+
+ ); +} From 62f51956b5e4f9d5c6f7873c84f932d2f4c9b18e Mon Sep 17 00:00:00 2001 From: srinidhi-2006-bit Date: Thu, 21 May 2026 20:35:10 +0530 Subject: [PATCH 2/2] fix: update live preview for framing and aspect ratio changes --- src/components/VideoPreview.tsx | 47 +++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/src/components/VideoPreview.tsx b/src/components/VideoPreview.tsx index 856ac383..2d5da385 100644 --- a/src/components/VideoPreview.tsx +++ b/src/components/VideoPreview.tsx @@ -2,7 +2,7 @@ import { useEffect, useRef, RefObject } from "react"; import { EditRecipe } from "@/lib/types"; - +import { getPresetById } from "@/lib/presets"; interface Props { file: File | null; videoRef: RefObject; @@ -35,18 +35,43 @@ export default function VideoPreview({ file, videoRef ,recipe }: Props) { if (!videoRef.current || !recipe) return; videoRef.current.playbackRate = recipe.speed; }, [recipe, videoRef]); + const preset = + recipe.preset !== "custom" + ? getPresetById(recipe.preset) + : null; + + const previewWidth = + recipe.preset === "custom" + ? recipe.customWidth || 1920 + : preset?.width || 1920; + + const previewHeight = + recipe.preset === "custom" + ? recipe.customHeight || 1080 + : preset?.height || 1080; + + const aspectRatio = `${previewWidth}/${previewHeight}`; return ( -
+
+ ref={videoRef} + controls + className={`w-full h-full ${ + recipe.framing === "fill" + ? "object-cover" + : "object-contain" + }`} + playsInline + muted={!recipe?.keepAudio} + > + +
); -} \ No newline at end of file +}