@remotion/studio 4.0.493 → 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 (27) hide show
  1. package/dist/components/Canvas.js +3 -0
  2. package/dist/components/InitialCompositionLoader.d.ts +1 -1
  3. package/dist/components/InitialCompositionLoader.js +6 -1
  4. package/dist/components/Timeline/Timeline.js +1 -0
  5. package/dist/components/Timeline/TimelineClipboardKeybindings.js +3 -0
  6. package/dist/components/Timeline/TimelineDeleteKeybindings.js +2 -0
  7. package/dist/components/Timeline/TimelineKeyframeControls.js +1 -0
  8. package/dist/components/Timeline/TimelineSequence.d.ts +1 -0
  9. package/dist/components/Timeline/TimelineSequence.js +42 -6
  10. package/dist/components/Timeline/TimelineSequenceItem.js +14 -2
  11. package/dist/components/Timeline/TimelineTrack.js +2 -1
  12. package/dist/components/Timeline/call-delete-keyframe.d.ts +1 -0
  13. package/dist/components/Timeline/call-delete-keyframe.js +4 -0
  14. package/dist/components/Timeline/delete-selected-keyframe.d.ts +4 -2
  15. package/dist/components/Timeline/delete-selected-keyframe.js +48 -5
  16. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +3 -1
  17. package/dist/components/Timeline/delete-selected-timeline-item.js +3 -1
  18. package/dist/components/import-assets.d.ts +25 -3
  19. package/dist/components/import-assets.js +54 -15
  20. package/dist/esm/{chunk-mndqr3zx.js → chunk-tdncqycp.js} +702 -529
  21. package/dist/esm/internals.mjs +702 -529
  22. package/dist/esm/previewEntry.mjs +701 -528
  23. package/dist/esm/renderEntry.mjs +1 -1
  24. package/dist/helpers/get-sequence-double-click-action.d.ts +6 -0
  25. package/dist/helpers/get-sequence-double-click-action.js +10 -1
  26. package/dist/helpers/inject-css.js +0 -2
  27. package/package.json +11 -11
@@ -805,6 +805,7 @@ const Canvas = ({ canvasContent, size }) => {
805
805
  files,
806
806
  compositionFile,
807
807
  compositionId: currentCompositionId,
808
+ destinationDimensions: contentDimensions === 'none' ? null : contentDimensions,
808
809
  dropPosition,
809
810
  });
810
811
  }
@@ -817,6 +818,7 @@ const Canvas = ({ canvasContent, size }) => {
817
818
  assetPaths: [assetPath],
818
819
  compositionFile,
819
820
  compositionId: currentCompositionId,
821
+ destinationDimensions: contentDimensions === 'none' ? null : contentDimensions,
820
822
  dropPosition,
821
823
  });
822
824
  }
@@ -873,6 +875,7 @@ const Canvas = ({ canvasContent, size }) => {
873
875
  url,
874
876
  compositionFile,
875
877
  compositionId: currentCompositionId,
878
+ destinationDimensions: contentDimensions === 'none' ? null : contentDimensions,
876
879
  dropPosition,
877
880
  });
878
881
  }
@@ -1,3 +1,3 @@
1
1
  import type React from 'react';
2
- export declare const useSelectComposition: () => (c: import("remotion").AnyComposition, push: boolean) => void;
2
+ export declare const useSelectComposition: () => (c: import("remotion").AnyComposition, push: boolean, frame?: number | null) => void;
3
3
  export declare const InitialCompositionLoader: React.FC;
