Skip to content

feat(editor): add Full Camera timeline effect#66

Merged
EtienneLescot merged 3 commits into
getopenscreen:mainfrom
rodrvc:feature/camera-animation
Jul 15, 2026
Merged

feat(editor): add Full Camera timeline effect#66
EtienneLescot merged 3 commits into
getopenscreen:mainfrom
rodrvc:feature/camera-animation

Conversation

@rodrvc

@rodrvc rodrvc commented Jul 3, 2026

Copy link
Copy Markdown

Summary

Adds a Full Camera timeline effect: a new timeline row where you can add segments (button or C shortcut) during which the webcam overlay smoothly grows to cover the canvas — a "cut to camera" moment — and then eases back to its normal position.

Design decisions, all following the existing ZoomRegion pattern 1:1 (no new abstractions):

  • Simple segments, not keyframes: CameraFullscreenRegion { id, startMs, endMs }, edited on the timeline exactly like zoom segments (drag to move, drag edges to resize, same overlap guards).
  • Transition fully contained in the segment: progress is exactly 0 at startMs and endMs; ease-out is intentionally slower (1.5x) than ease-in for a gentler return.
  • No distortion: the webcam keeps its aspect ratio the whole way (contain-fit, centered), with a small 2.5% margin so rounded corners stay visible instead of hitting the canvas edges.
  • Preview/export parity: interpolation and target-rect math are shared pure functions (cameraFullscreenUtils.ts, computeCameraFullscreenTargetRect) consumed by both the DOM preview and the frame renderer used for MP4/GIF export.
  • Plays nice with reactive zoom: while a Full Camera segment is active, the reactive webcam shrink is suppressed for that frame; zoom behavior itself is untouched.
  • Persistence with normalization (older projects load cleanly), undo/redo support, configurable shortcut (C), and i18n keys for all 13 locales.

Related issue

None — happy to open one first if you prefer tracking features via issues.

Type of change

  • Feature

Release impact

  • Minor

Desktop impact

  • Not platform-specific

Screenshots / video

The webcam grows from its PiP position to an aspect-ratio-preserving, near-fullscreen rect with a small margin, then eases back. (Can attach a short clip on request.)

Testing

  • npx tsc --noEmit, npm run lint, npm run i18n:check clean (i18n failures pre-existing at HEAD are untouched).
  • npm run test: 258 tests passing, including new unit tests for the easing envelope (containment, monotonicity, short-segment clamping, overlapping regions) and the target-rect math (aspect preservation, margin, portrait/landscape).
  • Manually tested on macOS (dev build): adding/moving/resizing/deleting segments, undo/redo, playback across segments, interaction with zoom + reactive shrink, project save/reload, and older projects without the new field.

Summary by CodeRabbit

  • New Features

    • Added a “camera fullscreen” timeline segment with a dedicated row, maximize-style control, and selection/creation via keyboard shortcut.
    • Updated preview/webcam PiP to smoothly transition into fullscreen during active segments.
    • Included camera fullscreen edits in GIF and MP4 export.
  • Bug Fixes

    • Persisted normalized camera fullscreen regions across load/save and undo/redo, with safer span clamping and overlap handling.
    • Improved selection consistency when switching, deleting, or when segments no longer exist.
  • Documentation

    • Updated timeline/shortcut labels and error messages across supported languages.
  • Tests

    • Added coverage for fullscreen progress computation and geometry targeting helpers.

@rodrvc rodrvc requested a review from EtienneLescot as a code owner July 3, 2026 21:11
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 49fd67cf-46c3-4e33-aab2-5674c533758a

📥 Commits

Reviewing files that changed from the base of the PR and between 28a2a8e and 3a41c02.

📒 Files selected for processing (3)
  • src/components/video-editor/timeline/TimelineEditor.tsx
  • src/i18n/locales/fr/shortcuts.json
  • src/lib/compositeLayout.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/i18n/locales/fr/shortcuts.json
  • src/lib/compositeLayout.test.ts
  • src/components/video-editor/timeline/TimelineEditor.tsx

📝 Walkthrough

