@remotion/studio 4.0.469 → 4.0.471

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/dist/Studio.js +1 -1
  2. package/dist/api/save-render-output.js +3 -12
  3. package/dist/components/AudioWaveform.js +19 -2
  4. package/dist/components/ContextMenu.d.ts +7 -2
  5. package/dist/components/ContextMenu.js +53 -9
  6. package/dist/components/EditorContent.js +5 -4
  7. package/dist/components/Menu/MenuItem.d.ts +1 -1
  8. package/dist/components/MenuBuildIndicator.js +0 -1
  9. package/dist/components/NewComposition/InputDragger.js +1 -0
  10. package/dist/components/Preview.js +6 -2
  11. package/dist/components/SelectedOutlineOverlay.d.ts +49 -0
  12. package/dist/components/SelectedOutlineOverlay.js +710 -0
  13. package/dist/components/Timeline/Timeline.js +102 -13
  14. package/dist/components/Timeline/TimelineDeleteKeybindings.d.ts +2 -0
  15. package/dist/components/Timeline/TimelineDeleteKeybindings.js +101 -0
  16. package/dist/components/Timeline/TimelineDragHandler.js +20 -244
  17. package/dist/components/Timeline/{TimelineEffectGroupRow.d.ts → TimelineEffectItem.d.ts} +1 -1
  18. package/dist/components/Timeline/TimelineEffectItem.js +323 -0
  19. package/dist/components/Timeline/{TimelineEffectFieldRow.d.ts → TimelineEffectPropItem.d.ts} +2 -1
  20. package/dist/components/Timeline/{TimelineEffectFieldRow.js → TimelineEffectPropItem.js} +97 -8
  21. package/dist/components/Timeline/TimelineExpandArrowButton.js +5 -1
  22. package/dist/components/Timeline/TimelineExpandedKeyframeRow.js +37 -5
  23. package/dist/components/Timeline/TimelineExpandedRow.d.ts +1 -0
  24. package/dist/components/Timeline/TimelineExpandedRow.js +9 -7
  25. package/dist/components/Timeline/TimelineExpandedSection.d.ts +1 -0
  26. package/dist/components/Timeline/TimelineExpandedSection.js +2 -2
  27. package/dist/components/Timeline/TimelineInOutDragHandler.d.ts +2 -0
  28. package/dist/components/Timeline/TimelineInOutDragHandler.js +324 -0
  29. package/dist/components/Timeline/TimelineInOutPointer.js +3 -1
  30. package/dist/components/Timeline/TimelineInOutPointerHandle.d.ts +1 -0
  31. package/dist/components/Timeline/TimelineInOutPointerHandle.js +5 -4
  32. package/dist/components/Timeline/TimelineKeyframeControls.d.ts +17 -0
  33. package/dist/components/Timeline/TimelineKeyframeControls.js +222 -0
  34. package/dist/components/Timeline/TimelineKeyframeDiamond.js +7 -6
  35. package/dist/components/Timeline/TimelineKeyframedValue.d.ts +8 -0
  36. package/dist/components/Timeline/TimelineKeyframedValue.js +36 -0
  37. package/dist/components/Timeline/TimelineList.js +3 -15
  38. package/dist/components/Timeline/TimelineRowChrome.d.ts +6 -1
  39. package/dist/components/Timeline/TimelineRowChrome.js +25 -7
  40. package/dist/components/Timeline/TimelineSelection.d.ts +53 -9
  41. package/dist/components/Timeline/TimelineSelection.js +305 -48
  42. package/dist/components/Timeline/TimelineSequence.d.ts +2 -0
  43. package/dist/components/Timeline/TimelineSequence.js +18 -6
  44. package/dist/components/Timeline/TimelineSequenceFrame.js +1 -0
  45. package/dist/components/Timeline/{TimelineListItem.d.ts → TimelineSequenceItem.d.ts} +2 -1
  46. package/dist/components/Timeline/{TimelineListItem.js → TimelineSequenceItem.js} +140 -34
  47. package/dist/components/Timeline/{TimelineFieldRow.d.ts → TimelineSequencePropItem.d.ts} +2 -1
  48. package/dist/components/Timeline/{TimelineFieldRow.js → TimelineSequencePropItem.js} +81 -5
  49. package/dist/components/Timeline/TimelineTimeIndicators.js +0 -1
  50. package/dist/components/Timeline/TimelineTrack.js +3 -1
  51. package/dist/components/Timeline/TimelineTranslateField.js +14 -22
  52. package/dist/components/Timeline/call-add-keyframe.d.ts +23 -0
  53. package/dist/components/Timeline/call-add-keyframe.js +54 -0
  54. package/dist/components/Timeline/call-delete-keyframe.d.ts +37 -0
  55. package/dist/components/Timeline/call-delete-keyframe.js +122 -0
  56. package/dist/components/Timeline/delete-selected-keyframe.d.ts +21 -0
  57. package/dist/components/Timeline/delete-selected-keyframe.js +92 -0
  58. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +17 -0
  59. package/dist/components/Timeline/delete-selected-timeline-item.js +178 -0
  60. package/dist/components/Timeline/duplicate-selected-timeline-item.d.ts +13 -0
  61. package/dist/components/Timeline/duplicate-selected-timeline-item.js +66 -0
  62. package/dist/components/Timeline/find-track-for-node-path-info.d.ts +7 -0
  63. package/dist/components/Timeline/find-track-for-node-path-info.js +13 -0
  64. package/dist/components/Timeline/get-keyframe-navigation.d.ts +9 -0
  65. package/dist/components/Timeline/get-keyframe-navigation.js +26 -0
  66. package/dist/components/Timeline/parse-keyframe-field-from-node-path.d.ts +8 -0
  67. package/dist/components/Timeline/parse-keyframe-field-from-node-path.js +26 -0
  68. package/dist/components/Timeline/reset-selected-timeline-props.d.ts +38 -0
  69. package/dist/components/Timeline/reset-selected-timeline-props.js +143 -0
  70. package/dist/components/Timeline/save-sequence-prop.d.ts +14 -2
  71. package/dist/components/Timeline/save-sequence-prop.js +42 -7
  72. package/dist/components/Timeline/sequence-props-subscription-store.d.ts +3 -2
  73. package/dist/components/Timeline/sequence-props-subscription-store.js +2 -1
  74. package/dist/components/Timeline/timeline-row-layout.d.ts +1 -0
  75. package/dist/components/Timeline/timeline-row-layout.js +2 -1
  76. package/dist/components/Timeline/timeline-scroll-logic.js +3 -3
  77. package/dist/components/Timeline/timeline-translate-utils.d.ts +2 -0
  78. package/dist/components/Timeline/timeline-translate-utils.js +20 -0
  79. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +10 -3
  80. package/dist/components/Timeline/use-sequence-props-subscription.js +2 -1
  81. package/dist/components/composition-menu-items.js +32 -1
  82. package/dist/error-overlay/remotion-overlay/OpenInEditor.js +0 -1
  83. package/dist/esm/{chunk-1mp51e0w.js → chunk-z0z9d4r0.js} +10422 -5958
  84. package/dist/esm/internals.mjs +10422 -5958
  85. package/dist/esm/previewEntry.mjs +10419 -5953
  86. package/dist/esm/renderEntry.mjs +3 -1
  87. package/dist/helpers/format-file-location.d.ts +9 -0
  88. package/dist/helpers/format-file-location.js +27 -0
  89. package/dist/helpers/get-box-quads-polyfill-internals.d.ts +82 -0
  90. package/dist/helpers/get-box-quads-polyfill-internals.js +2395 -0
  91. package/dist/helpers/get-box-quads-ponyfill.d.ts +10 -0
  92. package/dist/helpers/get-box-quads-ponyfill.js +23 -0
  93. package/dist/helpers/get-left-of-timeline-slider.js +1 -1
  94. package/dist/helpers/get-timeline-sequence-layout.js +10 -11
  95. package/dist/helpers/open-in-editor.d.ts +20 -2
  96. package/dist/helpers/open-in-editor.js +53 -30
  97. package/dist/helpers/use-menu-structure.js +8 -17
  98. package/dist/renderEntry.js +2 -2
  99. package/dist/state/z-index.js +5 -2
  100. package/package.json +10 -10
  101. package/dist/components/Timeline/TimelineEffectGroupRow.js +0 -153