@@ -16,14 +16,18 @@ const use_static_files_1 = require("./use-static-files");
16
16
  const useSelectComposition = () => {
17
17
  const { setCompositionFoldersExpanded } = (0, react_1.useContext)(folders_1.FolderContext);
18
18
  const { setCanvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionSetters);
19
+ const setFrame = remotion_1.Internals.useTimelineSetFrame();
19
20
  const isMobileLayout = (0, mobile_layout_1.useMobileLayout)();
20
21
  const { setSidebarCollapsedState } = (0, react_1.useContext)(sidebar_1.SidebarContext);
21
- return (0, react_1.useCallback)((c, push) => {
22
+ return (0, react_1.useCallback)((c, push, frame = null) => {
22
23
  var _a;
23
24
  if (push) {
24
25
  (0, url_state_1.pushUrl)(`/${c.id}`);
25
26
  }
26
27
  (_a = ExplorerPanelRef_1.explorerSidebarTabs.current) === null || _a === void 0 ? void 0 : _a.selectCompositionPanel();
28
+ if (frame !== null) {
29
+ setFrame((current) => ({ ...current, [c.id]: frame }));
30
+ }
27
31
  setCanvasContent({ type: 'composition', compositionId: c.id });
28
32
  const { folderName, parentFolderName } = c;
29
33
  if (folderName !== null) {
@@ -46,6 +50,7 @@ const useSelectComposition = () => {
46
50
  isMobileLayout,
47
51
  setCanvasContent,
48
52
  setCompositionFoldersExpanded,
53
+ setFrame,
49
54
  setSidebarCollapsedState,
50
55
  ]);
51
56
  };
@@ -164,6 +164,7 @@ const TimelineContextMenuArea = ({ children }) => {
164
164
  files,
165
165
  compositionFile,
166
166
  compositionId: currentCompositionId,
167
+ destinationDimensions: null,
167
168
  dropPosition: null,
168
169
  });
169
170
  }
@@ -532,6 +532,8 @@ const TimelineClipboardKeybindings = () => {
532
532
  setPropStatuses,
533
533
  clientId,
534
534
  confirm,
535
+ propStatuses,
536
+ timelinePosition: timelinePositionRef.current,
535
537
  });
536
538
  return deletePromise === null || deletePromise === void 0 ? void 0 : deletePromise.then((deleted) => {
537
539
  if (!deleted) {
@@ -621,6 +623,7 @@ const TimelineClipboardKeybindings = () => {
621
623
  fieldKey: keyframeTarget.fieldKey,
622
624
  sourceFrame,
623
625
  schema: keyframeTarget.schema,
626
+ valueWhenLastKeyframeDeleted: null,
624
627
  }));
625
628
  return (0, call_delete_keyframe_1.callDeleteKeyframes)({
626
629
  sequenceKeyframes: effectIndex === null ? deletions : [],
@@ -57,6 +57,8 @@ const TimelineDeleteKeybindings = () => {
57
57
  setPropStatuses,
58
58
  clientId,
59
59
  confirm,
60
+ propStatuses,
61
+ timelinePosition: timelinePositionRef.current,
60
62
  });
61
63
  if (deletePromise !== null) {
62
64
  deletePromise
@@ -213,6 +213,7 @@ const getDeleteChange = (target) => {
213
213
  fieldKey: target.fieldKey,
214
214
  sourceFrame: target.sourceFrame,
215
215
  schema: target.schema,
216
+ valueWhenLastKeyframeDeleted: null,
216
217
  };
217
218
  if (target.effectIndex === null) {
218
219
  return change;
@@ -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);
@@ -563,11 +563,23 @@ const TimelineSequenceItem = ({ connectedCompositions, nestedDepth, sequence, no
563
563
  }
564
564
  e.stopPropagation();
565
565
  if (action === 'open-connected-composition') {
566
- selectComposition(connectedCompositions[0], true);
566
+ selectComposition(connectedCompositions[0], true, (0, get_sequence_double_click_action_1.getConnectedCompositionFrame)({
567
+ timelinePosition,
568
+ sequence,
569
+ sequenceFrameOffset,
570
+ }));
567
571
  return;
568
572
  }
569
573
  openInEditor();
570
- }, [canOpenInEditor, connectedCompositions, openInEditor, selectComposition]);
574
+ }, [
575
+ canOpenInEditor,
576
+ connectedCompositions,
577
+ openInEditor,
578
+ selectComposition,
579
+ sequence,
580
+ sequenceFrameOffset,
581
+ timelinePosition,
582
+ ]);
571
583
  const canHandleSequenceDoubleClick = connectedCompositions.length === 1 || canOpenInEditor;
572
584
  const canRenameSelectedSequence = canRenameThisSequence &&
573
585
  selected &&
@@ -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
  }
