Skip to content

feat: implement undo/redo functionality in video editor#174

Open
FabLrc wants to merge 4 commits intosiddharthvaddem:mainfrom
FabLrc:feature/undo-redo
Open

feat: implement undo/redo functionality in video editor#174
FabLrc wants to merge 4 commits intosiddharthvaddem:mainfrom
FabLrc:feature/undo-redo

Conversation

@FabLrc
Copy link
Contributor

@FabLrc FabLrc commented Feb 27, 2026

Pull Request : implement undo/redo functionality in video editor

Description

Adds a full undo/redo system to the video editor, backed by a custom useEditorHistory hook using a snapshot history pattern. Includes keyboard shortcuts and a slider commit support.

Motivation

The editor had no way to revert accidental changes (deleted zoom region, wrong crop, slider overshoot, etc.). Users needed standard undo/redo behaviour without introducing a heavy state management library.

Type of Change

  • New Feature
  • Bug Fix
  • Refactor / Code Cleanup

Related Issue(s)

#170

Screenshot

image

Changes

New: src/hooks/useEditorHistory.ts

  • Custom hook encapsulating a past/present/future snapshot stack (max 80 entries)
  • Three operations:
    • pushState — discrete undo point (region add/delete, aspect ratio change, etc.)
    • updateState — live preview during drag/slider interaction; auto-saves a checkpoint on first call via a dirtyRef
    • commitState — resets the dirty flag when the interaction ends (pointer-up, slider commit)
  • Pure helper functions resolve() and withCheckpoint() keep the hook stateless and testable

Modified: VideoEditor.tsx

  • Replaced ~15 individual useState hooks for undoable fields with a single useEditorHistory call
  • All region mutations (pushState), slider interactions (updateState / commitState), and zoom focus drags wired accordingly
  • Global keyboard handler (capture phase) handles Ctrl+Z (undo), Ctrl+Shift+Z and Ctrl+Y (redo); uses e.key.toLowerCase() to handle the uppercase 'Z' returned by browsers when Shift is held

Modified: VideoPlayback.tsx

  • Added onZoomFocusDragEnd?: () => void prop, called on pointer-up/leave, so dragging the zoom focus point creates a single undo entry instead of one per frame

Modified: timeline/TimelineEditor.tsx

  • Single-letter shortcuts (Z, T, A, F) guarded with !e.ctrlKey && !e.metaKey && !e.altKey to prevent conflict with Ctrl+Z

Modified: SettingsPanel.tsx

  • Added onShadowCommit, onBorderRadiusCommit, onPaddingCommit props wired to Radix Slider's onValueCommit, completing the updateState/commitState pattern for all sliders

Modified: KeyboardShortcutsHelp.tsx

  • Added Undo (Ctrl+Z) and Redo (Ctrl+Shift+Z / Ctrl+Y) rows to the shortcuts tooltip

Testing

Tested on Windows

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.

import { DEFAULT_CROP_REGION } from "@/components/video-editor/types";
import type { AspectRatio } from "@/utils/aspectRatioUtils";

// Undoable state — selection IDs are intentionally excluded (undoing a

Choose a reason for hiding this comment

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

this comment seems incomplete

Copy link

@shivaylamba shivaylamba left a comment

Choose a reason for hiding this comment

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

looks good

@FabLrc FabLrc force-pushed the feature/undo-redo branch from ebfa687 to 0e85679 Compare March 1, 2026 11:48
FabLrc added 3 commits March 2, 2026 15:45
# Conflicts:
#	src/components/video-editor/KeyboardShortcutsHelp.tsx
#	src/components/video-editor/VideoEditor.tsx
#	src/components/video-editor/timeline/TimelineEditor.tsx
# Conflicts:
#	src/components/video-editor/VideoEditor.tsx
@siddharthvaddem
Copy link
Owner

LGTM, can you make sure to rebase this on top of main? I added linter checks, so the PR will fail these checks until you fix them. I would like this in for the next release.

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.

3 participants