@@ -41,7 +41,11 @@ const calculate_timeline_1 = require("../../helpers/calculate-timeline");
41
41
  const client_id_1 = require("../../helpers/client-id");
42
42
  const colors_1 = require("../../helpers/colors");
43
43
  const is_current_selected_still_1 = require("../../helpers/is-current-selected-still");
44
+ const open_in_editor_1 = require("../../helpers/open-in-editor");
45
+ const call_api_1 = require("../call-api");
46
+ const ContextMenu_1 = require("../ContextMenu");
44
47
  const is_menu_item_1 = require("../Menu/is-menu-item");
48
+ const NotificationCenter_1 = require("../Notifications/NotificationCenter");
45
49
  const SplitterContainer_1 = require("../Splitter/SplitterContainer");
46
50
  const SplitterElement_1 = require("../Splitter/SplitterElement");
47
51
  const SplitterHandle_1 = require("../Splitter/SplitterHandle");
@@ -52,6 +56,7 @@ const SubscribeToNodePaths_1 = require("./SubscribeToNodePaths");
52
56
  const timeline_refs_1 = require("./timeline-refs");
53
57
  const TimelineDragHandler_1 = require("./TimelineDragHandler");
54
58
  const TimelineHeightContainer_1 = require("./TimelineHeightContainer");
59
+ const TimelineInOutDragHandler_1 = require("./TimelineInOutDragHandler");
55
60
  const TimelineInOutPointer_1 = require("./TimelineInOutPointer");
56
61
  const TimelineList_1 = require("./TimelineList");
57
62
  const TimelinePinchZoom_1 = require("./TimelinePinchZoom");
@@ -62,6 +67,7 @@ const TimelineSlider_1 = require("./TimelineSlider");
62
67
  const TimelineTimeIndicators_1 = require("./TimelineTimeIndicators");
63
68
  const TimelineTracks_1 = require("./TimelineTracks");
64
69
  const TimelineWidthProvider_1 = require("./TimelineWidthProvider");
