@remotion/studio 4.0.496 → 4.0.498

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 (109) hide show
  1. package/dist/components/AudioWaveform.js +1 -11
  2. package/dist/components/Canvas.js +22 -203
  3. package/dist/components/Checkbox.js +1 -1
  4. package/dist/components/CompositionSelectorItem.js +2 -10
  5. package/dist/components/ConfigureLicenseModal.d.ts +4 -0
  6. package/dist/components/ConfigureLicenseModal.js +194 -0
  7. package/dist/components/Editor.d.ts +0 -1
  8. package/dist/components/Editor.js +2 -3
  9. package/dist/components/InspectorPanel/AlignmentControls.js +2 -0
  10. package/dist/components/InspectorPanel/CompositionInspector.js +2 -1
  11. package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +27 -2
  12. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +65 -8
  13. package/dist/components/InspectorPanel/use-composition-actions.js +7 -3
  14. package/dist/components/LicenseKeyValidation.d.ts +17 -0
  15. package/dist/components/LicenseKeyValidation.js +113 -0
  16. package/dist/components/Modals.js +2 -1
  17. package/dist/components/NewComposition/CodemodFooter.d.ts +1 -1
  18. package/dist/components/NewComposition/CodemodFooter.js +23 -4
  19. package/dist/components/NewComposition/InputDragger.d.ts +6 -0
  20. package/dist/components/NewComposition/InputDragger.js +12 -3
  21. package/dist/components/NewComposition/NewComposition.js +1 -1
  22. package/dist/components/NewComposition/use-rename-static-file.js +1 -1
  23. package/dist/components/RenderButton.js +0 -1
  24. package/dist/components/RenderModal/WebRenderModal.js +14 -8
  25. package/dist/components/SelectedOutlineElement.js +56 -88
  26. package/dist/components/SelectedOutlineOverlay.d.ts +1 -1
  27. package/dist/components/SelectedOutlineOverlay.js +10 -11
  28. package/dist/components/Timeline/MaxTimelineTracks.d.ts +0 -1
  29. package/dist/components/Timeline/MaxTimelineTracks.js +3 -3
  30. package/dist/components/Timeline/Timeline.js +19 -11
  31. package/dist/components/Timeline/TimelineAssetDropIndicator.d.ts +2 -0
  32. package/dist/components/Timeline/TimelineAssetDropIndicator.js +37 -0
  33. package/dist/components/Timeline/TimelineClipboardKeybindings.js +1 -7
  34. package/dist/components/Timeline/TimelineDragHandler.js +1 -1
  35. package/dist/components/Timeline/TimelineScrollable.js +3 -2
  36. package/dist/components/Timeline/TimelineSelection.d.ts +4 -0
  37. package/dist/components/Timeline/TimelineSelection.js +41 -6
  38. package/dist/components/Timeline/TimelineSequence.js +26 -14
  39. package/dist/components/Timeline/TimelineSequenceFrame.js +2 -4
  40. package/dist/components/Timeline/TimelineSequenceItem.js +7 -5
  41. package/dist/components/Timeline/TimelineSequencePropItem.js +4 -0
  42. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +23 -3
  43. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +135 -19
  44. package/dist/components/Timeline/TimelineTimeIndicators.d.ts +16 -0
  45. package/dist/components/Timeline/TimelineTimeIndicators.js +154 -35
  46. package/dist/components/Timeline/TimelineTranslateField.js +2 -1
  47. package/dist/components/Timeline/TimelineVideoInfo.d.ts +1 -0
  48. package/dist/components/Timeline/TimelineVideoInfo.js +4 -1
  49. package/dist/components/Timeline/call-update-keyframe-settings.d.ts +17 -0
  50. package/dist/components/Timeline/call-update-keyframe-settings.js +43 -1
  51. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +2 -0
  52. package/dist/components/Timeline/delete-selected-timeline-item.js +5 -4
  53. package/dist/components/Timeline/disable-sequence-interactivity.js +2 -0
  54. package/dist/components/Timeline/get-timeline-media-visualization-layout.d.ts +8 -0
  55. package/dist/components/Timeline/get-timeline-media-visualization-layout.js +10 -0
  56. package/dist/components/Timeline/get-timeline-video-info-widths.js +11 -3
  57. package/dist/components/Timeline/keyframe-clipboard.js +21 -5
  58. package/dist/components/Timeline/reset-selected-timeline-props.js +2 -0
  59. package/dist/components/Timeline/save-sequence-prop.d.ts +5 -3
  60. package/dist/components/Timeline/save-sequence-prop.js +43 -18
  61. package/dist/components/Timeline/should-clear-selection-on-pointer-down.d.ts +2 -0
  62. package/dist/components/Timeline/should-clear-selection-on-pointer-down.js +1 -1
  63. package/dist/components/Timeline/timeline-asset-drop-context.d.ts +1 -0
  64. package/dist/components/Timeline/timeline-asset-drop-context.js +5 -0
  65. package/dist/components/Timeline/timeline-scroll-logic.d.ts +7 -0
  66. package/dist/components/Timeline/timeline-scroll-logic.js +10 -1
  67. package/dist/components/Timeline/update-selected-easing.js +26 -23
  68. package/dist/components/Timeline/use-rename-sequence.js +2 -0
  69. package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.d.ts +5 -0
  70. package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.js +18 -9
  71. package/dist/components/Timeline/use-timeline-asset-drop.d.ts +1 -0
  72. package/dist/components/Timeline/use-timeline-asset-drop.js +168 -0
  73. package/dist/components/composition-menu-items.d.ts +15 -1
  74. package/dist/components/composition-menu-items.js +137 -107
  75. package/dist/components/drop-handler-data.d.ts +13 -0
  76. package/dist/components/drop-handler-data.js +117 -0
  77. package/dist/components/handle-drop.d.ts +13 -0
  78. package/dist/components/handle-drop.js +115 -0
  79. package/dist/components/import-assets.d.ts +26 -8
  80. package/dist/components/import-assets.js +161 -49
  81. package/dist/components/selected-outline-drag.d.ts +11 -1
  82. package/dist/components/selected-outline-drag.js +74 -1
  83. package/dist/esm/{chunk-0v4n7nkh.js → chunk-7a6q9hk2.js} +5271 -4259
  84. package/dist/esm/index.mjs +0 -19
  85. package/dist/esm/internals.mjs +5271 -4259
  86. package/dist/esm/previewEntry.mjs +5475 -4463
  87. package/dist/esm/renderEntry.mjs +1 -1
  88. package/dist/helpers/interactivity-enabled.d.ts +1 -1
  89. package/dist/helpers/interactivity-enabled.js +2 -2
  90. package/dist/helpers/is-video-with-last-frame-hold.d.ts +2 -0
  91. package/dist/helpers/is-video-with-last-frame-hold.js +9 -0
  92. package/dist/helpers/retry-payload.js +0 -1
  93. package/dist/helpers/url-state.d.ts +1 -0
  94. package/dist/helpers/url-state.js +5 -1
  95. package/dist/helpers/use-max-media-duration.js +5 -3
  96. package/dist/helpers/use-menu-structure.js +11 -3
  97. package/dist/icons/duplicate.d.ts +5 -0
  98. package/dist/icons/duplicate.js +10 -0
  99. package/dist/icons/snowflake.d.ts +5 -0
  100. package/dist/icons/snowflake.js +10 -0
  101. package/dist/icons/trash.d.ts +5 -0
  102. package/dist/icons/trash.js +8 -0
  103. package/dist/state/modals.d.ts +3 -1
  104. package/dist/visual-controls/VisualControls.js +1 -1
  105. package/package.json +11 -11
  106. package/dist/components/RenderModal/WebRenderModalLicense.d.ts +0 -9
  107. package/dist/components/RenderModal/WebRenderModalLicense.js +0 -189
  108. package/dist/components/RenderModal/WebRenderModalLicenseKeyDetails.d.ts +0 -13
  109. package/dist/components/RenderModal/WebRenderModalLicenseKeyDetails.js +0 -60
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useTimelineRowHighlightBackground = exports.useTimelineRowContainsSelection = exports.useTimelineGuideSelection = exports.useTimelineEasingSelection = exports.useTimelineKeyframeSelection = exports.useTimelineRowSelection = exports.useTimelineFocusableItem = exports.useTimelineMarqueeSelectableItem = exports.useTimelineMarqueeSelection = exports.useCurrentTimelineSelectionStateAsRef = exports.TIMELINE_SCRUBBER_ATTR = exports.TIMELINE_MARQUEE_ITEM_ATTR = exports.useTimelineSelection = exports.TimelineSelectionProvider = exports.TimelineSelectableItemsProvider = exports.TimelineSelectAllKeybindings = exports.getTimelineSequenceSelectionKey = exports.getSelectableTimelineItems = exports.getSelectableTimelineSequenceSelections = exports.getTimelineSelectionKey = exports.getTimelineSelectionFromNodePathInfo = exports.TimelineSelectionOrderProvider = exports.getTimelineMarqueeSelection = exports.timelineMarqueeRectsIntersect = exports.getClampedTimelineMarqueePoint = exports.getNormalizedTimelineMarqueeRect = exports.getAvailableTimelineSelectionState = exports.getTimelineSelectionAfterInteraction = exports.EMPTY_TIMELINE_SELECTION_STATE = exports.shouldSelectTimelineRowOnPointerDown = exports.isTimelineSelectionModifierEvent = exports.TIMELINE_TICKS_BACKGROUND = exports.TIMELINE_BACKGROUND = exports.getTimelineRowHighlightBackground = exports.getTimelineSelectedTrackHighlightStyle = exports.getTimelineColor = exports.getTimelineSelectedLabelStyle = exports.TIMELINE_SELECTED_LABEL_HORIZONTAL_PADDING = exports.TIMELINE_SELECTED_LABEL_TEXT = exports.TIMELINE_SELECTED_LABEL_BACKGROUND = exports.TIMELINE_SELECTED_BACKGROUND = void 0;
3
+ exports.useTimelineRowHighlightBackground = exports.useTimelineRowContainsSelection = exports.useTimelineGuideSelection = exports.useTimelineEasingSelection = exports.useTimelineKeyframeSelection = exports.useTimelineRowSelection = exports.useTimelineFocusableItem = exports.useTimelineMarqueeSelectableItem = exports.useTimelineMarqueeSelection = exports.useCurrentTimelineSelectionStateAsRef = exports.TIMELINE_SCRUBBER_ATTR = exports.TIMELINE_MARQUEE_ITEM_ATTR = exports.useTimelineSelection = exports.TimelineSelectionProvider = exports.TimelineSelectableItemsProvider = exports.TimelineSelectAllKeybindings = exports.getTimelineSequenceSelectionKey = exports.getSelectableTimelineItems = exports.getSelectableTimelineSequenceSelections = exports.getTimelineSelectionKey = exports.getTimelineSelectionFromNodePathInfo = exports.TimelineSelectionOrderProvider = exports.extendTimelineMarqueeSelection = exports.getTimelineMarqueeSelection = exports.timelineMarqueeRectsIntersect = exports.getClampedTimelineMarqueePoint = exports.getNormalizedTimelineMarqueeRect = exports.getAvailableTimelineSelectionState = exports.getTimelineSelectionAfterInteraction = exports.EMPTY_TIMELINE_SELECTION_STATE = exports.shouldSelectTimelineRowOnPointerDown = exports.isTimelineSelectionModifierEvent = exports.TIMELINE_TICKS_BACKGROUND = exports.TIMELINE_BACKGROUND = exports.getTimelineRowHighlightBackground = exports.getTimelineSelectedTrackHighlightStyle = exports.getTimelineColor = exports.getTimelineSelectedLabelStyle = exports.TIMELINE_SELECTED_LABEL_HORIZONTAL_PADDING = exports.TIMELINE_SELECTED_LABEL_TEXT = exports.TIMELINE_SELECTED_LABEL_BACKGROUND = exports.TIMELINE_SELECTED_BACKGROUND = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const studio_shared_1 = require("@remotion/studio-shared");
6
6
  const react_1 = require("react");
