@remotion/studio 4.0.492 → 4.0.494

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 (75) hide show
  1. package/dist/ResolveCompositionConfigInStudio.js +16 -6
  2. package/dist/components/Canvas.js +3 -0
  3. package/dist/components/CompositionSelector.js +1 -1
  4. package/dist/components/CompositionSelectorItem.js +1 -1
  5. package/dist/components/CurrentComposition.d.ts +1 -1
  6. package/dist/components/CurrentComposition.js +3 -4
  7. package/dist/components/InitialCompositionLoader.d.ts +1 -1
  8. package/dist/components/InitialCompositionLoader.js +6 -1
  9. package/dist/components/InspectorInfoHeader.d.ts +1 -0
  10. package/dist/components/InspectorInfoHeader.js +7 -2
  11. package/dist/components/InspectorPanel/CompositionDimensions.d.ts +6 -0
  12. package/dist/components/InspectorPanel/CompositionDimensions.js +173 -0
  13. package/dist/components/InspectorPanel/ConnectedCompositionsSection.d.ts +9 -0
  14. package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +32 -0
  15. package/dist/components/InspectorPanel/DefaultInspector.js +6 -3
  16. package/dist/components/InspectorPanel/EasingInspector.js +3 -3
  17. package/dist/components/InspectorPanel/KeyframeInspector.js +6 -4
  18. package/dist/components/InspectorPanel/KeyframeSettings.js +1 -1
  19. package/dist/components/InspectorPanel/SequenceInspectorHeader.d.ts +1 -1
  20. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +9 -6
  21. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +5 -2
  22. package/dist/components/InspectorPanel/common.d.ts +2 -1
  23. package/dist/components/InspectorPanel/common.js +11 -7
  24. package/dist/components/InspectorPanel/optimistic-composition-metadata.d.ts +22 -0
  25. package/dist/components/InspectorPanel/optimistic-composition-metadata.js +41 -0
  26. package/dist/components/InspectorPanel/styles.d.ts +2 -0
  27. package/dist/components/InspectorPanel/styles.js +7 -2
  28. package/dist/components/InspectorSequenceSection.js +2 -5
  29. package/dist/components/SelectedOutlineElement.js +21 -2
  30. package/dist/components/SelectedOutlineOverlay.d.ts +1 -1
  31. package/dist/components/SelectedOutlineOverlay.js +4 -3
  32. package/dist/components/Timeline/Timeline.js +9 -1
  33. package/dist/components/Timeline/TimelineClipboardKeybindings.js +136 -1
  34. package/dist/components/Timeline/TimelineDeleteKeybindings.js +2 -0
  35. package/dist/components/Timeline/TimelineKeyframeControls.js +1 -0
  36. package/dist/components/Timeline/TimelineList.js +2 -1
  37. package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +1 -3
  38. package/dist/components/Timeline/TimelineSelection.js +19 -5
  39. package/dist/components/Timeline/TimelineSequence.d.ts +1 -0
  40. package/dist/components/Timeline/TimelineSequence.js +42 -6
  41. package/dist/components/Timeline/TimelineSequenceItem.d.ts +2 -1
  42. package/dist/components/Timeline/TimelineSequenceItem.js +43 -8
  43. package/dist/components/Timeline/TimelineSequenceName.js +4 -0
  44. package/dist/components/Timeline/TimelineTrack.js +2 -1
  45. package/dist/components/Timeline/call-delete-keyframe.d.ts +1 -0
  46. package/dist/components/Timeline/call-delete-keyframe.js +4 -0
  47. package/dist/components/Timeline/delete-selected-keyframe.d.ts +4 -2
  48. package/dist/components/Timeline/delete-selected-keyframe.js +48 -5
  49. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +3 -1
  50. package/dist/components/Timeline/delete-selected-timeline-item.js +3 -1
  51. package/dist/components/Timeline/keyframe-clipboard.d.ts +34 -0
  52. package/dist/components/Timeline/keyframe-clipboard.js +278 -0
  53. package/dist/components/Timeline/timeline-field-display-utils.js +2 -1
  54. package/dist/components/Timeline/update-selected-easing.d.ts +1 -1
  55. package/dist/components/Timeline/update-selected-easing.js +4 -5
  56. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +3 -4
  57. package/dist/components/import-assets.d.ts +25 -3
  58. package/dist/components/import-assets.js +54 -15
  59. package/dist/components/selected-outline-measurement.d.ts +2 -5
  60. package/dist/components/selected-outline-measurement.js +3 -4
  61. package/dist/esm/{chunk-ewx0568t.js → chunk-tdncqycp.js} +5397 -4402
  62. package/dist/esm/internals.mjs +5397 -4402
  63. package/dist/esm/previewEntry.mjs +5987 -4996
  64. package/dist/esm/renderEntry.mjs +1 -1
  65. package/dist/helpers/calculate-timeline.d.ts +2 -1
  66. package/dist/helpers/calculate-timeline.js +36 -5
  67. package/dist/{components/InspectorPanel/get-compositions-matching-single-child.d.ts → helpers/get-connected-compositions.d.ts} +1 -1
  68. package/dist/{components/InspectorPanel/get-compositions-matching-single-child.js → helpers/get-connected-compositions.js} +3 -3
  69. package/dist/helpers/get-sequence-double-click-action.d.ts +12 -0
  70. package/dist/helpers/get-sequence-double-click-action.js +22 -0
  71. package/dist/helpers/get-timeline-sequence-sort-key.d.ts +2 -1
  72. package/dist/helpers/inject-css.js +0 -2
  73. package/package.json +11 -11
  74. package/dist/components/InspectorPanel/SequenceCompositionsSection.d.ts +0 -5
  75. package/dist/components/InspectorPanel/SequenceCompositionsSection.js +0 -37
@@ -3,6 +3,7 @@ import type { TSequence } from 'remotion';
3
3
  import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
4
4
  export declare const TimelineSequence: React.NamedExoticComponent<{
5
5
  readonly s: TSequence;
6
+ readonly connectedCompositions: readonly import("remotion").AnyComposition[];
6
7
  readonly nodePathInfo: SequenceNodePathInfo | null;
7
8
  readonly sequenceFrameOffset: number;
8
9
  }>;
