Skip to content

feat: add export resolution selector (Closes #17)#31

Merged
socialawy merged 1 commit into
mainfrom
feat/export-resolution-selector-14768703165762109044
Apr 4, 2026
Merged

feat: add export resolution selector (Closes #17)#31
socialawy merged 1 commit into
mainfrom
feat/export-resolution-selector-14768703165762109044

Conversation

@socialawy-dev
Copy link
Copy Markdown
Owner

Let users choose the export resolution before starting an export, with hardware tier gating.

  • Add resolution dropdown in ExportBar with options: 720p, 1080p, 4K.
  • Resize export offscreen canvas to match the selected resolution.
  • Hardware tier gating: Low tier (720p only), Medium tier (720p + 1080p), High tier (all resolutions). Unavailable options are disabled.
  • Display an estimated file size based on resolution and duration.
  • Default resolution: 1080p on Medium/High tier, 720p on Low tier.

PR created automatically by Jules for task 14768703165762109044 started by @socialawy

Let users choose the export resolution before starting an export, with hardware tier gating.

- Add resolution dropdown in ExportBar with options: 720p, 1080p, 4K.
- Resize export offscreen canvas to match the selected resolution.
- Hardware tier gating: Low tier (720p only), Medium tier (720p + 1080p), High tier (all resolutions). Unavailable options are disabled.
- Display an estimated file size based on resolution and duration.
- Default resolution: 1080p on Medium/High tier, 720p on Low tier.

Co-authored-by: socialawy <24765060+socialawy@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 4, 2026

⚠️ Groq Review: ESCALATE — API error (HTTP 400)

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 4, 2026

🚨 Escalation: This PR needs human review. @socialawy please check.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces configurable export resolutions (720p, 1080p, and 4K) with hardware tier-based gating and bitrate scaling. Key changes include state management for resolution in the settings store, UI updates in the ExportBar for selection and size estimation, and engine updates to support target dimensions. Review feedback highlights the need to handle aspect ratio preservation during resizing to avoid stretching, suggests moving resolution gating logic from a component-level useEffect into the store for cleaner state management, and recommends using shared constants instead of magic numbers for bitrate multipliers.

Comment thread src/engine/exporter.ts
Comment on lines +37 to +46
if (resolution === '720p') {
targetWidth = 1280;
targetHeight = 720;
} else if (resolution === '1080p') {
targetWidth = 1920;
targetHeight = 1080;
} else if (resolution === '4K') {
targetWidth = 3840;
targetHeight = 2160;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

Forcing fixed dimensions (e.g., 1280x720) for export presets will cause stretching or letterboxing issues if the project's native aspect ratio (defined in spec.meta) is not 16:9. Consider calculating the target dimensions based on the requested height while preserving the original aspect ratio. Additionally, these values should be centralized in a constant shared with the UI.

Suggested change
if (resolution === '720p') {
targetWidth = 1280;
targetHeight = 720;
} else if (resolution === '1080p') {
targetWidth = 1920;
targetHeight = 1080;
} else if (resolution === '4K') {
targetWidth = 3840;
targetHeight = 2160;
}
const RESOLUTION_HEIGHTS = {
'720p': 720,
'1080p': 1080,
'4K': 2160,
};
if (resolution && RESOLUTION_HEIGHTS[resolution]) {
const targetH = RESOLUTION_HEIGHTS[resolution];
const scale = targetH / spec.meta.height;
targetWidth = Math.round((spec.meta.width * scale) / 2) * 2; // Ensure even dimensions for encoders
targetHeight = targetH;
}

Comment on lines +31 to +39
useEffect(() => {
if (!exportResolution) {
setExportResolution(tier === 'low' ? '720p' : '1080p');
} else if (tier === 'low' && exportResolution !== '720p') {
setExportResolution('720p');
} else if (tier === 'medium' && exportResolution === '4K') {
setExportResolution('1080p');
}
}, [tier, exportResolution, setExportResolution]);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Managing resolution gating and defaults via useEffect in the component can lead to unnecessary re-renders and potential 'flashes' of invalid state in the UI. It is generally better to handle this logic within the store itself (e.g., using a middleware or by enforcing constraints in the setExportResolution action) or by deriving the 'effective' resolution in a selector.

Comment on lines +45 to +47
let resolutionMultiplier = 1;
if (exportResolution === '1080p') resolutionMultiplier = 2.25; // roughly 1920x1080 / 1280x720
else if (exportResolution === '4K') resolutionMultiplier = 9; // roughly 3840x2160 / 1280x720
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

These hardcoded multipliers are magic numbers that are directly tied to the resolution presets. It would be cleaner to define a shared constant or map that associates resolution names with their dimensions and bitrate multipliers to ensure consistency across the UI and the engine.

Suggested change
let resolutionMultiplier = 1;
if (exportResolution === '1080p') resolutionMultiplier = 2.25; // roughly 1920x1080 / 1280x720
else if (exportResolution === '4K') resolutionMultiplier = 9; // roughly 3840x2160 / 1280x720
const BITRATE_MULTIPLIERS: Record<string, number> = {
'720p': 1,
'1080p': 2.25,
'4K': 9,
};
const resolutionMultiplier = exportResolution ? BITRATE_MULTIPLIERS[exportResolution] : 1;

@socialawy socialawy merged commit e2e04d2 into main Apr 4, 2026
4 checks passed
socialawy added a commit that referenced this pull request Apr 10, 2026
…ctor-14768703165762109044

feat: add export resolution selector (Closes #17)
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.

2 participants