Skip to content

fix 231#234

Merged
siddharthvaddem merged 1 commit intomainfrom
codex/issue-231
Mar 18, 2026
Merged

fix 231#234
siddharthvaddem merged 1 commit intomainfrom
codex/issue-231

Conversation

@siddharthvaddem
Copy link
Owner

@siddharthvaddem siddharthvaddem commented Mar 18, 2026

Pull Request Template

Description

Motivation

Type of Change

  • New Feature
  • Bug Fix
  • Refactor / Code Cleanup
  • Documentation Update
  • Other (please specify)

Related Issue(s)

#231

Screenshots / Video

Screenshot (if applicable):

![Screenshot Description](path/to/screenshot.png)

Video (if applicable):

<video src="path/to/video.mp4" controls width="600"></video>

Testing

Checklist

  • I have performed a self-review of my code.
  • I have added any necessary screenshots or videos.
  • I have linked related issue(s) and updated the changelog if applicable.

Thank you for contributing!

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Export operations now require confirmation that the file was successfully created before marking exports as complete, improving reliability.
  • Improvements

    • Enhanced aspect ratio preservation during GIF and video exports for more accurate dimension calculations.
    • Optimized dimension handling to ensure compatibility with encoding requirements.

@coderabbitai
Copy link

coderabbitai bot commented Mar 18, 2026

📝 Walkthrough

Walkthrough

The changes integrate aspect ratio support throughout the video export pipeline, strengthening export success validation to require a file path and refactoring dimension calculations to preserve aspect ratios across GIF and MP4 exports with even dimension constraints.

Changes

Cohort / File(s) Summary
Export Success & Aspect Ratio Integration
src/components/video-editor/VideoEditor.tsx
Enhanced export success handling to require saveResult.path existence; computed aspect ratio value from crop region and source dimensions; added aspect ratio and crop region to dependency lists for handleExport and handleOpenExportDialog to ensure reactivity to aspect ratio changes.
Dimension Calculation Logic
src/lib/exporter/gifExporter.ts
Added targetAspectRatio optional parameter to calculateOutputDimensions; introduced toEven() helper for even dimension encoding; implemented aspect-ratio-aware scaling with special handling for "original" preset; replaced legacy boundary checks with maxHeight-driven calculations that preserve aspect ratio.
Export Dimension Tests
src/lib/exporter/gifExporter.test.ts
Added two unit tests for calculateOutputDimensions verifying correct scaling with 16/9 aspect ratio (medium preset: 1280×720) and original preset fitting within source bounds (1080×606).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • fix: avoid false early decode failures #233: Modifies export success handling in VideoEditor.tsx to require truthy saveResult.path before treating exports as saved, directly aligning with the same validation strengthening in this PR.

Poem

🐰 Hop, hop! The exports now respect the ratio fine,
Even dimensions hop in perfect line,
Aspect ratios dance through the code so bright,
Saving files with paths—feels so right!
Dimensions twice-blessed by toEven spell,
Your videos export, and all is well! 🎬✨

🚥 Pre-merge checks | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request description consists entirely of the template structure with all content sections left empty or marked as comments; no actual details about the changes, motivation, or testing are provided. Fill in all required sections: provide a clear description of changes, explain the motivation for fixing issue #231, mark the type of change, add testing instructions, and complete the checklist items.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'fix 231' is vague and generic, referring only to an issue number without describing what was actually fixed or the main change. Replace the title with a clear, descriptive summary of the main change, e.g., 'Fix aspect ratio handling in video export dimensions' or similar that reflects the actual implementation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/issue-231
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (4)
src/lib/exporter/gifExporter.ts (2)

70-73: Consider inlining the intermediate variable in toEven.

The helper works correctly but the intermediate evenValue variable is unnecessary.