@@ -40,6 +40,7 @@ const remotion_1 = require("remotion");
40
40
  const client_id_1 = require("../../helpers/client-id");
41
41
  const colors_1 = require("../../helpers/colors");
42
42
  const format_file_location_1 = require("../../helpers/format-file-location");
43
+ const get_sequence_double_click_action_1 = require("../../helpers/get-sequence-double-click-action");
43
44
  const get_timeline_sequence_layout_1 = require("../../helpers/get-timeline-sequence-layout");
44
45
  const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
45
46
  const open_in_editor_1 = require("../../helpers/open-in-editor");
@@ -49,6 +50,7 @@ const AudioWaveform_1 = require("../AudioWaveform");
49
50
  const call_api_1 = require("../call-api");
50
51
  const ConfirmationDialog_1 = require("../ConfirmationDialog");
51
52
  const ContextMenu_1 = require("../ContextMenu");
53
+ const InitialCompositionLoader_1 = require("../InitialCompositionLoader");
52
54
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
53
55
  const use_select_asset_1 = require("../use-select-asset");
54
56
  const disable_sequence_interactivity_1 = require("./disable-sequence-interactivity");
@@ -64,14 +66,14 @@ const TimelineVideoInfo_1 = require("./TimelineVideoInfo");
64
66
  const TimelineWidthProvider_1 = require("./TimelineWidthProvider");
65
67
  const use_resolved_stack_react_to_change_1 = require("./use-resolved-stack-react-to-change");
66
68
  const use_sequence_freeze_frame_menu_item_1 = require("./use-sequence-freeze-frame-menu-item");
