@remotion/studio 4.0.513 → 4.0.515

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 (204) hide show
  1. package/dist/Studio.js +2 -1
  2. package/dist/api/install-package.js +14 -1
  3. package/dist/components/AskAiModal.js +1 -1
  4. package/dist/components/AssetSelector.js +2 -0
  5. package/dist/components/AssetSelectorItem.d.ts +2 -1
  6. package/dist/components/AssetSelectorItem.js +19 -16
  7. package/dist/components/AudioWaveform.d.ts +3 -0
  8. package/dist/components/AudioWaveform.js +65 -199
  9. package/dist/components/Canvas.js +40 -5
  10. package/dist/components/CanvasOrLoading.js +5 -0
  11. package/dist/components/CompositionSelector.js +2 -0
  12. package/dist/components/ConfigureDefaultEditorModal.js +17 -11
  13. package/dist/components/Editor.js +16 -1
  14. package/dist/components/ElementInstallConfirmation.d.ts +1 -0
  15. package/dist/components/ElementInstallConfirmation.js +4 -2
  16. package/dist/components/FixComputedValueModal.d.ts +9 -0
  17. package/dist/components/FixComputedValueModal.js +217 -0
  18. package/dist/components/InitialCompositionLoader.js +19 -0
  19. package/dist/components/InlineDropdown.js +4 -4
  20. package/dist/components/InspectorInfoHeader.js +3 -3
  21. package/dist/components/InspectorOpenInEditor.js +3 -1
  22. package/dist/components/InspectorPanel/CompositionInspector.js +37 -5
  23. package/dist/components/InspectorPanel/CompositionInspectorHeader.js +2 -2
  24. package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +1 -1
  25. package/dist/components/InspectorPanel/EasingInspector.js +1 -1
  26. package/dist/components/InspectorPanel/KeyframeInspector.js +2 -2
  27. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +1 -1
  28. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +35 -6
  29. package/dist/components/InspectorPanel/common.d.ts +5 -5
  30. package/dist/components/InspectorPanel/common.js +8 -8
  31. package/dist/components/InspectorPanel/styles.d.ts +1 -1
  32. package/dist/components/InspectorPanel/styles.js +4 -2
  33. package/dist/components/InspectorSourceLocation.d.ts +1 -1
  34. package/dist/components/InspectorSourceLocation.js +2 -2
  35. package/dist/components/InstallPackage.d.ts +1 -1
  36. package/dist/components/InstallPackage.js +38 -6
  37. package/dist/components/LicenseKeyValidation.js +2 -2
  38. package/dist/components/Menu/MenuDivider.js +1 -1
  39. package/dist/components/Modals.js +11 -3
  40. package/dist/components/NewComposition/CodemodFooter.d.ts +1 -0
  41. package/dist/components/NewComposition/CodemodFooter.js +10 -8
  42. package/dist/components/NewComposition/DeleteComposition.js +1 -1
  43. package/dist/components/NewComposition/DeleteFolder.js +1 -1
  44. package/dist/components/NewComposition/DuplicateComposition.js +7 -2
  45. package/dist/components/NewComposition/NewComposition.js +1 -1
  46. package/dist/components/NewComposition/NewFolder.js +1 -1
  47. package/dist/components/NewComposition/RenameComposition.js +1 -1
  48. package/dist/components/NewComposition/RenameFolder.js +1 -1
  49. package/dist/components/NewComposition/duplicate-composition-api.d.ts +16 -0
  50. package/dist/components/NewComposition/duplicate-composition-api.js +16 -0
  51. package/dist/components/NoRegisterRoot.js +1 -1
  52. package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.js +4 -3
  53. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +1 -0
  54. package/dist/components/QuickSwitcher/fuzzy-search.js +1 -1
  55. package/dist/components/RefreshCompositionOverlay.js +1 -1
  56. package/dist/components/RenderButton.js +6 -3
  57. package/dist/components/RenderModal/GuiRenderStatus.js +3 -1
  58. package/dist/components/RenderModal/RenderModalOutputName.js +3 -3
  59. package/dist/components/RenderModal/WebRenderModal.js +10 -4
  60. package/dist/components/RenderModal/WebRenderModalAdvanced.d.ts +2 -0
  61. package/dist/components/RenderModal/WebRenderModalAdvanced.js +9 -2
  62. package/dist/components/RenderModal/render-modals.js +5 -1
  63. package/dist/components/RenderQueue/ClientRenderQueueProcessor.js +5 -1
  64. package/dist/components/RenderQueue/RenderQueueItem.js +3 -1
  65. package/dist/components/RenderQueue/RenderQueueOpenInFolder.js +3 -1
  66. package/dist/components/RenderQueue/RenderQueueRemoveItem.js +1 -1
  67. package/dist/components/RenderQueue/actions.js +12 -2
  68. package/dist/components/RenderQueue/client-side-render-types.d.ts +1 -0
  69. package/dist/components/RenderingSettings.d.ts +2 -0
  70. package/dist/components/RenderingSettings.js +355 -0
  71. package/dist/components/SelectedOutlineCanvasRotation.d.ts +1 -0
  72. package/dist/components/SelectedOutlineCanvasRotation.js +11 -4
  73. package/dist/components/SelectedOutlineElement.js +3 -3
  74. package/dist/components/SelectedOutlinePolygon.d.ts +2 -0
  75. package/dist/components/SelectedOutlinePolygon.js +54 -9
  76. package/dist/components/SettingsContext.d.ts +4 -1
  77. package/dist/components/SettingsContext.js +9 -2
  78. package/dist/components/SettingsModal.d.ts +1 -1
  79. package/dist/components/SettingsModal.js +10 -1
  80. package/dist/components/SettingsModalFooter.js +1 -1
  81. package/dist/components/StudioSettings.d.ts +2 -0
  82. package/dist/components/StudioSettings.js +185 -0
  83. package/dist/components/Timeline/LoopedIndicator.js +1 -1
  84. package/dist/components/Timeline/LoopedTimelineIndicators.d.ts +3 -0
  85. package/dist/components/Timeline/LoopedTimelineIndicators.js +22 -14
  86. package/dist/components/Timeline/Timeline.js +11 -9
  87. package/dist/components/Timeline/TimelineAssetField.d.ts +2 -2
  88. package/dist/components/Timeline/TimelineAssetField.js +1 -1
  89. package/dist/components/Timeline/TimelineClipboardKeybindings.js +6 -2
  90. package/dist/components/Timeline/TimelineDragHandler.js +62 -76
  91. package/dist/components/Timeline/TimelineEffectItem.js +23 -6
  92. package/dist/components/Timeline/TimelineEffectPropItem.d.ts +4 -2
  93. package/dist/components/Timeline/TimelineEffectPropItem.js +22 -13
  94. package/dist/components/Timeline/TimelineExpandArrowButton.js +10 -7
  95. package/dist/components/Timeline/TimelineExpandedKeyframeRow.js +4 -1
  96. package/dist/components/Timeline/TimelineExpandedRow.d.ts +1 -1
  97. package/dist/components/Timeline/TimelineExpandedRow.js +4 -4
  98. package/dist/components/Timeline/TimelineExpandedSection.js +8 -5
  99. package/dist/components/Timeline/TimelineHeightContainer.d.ts +0 -4
  100. package/dist/components/Timeline/TimelineHeightContainer.js +4 -4
  101. package/dist/components/Timeline/TimelineImageInfo.d.ts +1 -0
  102. package/dist/components/Timeline/TimelineImageInfo.js +3 -2
  103. package/dist/components/Timeline/TimelineKeyframeControls.js +6 -1
  104. package/dist/components/Timeline/TimelineList.d.ts +1 -5
  105. package/dist/components/Timeline/TimelineList.js +14 -9
  106. package/dist/components/Timeline/TimelinePinchZoom.js +5 -5
  107. package/dist/components/Timeline/TimelineRowChrome.d.ts +1 -2
  108. package/dist/components/Timeline/TimelineRowChrome.js +50 -7
  109. package/dist/components/Timeline/TimelineSchemaField.d.ts +7 -3
  110. package/dist/components/Timeline/TimelineSchemaField.js +71 -13
  111. package/dist/components/Timeline/TimelineScrollable.js +3 -1
  112. package/dist/components/Timeline/TimelineSelection.d.ts +13 -5
  113. package/dist/components/Timeline/TimelineSelection.js +95 -106
  114. package/dist/components/Timeline/TimelineSequence.js +59 -25
  115. package/dist/components/Timeline/TimelineSequenceItem.d.ts +1 -1
  116. package/dist/components/Timeline/TimelineSequenceItem.js +21 -12
  117. package/dist/components/Timeline/TimelineSequenceName.js +1 -1
  118. package/dist/components/Timeline/TimelineSequencePropItem.d.ts +2 -1
  119. package/dist/components/Timeline/TimelineSequencePropItem.js +3 -3
  120. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +33 -10
  121. package/dist/components/Timeline/TimelineSlider.js +42 -33
  122. package/dist/components/Timeline/TimelineTimeIndicators.js +90 -98
  123. package/dist/components/Timeline/TimelineTrack.js +4 -1
  124. package/dist/components/Timeline/TimelineTracks.d.ts +0 -2
  125. package/dist/components/Timeline/TimelineTracks.js +11 -4
  126. package/dist/components/Timeline/TimelineTransformOriginField.js +1 -1
  127. package/dist/components/Timeline/TimelineVideoInfo.d.ts +4 -4
  128. package/dist/components/Timeline/TimelineVideoInfo.js +155 -63
  129. package/dist/components/Timeline/TimelineViewport.d.ts +12 -0
  130. package/dist/components/Timeline/TimelineViewport.js +62 -0
  131. package/dist/components/Timeline/TimelineVirtualization.d.ts +22 -0
  132. package/dist/components/Timeline/TimelineVirtualization.js +144 -0
  133. package/dist/components/Timeline/TimelineZoomControls.js +16 -8
  134. package/dist/components/Timeline/call-add-keyframe.js +31 -3
  135. package/dist/components/Timeline/call-delete-keyframe.js +13 -3
  136. package/dist/components/Timeline/call-move-keyframe.js +11 -1
  137. package/dist/components/Timeline/call-update-keyframe-settings.js +31 -3
  138. package/dist/components/Timeline/delete-selected-timeline-item.js +8 -3
  139. package/dist/components/Timeline/duplicate-selected-timeline-item.js +4 -2
  140. package/dist/components/Timeline/get-timeline-keyframes.d.ts +1 -2
  141. package/dist/components/Timeline/get-timeline-keyframes.js +1 -8
  142. package/dist/components/Timeline/get-timeline-sequence-visible-layout.d.ts +30 -0
  143. package/dist/components/Timeline/get-timeline-sequence-visible-layout.js +61 -0
  144. package/dist/components/Timeline/save-effect-prop.js +3 -3
  145. package/dist/components/Timeline/split-selected-timeline-item.js +2 -2
  146. package/dist/components/Timeline/timeline-scroll-logic.d.ts +24 -0
  147. package/dist/components/Timeline/timeline-scroll-logic.js +127 -4
  148. package/dist/components/Timeline/use-timeline-height.d.ts +3 -5
  149. package/dist/components/Timeline/use-timeline-height.js +16 -18
  150. package/dist/components/UpdateCheck.d.ts +2 -10
  151. package/dist/components/UpdateCheck.js +8 -2
  152. package/dist/components/VisualControls/VisualControlHandle.js +8 -0
  153. package/dist/components/delete-jsx-node-api.d.ts +2 -0
  154. package/dist/components/delete-jsx-node-api.js +12 -0
  155. package/dist/components/effect-drag-and-drop.js +6 -3
  156. package/dist/components/effect-operations-api.d.ts +8 -0
  157. package/dist/components/effect-operations-api.js +52 -0
  158. package/dist/components/element-install-api.d.ts +3 -0
  159. package/dist/components/element-install-api.js +19 -0
  160. package/dist/components/import-assets.js +20 -9
  161. package/dist/components/reorder-sequence-api.d.ts +2 -0
  162. package/dist/components/reorder-sequence-api.js +12 -0
  163. package/dist/components/split-jsx-sequence-api.d.ts +2 -0
  164. package/dist/components/split-jsx-sequence-api.js +12 -0
  165. package/dist/components/split-video-from-audio-api.d.ts +2 -0
  166. package/dist/components/split-video-from-audio-api.js +12 -0
  167. package/dist/error-overlay/remotion-overlay/Overlay.js +1 -1
  168. package/dist/error-overlay/remotion-overlay/log-studio-error.js +4 -0
  169. package/dist/esm/{chunk-r46yxrjr.js → chunk-s6k99gh2.js} +1 -1
  170. package/dist/esm/{chunk-tv7r0jy3.js → chunk-v5a8vpv4.js} +11479 -7851
  171. package/dist/esm/index.mjs +7 -5
  172. package/dist/esm/internals.mjs +11479 -7851
  173. package/dist/esm/previewEntry.mjs +11311 -7683
  174. package/dist/esm/renderEntry.mjs +3 -4
  175. package/dist/helpers/browser-studio-operations.d.ts +5 -0
  176. package/dist/helpers/browser-studio-operations.js +27 -1
  177. package/dist/helpers/colors.d.ts +1 -1
  178. package/dist/helpers/colors.js +1 -1
  179. package/dist/helpers/get-timeline-max-zoom.d.ts +26 -0
  180. package/dist/helpers/get-timeline-max-zoom.js +45 -0
  181. package/dist/helpers/inject-css.js +7 -5
  182. package/dist/helpers/render-codec-label.d.ts +1 -1
  183. package/dist/helpers/retry-payload.js +1 -0
  184. package/dist/helpers/studio-runtime-config.d.ts +1 -1
  185. package/dist/helpers/studio-runtime-config.js +2 -3
  186. package/dist/helpers/timeline-layout.d.ts +3 -1
  187. package/dist/helpers/timeline-layout.js +6 -1
  188. package/dist/helpers/url-state.js +3 -2
  189. package/dist/helpers/use-max-media-duration.js +5 -3
  190. package/dist/helpers/use-media-metadata.js +37 -20
  191. package/dist/helpers/use-menu-structure.js +67 -84
  192. package/dist/helpers/use-runtime-values.d.ts +2 -1
  193. package/dist/helpers/use-runtime-values.js +7 -3
  194. package/dist/icons/cloud-download.d.ts +4 -0
  195. package/dist/icons/cloud-download.js +8 -0
  196. package/dist/icons/remotion-triangle.d.ts +2 -0
  197. package/dist/icons/remotion-triangle.js +7 -0
  198. package/dist/renderEntry.js +1 -1
  199. package/dist/state/composition-list.d.ts +13 -0
  200. package/dist/state/composition-list.js +21 -0
  201. package/dist/state/modals.d.ts +8 -2
  202. package/dist/state/timeline-zoom.d.ts +1 -2
  203. package/dist/state/timeline-zoom.js +9 -5
  204. package/package.json +14 -13