♻️ Minor simplification
 	const toEven = (value: number) => {
-		const evenValue = Math.max(2, Math.floor(value / 2) * 2);
-		return evenValue;
+		return Math.max(2, Math.floor(value / 2) * 2);
 	};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/exporter/gifExporter.ts` around lines 70 - 73, The helper function
toEven can be simplified by removing the unnecessary intermediate variable;
replace the body of toEven to directly return Math.max(2, Math.floor(value / 2)
* 2) instead of assigning it to evenValue first so the function becomes a
single-return expression while preserving existing behavior.

88-94: Non-original presets don't clamp to source dimensions.

For presets like "medium" (maxHeight=720) or "large" (maxHeight=1080), the code always scales to maxHeight even if the source is smaller (e.g., a 480p video would be upscaled to 720p). This may be intentional for consistent output sizes, but could result in quality loss from upscaling small sources.

Consider clamping to source dimensions when source is smaller than the preset:

💡 Optional: Avoid upscaling small sources
+	const effectiveMaxHeight = Math.min(maxHeight, sourceHeight);
-	const targetHeight = maxHeight;
+	const targetHeight = effectiveMaxHeight;
 	const targetWidth = Math.round(targetHeight * aspectRatio);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/exporter/gifExporter.ts` around lines 88 - 94, The current sizing
always uses maxHeight and can upscale small sources; change the target height
computation to clamp to the source height (e.g., targetHeight =
Math.min(maxHeight, sourceHeight or inputHeight)) before computing targetWidth
from aspectRatio, then keep using Math.round and toEven for targetWidth/height;
update any references to aspectRatio, maxHeight, targetHeight, targetWidth and
toEven in gifExporter.ts so presets won't upscale sources.
src/components/video-editor/VideoEditor.tsx (1)

1493-1499: Duplicated aspect ratio computation logic.

The aspectRatio === "native" conditional with getNativeAspectRatioValue / getAspectRatioValue is repeated in multiple places (Lines 990-993, 1235-1238, 1339-1345, 1493-1499). Consider extracting this into a shared helper or memoized value to reduce duplication and risk of divergence.

♻️ Extract aspect ratio computation

Add a memoized helper near the top of the component:

const currentAspectRatioValue = useMemo(() => {
	const video = videoPlaybackRef.current?.video;
	const sourceWidth = video?.videoWidth || 1920;
	const sourceHeight = video?.videoHeight || 1080;
	return aspectRatio === "native"
		? getNativeAspectRatioValue(sourceWidth, sourceHeight, cropRegion)
		: getAspectRatioValue(aspectRatio);
}, [aspectRatio, cropRegion, /* video dimensions need special handling */]);

Then use currentAspectRatioValue in all locations.