Walkthrough

This PR adds camera fullscreen timeline regions across editor state, timeline controls, preview playback, GIF/MP4 rendering, keyboard shortcuts, and localized strings.

Changes

Camera Fullscreen Feature

Layer / File(s) Summary
Types, geometry, and progress utilities
src/components/video-editor/types.ts, src/lib/compositeLayout.ts, src/lib/compositeLayout.test.ts, src/components/video-editor/videoPlayback/cameraFullscreenUtils.ts, src/components/video-editor/videoPlayback/cameraFullscreenUtils.test.ts
Defines camera fullscreen regions, target geometry, interpolation, eased progress, and coverage tests.
Persistence and editor history
src/components/video-editor/projectPersistence.ts, src/hooks/useEditorHistory.ts
Normalizes and stores camera fullscreen regions in project and undoable editor state.
Timeline controls and styling
src/components/video-editor/timeline/Item.tsx, src/components/video-editor/timeline/ItemGlass.module.css, src/components/video-editor/timeline/TimelineEditor.tsx
Adds a dedicated timeline row, blue styling, placement validation, selection, keyboard creation, deletion, and span editing.
Editor wiring
src/components/video-editor/VideoEditor.tsx
Threads regions through loading, saving, duration inference, selection, handlers, preview, timeline, and export configuration.
Preview playback
src/components/video-editor/VideoPlayback.tsx
Interpolates the webcam from its PiP rectangle toward a fullscreen target based on region progress.
Export rendering
src/lib/exporter/frameRenderer.ts, src/lib/exporter/gifExporter.ts, src/lib/exporter/videoExporter.ts
Applies camera fullscreen compositing to GIF/MP4 frames and disables source-copy rendering when regions are active.
Shortcut registration
src/lib/shortcuts.ts
Adds the addCameraFullscreen action with a default C binding and label.
Localized strings
src/i18n/locales/*/shortcuts.json, src/i18n/locales/*/timeline.json
Adds localized shortcut labels, timeline controls, hints, labels, and placement errors.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant VideoEditor
  participant TimelineEditor
  participant VideoPlayback
  participant ProgressUtility
  participant GeometryUtility
  VideoEditor->>TimelineEditor: cameraFullscreenRegions and editing handlers
  TimelineEditor-->>VideoEditor: add, update, select, or delete region
  VideoEditor->>VideoPlayback: cameraFullscreenRegions
  VideoPlayback->>ProgressUtility: timeMs and regions
  ProgressUtility-->>VideoPlayback: fullscreen progress
  VideoPlayback->>GeometryUtility: canvas size and webcam aspect
  GeometryUtility-->>VideoPlayback: fullscreen target rectangle
  VideoPlayback->>VideoPlayback: interpolate PiP rectangle to target
Loading
sequenceDiagram
  participant VideoEditor
  participant VideoExporter
  participant GifExporter
  participant FrameRenderer
  participant ProgressUtility
  participant GeometryUtility
  VideoEditor->>VideoExporter: cameraFullscreenRegions
  VideoEditor->>GifExporter: cameraFullscreenRegions
  VideoExporter->>FrameRenderer: cameraFullscreenRegions
  GifExporter->>FrameRenderer: cameraFullscreenRegions
  FrameRenderer->>ProgressUtility: frame time and regions
  ProgressUtility-->>FrameRenderer: fullscreen progress
  FrameRenderer->>GeometryUtility: canvas size and webcam rectangle
  GeometryUtility-->>FrameRenderer: fullscreen target rectangle
  FrameRenderer->>FrameRenderer: interpolate webcam compositing
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.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 clearly summarizes the main change by naming the new Full Camera timeline effect in the editor.
Description check ✅ Passed The description covers the required template sections and includes summary, type, impact, screenshots, and testing details.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ 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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/video-editor/VideoEditor.tsx (1)

862-884: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

doNewProject misses the camera-fullscreen resets.

This block resets every other selection and ID counter but omits the two new camera-fullscreen refs/setters added by this PR. selectedCameraFullscreenId does self-heal via the effect at Lines 1807-1814 after resetState(), and nextCameraFullscreenIdRef staying above 1 only affects ID numbering (IDs remain unique), but this is inconsistent with the sibling counters/selections reset here.

