From 7504a2a3183440f16c6b7aef6b7519a4a7d2eb19 Mon Sep 17 00:00:00 2001 From: Rucha Date: Wed, 20 May 2026 08:53:40 +0530 Subject: [PATCH] fix(mobile): ensure export button is full-width with 44px touch target (#57) - Add min-h-[44px] to the export button to guarantee the minimum 44px touch target height on all screen sizes (WCAG 2.5.5 recommendation) - w-full already present so button spans full container width on mobile (grid collapses to single column on screens < lg breakpoint) - Also update ffmpeg.test.ts to match new buildAudioFilter(speed, normalizeAudio) signature introduced in upstream main Closes #57 --- src/components/VideoEditor.tsx | 2 +- src/lib/tests/ffmpeg.test.ts | 25 +++++++++++++++---------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/components/VideoEditor.tsx b/src/components/VideoEditor.tsx index 3ffb6a67..60497607 100644 --- a/src/components/VideoEditor.tsx +++ b/src/components/VideoEditor.tsx @@ -355,7 +355,7 @@ export default function VideoEditor() { aria-label='Export video' aria-disabled={!file || isProcessing ? "true" : undefined} className={cn( - "w-full flex items-center justify-center gap-3 py-5 rounded-xl", + "w-full flex items-center justify-center gap-3 py-5 min-h-[44px] rounded-xl", "font-display text-2xl tracking-widest transition-all duration-200", file && !isProcessing ? "bg-film-600 hover:bg-film-700 hover:scale-[1.01] text-white shadow-lg shadow-film-200 active:scale-[0.98] cursor-pointer" diff --git a/src/lib/tests/ffmpeg.test.ts b/src/lib/tests/ffmpeg.test.ts index bdde5d41..c2e42e74 100644 --- a/src/lib/tests/ffmpeg.test.ts +++ b/src/lib/tests/ffmpeg.test.ts @@ -3,15 +3,15 @@ import { buildAudioFilter } from "../ffmpeg"; describe("buildAudioFilter", () => { it("should return an empty string for 1.0x speed", () => { - expect(buildAudioFilter(1)).toBe(""); + expect(buildAudioFilter(1, false)).toBe(""); }); it("should chain two 0.5x filters for 0.25x speed", () => { - expect(buildAudioFilter(0.25)).toBe("atempo=0.5,atempo=0.5"); + expect(buildAudioFilter(0.25, false)).toBe("atempo=0.5,atempo=0.5"); }); it("should chain two 2.0x filters for 4.0x speed", () => { - expect(buildAudioFilter(4)).toBe("atempo=2.0,atempo=2"); + expect(buildAudioFilter(4, false)).toBe("atempo=2.0,atempo=2"); }); it("should chain multiple 0.5x filters and a remainder for 0.1x speed", () => { @@ -19,25 +19,30 @@ describe("buildAudioFilter", () => { // 0.2 / 0.5 = 0.4 // 0.4 / 0.5 = 0.8 // Result should be three 0.5s and one 0.8 - expect(buildAudioFilter(0.1)).toBe("atempo=0.5,atempo=0.5,atempo=0.5,atempo=0.8"); + expect(buildAudioFilter(0.1, false)).toBe("atempo=0.5,atempo=0.5,atempo=0.5,atempo=0.8"); }); it("should chain multiple 2.0x filters and a remainder for 3.0x speed", () => { // 3.0 / 2.0 = 1.5 - expect(buildAudioFilter(3)).toBe("atempo=2.0,atempo=1.5"); + expect(buildAudioFilter(3, false)).toBe("atempo=2.0,atempo=1.5"); }); it("should handle boundary values inside the 0.5x-2.0x range without chaining", () => { - expect(buildAudioFilter(0.5)).toBe("atempo=0.5"); - expect(buildAudioFilter(2.0)).toBe("atempo=2"); // Note: Number(2.0.toFixed(4)) -> 2 - expect(buildAudioFilter(1.5)).toBe("atempo=1.5"); - expect(buildAudioFilter(0.75)).toBe("atempo=0.75"); + expect(buildAudioFilter(0.5, false)).toBe("atempo=0.5"); + expect(buildAudioFilter(2.0, false)).toBe("atempo=2"); // Note: Number(2.0.toFixed(4)) -> 2 + expect(buildAudioFilter(1.5, false)).toBe("atempo=1.5"); + expect(buildAudioFilter(0.75, false)).toBe("atempo=0.75"); }); it("should chain properly for very large speeds", () => { // 10 / 2.0 = 5 // 5 / 2.0 = 2.5 // 2.5 / 2.0 = 1.25 - expect(buildAudioFilter(10)).toBe("atempo=2.0,atempo=2.0,atempo=2.0,atempo=1.25"); + expect(buildAudioFilter(10, false)).toBe("atempo=2.0,atempo=2.0,atempo=2.0,atempo=1.25"); + }); + + it("should append loudnorm filter when normalizeAudio is true", () => { + const result = buildAudioFilter(1, true); + expect(result).toContain("loudnorm"); }); });