@@ -29,6 +29,20 @@ export declare const getAssetElementFromPath: (assetPath: string) => {
29
29
  } | null;
30
30
  position: InsertableCompositionElementPosition | null;
31
31
  } | null;
32
+ export declare const getAssetElementForDroppedFile: ({ fileType, src, }: {
33
+ fileType: FileType;
34
+ src: string;
35
+ }) => {
36
+ type: "asset";
37
+ assetType: "animated-image" | "audio" | "gif" | "image" | "video";
38
+ src: string;
39
+ srcType: "remote" | "static";
40
+ dimensions: {
41
+ width: number;
42
+ height: number;
43
+ } | null;
44
+ position: InsertableCompositionElementPosition | null;
45
+ } | null;
32
46
  export declare const getElementPositionForDrop: ({ dimensions, dropPosition, }: {
33
47
  dimensions: Dimensions | null;
34
48
  dropPosition: InsertElementDropPosition | null;
@@ -38,6 +52,11 @@ export declare const getCompositionPositionForDrop: ({ compositionDimensions, de
38
52
  destinationDimensions: Dimensions | null;
39
53
  dropPosition: InsertElementDropPosition | null;
40
54
  }) => InsertableCompositionElementPosition | null;
55
+ export declare const getAssetPositionForDrop: ({ assetDimensions, destinationDimensions, dropPosition, }: {
56
+ assetDimensions: Dimensions | null;
57
+ destinationDimensions: Dimensions | null;
58
+ dropPosition: InsertElementDropPosition | null;
59
+ }) => InsertableCompositionElementPosition | null;
41
60
  export declare const getComponentDimensions: (component: {
42
61
  componentName: string;
43
62
  dimensions?: import("@remotion/studio-shared").ComponentDimensions | undefined;
@@ -48,15 +67,17 @@ export declare const getComponentDimensions: (component: {
48
67
  export declare const pickFilesToImport: ({ multiple, }?: {
49
68
  readonly multiple?: boolean | undefined;
50
69
  }) => Promise<File[]>;
51
- export declare const importAssets: ({ compositionFile, compositionId, dropPosition, files, }: {
70
+ export declare const importAssets: ({ compositionFile, compositionId, destinationDimensions, dropPosition, files, }: {
52
71
  compositionFile: string;
53
72
  compositionId: string;
73
+ destinationDimensions: Dimensions | null;
54
74
  dropPosition: InsertElementDropPosition | null;
55
75
  files: File[];
56
76
  }) => Promise<void>;
57
- export declare const importRemoteAsset: ({ compositionFile, compositionId, dropPosition, url, }: {
77
+ export declare const importRemoteAsset: ({ compositionFile, compositionId, destinationDimensions, dropPosition, url, }: {
58
78
  compositionFile: string;
59
79
  compositionId: string;
80
+ destinationDimensions: Dimensions | null;
60
81
  dropPosition: InsertElementDropPosition | null;
61
82
  url: string;
62
83
  }) => Promise<void>;
@@ -65,10 +86,11 @@ export declare const insertRemoteAudio: ({ compositionFile, compositionId, url,
65
86
  compositionId: string;
66
87
  url: string;
67
88
  }) => Promise<void>;
68
- export declare const insertExistingAssets: ({ assetPaths, compositionFile, compositionId, dropPosition, }: {
89
+ export declare const insertExistingAssets: ({ assetPaths, compositionFile, compositionId, destinationDimensions, dropPosition, }: {
69
90
  assetPaths: string[];
70
91
  compositionFile: string;
71
92
  compositionId: string;
93
+ destinationDimensions: Dimensions | null;
72
94
  dropPosition: InsertElementDropPosition | null;
73
95
  }) => Promise<void>;
74
96
  export declare const insertComponent: ({ component, compositionFile, compositionId, dropPosition, }: {