70
+ const use_resolved_stack_1 = require("./use-resolved-stack");
65
71
  const container = {
66
72
  minHeight: '100%',
67
73
  flex: 1,
@@ -71,6 +77,89 @@ const container = {
71
77
  backgroundColor: colors_1.BACKGROUND,
72
78
  };
73
79
  const noop = () => undefined;
80
+ const TimelineClearSelectionArea = ({ children }) => {
81
+ var _a, _b;
82
+ const { clearSelection } = (0, TimelineSelection_1.useTimelineSelection)();
83
+ const { compositions, canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
84
+ const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
85
+ const [isAddingSolid, setIsAddingSolid] = (0, react_1.useState)(false);
86
+ const currentCompositionId = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition' ? canvasContent.compositionId : null;
87
+ const currentComposition = (0, react_1.useMemo)(() => {
88
+ var _a;
89
+ if (currentCompositionId === null) {
90
+ return null;
91
+ }
92
+ return ((_a = compositions.find((composition) => composition.id === currentCompositionId)) !== null && _a !== void 0 ? _a : null);
93
+ }, [compositions, currentCompositionId]);
94
+ const resolvedCompositionLocation = (0, use_resolved_stack_1.useResolvedStack)((_a = currentComposition === null || currentComposition === void 0 ? void 0 : currentComposition.stack) !== null && _a !== void 0 ? _a : null);
95
+ const compositionFile = (_b = resolvedCompositionLocation === null || resolvedCompositionLocation === void 0 ? void 0 : resolvedCompositionLocation.source) !== null && _b !== void 0 ? _b : null;
96
+ const compositionComponentInfo = (0, open_in_editor_1.useCachedCompositionComponentInfo)({
97
+ compositionFile,
98
+ compositionId: currentCompositionId,
99
+ });
100
+ // Selection-triggering click handlers in children call e.stopPropagation(),
101
+ // so any pointerdown that bubbles up here is by definition on empty space
102
+ // and should clear the current selection.
103
+ const onPointerDown = (0, react_1.useCallback)((e) => {
104
+ if (e.button !== 0) {
105
+ return;
106
+ }
107
+ clearSelection();
108
+ }, [clearSelection]);
109
+ const canInsertSolid = (compositionComponentInfo === null || compositionComponentInfo === void 0 ? void 0 : compositionComponentInfo.canAddSequence) === true &&
110
+ currentCompositionId !== null &&
111
+ compositionFile !== null &&
112
+ videoConfig !== null &&
113
+ !isAddingSolid;
114
+ const insertSolid = (0, react_1.useCallback)(async () => {
115
+ if (!canInsertSolid ||
116
+ currentCompositionId === null ||
117
+ compositionFile === null ||
118
+ videoConfig === null) {
119
+ return;
120
+ }
121
+ setIsAddingSolid(true);
122
+ try {
123
+ const result = await (0, call_api_1.callApi)('/api/insert-jsx-element', {
124
+ compositionFile,
125
+ compositionId: currentCompositionId,
126
+ element: {
127
+ type: 'solid',
128
+ width: videoConfig.width,
129
+ height: videoConfig.height,
130
+ },
131
+ });
132
+ if (result.success) {
133
+ (0, NotificationCenter_1.showNotification)('Added <Solid> to source file', 2000);
134
+ return;
135
+ }
136
+ (0, NotificationCenter_1.showNotification)(result.reason, 4000);
137
+ }
138
+ catch (err) {
139
+ (0, NotificationCenter_1.showNotification)(err.message, 4000);
140
+ }
141
+ finally {
142
+ setIsAddingSolid(false);
143
+ }
144
+ }, [canInsertSolid, compositionFile, currentCompositionId, videoConfig]);
145
+ const contextMenuItems = (0, react_1.useMemo)(() => {
146
+ return [
147
+ {
148
+ type: 'item',
149
+ id: 'insert-solid',
150
+ label: 'Add <Solid>',
151
+ value: 'insert-solid',
152
+ onClick: insertSolid,
153
+ keyHint: null,
154
+ leftItem: null,
155
+ subMenu: null,
156
+ quickSwitcherLabel: null,
157
+ disabled: !canInsertSolid,
158
+ },
159
+ ];
160
+ }, [insertSolid, canInsertSolid]);
161
+ return (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { ref: timeline_refs_1.timelineVerticalScroll, values: contextMenuItems, onOpen: null, style: container, className: 'css-reset ' + is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, onPointerDown: onPointerDown, children: children }));
162
+ };
74
163
  const TimelineInner = () => {
75
164
  var _a;
76
165
  const { sequences } = (0, react_1.useContext)(remotion_1.Internals.SequenceManager);
@@ -99,18 +188,18 @@ const TimelineInner = () => {
99
188
  : filtered;
100
189
  }, [filtered]);
101
190
  const hasBeenCut = filtered.length > shown.length;
102
- return (jsx_runtime_1.jsx("div", { ref: timeline_refs_1.timelineVerticalScroll, style: container, className: 'css-reset ' + is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: jsx_runtime_1.jsxs(TimelineSelection_1.TimelineSelectionProvider, { children: [sequences.map((sequence) => {
103
- if (!sequence.controls || !previewConnected || !sequence.getStack()) {
104
- return null;
105
- }
106
- return (jsx_runtime_1.jsx(SubscribeToNodePaths_1.SubscribeToNodePaths, { overrideId: sequence.controls.overrideId, schema: sequence.controls.schema, getStack: sequence.getStack, effects: sequence.effects }, sequence.id));
107
- }), jsx_runtime_1.jsx(SequencePropsObserver_1.SequencePropsObserver, {}), jsx_runtime_1.jsx(TimelineHeightContainer_1.TimelineHeightContainer, { shown: shown, hasBeenCut: hasBeenCut, children: isStill ? (jsx_runtime_1.jsx(TimelineList_1.TimelineList, { timeline: shown })) : (jsx_runtime_1.jsxs(TimelineWidthProvider_1.TimelineWidthProvider, { children: [
108
- jsx_runtime_1.jsx(TimelinePinchZoom_1.TimelinePinchZoom, {}), jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { orientation: "vertical", defaultFlex: 0.2, id: "names-to-timeline", maxFlex: 0.5, minFlex: 0.15, children: [
109
- jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "flexer", sticky: jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePlaceholders, {}), children: jsx_runtime_1.jsx(TimelineList_1.TimelineList, { timeline: shown }) }), jsx_runtime_1.jsx(SplitterHandle_1.SplitterHandle, { onCollapse: noop, allowToCollapse: "none" }), jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "anti-flexer", sticky: null, children: jsx_runtime_1.jsxs(TimelineScrollable_1.TimelineScrollable, { children: [
110
- jsx_runtime_1.jsx(TimelineTracks_1.TimelineTracks, { timeline: shown, hasBeenCut: hasBeenCut }), jsx_runtime_1.jsx(TimelineInOutPointer_1.TimelineInOutPointer, {}), jsx_runtime_1.jsx(TimelinePlayCursorSyncer_1.TimelinePlayCursorSyncer, {}), jsx_runtime_1.jsx(TimelineDragHandler_1.TimelineDragHandler, {}), jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimeIndicators, {}), jsx_runtime_1.jsx(TimelineSlider_1.TimelineSlider, {})
111
- ] }) })
112
- ] })
113
- ] })) })
114
- ] }) }));
191
+ return (jsx_runtime_1.jsxs(TimelineClearSelectionArea, { children: [sequences.map((sequence) => {
192
+ if (!sequence.controls || !previewConnected || !sequence.getStack()) {
193
+ return null;
194
+ }
195
+ return (jsx_runtime_1.jsx(SubscribeToNodePaths_1.SubscribeToNodePaths, { overrideId: sequence.controls.overrideId, schema: sequence.controls.schema, getStack: sequence.getStack, effects: sequence.effects }, sequence.id));
196
+ }), jsx_runtime_1.jsx(SequencePropsObserver_1.SequencePropsObserver, {}), jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectAllKeybindings, { timeline: shown }), jsx_runtime_1.jsx(TimelineHeightContainer_1.TimelineHeightContainer, { shown: shown, hasBeenCut: hasBeenCut, children: isStill ? (jsx_runtime_1.jsx(TimelineList_1.TimelineList, { timeline: shown })) : (jsx_runtime_1.jsxs(TimelineWidthProvider_1.TimelineWidthProvider, { children: [
197
+ jsx_runtime_1.jsx(TimelinePinchZoom_1.TimelinePinchZoom, {}), jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { orientation: "vertical", defaultFlex: 0.2, id: "names-to-timeline", maxFlex: 0.5, minFlex: 0.15, children: [
198
+ jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "flexer", sticky: jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePlaceholders, {}), children: jsx_runtime_1.jsx(TimelineList_1.TimelineList, { timeline: shown }) }), jsx_runtime_1.jsx(SplitterHandle_1.SplitterHandle, { onCollapse: noop, allowToCollapse: "none" }), jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "anti-flexer", sticky: null, children: jsx_runtime_1.jsxs(TimelineScrollable_1.TimelineScrollable, { children: [
199
+ jsx_runtime_1.jsx(TimelineTracks_1.TimelineTracks, { timeline: shown, hasBeenCut: hasBeenCut }), jsx_runtime_1.jsx(TimelinePlayCursorSyncer_1.TimelinePlayCursorSyncer, {}), jsx_runtime_1.jsx(TimelineInOutPointer_1.TimelineInOutPointer, {}), jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimeIndicators, {}), jsx_runtime_1.jsx(TimelineDragHandler_1.TimelineDragHandler, {}), jsx_runtime_1.jsx(TimelineInOutDragHandler_1.TimelineInOutDragHandler, {}), jsx_runtime_1.jsx(TimelineSlider_1.TimelineSlider, {})
200
+ ] }) })
201
+ ] })
202
+ ] })) })
203
+ ] }));
115
204
  };