@@ -265,6 +265,28 @@ const getTimelineMarqueeSelection = ({ candidates, lockedSelectionKind, marqueeR
265
265
  };
266
266
  };
267
267
  exports.getTimelineMarqueeSelection = getTimelineMarqueeSelection;
268
+ const extendTimelineMarqueeSelection = ({ currentSelection, marqueeSelection, }) => {
269
+ if (marqueeSelection.length === 0) {
270
+ return currentSelection;
271
+ }
272
+ const marqueeKind = getTimelineMarqueeSelectionKind(marqueeSelection[0]);
273
+ if (marqueeKind === null) {
274
+ return marqueeSelection;
275
+ }
276
+ const selectedKeys = new Set(currentSelection.map((item) => (0, exports.getTimelineSelectionKey)(item)));
277
+ return [
278
+ ...currentSelection.filter((item) => isTimelineSelectionCompatibleWithMarqueeKind(item, marqueeKind)),
279
+ ...marqueeSelection.filter((item) => {
280
+ const key = (0, exports.getTimelineSelectionKey)(item);
281
+ if (selectedKeys.has(key)) {
282
+ return false;
283
+ }
284
+ selectedKeys.add(key);
285
+ return true;
286
+ }),
287
+ ];
288
+ };
289
+ exports.extendTimelineMarqueeSelection = extendTimelineMarqueeSelection;
268
290
  const defaultTimelineSelectionContextValue = {
269
291
  canSelect: false,
270
292
  selectedItems: [],
@@ -573,7 +595,7 @@ const TimelineSelectionProvider = ({ children }) => {
573
595
  const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
574
596
  const timelineSelectionScope = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition' ? canvasContent.compositionId : null;
575
597
  const { expandParentTracks } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksSetterContext);
576
- const canSelect = interactivity_enabled_1.studioInteractivityEnabled &&
598
+ const canSelect = (0, interactivity_enabled_1.isStudioInteractivityEnabled)() &&
577
599
  previewServerState.type === 'connected' &&
578
600
  !window.remotion_isReadOnlyStudio;
579
601
  const [selectedItems, setSelectedItems] = (0, react_1.useState)([]);
@@ -864,7 +886,7 @@ const useCurrentTimelineSelectionStateAsRef = () => {
864
886
  };
865
887
  exports.useCurrentTimelineSelectionStateAsRef = useCurrentTimelineSelectionStateAsRef;
866
888
  const useTimelineMarqueeSelection = () => {
867
- const { canSelect, getMarqueeSelection, selectItems } = (0, exports.useTimelineSelection)();
889
+ const { canSelect, getMarqueeSelection, selectedItems, selectItems } = (0, exports.useTimelineSelection)();
868
890
  const { isHighestContext } = (0, z_index_1.useZIndex)();
869
891
  const [marqueeRect, setMarqueeRect] = (0, react_1.useState)(null);
870
892
  const onPointerDownCapture = (0, react_1.useCallback)((event) => {
@@ -874,7 +896,7 @@ const useTimelineMarqueeSelection = () => {
874
896
  if (event.button !== 0 || !canSelect) {
875
897
  return;
876
898
  }
877
- if (event.shiftKey || event.metaKey || event.ctrlKey) {
899
+ if (event.shiftKey) {
878
900
  return;
879
901
  }
880
902
  if (!(event.target instanceof Element)) {
@@ -908,6 +930,8 @@ const useTimelineMarqueeSelection = () => {
908
930
  document.body.style.webkitUserSelect = 'none';
909
931
  let hasDragged = false;
910
932
  let lockedSelectionKind = null;
933
+ const extendSelection = event.metaKey || event.ctrlKey;
934
+ const selectionBeforeMarquee = selectedItems;
911
935
  const cleanup = () => {
912
936
  var _a;
913
937
  window.removeEventListener('pointermove', onPointerMove);
@@ -941,7 +965,12 @@ const useTimelineMarqueeSelection = () => {
941
965
  const nextSelection = getMarqueeSelection(rect, lockedSelectionKind);
942
966
  lockedSelectionKind = nextSelection.lockedSelectionKind;
943
967
  setMarqueeRect(rect);
944
- selectItems(nextSelection.selectedItems);
968
+ selectItems(extendSelection
969
+ ? (0, exports.extendTimelineMarqueeSelection)({
970
+ currentSelection: selectionBeforeMarquee,
971
+ marqueeSelection: nextSelection.selectedItems,
972
+ })
973
+ : nextSelection.selectedItems);
945
974
  };
946
975
  const onPointerMove = (moveEvent) => {
947
976
  updateSelection(moveEvent.clientX, moveEvent.clientY);
@@ -956,7 +985,13 @@ const useTimelineMarqueeSelection = () => {
956
985
  window.addEventListener('pointermove', onPointerMove);
957
986
  window.addEventListener('pointerup', onPointerUp);
958
987
  window.addEventListener('pointercancel', onPointerCancel);
959
- }, [canSelect, getMarqueeSelection, isHighestContext, selectItems]);
988
+ }, [
989
+ canSelect,
990
+ getMarqueeSelection,
991
+ isHighestContext,
992
+ selectedItems,
993
+ selectItems,
994
+ ]);
960
995
  return { marqueeRect, onPointerDownCapture };
961
996
  };
962
997
  exports.useTimelineMarqueeSelection = useTimelineMarqueeSelection;
@@ -43,6 +43,7 @@ const format_file_location_1 = require("../../helpers/format-file-location");
43
43
  const get_sequence_double_click_action_1 = require("../../helpers/get-sequence-double-click-action");
44
44
  const get_timeline_sequence_layout_1 = require("../../helpers/get-timeline-sequence-layout");
45
45
  const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
46
+ const is_video_with_last_frame_hold_1 = require("../../helpers/is-video-with-last-frame-hold");
46
47
  const open_in_editor_1 = require("../../helpers/open-in-editor");
47
48
  const timeline_layout_1 = require("../../helpers/timeline-layout");
48
49
  const use_max_media_duration_1 = require("../../helpers/use-max-media-duration");
@@ -56,6 +57,7 @@ const use_select_asset_1 = require("../use-select-asset");
56
57
  const disable_sequence_interactivity_1 = require("./disable-sequence-interactivity");
57
58
  const duplicate_selected_timeline_item_1 = require("./duplicate-selected-timeline-item");
58
59
  const get_sequence_context_menu_items_1 = require("./get-sequence-context-menu-items");
60
+ const get_timeline_media_visualization_layout_1 = require("./get-timeline-media-visualization-layout");
59
61
  const LoopedTimelineIndicators_1 = require("./LoopedTimelineIndicators");
60
62
  const timeline_asset_link_1 = require("./timeline-asset-link");
61
63
  const TimelineImageInfo_1 = require("./TimelineImageInfo");
@@ -159,6 +161,7 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
159
161
  const video = remotion_1.Internals.useVideo();
160
162
  const maxMediaDuration = (0, use_max_media_duration_1.useMaxMediaDuration)(s, (_d = video === null || video === void 0 ? void 0 : video.fps) !== null && _d !== void 0 ? _d : 30);
161
163
  const effectiveMaxMediaDuration = s.loopDisplay ? null : maxMediaDuration;
164
+ const extendVideoLastFrame = (0, is_video_with_last_frame_hold_1.isVideoWithLastFrameHold)(s);
162
165
  const originalLocation = (0, use_resolved_stack_react_to_change_1.useResolveStackAndReactToChange)(s.getStack);
163
166
  const validatedLocation = (0, react_1.useMemo)(() => {
164
167
  var _a;
@@ -180,15 +183,15 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
180
183
  ? remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePath)
181
184
  : undefined;
182
185
  }, [propStatuses, nodePath]);
183
- const durationCanUpdate = Boolean(interactivity_enabled_1.studioInteractivityEnabled &&
186
+ const durationCanUpdate = Boolean((0, interactivity_enabled_1.isStudioInteractivityEnabled)() &&
184
187
  ((_a = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.durationInFrames) === null || _a === void 0 ? void 0 : _a.status) === 'static');
185
- const fromCanUpdate = Boolean(interactivity_enabled_1.studioInteractivityEnabled &&
188
+ const fromCanUpdate = Boolean((0, interactivity_enabled_1.isStudioInteractivityEnabled)() &&
186
189
  ((_b = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.from) === null || _b === void 0 ? void 0 : _b.status) === 'static');
187
- const trimBeforeCanUpdate = Boolean(interactivity_enabled_1.studioInteractivityEnabled &&
190
+ const trimBeforeCanUpdate = Boolean((0, interactivity_enabled_1.isStudioInteractivityEnabled)() &&
188
191
  ((_c = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.trimBefore) === null || _c === void 0 ? void 0 : _c.status) === 'static');
189
192
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
190
193
  const previewConnected = previewServerState.type === 'connected';
191
- const previewInteractive = previewConnected && interactivity_enabled_1.studioInteractivityEnabled;
194
+ const previewInteractive = previewConnected && (0, interactivity_enabled_1.isStudioInteractivityEnabled)();
192
195
  const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
193
196
  const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
194
197
  const selectAsset = (0, use_select_asset_1.useSelectAsset)();
@@ -343,7 +346,7 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
343
346
  disableInteractivityDisabled,
344
347
  duplicateDisabled,
345
348
  fileLocation,
346
- includeSourceEditItems: interactivity_enabled_1.studioInteractivityEnabled,
349
+ includeSourceEditItems: (0, interactivity_enabled_1.isStudioInteractivityEnabled)(),
347
350
  onDeleteSequenceFromSource,
348
351
  onDisableSequenceInteractivity,
349
352
  onDuplicateSequenceFromSource,
@@ -351,7 +354,7 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
351
354
  originalLocation,
352
355
  selectAsset,
353
356
  sequence: s,
354
- sourceActions: interactivity_enabled_1.studioInteractivityEnabled && freezeFrameMenuItem
357
+ sourceActions: (0, interactivity_enabled_1.isStudioInteractivityEnabled)() && freezeFrameMenuItem
355
358
  ? [freezeFrameMenuItem]
356
359
  : [],
357
360
  });
@@ -407,6 +410,20 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
407
410
  video,
408
411
  windowWidth,
409
412
  ]);
413
+ const mediaVisualizationLayout = (0, react_1.useMemo)(() => {
414
+ return (0, get_timeline_media_visualization_layout_1.getTimelineMediaVisualizationLayout)({
415
+ visualizationWidth: width,
416
+ premountWidth: premountWidth !== null && premountWidth !== void 0 ? premountWidth : 0,
417
+ postmountWidth: postmountWidth !== null && postmountWidth !== void 0 ? postmountWidth : 0,
418
+ });
419
+ }, [postmountWidth, premountWidth, width]);
420
+ const mediaVisualizationStyle = (0, react_1.useMemo)(() => {
421
+ return {
422
+ width: mediaVisualizationLayout.width,
423
+ marginLeft: mediaVisualizationLayout.marginLeft,
424
+ height: '100%',
425
+ };
426
+ }, [mediaVisualizationLayout]);
410
427
  const style = (0, react_1.useMemo)(() => {
411
428
  return {
412
429
  background: s.type === 'audio'
@@ -430,21 +447,16 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
430
447
  nodePath !== null &&
431
448
  validatedLocation !== null &&
432
449
  durationCanUpdate;
433
- const showLeftEdgeDragHandle = (s.type === 'sequence' ||
434
- s.type === 'image' ||
435
- s.type === 'audio' ||
436
- s.type === 'video') &&
437
- !s.isInsideSeries &&
450
+ const showLeftEdgeDragHandle = (0, TimelineSequenceRightEdgeDragHandle_1.isTimelineSequenceLeftEdgeDraggable)(s) &&
438
451
  nodePath !== null &&
439
452
  validatedLocation !== null &&
440
- Boolean(s.controls) &&
441
- fromCanUpdate &&
453
+ ((0, TimelineSequenceRightEdgeDragHandle_1.isCascadingSequence)(s) || fromCanUpdate) &&
442
454
  durationCanUpdate &&
443
455
  trimBeforeCanUpdate;
444
456
  if (maxMediaDuration === null && !s.loopDisplay) {
445
457
  return null;
446
458
  }
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] }));
459
+ 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("div", { style: mediaVisualizationStyle, children: jsx_runtime_1.jsx(AudioWaveform_1.AudioWaveform, { src: s.src, height: timeline_layout_1.TIMELINE_LAYER_HEIGHT_AUDIO, doesVolumeChange: s.doesVolumeChange, visualizationWidth: mediaVisualizationLayout.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, extendLastFrame: extendVideoLastFrame })) : null, s.type === 'image' ? (jsx_runtime_1.jsx("div", { style: mediaVisualizationStyle, children: jsx_runtime_1.jsx(TimelineImageInfo_1.TimelineImageInfo, { src: s.src, visualizationWidth: mediaVisualizationLayout.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] }));
448
460
  return previewConnected ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, onOpen: onContextMenuOpen, children: sequence })) : (sequence);
449
461
  };
450
462
  exports.TimelineSequence = react_1.default.memo(TimelineSequenceFn);
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TimelineSequenceFrame = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const colors_1 = require("../../helpers/colors");
6
+ const snowflake_1 = require("../../icons/snowflake");
6
7
  const relativeFrameStyle = {
7
8
  alignItems: 'center',
8
9
  display: 'flex',
@@ -20,11 +21,8 @@ const snowflakeStyle = {
20
21
  height: 12,
21
22
  width: 12,
22
23
  };
23
- const FreezeFrameIcon = () => {
24
- return (jsx_runtime_1.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 512 512", style: snowflakeStyle, fill: colors_1.CURRENT_COLOR, children: jsx_runtime_1.jsx("path", { d: "M288 32l0-32-64 0 0 88.4-64-64-39.6 39.6 103.6 103.6 0 56.4-56.4 0-103.6-103.6-39.6 39.6 64 64-88.4 0 0 64 88.4 0c-33.5 33.5-54.9 54.9-64 64L64 391.6c2.5-2.5 37.1-37.1 103.6-103.6l56.4 0 0 56.4C157.5 410.9 122.9 445.5 120.4 448L160 487.6c9.1-9.1 30.5-30.5 64-64l0 88.4 64 0 0-88.4 64 64 39.6-39.6-103.6-103.6 0-56.4 56.4 0 103.6 103.6 39.6-39.6-64-64 88.4 0 0-64-88.4 0c33.5-33.5 54.9-54.9 64-64L448 120.4c-2.5 2.5-37.1 37.1-103.6 103.6l-56.4 0 0-56.4C354.5 101.1 389.1 66.5 391.6 64L352 24.4c-9.1 9.1-30.5 30.5-64 64L288 32z" }) }));
25
- };
26
24
  const TimelineSequenceFrame = ({ roundedFrame, frozenFrame, premounted, postmounted }) => {
27
- return (jsx_runtime_1.jsxs("div", { style: relativeFrameStyle, children: [frozenFrame === null ? null : jsx_runtime_1.jsx(FreezeFrameIcon, {}), frozenFrame !== null && frozenFrame !== void 0 ? frozenFrame : (premounted
25
+ return (jsx_runtime_1.jsxs("div", { style: relativeFrameStyle, children: [frozenFrame === null ? null : (jsx_runtime_1.jsx(snowflake_1.SnowflakeIcon, { style: snowflakeStyle, color: colors_1.CURRENT_COLOR })), frozenFrame !== null && frozenFrame !== void 0 ? frozenFrame : (premounted
28
26
  ? '0 (Premounted)'
29
27
  : postmounted !== null
30
28
  ? `${postmounted} (Postmounted)`
@@ -177,7 +177,7 @@ const TimelineSequenceItem = ({ children, connectedCompositions, nestedDepth, se
177
177
  const nodePath = (_d = nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.sequenceSubscriptionKey) !== null && _d !== void 0 ? _d : null;
178
178
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
179
179
  const previewConnected = previewServerState.type === 'connected';
180
- const previewInteractive = previewConnected && interactivity_enabled_1.studioInteractivityEnabled;
180
+ const previewInteractive = previewConnected && (0, interactivity_enabled_1.isStudioInteractivityEnabled)();
181
181
  const { getIsExpanded } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksGetterContext);
182
182
  const { toggleTrack } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksSetterContext);
183
183
  const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
@@ -504,6 +504,8 @@ const TimelineSequenceItem = ({ children, connectedCompositions, nestedDepth, se
504
504
  ? JSON.stringify(fieldSchema.default)
505
505
  : null;
506
506
  (0, save_sequence_prop_1.saveSequenceProps)({
507
+ addedKeyframes: null,
508
+ movedKeyframes: null,
507
509
  changes: [
508
510
  {
509
511
  fileName: validatedLocation.source,
@@ -547,7 +549,7 @@ const TimelineSequenceItem = ({ children, connectedCompositions, nestedDepth, se
547
549
  }
548
550
  : inner;
549
551
  }, [effectDropHovered, inner]);
550
- const hasExpandableContent = interactivity_enabled_1.studioInteractivityEnabled &&
552
+ const hasExpandableContent = (0, interactivity_enabled_1.isStudioInteractivityEnabled)() &&
551
553
  (Boolean(sequence.controls) || sequence.effects.length > 0);
552
554
  const canToggleVisibility = previewInteractive &&
553
555
  Boolean(sequence.controls) &&
@@ -680,7 +682,7 @@ const TimelineSequenceItem = ({ children, connectedCompositions, nestedDepth, se
680
682
  disableInteractivityDisabled,
681
683
  duplicateDisabled,
682
684
  fileLocation,
683
- includeSourceEditItems: interactivity_enabled_1.studioInteractivityEnabled,
685
+ includeSourceEditItems: (0, interactivity_enabled_1.isStudioInteractivityEnabled)(),
684
686
  onDeleteSequenceFromSource,
685
687
  onDisableSequenceInteractivity,
686
688
  onDuplicateSequenceFromSource,
@@ -688,7 +690,7 @@ const TimelineSequenceItem = ({ children, connectedCompositions, nestedDepth, se
688
690
  originalLocation,
689
691
  selectAsset,
690
692
  sequence,
691
- sourceActions: interactivity_enabled_1.studioInteractivityEnabled
693
+ sourceActions: (0, interactivity_enabled_1.isStudioInteractivityEnabled)()
692
694
  ? [
693
695
  ...((nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.supportsEffects)
694
696
  ? [
@@ -817,7 +819,7 @@ const TimelineSequenceItem = ({ children, connectedCompositions, nestedDepth, se
817
819
  ] })) : null] }) }));
818
820
  const draggableTrackRow = canHandleSequenceDrag ? (jsx_runtime_1.jsxs("div", { draggable: canReorderSequence, onDragStart: onSequenceDragStart, onDragEnd: onSequenceDragEnd, onDragOver: onSequenceDragOver, onDragLeave: onSequenceDragLeave, onDrop: onSequenceDrop, style: sequenceReorderWrapper, children: [sequenceReorderLineStyle ? (jsx_runtime_1.jsx("div", { style: sequenceReorderLineStyle })) : null, sequenceDropRejection ? (jsx_runtime_1.jsx("div", { style: sequenceReorderRejectionStyle, children: sequenceDropRejection })) : null, trackRow] })) : (trackRow);
819
821
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [previewConnected ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, onOpen: selectable ? onSelect : null, children: draggableTrackRow })) : (draggableTrackRow), previewConnected &&
820
- interactivity_enabled_1.studioInteractivityEnabled &&
822
+ (0, interactivity_enabled_1.isStudioInteractivityEnabled)() &&
821
823
  isExpanded &&
822
824
  hasExpandableContent &&
823
825
  nodePathInfo &&
@@ -77,6 +77,8 @@ const Value = ({ field, nodePath, validatedLocation, schema, propStatus }) => {
77
77
  return Promise.resolve();
78
78
  }
79
79
  return (0, save_sequence_prop_1.saveSequenceProps)({
80
+ addedKeyframes: null,
81
+ movedKeyframes: null,
80
82
  changes: [
81
83
  {
82
84
  fileName: validatedLocation.source,
@@ -219,6 +221,8 @@ const TimelineSequencePropItem = ({ field, validatedLocation, rowDepth, nodePath
219
221
  : null;
220
222
  const fieldLabel = (_a = field.description) !== null && _a !== void 0 ? _a : field.key;
221
223
  (0, save_sequence_prop_1.saveSequenceProps)({
224
+ addedKeyframes: null,
225
+ movedKeyframes: null,
222
226
  changes: [
223
227
  {
224
228
  fileName: validatedLocation.source,
@@ -4,9 +4,11 @@ import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-s
4
4
  import type { MoveEffectKeyframeChange, MoveSequenceKeyframeChange } from './call-move-keyframe';
5
5
  import { type SaveSequencePropChange } from './save-sequence-prop';
6
6
  import { type TimelineSelection } from './TimelineSelection';
7
+ export declare const timelineSequenceFromDragSnapThresholdPx = 10;
7
8
  export type TimelineSequenceDurationDragTarget = {
8
9
  readonly fileName: string;
9
10
  readonly initialDuration: number;
11
+ readonly minimumDuration: number;
10
12
  readonly nodePath: SequencePropsSubscriptionKey;
11
13
  readonly schema: InteractivitySchema;
12
14
  };
@@ -15,10 +17,14 @@ export type TimelineSequenceLeftEdgeDragTarget = {
15
17
  readonly initialDuration: number;
16
18
  readonly initialFrom: number;
17
19
  readonly initialTrimBefore: number;
20
+ readonly minimumDuration: number;
18
21
  readonly nodePath: SequencePropsSubscriptionKey;
22
+ readonly playbackRate: number;
23
+ readonly positionField: 'from' | null;
19
24
  readonly schema: InteractivitySchema;
20
25
  };
21
26
  export type TimelineSequenceFromDragTarget = {
27
+ readonly canSnapToTimelineStart: boolean;
22
28
  readonly effectKeyframes: TimelineSequenceEffectKeyframeDragTarget[];
23
29
  readonly fileName: string;
24
30
  readonly initialFrom: number;
@@ -33,21 +39,29 @@ type TimelineSequenceKeyframeDragTarget = {
33
39
  type TimelineSequenceEffectKeyframeDragTarget = TimelineSequenceKeyframeDragTarget & {
34
40
  readonly effectIndex: number;
35
41
  };
42
+ export declare const isTransitionSeriesSequence: (sequence: TSequence) => boolean;
43
+ export declare const isCascadingSequence: (sequence: TSequence) => boolean;
36
44
  export declare const isTimelineSequenceDurationDraggable: (sequence: TSequence) => boolean;
37
- export declare const getTimelineSequenceDurationDragValue: ({ initialDuration, deltaFrames, }: {
45
+ export declare const isTimelineSequenceLeftEdgeDraggable: (sequence: TSequence) => boolean;
46
+ export declare const getTimelineSequenceDurationDragValue: ({ initialDuration, deltaFrames, minimumDuration, }: {
38
47
  readonly initialDuration: number;
39
48
  readonly deltaFrames: number;
49
+ readonly minimumDuration?: number | undefined;
40
50
  }) => number;
41
- export declare const getTimelineSequenceLeftEdgeDragDelta: ({ initialDuration, initialTrimBefore, deltaFrames, }: {
51
+ export declare const getTimelineSequenceLeftEdgeDragDelta: ({ initialDuration, initialTrimBefore, deltaFrames, playbackRate, minimumDuration, }: {
42
52
  readonly initialDuration: number;
43
53
  readonly initialTrimBefore: number;
44
54
  readonly deltaFrames: number;
55
+ readonly playbackRate: number;
56
+ readonly minimumDuration?: number | undefined;
45
57
  }) => number;
46
- export declare const getTimelineSequenceLeftEdgeDragValues: ({ initialDuration, initialFrom, initialTrimBefore, deltaFrames, }: {
58
+ export declare const getTimelineSequenceLeftEdgeDragValues: ({ initialDuration, initialFrom, initialTrimBefore, deltaFrames, playbackRate, minimumDuration, }: {
47
59
  readonly initialDuration: number;
48
60
  readonly initialFrom: number;
49
61
  readonly initialTrimBefore: number;
50
62
  readonly deltaFrames: number;
63
+ readonly playbackRate: number;
64
+ readonly minimumDuration?: number | undefined;
51
65
  }) => {
52
66
  durationInFrames: number;
53
67
  from: number;
@@ -65,6 +79,12 @@ export declare const getTimelineSequenceFromDragValue: ({ initialFrom, deltaFram
65
79
  readonly initialFrom: number;
66
80
  readonly deltaFrames: number;
67
81
  }) => number;
82
+ export declare const getTimelineSequenceFromDragDelta: ({ deltaFrames, pxPerFrame, snappingEnabled, targets, }: {
83
+ readonly deltaFrames: number;
84
+ readonly pxPerFrame: number;
85
+ readonly snappingEnabled: boolean;
86
+ readonly targets: readonly TimelineSequenceFromDragTarget[];
87
+ }) => number;
68
88
  export declare const getTimelineSequenceFromDragChanges: ({ targets, deltaFrames, }: {
69
89
  readonly targets: readonly TimelineSequenceFromDragTarget[];
70
90
  readonly deltaFrames: number;