@@ -1,10 +1,11 @@
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.getTimelineSequenceSelectionForEscape = 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_HOVER_BACKGROUND = exports.TIMELINE_SELECTED_BACKGROUND = void 0;
3
+ exports.useTimelineRowHighlightBackground = exports.useTimelineRowContainsSelection = exports.useTimelineGuideSelection = exports.useTimelineEasingSelection = exports.useTimelineKeyframeSelection = exports.useTimelineRowSelection = exports.useTimelineMarqueeSelectableItem = exports.useTimelineMarqueeSelection = exports.useCurrentTimelineSelectionStateAsRef = exports.TIMELINE_SCRUBBER_ATTR = exports.TIMELINE_MARQUEE_ITEM_ATTR = exports.useTimelineSelection = exports.TimelineSelectionProvider = exports.TimelineSelectableItemsProvider = exports.getTimelineSequenceSelectionForEscape = 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_HOVER_BACKGROUND = exports.TIMELINE_EXPANDED_SELECTED_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");
7
7
  const remotion_1 = require("remotion");
8
+ const browser_studio_operations_1 = require("../../helpers/browser-studio-operations");
8
9
  const client_id_1 = require("../../helpers/client-id");
9
10
  const colors_1 = require("../../helpers/colors");
10
11
  const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