Proposed fix
 		setSelectedZoomId(null);
+		setSelectedCameraFullscreenId(null);
 		setSelectedTrimId(null);
 		setSelectedSpeedId(null);
 		setSelectedAnnotationId(null);
 		setSelectedBlurId(null);
 		nextZoomIdRef.current = 1;
+		nextCameraFullscreenIdRef.current = 1;
 		nextTrimIdRef.current = 1;
 		nextSpeedIdRef.current = 1;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/video-editor/VideoEditor.tsx` around lines 862 - 884, The
doNewProject reset block in VideoEditor.tsx is missing the new camera-fullscreen
state cleanup. Update the same reset sequence that clears selection state and
reinitializes counters to also clear selectedCameraFullscreenId and reset
nextCameraFullscreenIdRef to its initial value, matching the pattern used for
the other selected IDs and next*Id refs in doNewProject.
🧹 Nitpick comments (1)
src/i18n/locales/tr/timeline.json (1)

8-8: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Inconsistent capitalization in addBlur string.

"addBlur": "Bulanık ekle (B)" uses lowercase "ekle" while every other sibling button capitalizes it, e.g. "addZoom": "Yakınlaştırma Ekle (Z)", "addCameraFullscreen": "Tam Ekran Kamera Ekle (C)". Worth aligning for consistency.

✏️ Suggested fix
-		"addBlur": "Bulanık ekle (B)",
+		"addBlur": "Bulanık Ekle (B)",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/i18n/locales/tr/timeline.json` at line 8, The addBlur localization string
in the timeline translations uses inconsistent capitalization compared with
sibling actions; update the value in the addBlur entry to match the title-style
capitalization used by addZoom and addCameraFullscreen. Keep the existing
meaning and hotkey, but make the action phrase consistent with the other button
labels in this locale file.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/components/video-editor/VideoEditor.tsx`:
- Around line 862-884: The doNewProject reset block in VideoEditor.tsx is
missing the new camera-fullscreen state cleanup. Update the same reset sequence
that clears selection state and reinitializes counters to also clear
selectedCameraFullscreenId and reset nextCameraFullscreenIdRef to its initial
value, matching the pattern used for the other selected IDs and next*Id refs in
doNewProject.

---

Nitpick comments:
In `@src/i18n/locales/tr/timeline.json`:
- Line 8: The addBlur localization string in the timeline translations uses
inconsistent capitalization compared with sibling actions; update the value in
the addBlur entry to match the title-style capitalization used by addZoom and
addCameraFullscreen. Keep the existing meaning and hotkey, but make the action
phrase consistent with the other button labels in this locale file.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 64d5b82b-4b63-4bdf-8a26-810303d67efd

📥 Commits

Reviewing files that changed from the base of the PR and between 2fc116b and 165668a.

📒 Files selected for processing (42)
  • src/components/video-editor/VideoEditor.tsx
  • src/components/video-editor/VideoPlayback.tsx
  • src/components/video-editor/projectPersistence.ts
  • src/components/video-editor/timeline/Item.tsx
  • src/components/video-editor/timeline/ItemGlass.module.css
  • src/components/video-editor/timeline/TimelineEditor.tsx
  • src/components/video-editor/types.ts
  • src/components/video-editor/videoPlayback/cameraFullscreenUtils.test.ts
  • src/components/video-editor/videoPlayback/cameraFullscreenUtils.ts
  • src/hooks/useEditorHistory.ts
  • src/i18n/locales/ar/shortcuts.json
  • src/i18n/locales/ar/timeline.json
  • src/i18n/locales/en/shortcuts.json
  • src/i18n/locales/en/timeline.json
  • src/i18n/locales/es/shortcuts.json
  • src/i18n/locales/es/timeline.json
  • src/i18n/locales/fr/shortcuts.json
  • src/i18n/locales/fr/timeline.json
  • src/i18n/locales/it/shortcuts.json
  • src/i18n/locales/it/timeline.json
  • src/i18n/locales/ja-JP/shortcuts.json
  • src/i18n/locales/ja-JP/timeline.json
  • src/i18n/locales/ko-KR/shortcuts.json
  • src/i18n/locales/ko-KR/timeline.json
  • src/i18n/locales/pt-BR/shortcuts.json
  • src/i18n/locales/pt-BR/timeline.json
  • src/i18n/locales/ru/shortcuts.json
  • src/i18n/locales/ru/timeline.json
  • src/i18n/locales/tr/shortcuts.json
  • src/i18n/locales/tr/timeline.json
  • src/i18n/locales/vi/shortcuts.json
  • src/i18n/locales/vi/timeline.json
  • src/i18n/locales/zh-CN/shortcuts.json
  • src/i18n/locales/zh-CN/timeline.json
  • src/i18n/locales/zh-TW/shortcuts.json
  • src/i18n/locales/zh-TW/timeline.json
  • src/lib/compositeLayout.test.ts
  • src/lib/compositeLayout.ts
  • src/lib/exporter/frameRenderer.ts
  • src/lib/exporter/gifExporter.ts
  • src/lib/exporter/videoExporter.ts
  • src/lib/shortcuts.ts

@rodrvc

rodrvc commented Jul 3, 2026

Copy link
Copy Markdown
Author

Addressed the review: added the missing camera-fullscreen selection/id-counter resets in doNewProject (1c697fd). Skipped the Turkish addBlur capitalization nit — that line predates this PR, so I left it out to keep the diff focused; happy to fix it in a follow-up.

@EtienneLescot

Copy link
Copy Markdown
Collaborator

@rodrvc thanks for you PR, I think this is a good idea.
did you test on all platforms?

@EtienneLescot EtienneLescot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you for the contribution! The implementation of the Full Camera effect is clean, structured, and consistent with other regions. I ran the typechecker and all unit tests locally, and they passed successfully.

I have left one inline comment regarding the transition easing calculation for the ease-out effect to avoid a visual pop/slam at the end of the transition.

Comment thread src/components/video-editor/videoPlayback/cameraFullscreenUtils.ts
@rodrvc

rodrvc commented Jul 6, 2026

Copy link
Copy Markdown
Author

Thanks for the review! Fixed the easing issue on the inline comment exactly as you suggested (1 - easeOutScreenStudio(progress) with progress going 0→1), and updated the corresponding unit test assertions accordingly — all passing.

Re: platforms — I only tested this manually on macOS. Full Camera itself is renderer-only (canvas/PIXI math for the easing envelope and target-rect, consumed by both the DOM preview and the frame renderer for MP4/GIF export); it doesn't touch any of the native platform helpers (WGC/WASAPI on Windows, ScreenCaptureKit on macOS), which are only involved in live capture, not in this edit/export pipeline. build.yml does compile/package on Windows, macOS, and Linux, so I'm fairly confident it works there too, but I haven't done a manual visual check on Windows/Linux yet. Happy to try to get access to a Windows/Linux box to confirm before merge if you'd like extra assurance.

@EtienneLescot

Copy link
Copy Markdown
Collaborator

@rodrvc Thank you.
In my experience, even when native code isn't affected, you can always bump onto something unexpected on one or another platform.
Currently the main bottleneck for me is e2e testing :-) So if you get a chance to test on windows and linux that would be highly appreciated!

Thank you for your contribution!

EtienneLescot
EtienneLescot previously approved these changes Jul 15, 2026
rodrvc and others added 2 commits July 15, 2026 12:00
Adds a new timeline row for Full Camera segments: during a segment the
webcam overlay grows to (almost) fill the canvas — keeping its aspect
ratio and a small margin so rounded corners stay visible — then eases
back to its normal layout, with a slower ease-out than ease-in. The
transition is fully contained within the segment bounds.

Follows the existing ZoomRegion pattern end to end: shared pure
interpolation math for preview and export parity, persistence with
normalization for older projects, undo/redo support, a configurable
keyboard shortcut (C), and i18n keys for all 13 locales. While a Full
Camera segment is active, the reactive webcam shrink is suppressed to
avoid conflicting transforms; zoom behavior itself is untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…project

Address review feedback: doNewProject reset every other selection and
region id counter but missed the two camera-fullscreen ones.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@EtienneLescot EtienneLescot force-pushed the feature/camera-animation branch from c19c8a1 to 28a2a8e Compare July 15, 2026 10:04

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/lib/compositeLayout.test.ts (1)

278-305: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Correct swapped dimension terms in test descriptions.

The terms "width" and "height" are reversed in some test descriptions and comments regarding which dimension acts as the limiting constraint. For example, fitting a portrait or square source into a landscape canvas hits the top/bottom edges first, making height the constrained dimension.

Consider fixing these to ensure the documentation accurately reflects the geometry logic.

📝 Proposed fixes
-		// Square aspect source so width is the constrained dimension in a landscape canvas.
+		// Square aspect source so height is the constrained dimension in a landscape canvas.
 		const rect = computeCameraFullscreenTargetRect(canvasSize, { width: 1080, height: 1080 });
-	it("fits a portrait source by constraining width, centering vertically and horizontally", () => {
+	it("fits a portrait source by constraining height, centering vertically and horizontally", () => {
 		const canvasSize = { width: 1920, height: 1080 };
-	it("fits a landscape source by constraining height when it would overflow", () => {
+	it("fits a landscape source by constraining width when it would overflow", () => {
 		const canvasSize = { width: 1080, height: 1920 }; // portrait canvas
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/compositeLayout.test.ts` around lines 278 - 305, Correct the
dimension terminology in the descriptions and comments around
computeCameraFullscreenTargetRect tests. For the square and portrait source
cases, describe height as the constrained dimension because the source reaches
the canvas’s top and bottom edges first; update the portrait test title
accordingly. Review the adjacent landscape test wording and ensure its
constraint description matches the actual geometry.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/video-editor/timeline/TimelineEditor.tsx`:
- Around line 1086-1089: Move the four ref assignments around zoomRegionsRef,
cameraFullscreenRegionsRef, trimRegionsRef, and speedRegionsRef into a useEffect
with the corresponding region values as dependencies. Define this
synchronization effect before the existing normalization useEffect so that
normalization reads the latest refs while keeping render pure.

In `@src/i18n/locales/fr/shortcuts.json`:
- Line 25: Update the addCameraFullscreen translation value in shortcuts.json to
use natural French grammar, including the article and “en plein écran” phrasing,
while leaving the translation key unchanged.

---

Nitpick comments:
In `@src/lib/compositeLayout.test.ts`:
- Around line 278-305: Correct the dimension terminology in the descriptions and
comments around computeCameraFullscreenTargetRect tests. For the square and
portrait source cases, describe height as the constrained dimension because the
source reaches the canvas’s top and bottom edges first; update the portrait test
title accordingly. Review the adjacent landscape test wording and ensure its
constraint description matches the actual geometry.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 54826504-6a30-4c87-810f-0f2cc36ea7f4

📥 Commits

Reviewing files that changed from the base of the PR and between c19c8a1 and 28a2a8e.

📒 Files selected for processing (42)
  • src/components/video-editor/VideoEditor.tsx
  • src/components/video-editor/VideoPlayback.tsx
  • src/components/video-editor/projectPersistence.ts
  • src/components/video-editor/timeline/Item.tsx
  • src/components/video-editor/timeline/ItemGlass.module.css
  • src/components/video-editor/timeline/TimelineEditor.tsx
  • src/components/video-editor/types.ts
  • src/components/video-editor/videoPlayback/cameraFullscreenUtils.test.ts
  • src/components/video-editor/videoPlayback/cameraFullscreenUtils.ts
  • src/hooks/useEditorHistory.ts
  • src/i18n/locales/ar/shortcuts.json
  • src/i18n/locales/ar/timeline.json
  • src/i18n/locales/en/shortcuts.json
  • src/i18n/locales/en/timeline.json
  • src/i18n/locales/es/shortcuts.json
  • src/i18n/locales/es/timeline.json
  • src/i18n/locales/fr/shortcuts.json
  • src/i18n/locales/fr/timeline.json
  • src/i18n/locales/it/shortcuts.json
  • src/i18n/locales/it/timeline.json
  • src/i18n/locales/ja-JP/shortcuts.json
  • src/i18n/locales/ja-JP/timeline.json
  • src/i18n/locales/ko-KR/shortcuts.json
  • src/i18n/locales/ko-KR/timeline.json
  • src/i18n/locales/pt-BR/shortcuts.json
  • src/i18n/locales/pt-BR/timeline.json
  • src/i18n/locales/ru/shortcuts.json
  • src/i18n/locales/ru/timeline.json
  • src/i18n/locales/tr/shortcuts.json
  • src/i18n/locales/tr/timeline.json
  • src/i18n/locales/vi/shortcuts.json
  • src/i18n/locales/vi/timeline.json
  • src/i18n/locales/zh-CN/shortcuts.json
  • src/i18n/locales/zh-CN/timeline.json
  • src/i18n/locales/zh-TW/shortcuts.json
  • src/i18n/locales/zh-TW/timeline.json
  • src/lib/compositeLayout.test.ts
  • src/lib/compositeLayout.ts
  • src/lib/exporter/frameRenderer.ts
  • src/lib/exporter/gifExporter.ts
  • src/lib/exporter/videoExporter.ts
  • src/lib/shortcuts.ts
🚧 Files skipped from review as they are similar to previous changes (35)
  • src/i18n/locales/es/shortcuts.json
  • src/i18n/locales/en/shortcuts.json
  • src/i18n/locales/zh-TW/shortcuts.json
  • src/i18n/locales/tr/timeline.json
  • src/i18n/locales/vi/shortcuts.json
  • src/i18n/locales/tr/shortcuts.json
  • src/lib/compositeLayout.ts
  • src/i18n/locales/vi/timeline.json
  • src/components/video-editor/projectPersistence.ts
  • src/lib/shortcuts.ts
  • src/i18n/locales/es/timeline.json
  • src/components/video-editor/videoPlayback/cameraFullscreenUtils.ts
  • src/i18n/locales/ar/shortcuts.json
  • src/i18n/locales/ja-JP/shortcuts.json
  • src/lib/exporter/videoExporter.ts
  • src/components/video-editor/timeline/Item.tsx
  • src/components/video-editor/VideoPlayback.tsx
  • src/i18n/locales/it/shortcuts.json
  • src/i18n/locales/pt-BR/timeline.json
  • src/i18n/locales/ko-KR/timeline.json
  • src/i18n/locales/ko-KR/shortcuts.json
  • src/lib/exporter/frameRenderer.ts
  • src/i18n/locales/en/timeline.json
  • src/i18n/locales/zh-CN/shortcuts.json
  • src/i18n/locales/it/timeline.json
  • src/components/video-editor/videoPlayback/cameraFullscreenUtils.test.ts
  • src/i18n/locales/zh-CN/timeline.json
  • src/i18n/locales/zh-TW/timeline.json
  • src/hooks/useEditorHistory.ts
  • src/components/video-editor/timeline/ItemGlass.module.css
  • src/i18n/locales/ar/timeline.json
  • src/i18n/locales/ja-JP/timeline.json
  • src/i18n/locales/ru/timeline.json
  • src/i18n/locales/fr/timeline.json
  • src/components/video-editor/VideoEditor.tsx

Comment thread src/components/video-editor/timeline/TimelineEditor.tsx Outdated
Comment thread src/i18n/locales/fr/shortcuts.json Outdated
- Sync region refs in an effect instead of during render (React purity /
  no-ref-current-in-render); ordered before the normalization effect so it
  still reads the freshest values.
- Fix fr shortcut label grammar: "Ajouter une caméra en plein écran".
- Correct swapped width/height wording in computeCameraFullscreenTargetRect
  test descriptions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@EtienneLescot EtienneLescot merged commit 501de43 into getopenscreen:main Jul 15, 2026
12 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.

2 participants