67
- const TimelineSequenceFn = ({ s, nodePathInfo, sequenceFrameOffset }) => {
69
+ const TimelineSequenceFn = ({ s, connectedCompositions, nodePathInfo, sequenceFrameOffset }) => {
68
70
  const windowWidth = (0, react_1.useContext)(TimelineWidthProvider_1.TimelineWidthContext);
69
71
  if (windowWidth === null) {
70
72
  return null;
71
73
  }
72
- return (jsx_runtime_1.jsx(TimelineSequenceInner, { windowWidth: windowWidth, s: s, nodePathInfo: nodePathInfo, sequenceFrameOffset: sequenceFrameOffset }));
74
+ return (jsx_runtime_1.jsx(TimelineSequenceInner, { windowWidth: windowWidth, s: s, connectedCompositions: connectedCompositions, nodePathInfo: nodePathInfo, sequenceFrameOffset: sequenceFrameOffset }));
73
75
  };
74
- const TimelineSequenceCurrentFrame = ({ s, displayDurationInFrames, premountWidth, postmountWidth, style, children, nodePathInfo, sequenceFrameOffset, fromCanUpdate, frozenFrame, onMoveDragPointerDown, }) => {
76
+ const TimelineSequenceCurrentFrame = ({ s, displayDurationInFrames, premountWidth, postmountWidth, style, children, nodePathInfo, sequenceFrameOffset, fromCanUpdate, frozenFrame, onMoveDragPointerDown, onDoubleClick, }) => {
75
77
  var _a, _b;
76
78
  const ref = (0, react_1.useRef)(null);
77
79
  const { onSelect, selectable, selected, selectionItem } = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
@@ -114,7 +116,7 @@ const TimelineSequenceCurrentFrame = ({ s, displayDurationInFrames, premountWidt
114
116
  opacity: isInRange ? 1 : 0.5,
115
117
  };
116
118
  }, [isInRange, style]);
117
- return (jsx_runtime_1.jsxs("div", { ref: ref, [TimelineSelection_1.TIMELINE_MARQUEE_ITEM_ATTR]: true, style: actualStyle, title: s.displayName, onPointerDown: selectable ? onPointerDown : undefined, children: [premountWidth ? (jsx_runtime_1.jsx("div", { style: {
119
+ return (jsx_runtime_1.jsxs("div", { ref: ref, [TimelineSelection_1.TIMELINE_MARQUEE_ITEM_ATTR]: true, style: actualStyle, title: s.displayName, onPointerDown: selectable ? onPointerDown : undefined, onDoubleClick: onDoubleClick, children: [premountWidth ? (jsx_runtime_1.jsx("div", { style: {
118
120
  width: premountWidth,
119
121
  height: '100%',
120
122
  background: `repeating-linear-gradient(
@@ -148,7 +150,7 @@ const TimelineSequenceCurrentFrame = ({ s, displayDurationInFrames, premountWidt
148
150
  alignItems: 'center',
149
151
  }, children: jsx_runtime_1.jsx(TimelineSequenceFrame_1.TimelineSequenceFrame, { premounted: isPremounting, postmounted: isPostmounting ? s.duration - 1 : null, roundedFrame: roundedFrame, frozenFrame: frozenFrame }) })) : null] }));
150
152
  };
151
- const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffset }) => {
153
+ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePathInfo, sequenceFrameOffset, }) => {
152
154
  // If a duration is 1, it is essentially a still and it should have width 0
153
155
  // Some compositions may not be longer than their media duration,
154
156
  // if that is the case, it needs to be asynchronously determined
@@ -190,6 +192,7 @@ const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffs
190
192
  const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
191
193
  const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
192
194
  const selectAsset = (0, use_select_asset_1.useSelectAsset)();
195
+ const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
193
196
  const confirm = (0, ConfirmationDialog_1.useConfirmationDialog)();
194
197
  const { onSelect, selectable } = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
195
198
  const fileLocation = (0, react_1.useMemo)(() => (0, format_file_location_1.formatFileLocation)({
@@ -205,6 +208,39 @@ const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffs
205
208
  (0, NotificationCenter_1.showNotification)(err.message, 2000);
206
209
  });
207
210
  }, [canOpenInEditor, originalLocation]);
211
+ const onSequenceDoubleClick = (0, react_1.useCallback)((e) => {
212
+ if ((0, TimelineSelection_1.isTimelineSelectionModifierEvent)(e)) {
213
+ e.stopPropagation();
214
+ return;
215
+ }
216
+ const action = (0, get_sequence_double_click_action_1.getSequenceDoubleClickAction)({
217
+ button: e.button,
218
+ canOpenInEditor,
219
+ numberOfConnectedCompositions: connectedCompositions.length,
220
+ });
221
+ if (action === null) {
222
+ return;
223
+ }
224
+ e.stopPropagation();
225
+ if (action === 'open-connected-composition') {
226
+ selectComposition(connectedCompositions[0], true, (0, get_sequence_double_click_action_1.getConnectedCompositionFrame)({
227
+ timelinePosition,
228
+ sequence: s,
229
+ sequenceFrameOffset,
230
+ }));
231
+ return;
232
+ }
233
+ openInEditor();
234
+ }, [
235
+ canOpenInEditor,
236
+ connectedCompositions,
237
+ openInEditor,
238
+ s,
239
+ selectComposition,
240
+ sequenceFrameOffset,
241
+ timelinePosition,
242
+ ]);
243
+ const canHandleSequenceDoubleClick = connectedCompositions.length === 1 || canOpenInEditor;
208
244
  const canDeleteFromSource = Boolean(nodePath && (validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source));
209
245
  const deleteDisabled = !previewInteractive || !s.controls || !canDeleteFromSource;
210
246
  const duplicateDisabled = deleteDisabled;
@@ -408,7 +444,7 @@ const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffs
408
444
  if (maxMediaDuration === null && !s.loopDisplay) {
409
445
  return null;
410
446
  }
411
- const sequence = (jsx_runtime_1.jsxs(TimelineSequenceCurrentFrame, { s: s, displayDurationInFrames: displayDurationInFrames, premountWidth: premountWidth, postmountWidth: postmountWidth, style: style, nodePathInfo: nodePathInfo, sequenceFrameOffset: sequenceFrameOffset, fromCanUpdate: fromCanUpdate, frozenFrame: frozenFrame, onMoveDragPointerDown: onMoveDragPointerDown, children: [s.type === 'audio' ? (jsx_runtime_1.jsx(AudioWaveform_1.AudioWaveform, { src: s.src, height: timeline_layout_1.TIMELINE_LAYER_HEIGHT_AUDIO, doesVolumeChange: s.doesVolumeChange, visualizationWidth: width, startFrom: s.startMediaFrom, durationInFrames: s.duration, volume: s.volume, playbackRate: s.playbackRate, loopDisplay: s.loopDisplay })) : null, s.type === 'video' ? (jsx_runtime_1.jsx(TimelineVideoInfo_1.TimelineVideoInfo, { src: s.src, visualizationWidth: width, naturalWidth: naturalWidth, startMediaFrom: s.startMediaFrom, mediaFrameAtSequenceZero: s.mediaFrameAtSequenceZero, sequenceFrameOffset: sequenceFrameOffset, durationInFrames: s.duration, playbackRate: s.playbackRate, volume: s.volume, doesVolumeChange: s.doesVolumeChange, premountWidth: premountWidth !== null && premountWidth !== void 0 ? premountWidth : 0, postmountWidth: postmountWidth !== null && postmountWidth !== void 0 ? postmountWidth : 0, loopDisplay: s.loopDisplay, frozenMediaFrame: s.frozenMediaFrame })) : null, s.type === 'image' ? (jsx_runtime_1.jsx(TimelineImageInfo_1.TimelineImageInfo, { src: s.src, visualizationWidth: width })) : null, s.loopDisplay === undefined ? null : (jsx_runtime_1.jsx(LoopedTimelineIndicators_1.LoopedTimelineIndicator, { loops: s.loopDisplay.numberOfTimes })), showLeftEdgeDragHandle && nodePathInfo && validatedLocation ? (jsx_runtime_1.jsx(TimelineSequenceRightEdgeDragHandle_1.TimelineSequenceLeftEdgeDragHandle, { nodePathInfo: nodePathInfo, windowWidth: windowWidth, timelineDurationInFrames: (_h = video.durationInFrames) !== null && _h !== void 0 ? _h : 1 })) : null, showRightEdgeDragHandle && nodePathInfo && validatedLocation ? (jsx_runtime_1.jsx(TimelineSequenceRightEdgeDragHandle_1.TimelineSequenceRightEdgeDragHandle, { nodePathInfo: nodePathInfo, windowWidth: windowWidth, timelineDurationInFrames: (_j = video.durationInFrames) !== null && _j !== void 0 ? _j : 1 })) : null] }));
447
+ const sequence = (jsx_runtime_1.jsxs(TimelineSequenceCurrentFrame, { s: s, displayDurationInFrames: displayDurationInFrames, premountWidth: premountWidth, postmountWidth: postmountWidth, style: style, nodePathInfo: nodePathInfo, sequenceFrameOffset: sequenceFrameOffset, fromCanUpdate: fromCanUpdate, frozenFrame: frozenFrame, onMoveDragPointerDown: onMoveDragPointerDown, onDoubleClick: canHandleSequenceDoubleClick ? onSequenceDoubleClick : undefined, children: [s.type === 'audio' ? (jsx_runtime_1.jsx(AudioWaveform_1.AudioWaveform, { src: s.src, height: timeline_layout_1.TIMELINE_LAYER_HEIGHT_AUDIO, doesVolumeChange: s.doesVolumeChange, visualizationWidth: width, startFrom: s.startMediaFrom, durationInFrames: s.duration, volume: s.volume, playbackRate: s.playbackRate, loopDisplay: s.loopDisplay })) : null, s.type === 'video' ? (jsx_runtime_1.jsx(TimelineVideoInfo_1.TimelineVideoInfo, { src: s.src, visualizationWidth: width, naturalWidth: naturalWidth, startMediaFrom: s.startMediaFrom, mediaFrameAtSequenceZero: s.mediaFrameAtSequenceZero, sequenceFrameOffset: sequenceFrameOffset, durationInFrames: s.duration, playbackRate: s.playbackRate, volume: s.volume, doesVolumeChange: s.doesVolumeChange, premountWidth: premountWidth !== null && premountWidth !== void 0 ? premountWidth : 0, postmountWidth: postmountWidth !== null && postmountWidth !== void 0 ? postmountWidth : 0, loopDisplay: s.loopDisplay, frozenMediaFrame: s.frozenMediaFrame })) : null, s.type === 'image' ? (jsx_runtime_1.jsx(TimelineImageInfo_1.TimelineImageInfo, { src: s.src, visualizationWidth: width })) : null, s.loopDisplay === undefined ? null : (jsx_runtime_1.jsx(LoopedTimelineIndicators_1.LoopedTimelineIndicator, { loops: s.loopDisplay.numberOfTimes })), showLeftEdgeDragHandle && nodePathInfo && validatedLocation ? (jsx_runtime_1.jsx(TimelineSequenceRightEdgeDragHandle_1.TimelineSequenceLeftEdgeDragHandle, { nodePathInfo: nodePathInfo, windowWidth: windowWidth, timelineDurationInFrames: (_h = video.durationInFrames) !== null && _h !== void 0 ? _h : 1 })) : null, showRightEdgeDragHandle && nodePathInfo && validatedLocation ? (jsx_runtime_1.jsx(TimelineSequenceRightEdgeDragHandle_1.TimelineSequenceRightEdgeDragHandle, { nodePathInfo: nodePathInfo, windowWidth: windowWidth, timelineDurationInFrames: (_j = video.durationInFrames) !== null && _j !== void 0 ? _j : 1 })) : null] }));
412
448
  return previewConnected ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, onOpen: onContextMenuOpen, children: sequence })) : (sequence);
413
449
  };
414
450
  exports.TimelineSequence = react_1.default.memo(TimelineSequenceFn);
@@ -1,8 +1,9 @@
1
1
  import React from 'react';
2
- import type { TSequence } from 'remotion';
2
+ import type { _InternalTypes, TSequence } from 'remotion';
3
3
  import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
4
4
  export declare const TimelineSequenceItem: React.FC<{
5
5
  readonly sequence: TSequence;
6
+ readonly connectedCompositions: readonly _InternalTypes['AnyComposition'][];
6
7
  readonly nestedDepth: number;
7
8
  readonly nodePathInfo: SequenceNodePathInfo | null;
8
9
  readonly keyframeDisplayOffset: number;
@@ -40,16 +40,19 @@ const remotion_1 = require("remotion");
40
40
  const client_id_1 = require("../../helpers/client-id");
41
41
  const colors_1 = require("../../helpers/colors");
42
42
  const format_file_location_1 = require("../../helpers/format-file-location");
43
+ const get_sequence_double_click_action_1 = require("../../helpers/get-sequence-double-click-action");
43
44
  const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
44
45
  const studio_runtime_config_1 = require("../../helpers/studio-runtime-config");
45
46
  const timeline_layout_1 = require("../../helpers/timeline-layout");
46
47
  const use_keybinding_1 = require("../../helpers/use-keybinding");
47
48
  const modals_1 = require("../../state/modals");
48
49
  const call_api_1 = require("../call-api");
50
+ const CompositionOrStillIcon_1 = require("../CompositionOrStillIcon");
49
51
  const ConfirmationDialog_1 = require("../ConfirmationDialog");
50
52
  const ContextMenu_1 = require("../ContextMenu");
51
53
  const effect_drag_and_drop_1 = require("../effect-drag-and-drop");
52
54
  const ExpandedTracksProvider_1 = require("../ExpandedTracksProvider");
55
+ const InitialCompositionLoader_1 = require("../InitialCompositionLoader");
53
56
  const layout_1 = require("../layout");
54
57
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
55
58
  const use_select_asset_1 = require("../use-select-asset");
@@ -76,6 +79,11 @@ const labelContainerStyle = {
76
79
  flexDirection: 'row',
77
80
  minWidth: 0,
78
81
  };
82
+ const connectedCompositionIconStyle = {
83
+ flexShrink: 0,
84
+ height: 12,
85
+ width: 12,
86
+ };
79
87
  const effectDropHighlight = {
80
88
  backgroundColor: colors_1.TIMELINE_DROP_BLUE_ALPHA_16,
81
89
  outline: colors_1.BORDER_TIMELINE_DROP_BLUE,
@@ -155,7 +163,7 @@ const getSequenceReorderDragData = (dataTransfer) => {
155
163
  const getDestinationIndex = ({ fromIndex, insertionIndex, }) => {
156
164
  return insertionIndex > fromIndex ? insertionIndex - 1 : insertionIndex;
157
165
  };
158
- const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDisplayOffset, sequenceFrameOffset, trackIndex, }) => {
166
+ const TimelineSequenceItem = ({ connectedCompositions, nestedDepth, sequence, nodePathInfo, keyframeDisplayOffset, sequenceFrameOffset, trackIndex, }) => {
159
167
  var _a, _b, _c;
160
168
  var _d, _e, _f;
161
169
  const nodePath = (_d = nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.sequenceSubscriptionKey) !== null && _d !== void 0 ? _d : null;
@@ -168,6 +176,7 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
168
176
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
169
177
  const { isHighestContext } = (0, use_keybinding_1.useKeybinding)();
170
178
  const selectAsset = (0, use_select_asset_1.useSelectAsset)();
179
+ const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
171
180
  const { onSelect, selectable, selected, selectionItem } = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
172
181
  const { selectedItems } = (0, TimelineSelection_1.useTimelineSelection)();
173
182
  const containsSelection = (0, TimelineSelection_1.useTimelineRowContainsSelection)(nodePathInfo);
@@ -202,6 +211,9 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
202
211
  sequence,
203
212
  validatedLocation,
204
213
  });
214
+ const timelineDisplayName = sequence.displayName === '' && connectedCompositions.length === 1
215
+ ? connectedCompositions[0].id
216
+ : displayName;
205
217
  const canDeleteFromSource = Boolean(nodePath && (validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source));
206
218
  const nodePathKey = (0, react_1.useMemo)(() => nodePath ? remotion_1.Internals.makeSequencePropsSubscriptionKey(nodePath) : null, [nodePath]);
207
219
  const parentId = (_e = sequence.parent) !== null && _e !== void 0 ? _e : null;
@@ -536,17 +548,39 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
536
548
  codeHiddenStatus !== undefined &&
537
549
  codeHiddenStatus !== null &&
538
550
  codeHiddenStatus.status === 'static';
539
- const onShowInEditorDoubleClick = (0, react_1.useCallback)((e) => {
540
- if (!canOpenInEditor) {
541
- return;
542
- }
551
+ const onSequenceDoubleClick = (0, react_1.useCallback)((e) => {
543
552
  if ((0, TimelineSelection_1.isTimelineSelectionModifierEvent)(e)) {
544
553
  e.stopPropagation();
545
554
  return;
546
555
  }
556
+ const action = (0, get_sequence_double_click_action_1.getSequenceDoubleClickAction)({
557
+ button: e.button,
558
+ canOpenInEditor,
559
+ numberOfConnectedCompositions: connectedCompositions.length,
560
+ });
561
+ if (action === null) {
562
+ return;
563
+ }
547
564
  e.stopPropagation();
565
+ if (action === 'open-connected-composition') {
566
+ selectComposition(connectedCompositions[0], true, (0, get_sequence_double_click_action_1.getConnectedCompositionFrame)({
567
+ timelinePosition,
568
+ sequence,
569
+ sequenceFrameOffset,
570
+ }));
571
+ return;
572
+ }
548
573
  openInEditor();
549
- }, [canOpenInEditor, openInEditor]);
574
+ }, [
575
+ canOpenInEditor,
576
+ connectedCompositions,
577
+ openInEditor,
578
+ selectComposition,
579
+ sequence,
580
+ sequenceFrameOffset,
581
+ timelinePosition,
582
+ ]);
583
+ const canHandleSequenceDoubleClick = connectedCompositions.length === 1 || canOpenInEditor;
550
584
  const canRenameSelectedSequence = canRenameThisSequence &&
551
585
  selected &&
552
586
  selectedItems.length === 1 &&
@@ -766,8 +800,9 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
766
800
  clientId: previewServerState.clientId,
767
801
  });
768
802
  }, [canDropEffect, nodePath, previewServerState, validatedLocation]);
769
- const trackRow = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: nestedDepth, eye: canToggleVisibility ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: sequence.type === 'audio' ? 'speaker' : 'eye', hidden: isItemHidden, onInvoked: onToggleVisibility })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: hasExpandableContent && nodePathInfo !== null ? (jsx_runtime_1.jsx(TimelineSequenceExpandArrow, { disabled: !previewInteractive, isExpanded: isExpanded, nodePathInfo: nodePathInfo, onToggleExpand: onToggleExpand, sequence: sequence })) : (jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {})), style: rowStyle, selected: selected, selectable: selectable, selectionItem: selectionItem, onSelect: onSelect, showSelectedBackground: true, containsSelection: containsSelection, outerHeight: outerHeight, onDragLeave: canDropEffect ? onEffectDragLeave : undefined, onDragOver: canDropEffect ? onEffectDragOver : undefined, onDrop: canDropEffect ? onEffectDrop : undefined, onDoubleClick: canOpenInEditor ? onShowInEditorDoubleClick : undefined, children: jsx_runtime_1.jsxs("div", { style: labelContainerStyle, children: [
770
- jsx_runtime_1.jsx(TimelineSequenceName_1.TimelineSequenceName, { displayName: displayName, fallbackDisplayName: fallbackDisplayName, selected: selected, containsSelection: containsSelection, editing: isRenaming, onCancelEditing: onCancelRenaming, onSaveName: onSaveName }), mediaSrc ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
803
+ const trackRow = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: nestedDepth, eye: canToggleVisibility ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: sequence.type === 'audio' ? 'speaker' : 'eye', hidden: isItemHidden, onInvoked: onToggleVisibility })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: hasExpandableContent && nodePathInfo !== null ? (jsx_runtime_1.jsx(TimelineSequenceExpandArrow, { disabled: !previewInteractive, isExpanded: isExpanded, nodePathInfo: nodePathInfo, onToggleExpand: onToggleExpand, sequence: sequence })) : (jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {})), style: rowStyle, selected: selected, selectable: selectable, selectionItem: selectionItem, onSelect: onSelect, showSelectedBackground: true, containsSelection: containsSelection, outerHeight: outerHeight, onDragLeave: canDropEffect ? onEffectDragLeave : undefined, onDragOver: canDropEffect ? onEffectDragOver : undefined, onDrop: canDropEffect ? onEffectDrop : undefined, onDoubleClick: canHandleSequenceDoubleClick ? onSequenceDoubleClick : undefined, children: jsx_runtime_1.jsxs("div", { style: labelContainerStyle, children: [connectedCompositions.length > 0 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
804
+ jsx_runtime_1.jsx(CompositionOrStillIcon_1.CompositionOrStillIcon, { color: (0, TimelineSelection_1.getTimelineColor)(false, false), composition: connectedCompositions[0], style: connectedCompositionIconStyle }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 })
805
+ ] })) : null, jsx_runtime_1.jsx(TimelineSequenceName_1.TimelineSequenceName, { displayName: timelineDisplayName, fallbackDisplayName: fallbackDisplayName, selected: selected, containsSelection: containsSelection, editing: isRenaming, onCancelEditing: onCancelRenaming, onSaveName: onSaveName }), mediaSrc ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
771
806
  jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }),
772
807
  " ",
773
808
  jsx_runtime_1.jsx(TimelineMediaInfo_1.TimelineMediaInfo, { src: mediaSrc })
@@ -24,7 +24,11 @@ const TimelineSequenceName = ({ displayName, fallbackDisplayName, selected, cont
24
24
  alignSelf: 'stretch',
25
25
  ...(0, TimelineSelection_1.getTimelineSelectedLabelStyle)(selected, false),
26
26
  display: 'inline-flex',
27
+ fontFamily: 'inherit',
27
28
  fontSize: 12,
29
+ lineHeight: 'normal',
30
+ minWidth: 0,
31
+ overflow: 'hidden',
28
32
  whiteSpace: 'nowrap',
29
33
  textOverflow: 'ellipsis',
30
34
  color: (0, TimelineSelection_1.getTimelineColor)(selected, false),
@@ -44,6 +44,7 @@ const TimelineSelection_1 = require("./TimelineSelection");
44
44
  const TimelineSequence_1 = require("./TimelineSequence");
45
45
  const TimelineWidthProvider_1 = require("./TimelineWidthProvider");
46
46
  const TimelineTrackUnmemoized = ({ track }) => {
47
+ var _a;
47
48
  const { getIsExpanded } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksGetterContext);
48
49
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
49
50
  const previewServerConnected = previewServerState.type === 'connected';
@@ -58,7 +59,7 @@ const TimelineTrackUnmemoized = ({ track }) => {
58
59
  previewServerConnected &&
59
60
  getIsExpanded(track.nodePathInfo);
60
61
  return (jsx_runtime_1.jsxs("div", { children: [
61
- jsx_runtime_1.jsxs("div", { style: layerStyle, children: [rowHighlightBackground && timelineWidth !== null ? (jsx_runtime_1.jsx("div", { style: (0, TimelineSelection_1.getTimelineSelectedTrackHighlightStyle)(timelineWidth, rowHighlightBackground) })) : null, jsx_runtime_1.jsx(TimelineSequence_1.TimelineSequence, { s: track.sequence, nodePathInfo: track.nodePathInfo, sequenceFrameOffset: track.sequenceFrameOffset })
62
+ jsx_runtime_1.jsxs("div", { style: layerStyle, children: [rowHighlightBackground && timelineWidth !== null ? (jsx_runtime_1.jsx("div", { style: (0, TimelineSelection_1.getTimelineSelectedTrackHighlightStyle)(timelineWidth, rowHighlightBackground) })) : null, jsx_runtime_1.jsx(TimelineSequence_1.TimelineSequence, { s: track.sequence, connectedCompositions: (_a = track.connectedCompositions) !== null && _a !== void 0 ? _a : [], nodePathInfo: track.nodePathInfo, sequenceFrameOffset: track.sequenceFrameOffset })
62
63
  ] }), showExpandedKeyframes && track.nodePathInfo ? (jsx_runtime_1.jsx(TimelineExpandedTrackKeyframes_1.TimelineExpandedTrackKeyframes, { sequence: track.sequence, nodePathInfo: track.nodePathInfo, keyframeDisplayOffset: track.keyframeDisplayOffset })) : null] }));
63
64
  };
64
65
  exports.TimelineTrack = react_1.default.memo(TimelineTrackUnmemoized);
@@ -6,6 +6,7 @@ export type DeleteSequenceKeyframeChange = {
6
6
  fieldKey: string;
7
7
  sourceFrame: number;
8
8
  schema: InteractivitySchema;
9
+ valueWhenLastKeyframeDeleted: unknown | null;
9
10
  };
10
11
  export type DeleteEffectKeyframeChange = DeleteSequenceKeyframeChange & {
11
12
  effectIndex: number;
@@ -83,6 +83,7 @@ const callDeleteKeyframes = ({ sequenceKeyframes, effectKeyframes, setPropStatus
83
83
  keyframes: keyframes.map((keyframe) => ({
84
84
  fieldKey: keyframe.fieldKey,
85
85
  frame: keyframe.sourceFrame,
86
+ valueWhenLastKeyframeDeleted: keyframe.valueWhenLastKeyframeDeleted,
86
87
  })),
87
88
  }));
88
89
  }
@@ -97,6 +98,7 @@ const callDeleteKeyframes = ({ sequenceKeyframes, effectKeyframes, setPropStatus
97
98
  effectIndex: keyframe.effectIndex,
98
99
  fieldKey: keyframe.fieldKey,
99
100
  frame: keyframe.sourceFrame,
101
+ valueWhenLastKeyframeDeleted: keyframe.valueWhenLastKeyframeDeleted,
100
102
  })),
101
103
  }));
102
104
  }
@@ -107,6 +109,7 @@ const callDeleteKeyframes = ({ sequenceKeyframes, effectKeyframes, setPropStatus
107
109
  key: keyframe.fieldKey,
108
110
  frame: keyframe.sourceFrame,
109
111
  schema: keyframe.schema,
112
+ valueWhenLastKeyframeDeleted: keyframe.valueWhenLastKeyframeDeleted,
110
113
  })),
111
114
  effectKeyframes: effectKeyframes.map((keyframe) => ({
112
115
  fileName: keyframe.fileName,
@@ -115,6 +118,7 @@ const callDeleteKeyframes = ({ sequenceKeyframes, effectKeyframes, setPropStatus
115
118
  key: keyframe.fieldKey,
116
119
  frame: keyframe.sourceFrame,
117
120
  schema: keyframe.schema,
121
+ valueWhenLastKeyframeDeleted: keyframe.valueWhenLastKeyframeDeleted,
118
122
  })),
119
123
  clientId,
120
124
  }).then(() => undefined);
@@ -1,4 +1,4 @@
1
- import type { OverrideIdToNodePaths, TSequence } from 'remotion';
1
+ import type { OverrideIdToNodePaths, PropStatuses, TSequence } from 'remotion';
2
2
  import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
3
3
  import type { SetPropStatuses } from './save-sequence-prop';
4
4
  export declare const deleteSelectedKeyframe: ({ nodePathInfo, frame, sequences, overrideIdsToNodePaths, setPropStatuses, clientId, }: {
@@ -9,7 +9,7 @@ export declare const deleteSelectedKeyframe: ({ nodePathInfo, frame, sequences,
9
9
  setPropStatuses: SetPropStatuses;
10
10
  clientId: string;
11
11
  }) => Promise<void> | null;
12
- export declare const deleteSelectedKeyframes: ({ keyframes, sequences, overrideIdsToNodePaths, setPropStatuses, clientId, }: {
12
+ export declare const deleteSelectedKeyframes: ({ keyframes, sequences, overrideIdsToNodePaths, setPropStatuses, clientId, propStatuses, timelinePosition, }: {
13
13
  keyframes: {
14
14
  nodePathInfo: SequenceNodePathInfo;
15
15
  frame: number;
@@ -18,4 +18,6 @@ export declare const deleteSelectedKeyframes: ({ keyframes, sequences, overrideI
18
18
  overrideIdsToNodePaths: OverrideIdToNodePaths;
19
19
  setPropStatuses: SetPropStatuses;
20
20
  clientId: string;
21
+ propStatuses: PropStatuses;
22
+ timelinePosition: number;
21
23
  }) => Promise<void> | null;
@@ -1,11 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.deleteSelectedKeyframes = exports.deleteSelectedKeyframe = void 0;
4
+ const remotion_1 = require("remotion");
4
5
  const call_delete_keyframe_1 = require("./call-delete-keyframe");
5
6
  const find_track_for_node_path_info_1 = require("./find-track-for-node-path-info");
6
7
  const parse_keyframe_field_from_node_path_1 = require("./parse-keyframe-field-from-node-path");
7
- const getSelectedKeyframeDeletion = ({ nodePathInfo, frame, sequences, overrideIdsToNodePaths, }) => {
8
- var _a, _b;
8
+ const getValueWhenLastKeyframeDeleted = ({ propStatus, playheadSourceFrame, }) => {
9
+ var _a;
10
+ if ((propStatus === null || propStatus === void 0 ? void 0 : propStatus.status) !== 'keyframed' || playheadSourceFrame === null) {
11
+ return null;
12
+ }
13
+ return ((_a = remotion_1.Internals.interpolateKeyframedStatus({
14
+ forceSpringAllowTail: null,
15
+ frame: playheadSourceFrame,
16
+ status: propStatus,
17
+ })) !== null && _a !== void 0 ? _a : null);
18
+ };
19
+ const getSelectedKeyframeDeletion = ({ nodePathInfo, frame, sequences, overrideIdsToNodePaths, propStatuses, timelinePosition, }) => {
20
+ var _a;
21
+ var _b, _c, _d;
9
22
  const field = (0, parse_keyframe_field_from_node_path_1.parseKeyframeFieldFromNodePath)(nodePathInfo.auxiliaryKeys);
10
23
  if (field === null) {
11
24
  return null;
@@ -15,11 +28,14 @@ const getSelectedKeyframeDeletion = ({ nodePathInfo, frame, sequences, overrideI
15
28
  overrideIdsToNodePaths,
16
29
  nodePathInfo,
17
30
  });
18
- const sequence = (_a = track === null || track === void 0 ? void 0 : track.sequence) !== null && _a !== void 0 ? _a : null;
31
+ const sequence = (_b = track === null || track === void 0 ? void 0 : track.sequence) !== null && _b !== void 0 ? _b : null;
19
32
  if (!(sequence === null || sequence === void 0 ? void 0 : sequence.controls)) {
20
33
  return null;
21
34
  }
22
- const sourceFrame = frame - ((_b = track === null || track === void 0 ? void 0 : track.keyframeDisplayOffset) !== null && _b !== void 0 ? _b : 0);
35
+ const sourceFrame = frame - ((_c = track === null || track === void 0 ? void 0 : track.keyframeDisplayOffset) !== null && _c !== void 0 ? _c : 0);
36
+ const playheadSourceFrame = timelinePosition === null
37
+ ? null
38
+ : timelinePosition - ((_d = track === null || track === void 0 ? void 0 : track.keyframeDisplayOffset) !== null && _d !== void 0 ? _d : 0);
23
39
  const nodePath = nodePathInfo.sequenceSubscriptionKey;
24
40
  const fileName = nodePath.absolutePath;
25
41
  if (field.type === 'effect') {
@@ -27,6 +43,20 @@ const getSelectedKeyframeDeletion = ({ nodePathInfo, frame, sequences, overrideI
27
43
  if (!effect) {
28
44
  return null;
29
45
  }
46
+ const effectStatus = propStatuses !== null
47
+ ? remotion_1.Internals.getEffectPropStatusesCtx({
48
+ propStatuses,
49
+ nodePath,
50
+ effectIndex: field.effectIndex,
51
+ })
52
+ : null;
53
+ const effectPropStatus = (effectStatus === null || effectStatus === void 0 ? void 0 : effectStatus.type) === 'can-update-effect'
54
+ ? effectStatus.props[field.fieldKey]
55
+ : null;
56
+ const effectValueWhenLastKeyframeDeleted = getValueWhenLastKeyframeDeleted({
57
+ propStatus: effectPropStatus,
58
+ playheadSourceFrame,
59
+ });
30
60
  return {
31
61
  type: 'effect',
32
62
  fileName,
@@ -35,8 +65,16 @@ const getSelectedKeyframeDeletion = ({ nodePathInfo, frame, sequences, overrideI
35
65
  fieldKey: field.fieldKey,
36
66
  sourceFrame,
37
67
  schema: effect.schema,
68
+ valueWhenLastKeyframeDeleted: effectValueWhenLastKeyframeDeleted,
38
69
  };
39
70
  }
71
+ const sequencePropStatus = propStatuses !== null
72
+ ? (_a = remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePath)) === null || _a === void 0 ? void 0 : _a[field.fieldKey]
73
+ : null;
74
+ const sequenceValueWhenLastKeyframeDeleted = getValueWhenLastKeyframeDeleted({
75
+ propStatus: sequencePropStatus,
76
+ playheadSourceFrame,
77
+ });
40
78
  return {
41
79
  type: 'sequence',
42
80
  fileName,
@@ -44,6 +82,7 @@ const getSelectedKeyframeDeletion = ({ nodePathInfo, frame, sequences, overrideI
44
82
  fieldKey: field.fieldKey,
45
83
  sourceFrame,
46
84
  schema: sequence.controls.schema,
85
+ valueWhenLastKeyframeDeleted: sequenceValueWhenLastKeyframeDeleted,
47
86
  };
48
87
  };
49
88
  const deleteSelectedKeyframe = ({ nodePathInfo, frame, sequences, overrideIdsToNodePaths, setPropStatuses, clientId, }) => {
@@ -52,6 +91,8 @@ const deleteSelectedKeyframe = ({ nodePathInfo, frame, sequences, overrideIdsToN
52
91
  frame,
53
92
  sequences,
54
93
  overrideIdsToNodePaths,
94
+ propStatuses: null,
95
+ timelinePosition: null,
55
96
  });
56
97
  if (deletion === null) {
57
98
  return null;
@@ -70,13 +111,15 @@ const deleteSelectedKeyframe = ({ nodePathInfo, frame, sequences, overrideIdsToN
70
111
  });
71
112
  };
72
113
  exports.deleteSelectedKeyframe = deleteSelectedKeyframe;
73
- const deleteSelectedKeyframes = ({ keyframes, sequences, overrideIdsToNodePaths, setPropStatuses, clientId, }) => {
114
+ const deleteSelectedKeyframes = ({ keyframes, sequences, overrideIdsToNodePaths, setPropStatuses, clientId, propStatuses, timelinePosition, }) => {
74
115
  const deletions = keyframes
75
116
  .map((keyframe) => getSelectedKeyframeDeletion({
76
117
  nodePathInfo: keyframe.nodePathInfo,
77
118
  frame: keyframe.frame,
78
119
  sequences,
79
120
  overrideIdsToNodePaths,
121
+ propStatuses,
122
+ timelinePosition,
80
123
  }))
81
124
  .filter((deletion) => deletion !== null);
82
125
  if (deletions.length === 0) {
@@ -17,11 +17,13 @@ export declare const getTimelineSelectionAfterDeletingItems: ({ selections, sequ
17
17
  readonly propStatuses?: PropStatuses | undefined;
18
18
  readonly timelinePosition?: number | undefined;
19
19
  }) => readonly TimelineSelection[];
20
- export declare const deleteSelectedTimelineItems: ({ selections, sequences, overrideIdsToNodePaths, setPropStatuses, clientId, confirm, }: {
20
+ export declare const deleteSelectedTimelineItems: ({ selections, sequences, overrideIdsToNodePaths, setPropStatuses, clientId, confirm, propStatuses, timelinePosition, }: {
21
21
  selections: readonly TimelineSelection[];
22
22
  sequences: TSequence[];
23
23
  overrideIdsToNodePaths: OverrideIdToNodePaths;
24
24
  setPropStatuses: SetPropStatuses;
25
25
  clientId: string;
26
26
  confirm: ConfirmationDialogFunction;
27
+ propStatuses: PropStatuses;
28
+ timelinePosition: number;
27
29
  }) => Promise<boolean> | null;
@@ -253,7 +253,7 @@ const assertTimelineSelectionsHaveSameType = (selections) => {
253
253
  }
254
254
  };
255
255
  const containsOnlyKeyframesAndEasings = (selections) => selections.every((selection) => selection.type === 'keyframe' || selection.type === 'easing');
256
- const deleteSelectedTimelineItems = ({ selections, sequences, overrideIdsToNodePaths, setPropStatuses, clientId, confirm, }) => {
256
+ const deleteSelectedTimelineItems = ({ selections, sequences, overrideIdsToNodePaths, setPropStatuses, clientId, confirm, propStatuses, timelinePosition, }) => {
257
257
  var _a;
258
258
  const firstSelection = selections[0];
259
259
  if (!firstSelection) {
@@ -273,6 +273,8 @@ const deleteSelectedTimelineItems = ({ selections, sequences, overrideIdsToNodeP
273
273
  overrideIdsToNodePaths,
274
274
  setPropStatuses,
275
275
  clientId,
276
+ propStatuses,
277
+ timelinePosition,
276
278
  });
277
279
  return (_a = promise === null || promise === void 0 ? void 0 : promise.then(() => true)) !== null && _a !== void 0 ? _a : null;
278
280
  }
@@ -0,0 +1,34 @@
1
+ import type { KeyframeClipboardData } from '@remotion/studio-shared';
2
+ import { type InteractivitySchema, type OverrideIdToNodePaths, type PropStatuses, type SequencePropsSubscriptionKey, type TSequence } from 'remotion';
3
+ import type { TimelineSelection } from './TimelineSelection';
4
+ export declare const getKeyframeClipboardDataFromSelections: ({ selections, sequences, overrideIdsToNodePaths, propStatuses, }: {
5
+ readonly selections: readonly TimelineSelection[];
6
+ readonly sequences: TSequence[];
7
+ readonly overrideIdsToNodePaths: OverrideIdToNodePaths;
8
+ readonly propStatuses: PropStatuses;
9
+ }) => KeyframeClipboardData | null;
10
+ export type PasteKeyframeTarget = {
11
+ readonly type: 'valid';
12
+ readonly fileName: string;
13
+ readonly nodePath: SequencePropsSubscriptionKey;
14
+ readonly fieldKey: string;
15
+ readonly effectIndex: number | null;
16
+ readonly keyframes: readonly {
17
+ readonly sourceFrame: number;
18
+ readonly value: unknown;
19
+ }[];
20
+ readonly keyframesToDelete: readonly number[];
21
+ readonly easing: KeyframeClipboardData['easing'];
22
+ readonly firstEasingSegmentIndex: number;
23
+ readonly schema: InteractivitySchema;
24
+ } | {
25
+ readonly type: 'none' | 'multiple' | 'uncopyable' | 'incompatible';
26
+ };
27
+ export declare const getPasteKeyframeTarget: ({ selectedItems, payload, timelinePosition, sequences, overrideIdsToNodePaths, propStatuses, }: {
28
+ readonly selectedItems: readonly TimelineSelection[];
29
+ readonly payload: KeyframeClipboardData;
30
+ readonly timelinePosition: number;
31
+ readonly sequences: TSequence[];
32
+ readonly overrideIdsToNodePaths: OverrideIdToNodePaths;
33
+ readonly propStatuses: PropStatuses;
34
+ }) => PasteKeyframeTarget;