@@ -21,9 +22,11 @@ const imperative_state_1 = require("./imperative-state");
21
22
  const parse_keyframe_field_from_node_path_1 = require("./parse-keyframe-field-from-node-path");
22
23
  const timeline_expanded_filter_1 = require("./timeline-expanded-filter");
23
24
  const timeline_refs_1 = require("./timeline-refs");
25
+ const timeline_scroll_logic_1 = require("./timeline-scroll-logic");
24
26
  const TimelineClipboardKeybindings_1 = require("./TimelineClipboardKeybindings");
25
27
  const TimelineDeleteKeybindings_1 = require("./TimelineDeleteKeybindings");
26
28
  exports.TIMELINE_SELECTED_BACKGROUND = colors_1.TIMELINE_SELECTED_BACKGROUND_COLOR;
29
+ exports.TIMELINE_EXPANDED_SELECTED_BACKGROUND = colors_1.BACKGROUND;
27
30
  exports.TIMELINE_HOVER_BACKGROUND = colors_1.WHITE_ALPHA_05;
28
31
  exports.TIMELINE_SELECTED_LABEL_BACKGROUND = colors_1.TIMELINE_SELECTED_LABEL_BACKGROUND_COLOR;
29
32
  exports.TIMELINE_SELECTED_LABEL_TEXT = colors_1.BLACK;
@@ -58,9 +61,9 @@ const getTimelineSelectedTrackHighlightStyle = (timelineWidth, backgroundColor =
58
61
  width: timelineWidth,
59
62
  });
60
63
  exports.getTimelineSelectedTrackHighlightStyle = getTimelineSelectedTrackHighlightStyle;