116
205
  exports.Timeline = react_1.default.memo(TimelineInner);
@@ -0,0 +1,2 @@
1
+ import type React from 'react';
2
+ export declare const TimelineDeleteKeybindings: React.FC;
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TimelineDeleteKeybindings = void 0;
4
+ const react_1 = require("react");
5
+ const remotion_1 = require("remotion");
6
+ const client_id_1 = require("../../helpers/client-id");
7
+ const use_keybinding_1 = require("../../helpers/use-keybinding");
8
+ const delete_selected_timeline_item_1 = require("./delete-selected-timeline-item");
9
+ const duplicate_selected_timeline_item_1 = require("./duplicate-selected-timeline-item");
10
+ const reset_selected_timeline_props_1 = require("./reset-selected-timeline-props");
11
+ const TimelineSelection_1 = require("./TimelineSelection");
12
+ const TimelineDeleteKeybindings = () => {
13
+ const keybindings = (0, use_keybinding_1.useKeybinding)();
14
+ const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
15
+ const { sequences } = (0, react_1.useContext)(remotion_1.Internals.SequenceManager);
16
+ const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
17
+ const { codeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeCodeValuesContext);
18
+ const { setCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
19
+ const { canSelect } = (0, TimelineSelection_1.useTimelineSelection)();
20
+ const currentSelection = (0, TimelineSelection_1.useCurrentTimelineSelectionStateAsRef)();
21
+ (0, react_1.useEffect)(() => {
22
+ if (!canSelect || previewServerState.type !== 'connected') {
23
+ return;
24
+ }
25
+ const { clientId } = previewServerState;
26
+ const backspace = keybindings.registerKeybinding({
27
+ event: 'keydown',
28
+ key: 'Backspace',
29
+ callback: () => {
30
+ const { selectedItems, clearSelection } = currentSelection.current;
31
+ if (selectedItems.length === 0) {
32
+ return;
33
+ }
34
+ const resetPromise = (0, reset_selected_timeline_props_1.resetSelectedTimelineProps)({
35
+ selections: selectedItems,
36
+ sequences,
37
+ overrideIdsToNodePaths: overrideIdToNodePathMappings,
38
+ codeValues,
39
+ setCodeValues,
40
+ clientId,
41
+ });
42
+ if (resetPromise !== null) {
43
+ resetPromise.catch(() => undefined);
44
+ return;
45
+ }
46
+ const deletePromise = (0, delete_selected_timeline_item_1.deleteSelectedTimelineItems)({
47
+ selections: selectedItems,
48
+ sequences,
49
+ overrideIdsToNodePaths: overrideIdToNodePathMappings,
50
+ setCodeValues,
51
+ clientId,
52
+ });
53
+ if (deletePromise === null) {
54
+ return;
55
+ }
56
+ clearSelection();
57
+ deletePromise.catch(() => undefined);
58
+ },
59
+ commandCtrlKey: false,
60
+ preventDefault: true,
61
+ triggerIfInputFieldFocused: false,
62
+ keepRegisteredWhenNotHighestContext: false,
63
+ });
64
+ const duplicate = keybindings.registerKeybinding({
65
+ event: 'keydown',
66
+ key: 'd',
67
+ callback: () => {
68
+ const { selectedItems } = currentSelection.current;
69
+ if (selectedItems.length === 0) {
70
+ return;
71
+ }
72
+ const duplicatePromise = (0, duplicate_selected_timeline_item_1.duplicateSelectedTimelineItems)({
73
+ selections: selectedItems,
74
+ });
75
+ if (duplicatePromise === null) {
76
+ return;
77
+ }
78
+ duplicatePromise.catch(() => undefined);
79
+ },
80
+ commandCtrlKey: true,
81
+ preventDefault: true,
82
+ triggerIfInputFieldFocused: false,
83
+ keepRegisteredWhenNotHighestContext: false,
84
+ });
85
+ return () => {
86
+ backspace.unregister();
87
+ duplicate.unregister();
88
+ };
89
+ }, [
90
+ canSelect,
91
+ codeValues,
92
+ currentSelection,
93
+ keybindings,
94
+ overrideIdToNodePathMappings,
95
+ previewServerState,
96
+ sequences,
97
+ setCodeValues,
98
+ ]);
99
+ return null;
100
+ };
101
+ exports.TimelineDeleteKeybindings = TimelineDeleteKeybindings;
@@ -38,21 +38,15 @@ const jsx_runtime_1 = require("react/jsx-runtime");
38
38
  const player_1 = require("@remotion/player");
39
39
  const react_1 = __importStar(require("react"));
40
40
  const remotion_1 = require("remotion");
41
- const get_left_of_timeline_slider_1 = require("../../helpers/get-left-of-timeline-slider");
42
41
  const timeline_layout_1 = require("../../helpers/timeline-layout");
43
- const in_out_1 = require("../../state/in-out");
44
42
  const timeline_zoom_1 = require("../../state/timeline-zoom");
45
43
  const z_index_1 = require("../../state/z-index");
46
- const ContextMenu_1 = require("../ContextMenu");
47
- const ForceSpecificCursor_1 = require("../ForceSpecificCursor");
48
44
  const is_menu_item_1 = require("../Menu/is-menu-item");
49
- const TimelineInOutToggle_1 = require("../TimelineInOutToggle");
50
45
  const timeline_refs_1 = require("./timeline-refs");
51
46
  const timeline_scroll_logic_1 = require("./timeline-scroll-logic");
52
- const TimelineInOutPointer_1 = require("./TimelineInOutPointer");
53
- const TimelineInOutPointerHandle_1 = require("./TimelineInOutPointerHandle");
47
+ const TimelineSelection_1 = require("./TimelineSelection");
54
48
  const TimelineSlider_1 = require("./TimelineSlider");
55
- const TimelineWidthProvider_1 = require("./TimelineWidthProvider");
49
+ const TimelineTimeIndicators_1 = require("./TimelineTimeIndicators");
56
50
  const inner = {
57
51
  overflowY: 'auto',
58
52
  overflowX: 'hidden',
@@ -69,6 +63,7 @@ const style = {
69
63
  height: '100%',
70
64
  userSelect: 'none',
71
65
  WebkitUserSelect: 'none',
66
+ position: 'absolute',
72
67
  };
73
68
  const getClientXWithScroll = (x) => {
74
69
  var _a;
@@ -87,6 +82,7 @@ const TimelineDragHandler = () => {
87
82
  return {
88
83
  ...container,
89
84
  width: 100 * zoom + '%',
85
+ ...(TimelineSelection_1.TIMELINE_TOP_DRAG ? { height: TimelineTimeIndicators_1.TIMELINE_TIME_INDICATOR_HEIGHT } : {}),
90
86
  };
91
87
  }, [canvasContent, zoomMap]);
92
88
  if (!canvasContent || canvasContent.type !== 'composition') {
@@ -105,20 +101,8 @@ const TimelineDragHandlerInner = () => {
105
101
  });
106
102
  const { isHighestContext } = (0, z_index_1.useZIndex)();
107
103
  const setFrame = remotion_1.Internals.useTimelineSetFrame();
108
- const [inOutDragging, setInOutDragging] = (0, react_1.useState)({
109
- dragging: false,
110
- });
111
- const timelineWidth = (0, react_1.useContext)(TimelineWidthProvider_1.TimelineWidthContext);
112
- const get = (0, react_1.useCallback)((frame) => {
113
- if (timelineWidth === null) {
114
- throw new Error('timeline width is not yet determined');
115
- }
116
- return (0, get_left_of_timeline_slider_1.getXPositionOfItemInTimelineImperatively)(frame, videoConfig.durationInFrames, timelineWidth);
117
- }, [timelineWidth, videoConfig.durationInFrames]);
118
104
  const width = (_b = (_a = timeline_refs_1.scrollableRef.current) === null || _a === void 0 ? void 0 : _a.scrollWidth) !== null && _b !== void 0 ? _b : 0;
119
105
  const left = (_c = size === null || size === void 0 ? void 0 : size.left) !== null && _c !== void 0 ? _c : 0;
120
- const { inFrame, outFrame } = (0, in_out_1.useTimelineInOutFramePosition)();
121
- const { setInAndOutFrames } = (0, in_out_1.useTimelineSetInOutFramePosition)();
122
106
  const [dragging, setDragging] = (0, react_1.useState)({
123
107
  dragging: false,
124
108
  });
@@ -141,39 +125,9 @@ const TimelineDragHandlerInner = () => {
141
125
  if (!videoConfig) {
142
126
  return;
143
127
  }
128
+ e.stopPropagation();
144
129
  document.body.style.userSelect = 'none';
145
130
  document.body.style.webkitUserSelect = 'none';
146
- if (e.target === TimelineInOutPointerHandle_1.inPointerHandle.current) {
147
- if (inFrame === null) {
148
- throw new Error('expected outframe');
149
- }
150
- const inMarker = get(inFrame);
151
- const outMarker = outFrame === null ? Infinity : get(outFrame - 1);
152
- (0, ForceSpecificCursor_1.forceSpecificCursor)('ew-resize');
153
- setInOutDragging({
154
- dragging: 'in',
155
- initialOffset: getClientXWithScroll(e.clientX),
156
- boundaries: [-Infinity, outMarker - inMarker],
157
- });
158
- return;
159
- }
160
- if (e.target === TimelineInOutPointerHandle_1.outPointerHandle.current) {
161
- if (outFrame === null) {
162
- throw new Error('expected outframe');
163
- }
164
- const outMarker = get(outFrame);
165
- const inMarker = inFrame === null ? -Infinity : get(inFrame + 1);
166
- (0, ForceSpecificCursor_1.forceSpecificCursor)('ew-resize');
167
- setInOutDragging({
168
- dragging: 'out',
169
- initialOffset: getClientXWithScroll(e.clientX),
170
- boundaries: [inMarker - outMarker, Infinity],
171
- });
172
- return;
173
- }
174
- if (e.button !== 0) {
175
- return;
176
- }
177
131
  const frame = (0, timeline_scroll_logic_1.getFrameFromX)({
178
132
  clientX: getClientXWithScroll(e.clientX) - left,
179
133
  durationInFrames: videoConfig.durationInFrames,
@@ -186,18 +140,7 @@ const TimelineDragHandlerInner = () => {
186
140
  wasPlaying: playing,
187
141
  });
188
142
  pause();
189
- }, [
190
- isHighestContext,
191
- videoConfig,
192
- left,
193
- width,
194
- seek,
195
- playing,
196
- pause,
197
- inFrame,
198
- get,
199
- outFrame,
200
- ]);
143
+ }, [isHighestContext, videoConfig, left, width, seek, playing, pause]);
201
144
  const onPointerMoveScrubbing = (0, react_1.useCallback)((e) => {
202
145
  var _a;
203
146
  if (!videoConfig) {
@@ -277,45 +220,6 @@ const TimelineDragHandlerInner = () => {
277
220
  seek(frame);
278
221
  }
279
222
  }, [videoConfig, dragging.dragging, left, width, seek]);
280
- const onPointerMoveInOut = (0, react_1.useCallback)((e) => {
281
- if (!videoConfig) {
282
- return;
283
- }
284
- if (!inOutDragging.dragging) {
285
- return;
286
- }
287
- const offset = Math.max(inOutDragging.boundaries[0], Math.min(inOutDragging.boundaries[1], getClientXWithScroll(e.clientX) - inOutDragging.initialOffset));
288
- if (inOutDragging.dragging === 'in') {
289
- if (!TimelineInOutPointerHandle_1.inPointerHandle.current) {
290
- throw new Error('in pointer handle');
291
- }
292
- if (!TimelineInOutPointer_1.inMarkerAreaRef.current) {
293
- throw new Error('expected inMarkerAreaRef');
294
- }
295
- if (!inFrame) {
296
- throw new Error('expected inframes');
297
- }
298
- TimelineInOutPointerHandle_1.inPointerHandle.current.style.transform = `translateX(${get(inFrame) + offset}px)`;
299
- TimelineInOutPointer_1.inMarkerAreaRef.current.style.width =
300
- String(get(inFrame) + offset) + 'px';
301
- }
302
- if (inOutDragging.dragging === 'out') {
303
- if (!TimelineInOutPointerHandle_1.outPointerHandle.current) {
304
- throw new Error('in pointer handle');
305
- }
306
- if (!TimelineInOutPointer_1.outMarkerAreaRef.current) {
307
- throw new Error('in outMarkerAreaRef');
308
- }
309
- if (!outFrame) {
310
- throw new Error('expected outframes');
311
- }
312
- TimelineInOutPointerHandle_1.outPointerHandle.current.style.transform = `translateX(${get(outFrame) + offset}px)`;
313
- TimelineInOutPointer_1.outMarkerAreaRef.current.style.left =
314
- String(get(outFrame) + offset) + 'px';
315
- TimelineInOutPointer_1.outMarkerAreaRef.current.style.width =
316
- String(width - get(outFrame) - offset) + 'px';
317
- }
318
- }, [get, inFrame, inOutDragging, outFrame, videoConfig, width]);
319
223
  const onPointerUpScrubbing = (0, react_1.useCallback)((e) => {
320
224
  stopInterval();
321
225
  document.body.style.userSelect = '';
@@ -344,84 +248,6 @@ const TimelineDragHandlerInner = () => {
344
248
  play();
345
249
  }
346
250
  }, [dragging, left, play, videoConfig, setFrame, width]);
347
- const onPointerUpInOut = (0, react_1.useCallback)((e) => {
348
- document.body.style.userSelect = '';
349
- document.body.style.webkitUserSelect = '';
350
- (0, ForceSpecificCursor_1.stopForcingSpecificCursor)();
351
- if (!videoConfig) {
352
- return;
353
- }
354
- if (!inOutDragging.dragging) {
355
- return;
356
- }
357
- setInOutDragging({
358
- dragging: false,
359
- });
360
- const frame = (0, timeline_scroll_logic_1.getFrameFromX)({
361
- clientX: getClientXWithScroll(e.clientX) - left,
362
- durationInFrames: videoConfig.durationInFrames,
363
- width,
364
- extrapolate: 'extend',
365
- });
366
- if (inOutDragging.dragging === 'in') {
367
- if (frame < 1) {
368
- return setInAndOutFrames((prev) => {
369
- var _a;
370
- return ({
371
- ...prev,
372
- [videoConfig.id]: {
373
- ...((_a = prev[videoConfig.id]) !== null && _a !== void 0 ? _a : TimelineInOutToggle_1.defaultInOutValue),
374
- inFrame: null,
375
- },
376
- });
377
- });
378
- }
379
- const maxFrame = outFrame === null ? Infinity : outFrame - 1;
380
- setInAndOutFrames((prev) => {
381
- var _a;
382
- return ({
383
- ...prev,
384
- [videoConfig.id]: {
385
- ...((_a = prev[videoConfig.id]) !== null && _a !== void 0 ? _a : TimelineInOutToggle_1.defaultInOutValue),
386
- inFrame: Math.min(maxFrame, frame),
387
- },
388
- });
389
- });
390
- }
391
- else {
392
- if (frame > videoConfig.durationInFrames - 2) {
393
- return setInAndOutFrames((prev) => {
394
- var _a;
395
- return ({
396
- ...prev,
397
- [videoConfig.id]: {
398
- ...((_a = prev[videoConfig.id]) !== null && _a !== void 0 ? _a : TimelineInOutToggle_1.defaultInOutValue),
399
- outFrame: null,
400
- },
401
- });
402
- });
403
- }
404
- const minFrame = inFrame === null ? -Infinity : inFrame + 1;
405
- setInAndOutFrames((prev) => {
406
- var _a;
407
- return ({
408
- ...prev,
409
- [videoConfig.id]: {
410
- ...((_a = prev[videoConfig.id]) !== null && _a !== void 0 ? _a : TimelineInOutToggle_1.defaultInOutValue),
411
- outFrame: Math.max(minFrame, frame),
412
- },
413
- });
414
- });
415
- }
416
- }, [
417
- inFrame,
418
- inOutDragging.dragging,
419
- left,
420
- outFrame,
421
- setInAndOutFrames,
422
- videoConfig,
423
- width,
424
- ]);
425
251
  (0, react_1.useEffect)(() => {
426
252
  if (!dragging.dragging) {
427
253
  return;
@@ -433,74 +259,24 @@ const TimelineDragHandlerInner = () => {
433
259
  window.removeEventListener('pointerup', onPointerUpScrubbing);
434
260
  };
435
261
  }, [dragging.dragging, onPointerMoveScrubbing, onPointerUpScrubbing]);
262
+ const ref = (0, react_1.useRef)(null);
436
263
  (0, react_1.useEffect)(() => {
437
- if (inOutDragging.dragging === false) {
264
+ const currentRef = ref.current;
265
+ if (!currentRef) {
438
266
  return;
439
267
  }
440
- window.addEventListener('pointermove', onPointerMoveInOut);
441
- window.addEventListener('pointerup', onPointerUpInOut);
268
+ const { current } = timeline_refs_1.timelineVerticalScroll;
269
+ if (!current) {
270
+ return;
271
+ }
272
+ const onScroll = () => {
273
+ currentRef.style.top = current.scrollTop + 'px';
274
+ };
275
+ current.addEventListener('scroll', onScroll);
442
276
  return () => {
443
- window.removeEventListener('pointermove', onPointerMoveInOut);
444
- window.removeEventListener('pointerup', onPointerUpInOut);
277
+ current.removeEventListener('scroll', onScroll);
445
278
  };
446
- }, [inOutDragging.dragging, onPointerMoveInOut, onPointerUpInOut]);
447
- const inContextMenu = (0, react_1.useMemo)(() => {
448
- return [
449
- {
450
- id: 'hide-in',
451
- keyHint: null,
452
- label: 'Clear In marker',
453
- leftItem: null,
454
- onClick: (_, e) => {
455
- e === null || e === void 0 ? void 0 : e.stopPropagation();
456
- e === null || e === void 0 ? void 0 : e.preventDefault();
457
- setInAndOutFrames((prev) => {
458
- var _a;
459
- return ({
460
- ...prev,
461
- [videoConfig.id]: {
462
- ...((_a = prev[videoConfig.id]) !== null && _a !== void 0 ? _a : TimelineInOutToggle_1.defaultInOutValue),
463
- inFrame: null,
464
- },
465
- });
466
- });
467
- },
468
- quickSwitcherLabel: null,
469
- subMenu: null,
470
- type: 'item',
471
- value: 'hide-in',
472
- },
473
- ];
474
- }, [setInAndOutFrames, videoConfig.id]);
475
- const outContextMenu = (0, react_1.useMemo)(() => {
476
- return [
477
- {
478
- id: 'hide-out',
479
- keyHint: null,
480
- label: 'Clear Out marker',
481
- leftItem: null,
482
- onClick: (_, e) => {
483
- e === null || e === void 0 ? void 0 : e.stopPropagation();
484
- e === null || e === void 0 ? void 0 : e.preventDefault();
485
- setInAndOutFrames((prev) => {
486
- var _a;
487
- return ({
488
- ...prev,
489
- [videoConfig.id]: {
490
- ...((_a = prev[videoConfig.id]) !== null && _a !== void 0 ? _a : TimelineInOutToggle_1.defaultInOutValue),
491
- outFrame: null,
492
- },
493
- });
494
- });
495
- },
496
- quickSwitcherLabel: null,
497
- subMenu: null,
498
- type: 'item',
499
- value: 'hide-out',
500
- },
501
- ];
502
- }, [setInAndOutFrames, videoConfig.id]);
503
- return (jsx_runtime_1.jsxs("div", { style: style, onPointerDown: onPointerDown, children: [
504
- jsx_runtime_1.jsx("div", { style: inner, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME }), inFrame !== null && (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: inContextMenu, onOpen: null, children: jsx_runtime_1.jsx(TimelineInOutPointerHandle_1.TimelineInOutPointerHandle, { type: "in", atFrame: inFrame, dragging: inOutDragging.dragging === 'in' }) })), outFrame !== null && (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: outContextMenu, onOpen: null, children: jsx_runtime_1.jsx(TimelineInOutPointerHandle_1.TimelineInOutPointerHandle, { type: "out", dragging: inOutDragging.dragging === 'out', atFrame: outFrame }) }))] }));
279
+ }, []);
280
+ return (jsx_runtime_1.jsx("div", { ref: ref, style: style, onPointerDown: onPointerDown, children: jsx_runtime_1.jsx("div", { style: inner, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME }) }));
505
281
  };
506
282
  const TimelineDragHandlerInnerMemo = react_1.default.memo(TimelineDragHandlerInner);
@@ -3,7 +3,7 @@ import type { SequencePropsSubscriptionKey, SequenceSchema } from 'remotion';
3
3
  import type { CodePosition } from '../../error-overlay/react-overlay/utils/get-source-map';
4
4
  import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
5
5
  import type { GetIsExpanded } from '../ExpandedTracksProvider';
6
- export declare const TimelineEffectGroupRow: React.FC<{
6
+ export declare const TimelineEffectItem: React.FC<{
7
7
  readonly label: string;
8
8
  readonly nodePathInfo: SequenceNodePathInfo;
9
9
  readonly effectIndex: number;