From 12061146ed2a7ff68b5570fbc893503d3c999144 Mon Sep 17 00:00:00 2001 From: rahul-rajak-nsut Date: Wed, 20 May 2026 22:38:45 +0530 Subject: [PATCH 1/2] feat: enable noUncheckedIndexedAccess and fix resulting type errors --- src/components/OnboardingTour.tsx | 8 ++++---- src/components/ThumbnailStrip.tsx | 6 +++--- src/components/TipCarousel.tsx | 3 ++- src/components/VideoEditor.tsx | 2 +- src/components/WaveformCanvas.tsx | 2 +- tsconfig.json | 1 + 6 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/components/OnboardingTour.tsx b/src/components/OnboardingTour.tsx index 4a9fa0e6..d5c163bc 100644 --- a/src/components/OnboardingTour.tsx +++ b/src/components/OnboardingTour.tsx @@ -251,7 +251,7 @@ export default function OnboardingTour() { useEffect(() => { if (localStorage.getItem(TOUR_KEY)) return; const t = setTimeout(async () => { - const rect = await measureTarget(TOUR_STEPS[0].targetId); + const rect = await measureTarget(TOUR_STEPS[0]?.targetId ?? ""); if (rect) { setTargetRect(rect); setVisible(true); @@ -267,7 +267,7 @@ useEffect(() => { isFirstRender.current = false; return; } - measureTarget(TOUR_STEPS[stepIndex].targetId).then((rect) => { + measureTarget(TOUR_STEPS[stepIndex]?.targetId ?? "").then((rect) => { if (rect) { setTargetRect(rect); setTimeout(() => tooltipRef.current?.focus(), 50); @@ -285,7 +285,7 @@ useEffect(() => { useEffect(() => { if (!visible) return; const onResize = () => { - measureTarget(TOUR_STEPS[stepIndex].targetId).then(setTargetRect); + measureTarget(TOUR_STEPS[stepIndex]?.targetId ?? "").then(setTargetRect); }; window.addEventListener("resize", onResize); return () => window.removeEventListener("resize", onResize); @@ -318,7 +318,7 @@ useEffect(() => { /> ((resolve) => { const onSeeked = () => { video.removeEventListener("seeked", onSeeked); @@ -117,7 +117,7 @@ export default function ThumbnailStrip({ const activeIndex = thumbnails.findIndex( (t, i) => currentTime >= t.time && - (i === thumbnails.length - 1 || currentTime < thumbnails[i + 1].time) + (i === thumbnails.length - 1 || currentTime < (thumbnails[i + 1]?.time ?? Infinity)) ); if (!videoSrc) return null; diff --git a/src/components/TipCarousel.tsx b/src/components/TipCarousel.tsx index 0500dd19..c16fde92 100644 --- a/src/components/TipCarousel.tsx +++ b/src/components/TipCarousel.tsx @@ -80,7 +80,8 @@ export default function TipCarousel() { }; const activeTip = TIPS[activeIdx]; - const IconComponent = activeTip.icon; + if (!activeTip) return null; + const IconComponent = activeTip.icon; return (

- We detected a {recommendedPreset.label.replace(/\s/g, "")} video → Recommended: {recommendedPreset.platform.split("·")[0].trim()} ({recommendedPreset.label.replace(/\s/g, "")}) + We detected a {recommendedPreset.label.replace(/\s/g, "")} video → Recommended: {(recommendedPreset.platform.split("·")[0] ?? "").trim()} ({recommendedPreset.label.replace(/\s/g, "")})

)} diff --git a/src/components/WaveformCanvas.tsx b/src/components/WaveformCanvas.tsx index a170a0e7..cff6a6bc 100644 --- a/src/components/WaveformCanvas.tsx +++ b/src/components/WaveformCanvas.tsx @@ -54,7 +54,7 @@ export default function WaveformCanvas({ samples, loading, hasAudio }: Props) { ctx.globalAlpha = 0.7; for (let i = 0; i < samples.length; i++) { - const amplitude = samples[i]; + const amplitude = samples[i] ?? 0; const barHeight = Math.max(amplitude * (height * 0.92), 1.5); const x = i * barWidth; const y = midY - barHeight / 2; diff --git a/tsconfig.json b/tsconfig.json index 5310d2e1..5fe25c1c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,6 +5,7 @@ "allowJs": true, "skipLibCheck": true, "strict": true, + "noUncheckedIndexedAccess": true, "noEmit": true, "esModuleInterop": true, "module": "esnext", From 011a35b8eeec6304ad7ab6199b05a0325a0969c9 Mon Sep 17 00:00:00 2001 From: rahul-rajak-nsut Date: Thu, 21 May 2026 02:24:22 +0530 Subject: [PATCH 2/2] fix: add JS validation for custom preset width/height inputs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Validate width/height in handleWidthChange and handleHeightChange - Reject values outside 16–7680 range and NaN before updating state - Add autoComplete='off' to width and height inputs Fixes #24 --- src/components/PresetSelector.tsx | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/components/PresetSelector.tsx b/src/components/PresetSelector.tsx index 817c8d06..5ec5bd7c 100644 --- a/src/components/PresetSelector.tsx +++ b/src/components/PresetSelector.tsx @@ -56,7 +56,7 @@ const QUICK_ACTIONS = [ platform: "Instagram", icon: ( - + ), }, @@ -66,7 +66,7 @@ const QUICK_ACTIONS = [ platform: "TikTok", icon: ( - + ), }, @@ -76,7 +76,7 @@ const QUICK_ACTIONS = [ platform: "YouTube", icon: ( - + ), }, @@ -86,7 +86,7 @@ const QUICK_ACTIONS = [ platform: "YouTube", icon: ( - + ), }, @@ -96,7 +96,7 @@ const QUICK_ACTIONS = [ platform: "Twitter", icon: ( - + ), }, @@ -122,14 +122,18 @@ export default function PresetSelector({ recipe, onChange }: Props) { const handleWidthChange = useCallback( (width: number) => { - onChange({ customWidth: width }); + if (!isNaN(width) && width >= 16 && width <= 7680) { + onChange({ customWidth: width }); + } }, [onChange], ); const handleHeightChange = useCallback( (height: number) => { - onChange({ customHeight: height }); + if (!isNaN(height) && height >= 16 && height <= 7680) { + onChange({ customHeight: height }); + } }, [onChange], ); @@ -280,6 +284,7 @@ export default function PresetSelector({ recipe, onChange }: Props) {