61
- const getTimelineRowHighlightBackground = ({ showSelectedBackground, selected, containsSelection, hovered, }) => {
64
+ const getTimelineRowHighlightBackground = ({ showSelectedBackground, selected, containsSelection, hovered, selectedBackground, }) => {
62
65
  if (showSelectedBackground && (selected || containsSelection)) {
63
- return exports.TIMELINE_SELECTED_BACKGROUND;
66
+ return selectedBackground;
64
67
  }
65
68
  return hovered ? exports.TIMELINE_HOVER_BACKGROUND : undefined;
66
69
  };
@@ -294,12 +297,12 @@ const extendTimelineMarqueeSelection = ({ currentSelection, marqueeSelection, })
294
297
  exports.extendTimelineMarqueeSelection = extendTimelineMarqueeSelection;
295
298
  const defaultTimelineSelectionContextValue = {
296
299
  canSelect: false,
300
+ revealRequest: null,
297
301
  selectedItems: [],
298
302
  isSelected: () => false,
299
303
  selectItem: () => undefined,
300
304
  selectItems: () => undefined,
301
305
  registerMarqueeSelectableItem: () => () => undefined,
302
- registerFocusableItem: () => () => undefined,
303
306
  getMarqueeSelection: () => ({
304
307
  lockedSelectionKind: null,
305
308
  selectedItems: [],
@@ -317,7 +320,6 @@ const TimelineSelectionOrderProvider = ({ children, items }) => {
317
320
  };
318
321
  exports.TimelineSelectionOrderProvider = TimelineSelectionOrderProvider;
319
322
  const CurrentTimelineSelectionContext = (0, react_1.createContext)(null);
320
- const TIMELINE_SELECTION_REVEAL_RETRY_COUNT = 2;
321
323
  const parseEffectIndex = (effectIndex) => {
322
324
  const parsed = Number(effectIndex);
323
325
  if (!Number.isInteger(parsed) || parsed < 0) {
@@ -644,13 +646,12 @@ const TimelineSelectionProvider = ({ children }) => {
644
646
  const canSelect = (0, interactivity_enabled_1.isStudioSelectionEnabled)() &&
645
647
  (previewServerState.type === 'connected' ||
646
648
  window.remotion_isReadOnlyStudio);
649
+ const keyframeOperationsAvailable = (0, browser_studio_operations_1.canUseKeyframeOperations)();
647
650
  const [selectedItems, setSelectedItems] = (0, react_1.useState)([]);
648
651
  const selectionAnchor = (0, react_1.useRef)(null);
649
652
  const selectionScope = (0, react_1.useRef)(null);
650
653
  const marqueeSelectableItems = (0, react_1.useRef)(new Map());
651
654
  const marqueeRegistrationCounter = (0, react_1.useRef)(0);
652
- const focusableItems = (0, react_1.useRef)(new Map());
653
- const focusableRegistrationCounter = (0, react_1.useRef)(0);
654
655
  const [revealRequest, setRevealRequest] = (0, react_1.useState)(null);
655
656
  (0, react_1.useEffect)(() => {
656
657
  if (!canSelect) {
@@ -661,7 +662,9 @@ const TimelineSelectionProvider = ({ children }) => {
661
662
  }
662
663
  }, [canSelect]);
663
664
  const canSelectItem = (0, react_1.useCallback)((item) => canSelect &&
664
- (!window.remotion_isReadOnlyStudio || item.type === 'sequence'), [canSelect]);
665
+ (!window.remotion_isReadOnlyStudio ||
666
+ keyframeOperationsAvailable ||
667
+ item.type === 'sequence'), [canSelect, keyframeOperationsAvailable]);
665
668
  const getCurrentAvailableSelectionState = (0, react_1.useCallback)((currentSelectedItems) => {
666
669
  if (selectionScope.current !== timelineSelectionScope) {
667
670
  return exports.EMPTY_TIMELINE_SELECTION_STATE;
@@ -673,58 +676,11 @@ const TimelineSelectionProvider = ({ children }) => {
673
676
  }, [timelineSelectionScope]);
674
677
  const availableSelectionState = getCurrentAvailableSelectionState(selectedItems);
675
678
  const availableSelectedItems = availableSelectionState.selectedItems;
676
- const revealSelectionKey = (0, react_1.useCallback)((selectedKey) => {
677
- let cancelled = false;
678
- let animationFrame = null;
679
- const reveal = (attempt) => {
680
- var _a;
681
- var _b;
682
- if (cancelled) {
683
- return;
684
- }
685
- const scrollParent = timeline_refs_1.timelineVerticalScroll.current;
686
- const focusableRegistrations = focusableItems.current.get(selectedKey);
687
- const focusableElement = scrollParent && focusableRegistrations
688
- ? [...focusableRegistrations.values()]
689
- .sort((a, b) => a.order - b.order)
690
- .map((registered) => registered.getElement())
691
- .find((element) => element !== null && scrollParent.contains(element))
692
- : null;
693
- const rect = (_b = focusableElement === null || focusableElement === void 0 ? void 0 : focusableElement.getBoundingClientRect()) !== null && _b !== void 0 ? _b : (_a = marqueeSelectableItems.current.get(selectedKey)) === null || _a === void 0 ? void 0 : _a.getRect();
694
- if (!scrollParent || !rect) {
695
- if (attempt < TIMELINE_SELECTION_REVEAL_RETRY_COUNT) {
696
- animationFrame = requestAnimationFrame(() => reveal(attempt + 1));
697
- }
698
- return;
699
- }
700
- const parentRect = scrollParent.getBoundingClientRect();
701
- if (rect.top >= parentRect.top && rect.bottom <= parentRect.bottom) {
702
- return;
703
- }
704
- const elementCenter = rect.top + rect.height / 2;
705
- const parentCenter = parentRect.top + parentRect.height / 2;
706
- scrollParent.scrollTop += elementCenter - parentCenter;
707
- };
708
- animationFrame = requestAnimationFrame(() => reveal(0));
709
- return () => {
710
- cancelled = true;
711
- if (animationFrame !== null) {
712
- cancelAnimationFrame(animationFrame);
713
- }
714
- };
715
- }, []);
716
- (0, react_1.useEffect)(() => {
717
- if (revealRequest === null) {
718
- return;
719
- }
720
- return revealSelectionKey(revealRequest.key);
721
- }, [revealRequest, revealSelectionKey]);
722
679
  const requestRevealSelectionItem = (0, react_1.useCallback)((item) => {
723
- const key = (0, exports.getTimelineSelectionKey)(item);
724
680
  setRevealRequest((previousRequest) => {
725
681
  var _a;
726
682
  return ({
727
- key,
683
+ item,
728
684
  token: ((_a = previousRequest === null || previousRequest === void 0 ? void 0 : previousRequest.token) !== null && _a !== void 0 ? _a : 0) + 1,
729
685
  });
730
686
  });
@@ -832,25 +788,6 @@ const TimelineSelectionProvider = ({ children }) => {
832
788
  marqueeSelectableItems.current.delete(key);
833
789
  };
834
790
  }, []);
835
- const registerFocusableItem = (0, react_1.useCallback)((item, getElement) => {
836
- var _a;
837
- const key = (0, exports.getTimelineSelectionKey)(item);
838
- const registrationOrder = focusableRegistrationCounter.current;
839
- focusableRegistrationCounter.current += 1;
840
- const registrations = (_a = focusableItems.current.get(key)) !== null && _a !== void 0 ? _a : new Map();
841
- registrations.set(registrationOrder, {
842
- getElement,
843
- order: registrationOrder,
844
- });
845
- focusableItems.current.set(key, registrations);
846
- return () => {
847
- const latestRegistrations = focusableItems.current.get(key);
848
- latestRegistrations === null || latestRegistrations === void 0 ? void 0 : latestRegistrations.delete(registrationOrder);
849
- if ((latestRegistrations === null || latestRegistrations === void 0 ? void 0 : latestRegistrations.size) === 0) {
850
- focusableItems.current.delete(key);
851
- }
852
- };
853
- }, []);
854
791
  const getMarqueeSelectionForRect = (0, react_1.useCallback)((marqueeRect, lockedSelectionKind) => {
855
792
  const candidates = [...marqueeSelectableItems.current.values()]
856
793
  .sort((a, b) => a.order - b.order)
@@ -891,23 +828,23 @@ const TimelineSelectionProvider = ({ children }) => {
891
828
  }, [availableSelectedItems]);
892
829
  const value = (0, react_1.useMemo)(() => ({
893
830
  canSelect,
831
+ revealRequest,
894
832
  selectedItems: availableSelectedItems,
895
833
  isSelected,
896
834
  selectItem,
897
835
  selectItems,
898
836
  registerMarqueeSelectableItem,
899
- registerFocusableItem,
900
837
  getMarqueeSelection: getMarqueeSelectionForRect,
901
838
  containsSelection,
902
839
  clearSelection,
903
840
  }), [
904
841
  canSelect,
842
+ revealRequest,
905
843
  availableSelectedItems,
906
844
  isSelected,
907
845
  selectItem,
908
846
  selectItems,
909
847
  registerMarqueeSelectableItem,
910
- registerFocusableItem,
911
848
  getMarqueeSelectionForRect,
912
849
  containsSelection,
913
850
  clearSelection,
@@ -938,6 +875,7 @@ const useTimelineMarqueeSelection = () => {
938
875
  const { isHighestContext } = (0, z_index_1.useZIndex)();
939
876
  const [marqueeRect, setMarqueeRect] = (0, react_1.useState)(null);
940
877
  const onPointerDownCapture = (0, react_1.useCallback)((event) => {
878
+ var _a, _b;
941
879
  if (!isHighestContext) {
942
880
  return;
943
881
  }
@@ -955,15 +893,18 @@ const useTimelineMarqueeSelection = () => {
955
893
  return;
956
894
  }
957
895
  const { currentTarget: target } = event;
896
+ const scrollable = timeline_refs_1.scrollableRef.current;
897
+ const verticalScroll = timeline_refs_1.timelineVerticalScroll.current;
898
+ const initialScrollLeft = (_a = scrollable === null || scrollable === void 0 ? void 0 : scrollable.scrollLeft) !== null && _a !== void 0 ? _a : 0;
899
+ const initialScrollTop = (_b = verticalScroll === null || verticalScroll === void 0 ? void 0 : verticalScroll.scrollTop) !== null && _b !== void 0 ? _b : 0;
958
900
  const initialBounds = target.getBoundingClientRect();
959
- const marqueeBounds = {
960
- bottom: initialBounds.bottom,
961
- left: initialBounds.left,
962
- right: initialBounds.right,
963
- top: initialBounds.top,
964
- };
965
901
  const start = (0, exports.getClampedTimelineMarqueePoint)({
966
- bounds: marqueeBounds,
902
+ bounds: {
903
+ bottom: initialBounds.bottom,
904
+ left: initialBounds.left,
905
+ right: initialBounds.right,
906
+ top: initialBounds.top,
907
+ },
967
908
  x: event.clientX,
968
909
  y: event.clientY,
969
910
  });
@@ -975,34 +916,64 @@ const useTimelineMarqueeSelection = () => {
975
916
  document.body.style.webkitUserSelect = 'none';
976
917
  let hasDragged = false;
977
918
  let lockedSelectionKind = null;
919
+ let lastClientX = event.clientX;
920
+ let lastClientY = event.clientY;
978
921
  const extendSelection = event.metaKey || event.ctrlKey;
979
922
  const selectionBeforeMarquee = selectedItems;
980
- const cleanup = () => {
981
- document.body.style.userSelect = previousUserSelect;
982
- document.body.style.webkitUserSelect = previousWebkitUserSelect;
983
- setMarqueeRect(null);
984
- };
985
923
  const updateSelection = (clientX, clientY) => {
924
+ var _a, _b, _c;
925
+ lastClientX = clientX;
926
+ lastClientY = clientY;
927
+ // The container moves when the timeline scrolls vertically, so read
928
+ // the bounds live. Restrict them to the visible viewport of the
929
+ // vertical scroller so the fixed-positioned marquee cannot paint
930
+ // outside the visible timeline area.
931
+ const liveBounds = target.getBoundingClientRect();
932
+ const verticalRect = (_a = verticalScroll === null || verticalScroll === void 0 ? void 0 : verticalScroll.getBoundingClientRect()) !== null && _a !== void 0 ? _a : null;
933
+ const bounds = {
934
+ bottom: verticalRect === null
935
+ ? liveBounds.bottom
936
+ : Math.min(liveBounds.bottom, verticalRect.bottom),
937
+ left: liveBounds.left,
938
+ right: liveBounds.right,
939
+ top: verticalRect === null
940
+ ? liveBounds.top
941
+ : Math.max(liveBounds.top, verticalRect.top),
942
+ };
943
+ // The anchor is fixed to timeline content, not to the screen:
944
+ // compensate for any scrolling that happened since pointerdown so the
945
+ // marquee keeps covering the originally spanned content while
946
+ // edge auto-scrolling. It is deliberately not clamped to the bounds -
947
+ // it may sit outside the viewport, and the selection should still
948
+ // include everything between it and the pointer.
949
+ const scrollDeltaX = ((_b = scrollable === null || scrollable === void 0 ? void 0 : scrollable.scrollLeft) !== null && _b !== void 0 ? _b : 0) - initialScrollLeft;
950
+ const scrollDeltaY = ((_c = verticalScroll === null || verticalScroll === void 0 ? void 0 : verticalScroll.scrollTop) !== null && _c !== void 0 ? _c : 0) - initialScrollTop;
951
+ const anchorX = startX - scrollDeltaX;
952
+ const anchorY = startY - scrollDeltaY;
986
953
  const current = (0, exports.getClampedTimelineMarqueePoint)({
987
- bounds: marqueeBounds,
954
+ bounds,
988
955
  x: clientX,
989
956
  y: clientY,
990
957
  });
991
958
  if (!hasDragged &&
992
- Math.max(Math.abs(current.x - startX), Math.abs(current.y - startY)) <
993
- 3) {
959
+ Math.max(Math.abs(current.x - anchorX), Math.abs(current.y - anchorY)) < 3) {
994
960
  return;
995
961
  }
996
962
  hasDragged = true;
997
963
  const rect = (0, exports.getNormalizedTimelineMarqueeRect)({
998
964
  currentX: current.x,
999
965
  currentY: current.y,
1000
- startX,
1001
- startY,
966
+ startX: anchorX,
967
+ startY: anchorY,
1002
968
  });
1003
969
  const nextSelection = getMarqueeSelection(rect, lockedSelectionKind);
1004
970
  lockedSelectionKind = nextSelection.lockedSelectionKind;
1005
- setMarqueeRect(rect);
971
+ setMarqueeRect({
972
+ bottom: Math.min(rect.bottom, bounds.bottom),
973
+ left: Math.max(rect.left, bounds.left),
974
+ right: Math.min(rect.right, bounds.right),
975
+ top: Math.max(rect.top, bounds.top),
976
+ });
1006
977
  selectItems(extendSelection
1007
978
  ? (0, exports.extendTimelineMarqueeSelection)({
1008
979
  currentSelection: selectionBeforeMarquee,
@@ -1010,8 +981,35 @@ const useTimelineMarqueeSelection = () => {
1010
981
  })
1011
982
  : nextSelection.selectedItems);
1012
983
  };
984
+ const autoScroll = (0, timeline_scroll_logic_1.startTimelineEdgeAutoScroll)({
985
+ includeVertical: true,
986
+ onTick: (directions) => {
987
+ if (scrollable && directions.x !== null) {
988
+ scrollable.scrollLeft +=
989
+ directions.x === 'left' ? -timeline_scroll_logic_1.SCROLL_INCREMENT : timeline_scroll_logic_1.SCROLL_INCREMENT;
990
+ }
991
+ if (verticalScroll && directions.y !== null) {
992
+ verticalScroll.scrollTop +=
993
+ directions.y === 'up'
994
+ ? -timeline_scroll_logic_1.EDGE_SCROLL_VERTICAL_INCREMENT
995
+ : timeline_scroll_logic_1.EDGE_SCROLL_VERTICAL_INCREMENT;
996
+ }
997
+ updateSelection(lastClientX, lastClientY);
998
+ },
999
+ });
1000
+ const cleanup = () => {
1001
+ autoScroll.stop();
1002
+ document.body.style.userSelect = previousUserSelect;
1003
+ document.body.style.webkitUserSelect = previousWebkitUserSelect;
1004
+ setMarqueeRect(null);
1005
+ };
1013
1006
  const onPointerMove = (moveEvent) => {
1014
1007
  updateSelection(moveEvent.clientX, moveEvent.clientY);
1008
+ // Only auto-scroll for an actual marquee drag, not a plain click
1009
+ // near an edge
1010
+ if (hasDragged) {
1011
+ autoScroll.update(moveEvent);
1012
+ }
1015
1013
  };
1016
1014
  (0, pointer_session_1.startCapturedPointerSession)({
1017
1015
  event,
@@ -1049,16 +1047,6 @@ const useTimelineMarqueeSelectableItem = (item, ref) => {
1049
1047
  }, [item, ref, registerMarqueeSelectableItem]);
1050
1048
  };
1051
1049
  exports.useTimelineMarqueeSelectableItem = useTimelineMarqueeSelectableItem;
1052
- const useTimelineFocusableItem = (item, ref) => {
1053
- const { registerFocusableItem } = (0, exports.useTimelineSelection)();
1054
- (0, react_1.useEffect)(() => {
1055
- if (item === null) {
1056
- return;
1057
- }
1058
- return registerFocusableItem(item, () => ref.current);
1059
- }, [item, ref, registerFocusableItem]);
1060
- };
1061
- exports.useTimelineFocusableItem = useTimelineFocusableItem;
1062
1050
  const useTimelineRowSelection = (nodePathInfo) => {
1063
1051
  const { canSelect, isSelected, selectItem } = (0, exports.useTimelineSelection)();
1064
1052
  const selectableTimelineItemsRef = (0, react_1.useContext)(SelectableTimelineItemsContext);
@@ -1147,7 +1135,7 @@ const useTimelineRowContainsSelection = (nodePathInfo) => {
1147
1135
  return containsSelection(nodePathInfo);
1148
1136
  };
1149
1137
  exports.useTimelineRowContainsSelection = useTimelineRowContainsSelection;
1150
- const useTimelineRowHighlightBackground = (nodePathInfo, hovered = false) => {
1138
+ const useTimelineRowHighlightBackground = (nodePathInfo, { hovered, selectedBackground, }) => {
1151
1139
  const { selected } = (0, exports.useTimelineRowSelection)(nodePathInfo);
1152
1140
  const containsSelection = (0, exports.useTimelineRowContainsSelection)(nodePathInfo);
1153
1141
  return (0, exports.getTimelineRowHighlightBackground)({
@@ -1155,6 +1143,7 @@ const useTimelineRowHighlightBackground = (nodePathInfo, hovered = false) => {
1155
1143
  selected,
1156
1144
  containsSelection,
1157
1145
  hovered,
1146
+ selectedBackground,
1158
1147
  });
1159
1148
  };
1160
1149
  exports.useTimelineRowHighlightBackground = useTimelineRowHighlightBackground;
@@ -47,16 +47,16 @@ const timeline_layout_1 = require("../../helpers/timeline-layout");
47
47
  const use_max_media_duration_1 = require("../../helpers/use-max-media-duration");
48
48
  const modals_1 = require("../../state/modals");
49
49
  const AudioWaveform_1 = require("../AudioWaveform");
50
- const call_api_1 = require("../call-api");
51
50
  const ConfirmationDialog_1 = require("../ConfirmationDialog");
52
51
  const ContextMenu_1 = require("../ContextMenu");
52
+ const delete_jsx_node_api_1 = require("../delete-jsx-node-api");
53
53
  const InitialCompositionLoader_1 = require("../InitialCompositionLoader");
54
54
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
55
55
  const use_select_asset_1 = require("../use-select-asset");
56
56
  const disable_sequence_interactivity_1 = require("./disable-sequence-interactivity");
57
57
  const duplicate_selected_timeline_item_1 = require("./duplicate-selected-timeline-item");
58
58
  const get_sequence_context_menu_items_1 = require("./get-sequence-context-menu-items");
59
- const get_timeline_media_visualization_layout_1 = require("./get-timeline-media-visualization-layout");
59
+ const get_timeline_sequence_visible_layout_1 = require("./get-timeline-sequence-visible-layout");
60
60
  const imperative_state_1 = require("./imperative-state");
61
61
  const LoopedTimelineIndicators_1 = require("./LoopedTimelineIndicators");
62
62
  const timeline_asset_link_1 = require("./timeline-asset-link");
@@ -65,6 +65,7 @@ const TimelineSelection_1 = require("./TimelineSelection");
65
65
  const TimelineSequenceFrame_1 = require("./TimelineSequenceFrame");
66
66
  const TimelineSequenceRightEdgeDragHandle_1 = require("./TimelineSequenceRightEdgeDragHandle");
67
67
  const TimelineVideoInfo_1 = require("./TimelineVideoInfo");
68
+ const TimelineViewport_1 = require("./TimelineViewport");
68
69
  const TimelineWidthProvider_1 = require("./TimelineWidthProvider");
69
70
  const use_open_sequence_in_apps_1 = require("./use-open-sequence-in-apps");
70
71
  const use_sequence_freeze_frame_menu_item_1 = require("./use-sequence-freeze-frame-menu-item");
@@ -75,8 +76,8 @@ const TimelineSequenceFn = ({ s, connectedCompositions, nodePathInfo, sequenceFr
75
76
  }
76
77
  return (jsx_runtime_1.jsx(TimelineSequenceInner, { windowWidth: windowWidth, s: s, connectedCompositions: connectedCompositions, nodePathInfo: nodePathInfo, sequenceFrameOffset: sequenceFrameOffset }));
77
78
  };
78
- const TimelineSequenceCurrentFrame = ({ s, displayDurationInFrames, premountWidth, postmountWidth, style, children, nodePathInfo, sequenceFrameOffset, fromCanUpdate, frozenFrame, onMoveDragPointerDown, onDoubleClick, }) => {
79
- var _a, _b;
79
+ const TimelineSequenceCurrentFrame = ({ s, displayDurationInFrames, premount, postmount, style, children, nodePathInfo, sequenceFrameOffset, fromCanUpdate, frozenFrame, onMoveDragPointerDown, onDoubleClick, }) => {
80
+ var _a, _b, _c;
80
81
  const ref = (0, react_1.useRef)(null);
81
82
  const { onSelect, selectable, selected, selectionItem } = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
82
83
  (0, TimelineSelection_1.useTimelineMarqueeSelectableItem)(selectionItem, ref);
@@ -118,8 +119,9 @@ const TimelineSequenceCurrentFrame = ({ s, displayDurationInFrames, premountWidt
118
119
  opacity: isInRange ? 1 : 0.5,
119
120
  };
120
121
  }, [isInRange, style]);
121
- 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: {
122
- width: premountWidth,
122
+ 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: [premount ? (jsx_runtime_1.jsx("div", { style: {
123
+ left: premount.left,
124
+ width: premount.width,
123
125
  height: '100%',
124
126
  background: `repeating-linear-gradient(
125
127
  -45deg,
@@ -129,8 +131,9 @@ const TimelineSequenceCurrentFrame = ({ s, displayDurationInFrames, premountWidt
129
131
  ${isPremounting ? colors_1.WHITE_ALPHA_50 : colors_1.WHITE_ALPHA_20} 4px
130
132
  )`,
131
133
  position: 'absolute',
132
- } })) : null, postmountWidth ? (jsx_runtime_1.jsx("div", { style: {
133
- width: postmountWidth,
134
+ } })) : null, postmount ? (jsx_runtime_1.jsx("div", { style: {
135
+ left: postmount.left,
136
+ width: postmount.width,
134
137
  height: '100%',
135
138
  background: `repeating-linear-gradient(
136
139
  -45deg,
@@ -140,13 +143,12 @@ const TimelineSequenceCurrentFrame = ({ s, displayDurationInFrames, premountWidt
140
143
  ${isPostmounting ? colors_1.WHITE_ALPHA_50 : colors_1.WHITE_ALPHA_20} 4px
141
144
  )`,
142
145
  position: 'absolute',
143
- right: 0,
144
146
  } })) : null, children, s.type !== 'audio' &&
145
147
  s.type !== 'video' &&
146
148
  s.type !== 'image' &&
147
149
  s.loopDisplay === undefined &&
148
150
  (isInRange || isPremounting || isPostmounting) ? (jsx_runtime_1.jsx("div", { style: {
149
- paddingLeft: 5 + (premountWidth !== null && premountWidth !== void 0 ? premountWidth : 0),
151
+ paddingLeft: 5 + ((_c = premount === null || premount === void 0 ? void 0 : premount.width) !== null && _c !== void 0 ? _c : 0),
150
152
  height: '100%',
151
153
  display: 'flex',
152
154
  alignItems: 'center',
@@ -159,6 +161,7 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
159
161
  var _a, _b, _c;
160
162
  var _d, _e, _f, _g, _h, _j;
161
163
  const video = remotion_1.Internals.useVideo();
164
+ const renderWindow = (0, react_1.useContext)(TimelineViewport_1.TimelineViewportContext);
162
165
  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);
163
166
  const effectiveMaxMediaDuration = s.loopDisplay ? null : maxMediaDuration;
164
167
  const extendVideoLastFrame = (0, is_video_with_last_frame_hold_1.isVideoWithLastFrameHold)(s);
@@ -270,7 +273,7 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
270
273
  }
271
274
  }
272
275
  try {
273
- const result = await (0, call_api_1.callApi)('/api/delete-jsx-node', {
276
+ const result = await (0, delete_jsx_node_api_1.deleteJsxNode)({
274
277
  nodes: [
275
278
  {
276
279
  fileName: validatedLocation.source,
@@ -403,7 +406,7 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
403
406
  const displayDurationInFrames = s.loopDisplay
404
407
  ? s.loopDisplay.durationInFrames * s.loopDisplay.numberOfTimes
405
408
  : s.duration;
406
- const { marginLeft, width, naturalWidth, premountWidth, postmountWidth } = (0, react_1.useMemo)(() => {
409
+ const { marginLeft, width, premountWidth, postmountWidth } = (0, react_1.useMemo)(() => {
407
410
  return (0, get_timeline_sequence_layout_1.getTimelineSequenceLayout)({
408
411
  durationInFrames: displayDurationInFrames,
409
412
  startFrom: s.loopDisplay ? s.from + s.loopDisplay.startOffset : s.from,
@@ -421,21 +424,30 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
421
424
  video,
422
425
  windowWidth,
423
426
  ]);
424
- const mediaVisualizationLayout = (0, react_1.useMemo)(() => {
425
- return (0, get_timeline_media_visualization_layout_1.getTimelineMediaVisualizationLayout)({
426
- visualizationWidth: width,
427
+ const visibleLayout = (0, react_1.useMemo)(() => {
428
+ if (renderWindow === null) {
429
+ return null;
430
+ }
431
+ return (0, get_timeline_sequence_visible_layout_1.getTimelineSequenceVisibleLayout)({
432
+ marginLeft,
433
+ width,
427
434
  premountWidth: premountWidth !== null && premountWidth !== void 0 ? premountWidth : 0,
428
435
  postmountWidth: postmountWidth !== null && postmountWidth !== void 0 ? postmountWidth : 0,
436
+ renderWindowLeft: renderWindow.left - timeline_layout_1.TIMELINE_PADDING,
437
+ renderWindowWidth: renderWindow.width,
429
438
  });
430
- }, [postmountWidth, premountWidth, width]);
439
+ }, [marginLeft, postmountWidth, premountWidth, renderWindow, width]);
431
440
  const mediaVisualizationStyle = (0, react_1.useMemo)(() => {
441
+ var _a, _b;
442
+ var _c, _d;
432
443
  return {
433
- width: mediaVisualizationLayout.width,
434
- marginLeft: mediaVisualizationLayout.marginLeft,
444
+ width: (_c = (_a = visibleLayout === null || visibleLayout === void 0 ? void 0 : visibleLayout.media) === null || _a === void 0 ? void 0 : _a.width) !== null && _c !== void 0 ? _c : 0,
445
+ marginLeft: (_d = (_b = visibleLayout === null || visibleLayout === void 0 ? void 0 : visibleLayout.media) === null || _b === void 0 ? void 0 : _b.left) !== null && _d !== void 0 ? _d : 0,
435
446
  height: '100%',
436
447
  };
437
- }, [mediaVisualizationLayout]);
448
+ }, [visibleLayout]);
438
449
  const style = (0, react_1.useMemo)(() => {
450
+ var _a, _b;
439
451
  return {
440
452
  background: s.type === 'audio'
441
453
  ? colors_1.TIMELINE_AUDIO_GRADIENT
@@ -445,15 +457,24 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
445
457
  ? colors_1.TIMELINE_IMAGE_GRADIENT
446
458
  : colors_1.BLUE,
447
459
  border: `${get_timeline_sequence_layout_1.SEQUENCE_BORDER_WIDTH}px solid ${colors_1.WHITE_ALPHA_20}`,
448
- borderRadius: 2,
460
+ borderLeftColor: (visibleLayout === null || visibleLayout === void 0 ? void 0 : visibleLayout.leftEdgeVisible)
461
+ ? colors_1.WHITE_ALPHA_20
462
+ : colors_1.TRANSPARENT,
463
+ borderRightColor: (visibleLayout === null || visibleLayout === void 0 ? void 0 : visibleLayout.rightEdgeVisible)
464
+ ? colors_1.WHITE_ALPHA_20
465
+ : colors_1.TRANSPARENT,
466
+ borderTopLeftRadius: (visibleLayout === null || visibleLayout === void 0 ? void 0 : visibleLayout.leftEdgeVisible) ? 2 : 0,
467
+ borderBottomLeftRadius: (visibleLayout === null || visibleLayout === void 0 ? void 0 : visibleLayout.leftEdgeVisible) ? 2 : 0,
468
+ borderTopRightRadius: (visibleLayout === null || visibleLayout === void 0 ? void 0 : visibleLayout.rightEdgeVisible) ? 2 : 0,
469
+ borderBottomRightRadius: (visibleLayout === null || visibleLayout === void 0 ? void 0 : visibleLayout.rightEdgeVisible) ? 2 : 0,
449
470
  position: 'absolute',
450
471
  height: (0, timeline_layout_1.getTimelineLayerHeight)(s.type),
451
- marginLeft,
452
- width,
472
+ marginLeft: (_a = visibleLayout === null || visibleLayout === void 0 ? void 0 : visibleLayout.marginLeft) !== null && _a !== void 0 ? _a : 0,
473
+ width: (_b = visibleLayout === null || visibleLayout === void 0 ? void 0 : visibleLayout.width) !== null && _b !== void 0 ? _b : 0,
453
474
  color: colors_1.WHITE,
454
475
  overflow: 'hidden',
455
476
  };
456
- }, [marginLeft, s.type, width]);
477
+ }, [s.type, visibleLayout]);
457
478
  const showRightEdgeDragHandle = (0, TimelineSequenceRightEdgeDragHandle_1.isTimelineSequenceDurationDraggable)(s) &&
458
479
  nodePath !== null &&
459
480
  validatedLocation !== null &&
@@ -464,10 +485,23 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
464
485
  ((0, TimelineSequenceRightEdgeDragHandle_1.isCascadingSequence)(s) || fromCanUpdate) &&
465
486
  durationCanUpdate &&
466
487
  trimBeforeCanUpdate;
467
- if (maxMediaDuration === null && !s.loopDisplay) {
488
+ if ((maxMediaDuration === null && !s.loopDisplay) || visibleLayout === null) {
468
489
  return null;
469
490
  }
470
- 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] }));
491
+ const frameIncrement = (windowWidth - timeline_layout_1.TIMELINE_PADDING * 2) / video.durationInFrames;
492
+ const mediaDisplayOffsetInFrames = visibleLayout.media
493
+ ? visibleLayout.media.offset / frameIncrement
494
+ : 0;
495
+ const mediaDisplayDurationInFrames = visibleLayout.media
496
+ ? visibleLayout.media.width / frameIncrement
497
+ : 0;
498
+ const sequence = (jsx_runtime_1.jsxs(TimelineSequenceCurrentFrame, { s: s, displayDurationInFrames: displayDurationInFrames, premount: visibleLayout.premount, postmount: visibleLayout.postmount, style: style, nodePathInfo: nodePathInfo, sequenceFrameOffset: sequenceFrameOffset, fromCanUpdate: fromCanUpdate, frozenFrame: frozenFrame, onMoveDragPointerDown: onMoveDragPointerDown, onDoubleClick: canHandleSequenceDoubleClick ? onSequenceDoubleClick : undefined, children: [s.type === 'audio' && visibleLayout.media ? (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, muted: s.muted, visualizationWidth: visibleLayout.media.width, startFrom: s.startMediaFrom, durationInFrames: s.duration, displayOffsetInFrames: mediaDisplayOffsetInFrames, displayDurationInFrames: mediaDisplayDurationInFrames, volume: s.volume, playbackRate: s.playbackRate, loopDisplay: s.loopDisplay }) })) : null, s.type === 'video' && visibleLayout.media ? (jsx_runtime_1.jsx(TimelineVideoInfo_1.TimelineVideoInfo, { src: s.src, visualizationWidth: visibleLayout.media.width, displayOffsetInFrames: mediaDisplayOffsetInFrames, displayDurationInFrames: mediaDisplayDurationInFrames, startMediaFrom: s.startMediaFrom, mediaFrameAtSequenceZero: s.mediaFrameAtSequenceZero, sequenceFrameOffset: sequenceFrameOffset, playbackRate: s.playbackRate, volume: s.volume, muted: s.muted, doesVolumeChange: s.doesVolumeChange, marginLeft: visibleLayout.media.left, loopDisplay: s.loopDisplay, frozenMediaFrame: s.frozenMediaFrame, extendLastFrame: extendVideoLastFrame })) : null, s.type === 'image' && visibleLayout.media ? (jsx_runtime_1.jsx("div", { style: mediaVisualizationStyle, children: jsx_runtime_1.jsx(TimelineImageInfo_1.TimelineImageInfo, { src: s.src, visualizationWidth: visibleLayout.media.width, offsetInPixels: visibleLayout.media.offset }) })) : null, s.loopDisplay === undefined ? null : (jsx_runtime_1.jsx(LoopedTimelineIndicators_1.LoopedTimelineIndicator, { loops: s.loopDisplay.numberOfTimes, fullWidth: width, visibleOffset: visibleLayout.cropLeft, visibleWidth: visibleLayout.width })), showLeftEdgeDragHandle &&
499
+ visibleLayout.leftEdgeVisible &&
500
+ nodePathInfo &&
501
+ validatedLocation ? (jsx_runtime_1.jsx(TimelineSequenceRightEdgeDragHandle_1.TimelineSequenceLeftEdgeDragHandle, { nodePathInfo: nodePathInfo, windowWidth: windowWidth, timelineDurationInFrames: (_h = video.durationInFrames) !== null && _h !== void 0 ? _h : 1 })) : null, showRightEdgeDragHandle &&
502
+ visibleLayout.rightEdgeVisible &&
503
+ nodePathInfo &&
504
+ validatedLocation ? (jsx_runtime_1.jsx(TimelineSequenceRightEdgeDragHandle_1.TimelineSequenceRightEdgeDragHandle, { nodePathInfo: nodePathInfo, windowWidth: windowWidth, timelineDurationInFrames: (_j = video.durationInFrames) !== null && _j !== void 0 ? _j : 1 })) : null] }));
471
505
  return previewConnected || window.remotion_isReadOnlyStudio ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { getItems: getContextMenuItems, children: sequence })) : (sequence);
472
506
  };
473
507
  exports.TimelineSequence = react_1.default.memo(TimelineSequenceFn);
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import type { TSequence } from 'remotion';
3
3
  import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
4
4
  export declare const TimelineSequenceItem: React.NamedExoticComponent<{
5
- readonly children: React.ReactNode;
5
+ readonly afterDropLineOffset: number;
6
6
  readonly sequence: TSequence;
7
7
  readonly connectedCompositions: readonly import("remotion").AnyComposition[];
8
8
  readonly nestedDepth: number;