Skip to content

feat: extend speed options with higher presets and custom speed input#291

Open
1shanpanta wants to merge 1 commit intosiddharthvaddem:mainfrom
1shanpanta:feat/extended-speed-options
Open

feat: extend speed options with higher presets and custom speed input#291
1shanpanta wants to merge 1 commit intosiddharthvaddem:mainfrom
1shanpanta:feat/extended-speed-options

Conversation

@1shanpanta
Copy link
Copy Markdown

@1shanpanta 1shanpanta commented Apr 3, 2026

Description

Extends playback speed options beyond the original 2x cap. Adds 3x, 4x, 5x speed presets and a custom playback speed input field that accepts any integer value up to 16x.

Motivation

Issue #252 requests higher speed options because trimming isn't always applicable -- users need to fast-forward through slow sections of code reviews and demos while still showing what happened. A commenter also requested a custom input field for speeds beyond the presets, similar to how iMovie supports custom speed values.

Type of Change

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

Related Issue(s)

Closes #252

Screenshots / Video

Screenshot (if applicable):
Will add screenshot of the new speed panel UI

Video (if applicable):
N/A

Testing

  • npx tsc --noEmit -- 0 errors
  • npm run lint -- clean
  • npx vite build -- builds successfully
  • npx vitest --run -- 14 pass, 2 pre-existing failures on main (compositeLayout, unrelated)
  • Manual testing: presets work, custom input accepts 1-16, toast shows on >16, delete/retype works smoothly, preset selection clears custom input

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.

Summary by CodeRabbit

  • New Features

    • Custom playback speed input now available in video editor settings
    • Playback speed range expanded to 0.1x–16x (previously 0.25x–2x)
    • New preset speed options: 3x, 4x, 5x
    • Speed validation with error notifications for out-of-range values
  • Localization

    • Translations added for custom speed feature (English, Spanish, Chinese)

add 3x, 4x, 5x speed presets and a custom playback speed input field
that accepts any integer value up to 16x. change PlaybackSpeed type
from a fixed union to number with min/max constants and clamp utility.
update project persistence to validate any speed in range instead of
exact value matching. add i18n keys for en, es, zh-CN.

closes siddharthvaddem#252
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 3, 2026

📝 Walkthrough

Walkthrough

The PR extends the video editor's playback speed feature from fixed preset options (max 2×) to support custom speeds within a range of 0.1× to 16×, including a new custom input component, type generalization, validation logic, and localized UI text.

Changes

Cohort / File(s) Summary
Type System & Constants
src/components/video-editor/types.ts
Generalized PlaybackSpeed type from discrete literal union to number; added MIN_PLAYBACK_SPEED (0.1) and MAX_PLAYBACK_SPEED (16) constants; introduced clampPlaybackSpeed() utility for range enforcement with 2-decimal rounding; extended SPEED_OPTIONS with 3×, 4×, 5× presets.
Settings Panel UI
src/components/video-editor/SettingsPanel.tsx
Added new CustomSpeedInput component with internal draft state, sanitization, and blur-to-revert logic; integrated custom speed row below preset buttons with conditional rendering (active input when speed selected, disabled placeholder otherwise); reduced grid columns from 7 to 5.
Data Normalization
src/components/video-editor/projectPersistence.ts
Replaced allowlist-based speed validation with range-based check using MIN_PLAYBACK_SPEED/MAX_PLAYBACK_SPEED constants; now uses clampPlaybackSpeed() for valid values, falls back to DEFAULT_PLAYBACK_SPEED otherwise.
Localization
src/i18n/locales/{en,es,zh-CN}/settings.json
Added translation keys speed.customPlaybackSpeed and speed.maxSpeedError across English, Spanish, and Simplified Chinese locales.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Poem

🐰 Speed needs wings, so here's the twist,
Custom velocities can't be missed—
From 0.1× to 16× fast,
Those boring code reviews won't last! 🚀

🚥 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 summarizes the main changes: extending speed options with higher presets (3x, 4x, 5x) and adding a custom speed input field, directly addressing the PR's primary objectives.
Description check ✅ Passed The description follows the template structure with all key sections completed: description, motivation, type of change, related issues, testing details, and checklist items checked off appropriately.
Linked Issues check ✅ Passed The PR fully implements the requirements from issue #252 [#252]: adds higher speed presets (3x, 4x, 5x) and implements a custom input field accepting values up to 16x with proper validation.
Out of Scope Changes check ✅ Passed All changes are directly related to the linked issue #252: speed option extension, custom input implementation, type system updates, UI layout adjustments, validation logic, and i18n entries are all in-scope.

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

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

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.

Copy link
Copy Markdown

@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 (1)
src/components/video-editor/SettingsPanel.tsx (1)

58-119: The render-time state synchronization pattern could cause issues.

Lines 71-75 update state (setDraft) during render when the value changes. While this works, it's an anti-pattern that React may warn about and can cause unexpected re-renders.

♻️ Consider using useEffect for synchronization
 function CustomSpeedInput({
 	value,
 	onChange,
 	onError,
 }: {
 	value: number;
 	onChange: (val: number) => void;
 	onError: () => void;
 }) {
 	const isPreset = SPEED_OPTIONS.some((o) => o.speed === value);
 	const [draft, setDraft] = useState(isPreset ? "" : String(Math.round(value)));
 	const [isFocused, setIsFocused] = useState(false);
 
-	const prevValue = useRef(value);
-	if (!isFocused && prevValue.current !== value) {
-		prevValue.current = value;
-		setDraft(isPreset ? "" : String(Math.round(value)));
-	}
+	useEffect(() => {
+		if (!isFocused) {
+			const newIsPreset = SPEED_OPTIONS.some((o) => o.speed === value);
+			setDraft(newIsPreset ? "" : String(Math.round(value)));
+		}
+	}, [value, isFocused]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/video-editor/SettingsPanel.tsx` around lines 58 - 119, The
component CustomSpeedInput currently updates state during render via
prevValue/ref logic (prevValue, setDraft, isFocused, isPreset), which is an
anti-pattern; move that synchronization into a useEffect that watches [value,
isFocused, isPreset] (and optionally SPEED_OPTIONS-derived isPreset) and inside
the effect update prevValue.current and call setDraft(isPreset ? "" :
String(Math.round(value))) only when not focused and prevValue.current !==
value, removing the inline render-time setDraft branch so all state updates
occur inside the effect.
🤖 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/SettingsPanel.tsx`:
- Around line 58-119: The component CustomSpeedInput currently updates state
during render via prevValue/ref logic (prevValue, setDraft, isFocused,
isPreset), which is an anti-pattern; move that synchronization into a useEffect
that watches [value, isFocused, isPreset] (and optionally SPEED_OPTIONS-derived
isPreset) and inside the effect update prevValue.current and call
setDraft(isPreset ? "" : String(Math.round(value))) only when not focused and
prevValue.current !== value, removing the inline render-time setDraft branch so
all state updates occur inside the effect.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6b506ae2-bcfb-44f2-a4d5-e7c04c4ca6d9

📥 Commits

Reviewing files that changed from the base of the PR and between 2f36160 and 3895ca9.

📒 Files selected for processing (6)
  • src/components/video-editor/SettingsPanel.tsx
  • src/components/video-editor/projectPersistence.ts
  • src/components/video-editor/types.ts
  • src/i18n/locales/en/settings.json
  • src/i18n/locales/es/settings.json
  • src/i18n/locales/zh-CN/settings.json

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.

[Feature]: Increase speed tool to above 2x

1 participant