Skip to content

feat: GIF quality and compression preset#598

Open
mvanhorn wants to merge 1 commit into
webadderallorg:mainfrom
mvanhorn:fix/336-recordly-gif-compression-preset
Open

feat: GIF quality and compression preset#598
mvanhorn wants to merge 1 commit into
webadderallorg:mainfrom
mvanhorn:fix/336-recordly-gif-compression-preset

Conversation

@mvanhorn
Copy link
Copy Markdown

@mvanhorn mvanhorn commented May 27, 2026

Summary

  • Adds GIF quality / compression preset to the ExportSettingsMenu, picking up where @meiiie's draft (feat(export): add GIF compression preset #357) left off after she stepped back to reduce PR noise.
  • Three presets: low (fast, small file), balanced (default - current behavior), high (slow, larger file).
  • Wires through src/lib/exporter/types.ts for the typed preset, the ExportSettingsMenu UI, and VideoEditor's invocation path.
  • Tests for the type narrowing and component behavior; existing exports continue to use balanced.

cc @meiiie - picking up your 2026-05-09 re-up invitation. Happy to adjust the preset boundaries or naming if you'd prefer different defaults.

Closes #336.

AI was used for assistance.

Summary by CodeRabbit

  • New Features

    • GIF export now includes selectable quality presets: High, Balanced, and Small file. Users can optimize exports based on their desired quality or file size requirements.
  • Tests

    • Added test coverage for quality preset selection and GIF export configuration.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 27, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d1b06bfa-c098-4664-85c2-9e74b7314dae

📥 Commits

Reviewing files that changed from the base of the PR and between 24e6779 and 23fae67.

📒 Files selected for processing (13)
  • src/components/video-editor/ExportSettingsMenu.test.tsx
  • src/components/video-editor/ExportSettingsMenu.tsx
  • src/components/video-editor/VideoEditor.tsx
  • src/components/video-editor/editorPreferences.test.ts
  • src/components/video-editor/editorPreferences.ts
  • src/components/video-editor/exportStartSettings.test.ts
  • src/components/video-editor/exportStartSettings.ts
  • src/components/video-editor/projectPersistence.ts
  • src/lib/exporter/gifExporter.test.ts
  • src/lib/exporter/gifExporter.ts
  • src/lib/exporter/index.ts
  • src/lib/exporter/types.test.ts
  • src/lib/exporter/types.ts

📝 Walkthrough

Walkthrough

This PR adds a three-tier GIF quality preset system (high, balanced, small) enabling users to reduce exported GIF file size at export time. The change integrates quality preset selection across type definitions, encoder configuration, editor state persistence, export resolution, component state management, and UI controls.

Changes

GIF Quality Preset Feature

Layer / File(s) Summary
Quality preset type system and constants
src/lib/exporter/types.ts, src/lib/exporter/index.ts, src/lib/exporter/types.test.ts
Defines GifQualityPreset union type ("high" | "balanced" | "small"), GIF_QUALITY_PRESETS mapping with quality values and display labels, VALID_GIF_QUALITY_PRESETS constant, and isValidGifQualityPreset type-guard validator. Tests confirm valid preset acceptance, unknown input rejection, and quality-number mappings.
GIF encoder quality integration
src/lib/exporter/gifExporter.ts, src/lib/exporter/gifExporter.test.ts
Adds qualityPreset field to GifExporterConfig. Implements getGifQuality helper that validates and maps presets to numeric quality values, defaulting to "balanced". Wires getGifQuality(this.config.qualityPreset) into gif.js encoder initialization. Tests verify preset-to-quality mapping and validate blob size differences across presets.
Editor state and preferences persistence
src/components/video-editor/projectPersistence.ts, src/components/video-editor/editorPreferences.ts, src/components/video-editor/editorPreferences.test.ts
Adds gifQualityPreset: GifQualityPreset to ProjectEditorState with isValidGifQualityPreset normalization (defaulting to "balanced"). Updates PersistedEditorControls and DEFAULT_EDITOR_PREFERENCES to include and propagate preset. Normalizes preset through editor snapshots and preference loads/saves. Tests verify default clamping on invalid input and round-trip persistence.
Export settings resolution
src/components/video-editor/exportStartSettings.ts, src/components/video-editor/exportStartSettings.test.ts
Extends resolveExportStartSettings function to accept gifQualityPreset parameter and populate gifConfig.qualityPreset when exportFormat is "gif". Tests verify preset flows from editor options into resolved export configuration for both normal and original-size GIF exports.
VideoEditor component state and export pipeline
src/components/video-editor/VideoEditor.tsx
Introduces gifQualityPreset React state initialized from initialEditorPreferences. Wires preset through editor snapshot capture/apply, persisted state serialization, preference loading/saving, loaded-project re-application, export dropdown start-settings resolution, and GifExporter config. Includes all memoization dependencies and state synchronization callbacks.
ExportSettingsMenu GIF quality toggle
src/components/video-editor/ExportSettingsMenu.tsx, src/components/video-editor/ExportSettingsMenu.test.tsx
Adds gifQualityPreset and onGifQualityPresetChange props to component. Renders localized GIF quality toggle with buttons for each preset from GIF_QUALITY_PRESETS, highlights active selection, and triggers callback on change. Test verifies server-render output includes quality option labels.

Sequence Diagram

sequenceDiagram
  participant UI as ExportSettingsMenu
  participant Editor as VideoEditor State
  participant Settings as resolveExportStartSettings
  participant Encoder as GifExporter
  participant Quality as getGifQuality

  UI->>UI: User selects quality preset
  UI->>Editor: onGifQualityPresetChange(preset)
  Editor->>Editor: Update gifQualityPreset state
  Editor->>Editor: Persist to localStorage
  
  Note over Editor: Export initiated
  
  Editor->>Settings: resolveExportStartSettings({..., gifQualityPreset})
  Settings->>Settings: Build gifConfig with qualityPreset
  Settings-->>Editor: ExportSettings with gifConfig.qualityPreset
  
  Editor->>Encoder: Create GifExporter({ qualityPreset })
  Encoder->>Quality: getGifQuality(qualityPreset)
  Quality->>Quality: Validate against GIF_QUALITY_PRESETS
  Quality-->>Encoder: Numeric quality value
  Encoder->>Encoder: Initialize gif.js with quality
  Encoder-->>Editor: GIF encoding with applied quality
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • webadderallorg/Recordly#567: Both PRs modify resolveExportStartSettings — the prior refactor introduces the resolver; this PR extends it to accept gifQualityPreset and populate gifConfig.qualityPreset.

Suggested labels

enhancement, export, gif

Poem

🐰 Three tiers of GIF delight,
High quality shines so bright,
Balanced strikes the perfect way,
Small files save the disk today—
Presets make exports lean and light!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding GIF quality and compression preset functionality to the export system.
Description check ✅ Passed The description covers the purpose, motivation, and implementation details; however, it lacks the suggested template structure including explicit Type of Change, Testing Guide, and Checklist sections.
Linked Issues check ✅ Passed The PR implements the core requirement from #336: providing in-app controls to trade visual quality for smaller GIF file size. Three presets (low/balanced/high) enable users to reduce file size without external tools.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing GIF quality presets. The PR introduces the type definitions, UI controls, exporter integration, and tests—all within the bounds of #336 requirements.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Option to reduce exported GIF file size

1 participant