Note: Since videoPlaybackRef.current?.video dimensions may change after load, you may need to track them in state or use a different approach.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/video-editor/VideoEditor.tsx` around lines 1493 - 1499,
Extract the duplicated aspect-ratio logic into a memoized helper (e.g., const
currentAspectRatioValue = useMemo(...)) computed from aspectRatio, cropRegion
and the video dimensions from videoPlaybackRef.current?.video (use
video?.videoWidth || 1920 and video?.videoHeight || 1080 inside the memo);
replace all inline conditionals that call getNativeAspectRatioValue(...) /
getAspectRatioValue(...) with currentAspectRatioValue in usages across the
component (locations where aspectRatio === "native" is repeated, e.g., around
VideoEditor render logic and any functions using those values); ensure the
memo's dependencies include aspectRatio and cropRegion and add handling to
update video dimensions (store dimensions in state or include a derived ref
value) so the memo updates after the video loads.
src/lib/exporter/gifExporter.test.ts (1)

1-19: Tests look correct but coverage is limited.

The two tests verify key scenarios:

  1. Scaled export with explicit aspect ratio (16:9 "medium" → 1280×720) ✓
  2. Original preset fitting within source bounds (1080×1920 with 16:9 → 1080×606) ✓

Consider adding tests for edge cases:

  • Invalid/zero aspect ratio (fallback behavior)
  • Portrait aspect ratios (e.g., 9:16)
  • "large" preset
  • Source dimensions smaller than preset maxHeight
💡 Additional test cases to consider
it("falls back to source aspect ratio when targetAspectRatio is invalid", () => {
	expect(calculateOutputDimensions(1920, 1080, "medium", GIF_SIZE_PRESETS, 0)).toEqual({
		width: 1280,
		height: 720,
	});
});

it("handles portrait aspect ratios", () => {
	expect(calculateOutputDimensions(1920, 1080, "medium", GIF_SIZE_PRESETS, 9 / 16)).toEqual({
		width: 404, // 720 * (9/16) ≈ 405 → toEven → 404
		height: 720,
	});
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/exporter/gifExporter.test.ts` around lines 1 - 19, Add additional
unit tests for calculateOutputDimensions to cover edge cases: (1) invalid/zero
targetAspectRatio — verify it falls back to source aspect ratio (use
GIF_SIZE_PRESETS and the "medium" preset in a test like "falls back to source
aspect ratio when targetAspectRatio is invalid"), (2) portrait aspect ratios —
test with 9/16 to ensure width/height are computed and evened correctly (e.g.,
"handles portrait aspect ratios"), (3) the "large" preset — ensure scaled
dimensions match expected large preset behavior, and (4) source dimensions
smaller than a preset's maxHeight — ensure output is clamped to source bounds.
Reference calculateOutputDimensions and GIF_SIZE_PRESETS when writing each new
it() case.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/components/video-editor/VideoEditor.tsx`:
- Around line 1493-1499: Extract the duplicated aspect-ratio logic into a
memoized helper (e.g., const currentAspectRatioValue = useMemo(...)) computed
from aspectRatio, cropRegion and the video dimensions from
videoPlaybackRef.current?.video (use video?.videoWidth || 1920 and
video?.videoHeight || 1080 inside the memo); replace all inline conditionals
that call getNativeAspectRatioValue(...) / getAspectRatioValue(...) with
currentAspectRatioValue in usages across the component (locations where
aspectRatio === "native" is repeated, e.g., around VideoEditor render logic and
any functions using those values); ensure the memo's dependencies include
aspectRatio and cropRegion and add handling to update video dimensions (store
dimensions in state or include a derived ref value) so the memo updates after
the video loads.

In `@src/lib/exporter/gifExporter.test.ts`:
- Around line 1-19: Add additional unit tests for calculateOutputDimensions to
cover edge cases: (1) invalid/zero targetAspectRatio — verify it falls back to
source aspect ratio (use GIF_SIZE_PRESETS and the "medium" preset in a test like
"falls back to source aspect ratio when targetAspectRatio is invalid"), (2)
portrait aspect ratios — test with 9/16 to ensure width/height are computed and
evened correctly (e.g., "handles portrait aspect ratios"), (3) the "large"
preset — ensure scaled dimensions match expected large preset behavior, and (4)
source dimensions smaller than a preset's maxHeight — ensure output is clamped
to source bounds. Reference calculateOutputDimensions and GIF_SIZE_PRESETS when
writing each new it() case.

In `@src/lib/exporter/gifExporter.ts`:
- Around line 70-73: The helper function toEven can be simplified by removing
the unnecessary intermediate variable; replace the body of toEven to directly
return Math.max(2, Math.floor(value / 2) * 2) instead of assigning it to
evenValue first so the function becomes a single-return expression while
preserving existing behavior.
- Around line 88-94: The current sizing always uses maxHeight and can upscale
small sources; change the target height computation to clamp to the source
height (e.g., targetHeight = Math.min(maxHeight, sourceHeight or inputHeight))
before computing targetWidth from aspectRatio, then keep using Math.round and
toEven for targetWidth/height; update any references to aspectRatio, maxHeight,
targetHeight, targetWidth and toEven in gifExporter.ts so presets won't upscale
sources.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 029e9566-0b61-4dcb-999c-fc4b2b268bb1

📥 Commits

Reviewing files that changed from the base of the PR and between d968689 and 69f1b4d.

📒 Files selected for processing (3)
  • src/components/video-editor/VideoEditor.tsx
  • src/lib/exporter/gifExporter.test.ts
  • src/lib/exporter/gifExporter.ts

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 69f1b4d20f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@siddharthvaddem siddharthvaddem merged commit 4563641 into main Mar 18, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant