@remotion/studio 4.0.513 → 4.0.514

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 (174) hide show
  1. package/dist/Studio.js +2 -1
  2. package/dist/components/AskAiModal.js +1 -1
  3. package/dist/components/AssetSelector.js +2 -0
  4. package/dist/components/AssetSelectorItem.js +1 -2
  5. package/dist/components/AudioWaveform.d.ts +3 -0
  6. package/dist/components/AudioWaveform.js +55 -67
  7. package/dist/components/Canvas.js +40 -5
  8. package/dist/components/CanvasOrLoading.js +5 -0
  9. package/dist/components/CompositionSelector.js +2 -0
  10. package/dist/components/ConfigureDefaultEditorModal.js +17 -11
  11. package/dist/components/Editor.js +16 -1
  12. package/dist/components/ElementInstallConfirmation.d.ts +1 -0
  13. package/dist/components/ElementInstallConfirmation.js +4 -2
  14. package/dist/components/FixComputedValueModal.d.ts +9 -0
  15. package/dist/components/FixComputedValueModal.js +217 -0
  16. package/dist/components/InitialCompositionLoader.js +19 -0
  17. package/dist/components/InlineDropdown.js +4 -4
  18. package/dist/components/InspectorInfoHeader.js +3 -3
  19. package/dist/components/InspectorOpenInEditor.js +3 -1
  20. package/dist/components/InspectorPanel/CompositionInspector.js +11 -1
  21. package/dist/components/InspectorPanel/CompositionInspectorHeader.js +2 -2
  22. package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +1 -1
  23. package/dist/components/InspectorPanel/EasingInspector.js +1 -1
  24. package/dist/components/InspectorPanel/KeyframeInspector.js +2 -2
  25. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +1 -1
  26. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +35 -6
  27. package/dist/components/InspectorPanel/common.d.ts +5 -5
  28. package/dist/components/InspectorPanel/common.js +8 -8
  29. package/dist/components/InspectorPanel/styles.d.ts +1 -1
  30. package/dist/components/InspectorPanel/styles.js +4 -2
  31. package/dist/components/InspectorSourceLocation.d.ts +1 -1
  32. package/dist/components/InspectorSourceLocation.js +2 -2
  33. package/dist/components/LicenseKeyValidation.js +2 -2
  34. package/dist/components/Modals.js +2 -1
  35. package/dist/components/NewComposition/CodemodFooter.d.ts +1 -0
  36. package/dist/components/NewComposition/CodemodFooter.js +10 -8
  37. package/dist/components/NewComposition/DeleteComposition.js +1 -1
  38. package/dist/components/NewComposition/DeleteFolder.js +1 -1
  39. package/dist/components/NewComposition/DuplicateComposition.js +7 -2
  40. package/dist/components/NewComposition/NewComposition.js +1 -1
  41. package/dist/components/NewComposition/NewFolder.js +1 -1
  42. package/dist/components/NewComposition/RenameComposition.js +1 -1
  43. package/dist/components/NewComposition/RenameFolder.js +1 -1
  44. package/dist/components/NewComposition/duplicate-composition-api.d.ts +16 -0
  45. package/dist/components/NewComposition/duplicate-composition-api.js +16 -0
  46. package/dist/components/NoRegisterRoot.js +1 -1
  47. package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.js +4 -3
  48. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +1 -0
  49. package/dist/components/QuickSwitcher/fuzzy-search.js +1 -1
  50. package/dist/components/RefreshCompositionOverlay.js +1 -1
  51. package/dist/components/RenderButton.js +6 -3
  52. package/dist/components/RenderModal/WebRenderModal.js +6 -2
  53. package/dist/components/RenderModal/WebRenderModalAdvanced.d.ts +2 -0
  54. package/dist/components/RenderModal/WebRenderModalAdvanced.js +9 -2
  55. package/dist/components/RenderModal/render-modals.js +5 -1
  56. package/dist/components/RenderQueue/ClientRenderQueueProcessor.js +5 -1
  57. package/dist/components/RenderQueue/actions.js +12 -2
  58. package/dist/components/RenderQueue/client-side-render-types.d.ts +1 -0
  59. package/dist/components/RenderingSettings.d.ts +2 -0
  60. package/dist/components/RenderingSettings.js +355 -0
  61. package/dist/components/SelectedOutlineElement.js +3 -3
  62. package/dist/components/SelectedOutlinePolygon.d.ts +1 -0
  63. package/dist/components/SelectedOutlinePolygon.js +53 -9
  64. package/dist/components/SettingsContext.d.ts +4 -1
  65. package/dist/components/SettingsContext.js +9 -2
  66. package/dist/components/SettingsModal.d.ts +1 -1
  67. package/dist/components/SettingsModal.js +10 -1
  68. package/dist/components/SettingsModalFooter.js +1 -1
  69. package/dist/components/StudioSettings.d.ts +2 -0
  70. package/dist/components/StudioSettings.js +185 -0
  71. package/dist/components/Timeline/LoopedIndicator.js +1 -1
  72. package/dist/components/Timeline/LoopedTimelineIndicators.d.ts +3 -0
  73. package/dist/components/Timeline/LoopedTimelineIndicators.js +22 -14
  74. package/dist/components/Timeline/Timeline.js +11 -9
  75. package/dist/components/Timeline/TimelineAssetField.d.ts +2 -2
  76. package/dist/components/Timeline/TimelineAssetField.js +1 -1
  77. package/dist/components/Timeline/TimelineDragHandler.js +62 -76
  78. package/dist/components/Timeline/TimelineEffectItem.js +1 -1
  79. package/dist/components/Timeline/TimelineEffectPropItem.d.ts +4 -2
  80. package/dist/components/Timeline/TimelineEffectPropItem.js +16 -11
  81. package/dist/components/Timeline/TimelineExpandedRow.d.ts +1 -1
  82. package/dist/components/Timeline/TimelineExpandedRow.js +4 -4
  83. package/dist/components/Timeline/TimelineExpandedSection.js +1 -1
  84. package/dist/components/Timeline/TimelineHeightContainer.d.ts +0 -4
  85. package/dist/components/Timeline/TimelineHeightContainer.js +4 -4
  86. package/dist/components/Timeline/TimelineImageInfo.d.ts +1 -0
  87. package/dist/components/Timeline/TimelineImageInfo.js +3 -2
  88. package/dist/components/Timeline/TimelineKeyframeControls.js +6 -1
  89. package/dist/components/Timeline/TimelineList.d.ts +1 -5
  90. package/dist/components/Timeline/TimelineList.js +14 -9
  91. package/dist/components/Timeline/TimelinePinchZoom.js +5 -5
  92. package/dist/components/Timeline/TimelineRowChrome.d.ts +0 -2
  93. package/dist/components/Timeline/TimelineRowChrome.js +12 -5
  94. package/dist/components/Timeline/TimelineSchemaField.d.ts +7 -3
  95. package/dist/components/Timeline/TimelineSchemaField.js +71 -13
  96. package/dist/components/Timeline/TimelineScrollable.js +3 -1
  97. package/dist/components/Timeline/TimelineSelection.d.ts +5 -2
  98. package/dist/components/Timeline/TimelineSelection.js +90 -103
  99. package/dist/components/Timeline/TimelineSequence.js +59 -25
  100. package/dist/components/Timeline/TimelineSequenceItem.d.ts +1 -1
  101. package/dist/components/Timeline/TimelineSequenceItem.js +15 -9
  102. package/dist/components/Timeline/TimelineSequencePropItem.d.ts +2 -1
  103. package/dist/components/Timeline/TimelineSequencePropItem.js +3 -3
  104. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +33 -10
  105. package/dist/components/Timeline/TimelineSlider.js +42 -33
  106. package/dist/components/Timeline/TimelineTimeIndicators.js +90 -98
  107. package/dist/components/Timeline/TimelineTracks.d.ts +0 -2
  108. package/dist/components/Timeline/TimelineTracks.js +11 -4
  109. package/dist/components/Timeline/TimelineTransformOriginField.js +1 -1
  110. package/dist/components/Timeline/TimelineVideoInfo.d.ts +4 -4
  111. package/dist/components/Timeline/TimelineVideoInfo.js +151 -61
  112. package/dist/components/Timeline/TimelineViewport.d.ts +12 -0
  113. package/dist/components/Timeline/TimelineViewport.js +62 -0
  114. package/dist/components/Timeline/TimelineVirtualization.d.ts +22 -0
  115. package/dist/components/Timeline/TimelineVirtualization.js +144 -0
  116. package/dist/components/Timeline/TimelineZoomControls.js +16 -8
  117. package/dist/components/Timeline/call-add-keyframe.js +31 -3
  118. package/dist/components/Timeline/call-delete-keyframe.js +13 -3
  119. package/dist/components/Timeline/call-move-keyframe.js +11 -1
  120. package/dist/components/Timeline/call-update-keyframe-settings.js +31 -3
  121. package/dist/components/Timeline/delete-selected-timeline-item.js +2 -1
  122. package/dist/components/Timeline/get-timeline-keyframes.d.ts +1 -2
  123. package/dist/components/Timeline/get-timeline-keyframes.js +1 -8
  124. package/dist/components/Timeline/get-timeline-sequence-visible-layout.d.ts +30 -0
  125. package/dist/components/Timeline/get-timeline-sequence-visible-layout.js +61 -0
  126. package/dist/components/Timeline/split-selected-timeline-item.js +2 -2
  127. package/dist/components/Timeline/timeline-scroll-logic.d.ts +24 -0
  128. package/dist/components/Timeline/timeline-scroll-logic.js +127 -4
  129. package/dist/components/Timeline/use-timeline-height.d.ts +3 -5
  130. package/dist/components/Timeline/use-timeline-height.js +16 -18
  131. package/dist/components/UpdateCheck.d.ts +2 -10
  132. package/dist/components/UpdateCheck.js +8 -2
  133. package/dist/components/VisualControls/VisualControlHandle.js +8 -0
  134. package/dist/components/delete-jsx-node-api.d.ts +2 -0
  135. package/dist/components/delete-jsx-node-api.js +12 -0
  136. package/dist/components/element-install-api.d.ts +3 -0
  137. package/dist/components/element-install-api.js +19 -0
  138. package/dist/components/import-assets.js +20 -9
  139. package/dist/components/reorder-sequence-api.d.ts +2 -0
  140. package/dist/components/reorder-sequence-api.js +12 -0
  141. package/dist/components/split-jsx-sequence-api.d.ts +2 -0
  142. package/dist/components/split-jsx-sequence-api.js +12 -0
  143. package/dist/components/split-video-from-audio-api.d.ts +2 -0
  144. package/dist/components/split-video-from-audio-api.js +12 -0
  145. package/dist/error-overlay/remotion-overlay/Overlay.js +1 -1
  146. package/dist/esm/{chunk-tv7r0jy3.js → chunk-xn2q7eem.js} +11073 -7495
  147. package/dist/esm/index.mjs +7 -5
  148. package/dist/esm/internals.mjs +11073 -7495
  149. package/dist/esm/previewEntry.mjs +10905 -7327
  150. package/dist/esm/renderEntry.mjs +2 -3
  151. package/dist/helpers/browser-studio-operations.d.ts +2 -0
  152. package/dist/helpers/browser-studio-operations.js +10 -1
  153. package/dist/helpers/get-timeline-max-zoom.d.ts +26 -0
  154. package/dist/helpers/get-timeline-max-zoom.js +45 -0
  155. package/dist/helpers/inject-css.js +2 -2
  156. package/dist/helpers/render-codec-label.d.ts +1 -1
  157. package/dist/helpers/retry-payload.js +1 -0
  158. package/dist/helpers/studio-runtime-config.d.ts +1 -1
  159. package/dist/helpers/studio-runtime-config.js +2 -3
  160. package/dist/helpers/timeline-layout.d.ts +3 -1
  161. package/dist/helpers/timeline-layout.js +6 -1
  162. package/dist/helpers/url-state.js +3 -2
  163. package/dist/helpers/use-menu-structure.js +1 -5
  164. package/dist/helpers/use-runtime-values.d.ts +2 -1
  165. package/dist/helpers/use-runtime-values.js +7 -3
  166. package/dist/icons/remotion-triangle.d.ts +2 -0
  167. package/dist/icons/remotion-triangle.js +7 -0
  168. package/dist/renderEntry.js +1 -1
  169. package/dist/state/composition-list.d.ts +13 -0
  170. package/dist/state/composition-list.js +21 -0
  171. package/dist/state/modals.d.ts +7 -1
  172. package/dist/state/timeline-zoom.d.ts +1 -2
  173. package/dist/state/timeline-zoom.js +9 -5
  174. 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_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,6 +22,7 @@ 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;
@@ -294,12 +296,12 @@ const extendTimelineMarqueeSelection = ({ currentSelection, marqueeSelection, })
294
296
  exports.extendTimelineMarqueeSelection = extendTimelineMarqueeSelection;
295
297
  const defaultTimelineSelectionContextValue = {
296
298
  canSelect: false,
299
+ revealRequest: null,
297
300
  selectedItems: [],
298
301
  isSelected: () => false,
299
302
  selectItem: () => undefined,
300
303
  selectItems: () => undefined,
301
304
  registerMarqueeSelectableItem: () => () => undefined,
302
- registerFocusableItem: () => () => undefined,
303
305
  getMarqueeSelection: () => ({
304
306
  lockedSelectionKind: null,
305
307
  selectedItems: [],
@@ -317,7 +319,6 @@ const TimelineSelectionOrderProvider = ({ children, items }) => {
317
319
  };
318
320
  exports.TimelineSelectionOrderProvider = TimelineSelectionOrderProvider;
319
321
  const CurrentTimelineSelectionContext = (0, react_1.createContext)(null);
320
- const TIMELINE_SELECTION_REVEAL_RETRY_COUNT = 2;
321
322
  const parseEffectIndex = (effectIndex) => {
322
323
  const parsed = Number(effectIndex);
323
324
  if (!Number.isInteger(parsed) || parsed < 0) {
@@ -644,13 +645,12 @@ const TimelineSelectionProvider = ({ children }) => {
644
645
  const canSelect = (0, interactivity_enabled_1.isStudioSelectionEnabled)() &&
645
646
  (previewServerState.type === 'connected' ||
646
647
  window.remotion_isReadOnlyStudio);
648
+ const keyframeOperationsAvailable = (0, browser_studio_operations_1.canUseKeyframeOperations)();
647
649
  const [selectedItems, setSelectedItems] = (0, react_1.useState)([]);
648
650
  const selectionAnchor = (0, react_1.useRef)(null);
649
651
  const selectionScope = (0, react_1.useRef)(null);
650
652
  const marqueeSelectableItems = (0, react_1.useRef)(new Map());
651
653
  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
654
  const [revealRequest, setRevealRequest] = (0, react_1.useState)(null);
655
655
  (0, react_1.useEffect)(() => {
656
656
  if (!canSelect) {
@@ -661,7 +661,9 @@ const TimelineSelectionProvider = ({ children }) => {
661
661
  }
662
662
  }, [canSelect]);
663
663
  const canSelectItem = (0, react_1.useCallback)((item) => canSelect &&
664
- (!window.remotion_isReadOnlyStudio || item.type === 'sequence'), [canSelect]);
664
+ (!window.remotion_isReadOnlyStudio ||
665
+ keyframeOperationsAvailable ||
666
+ item.type === 'sequence'), [canSelect, keyframeOperationsAvailable]);
665
667
  const getCurrentAvailableSelectionState = (0, react_1.useCallback)((currentSelectedItems) => {
666
668
  if (selectionScope.current !== timelineSelectionScope) {
667
669
  return exports.EMPTY_TIMELINE_SELECTION_STATE;
@@ -673,58 +675,11 @@ const TimelineSelectionProvider = ({ children }) => {
673
675
  }, [timelineSelectionScope]);
674
676
  const availableSelectionState = getCurrentAvailableSelectionState(selectedItems);
675
677
  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
678
  const requestRevealSelectionItem = (0, react_1.useCallback)((item) => {
723
- const key = (0, exports.getTimelineSelectionKey)(item);
724
679
  setRevealRequest((previousRequest) => {
725
680
  var _a;
726
681
  return ({
727
- key,
682
+ item,
728
683
  token: ((_a = previousRequest === null || previousRequest === void 0 ? void 0 : previousRequest.token) !== null && _a !== void 0 ? _a : 0) + 1,
729
684
  });
730
685
  });
@@ -832,25 +787,6 @@ const TimelineSelectionProvider = ({ children }) => {
832
787
  marqueeSelectableItems.current.delete(key);
833
788
  };
834
789
  }, []);
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
790
  const getMarqueeSelectionForRect = (0, react_1.useCallback)((marqueeRect, lockedSelectionKind) => {
855
791
  const candidates = [...marqueeSelectableItems.current.values()]
856
792
  .sort((a, b) => a.order - b.order)
@@ -891,23 +827,23 @@ const TimelineSelectionProvider = ({ children }) => {
891
827
  }, [availableSelectedItems]);
892
828
  const value = (0, react_1.useMemo)(() => ({
893
829
  canSelect,
830
+ revealRequest,
894
831
  selectedItems: availableSelectedItems,
895
832
  isSelected,
896
833
  selectItem,
897
834
  selectItems,
898
835
  registerMarqueeSelectableItem,
899
- registerFocusableItem,
900
836
  getMarqueeSelection: getMarqueeSelectionForRect,
901
837
  containsSelection,
902
838
  clearSelection,
903
839
  }), [
904
840
  canSelect,
841
+ revealRequest,
905
842
  availableSelectedItems,
906
843
  isSelected,
907
844
  selectItem,
908
845
  selectItems,
909
846
  registerMarqueeSelectableItem,
910
- registerFocusableItem,
911
847
  getMarqueeSelectionForRect,
912
848
  containsSelection,
913
849
  clearSelection,
@@ -938,6 +874,7 @@ const useTimelineMarqueeSelection = () => {
938
874
  const { isHighestContext } = (0, z_index_1.useZIndex)();
939
875
  const [marqueeRect, setMarqueeRect] = (0, react_1.useState)(null);
940
876
  const onPointerDownCapture = (0, react_1.useCallback)((event) => {
877
+ var _a, _b;
941
878
  if (!isHighestContext) {
942
879
  return;
943
880
  }
@@ -955,15 +892,18 @@ const useTimelineMarqueeSelection = () => {
955
892
  return;
956
893
  }
957
894
  const { currentTarget: target } = event;
895
+ const scrollable = timeline_refs_1.scrollableRef.current;
896
+ const verticalScroll = timeline_refs_1.timelineVerticalScroll.current;
897
+ const initialScrollLeft = (_a = scrollable === null || scrollable === void 0 ? void 0 : scrollable.scrollLeft) !== null && _a !== void 0 ? _a : 0;
898
+ const initialScrollTop = (_b = verticalScroll === null || verticalScroll === void 0 ? void 0 : verticalScroll.scrollTop) !== null && _b !== void 0 ? _b : 0;
958
899
  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
900
  const start = (0, exports.getClampedTimelineMarqueePoint)({
966
- bounds: marqueeBounds,
901
+ bounds: {
902
+ bottom: initialBounds.bottom,
903
+ left: initialBounds.left,
904
+ right: initialBounds.right,
905
+ top: initialBounds.top,
906
+ },
967
907
  x: event.clientX,
968
908
  y: event.clientY,
969
909
  });
@@ -975,34 +915,64 @@ const useTimelineMarqueeSelection = () => {
975
915
  document.body.style.webkitUserSelect = 'none';
976
916
  let hasDragged = false;
977
917
  let lockedSelectionKind = null;
918
+ let lastClientX = event.clientX;
919
+ let lastClientY = event.clientY;
978
920
  const extendSelection = event.metaKey || event.ctrlKey;
979
921
  const selectionBeforeMarquee = selectedItems;
980
- const cleanup = () => {
981
- document.body.style.userSelect = previousUserSelect;
982
- document.body.style.webkitUserSelect = previousWebkitUserSelect;
983
- setMarqueeRect(null);
984
- };
985
922
  const updateSelection = (clientX, clientY) => {
923
+ var _a, _b, _c;
924
+ lastClientX = clientX;
925
+ lastClientY = clientY;
926
+ // The container moves when the timeline scrolls vertically, so read
927
+ // the bounds live. Restrict them to the visible viewport of the
928
+ // vertical scroller so the fixed-positioned marquee cannot paint
929
+ // outside the visible timeline area.
930
+ const liveBounds = target.getBoundingClientRect();
931
+ const verticalRect = (_a = verticalScroll === null || verticalScroll === void 0 ? void 0 : verticalScroll.getBoundingClientRect()) !== null && _a !== void 0 ? _a : null;
932
+ const bounds = {
933
+ bottom: verticalRect === null
934
+ ? liveBounds.bottom
935
+ : Math.min(liveBounds.bottom, verticalRect.bottom),
936
+ left: liveBounds.left,
937
+ right: liveBounds.right,
938
+ top: verticalRect === null
939
+ ? liveBounds.top
940
+ : Math.max(liveBounds.top, verticalRect.top),
941
+ };
942
+ // The anchor is fixed to timeline content, not to the screen:
943
+ // compensate for any scrolling that happened since pointerdown so the
944
+ // marquee keeps covering the originally spanned content while
945
+ // edge auto-scrolling. It is deliberately not clamped to the bounds -
946
+ // it may sit outside the viewport, and the selection should still
947
+ // include everything between it and the pointer.
948
+ const scrollDeltaX = ((_b = scrollable === null || scrollable === void 0 ? void 0 : scrollable.scrollLeft) !== null && _b !== void 0 ? _b : 0) - initialScrollLeft;
949
+ const scrollDeltaY = ((_c = verticalScroll === null || verticalScroll === void 0 ? void 0 : verticalScroll.scrollTop) !== null && _c !== void 0 ? _c : 0) - initialScrollTop;
950
+ const anchorX = startX - scrollDeltaX;
951
+ const anchorY = startY - scrollDeltaY;
986
952
  const current = (0, exports.getClampedTimelineMarqueePoint)({
987
- bounds: marqueeBounds,
953
+ bounds,
988
954
  x: clientX,
989
955
  y: clientY,
990
956
  });
991
957
  if (!hasDragged &&
992
- Math.max(Math.abs(current.x - startX), Math.abs(current.y - startY)) <
993
- 3) {
958
+ Math.max(Math.abs(current.x - anchorX), Math.abs(current.y - anchorY)) < 3) {
994
959
  return;
995
960
  }
996
961
  hasDragged = true;
997
962
  const rect = (0, exports.getNormalizedTimelineMarqueeRect)({
998
963
  currentX: current.x,
999
964
  currentY: current.y,
1000
- startX,
1001
- startY,
965
+ startX: anchorX,
966
+ startY: anchorY,
1002
967
  });
1003
968
  const nextSelection = getMarqueeSelection(rect, lockedSelectionKind);
1004
969
  lockedSelectionKind = nextSelection.lockedSelectionKind;
1005
- setMarqueeRect(rect);
970
+ setMarqueeRect({
971
+ bottom: Math.min(rect.bottom, bounds.bottom),
972
+ left: Math.max(rect.left, bounds.left),
973
+ right: Math.min(rect.right, bounds.right),
974
+ top: Math.max(rect.top, bounds.top),
975
+ });
1006
976
  selectItems(extendSelection
1007
977
  ? (0, exports.extendTimelineMarqueeSelection)({
1008
978
  currentSelection: selectionBeforeMarquee,
@@ -1010,8 +980,35 @@ const useTimelineMarqueeSelection = () => {
1010
980
  })
1011
981
  : nextSelection.selectedItems);
1012
982
  };
983
+ const autoScroll = (0, timeline_scroll_logic_1.startTimelineEdgeAutoScroll)({
984
+ includeVertical: true,
985
+ onTick: (directions) => {
986
+ if (scrollable && directions.x !== null) {
987
+ scrollable.scrollLeft +=
988
+ directions.x === 'left' ? -timeline_scroll_logic_1.SCROLL_INCREMENT : timeline_scroll_logic_1.SCROLL_INCREMENT;
989
+ }
990
+ if (verticalScroll && directions.y !== null) {
991
+ verticalScroll.scrollTop +=
992
+ directions.y === 'up'
993
+ ? -timeline_scroll_logic_1.EDGE_SCROLL_VERTICAL_INCREMENT
994
+ : timeline_scroll_logic_1.EDGE_SCROLL_VERTICAL_INCREMENT;
995
+ }
996
+ updateSelection(lastClientX, lastClientY);
997
+ },
998
+ });
999
+ const cleanup = () => {
1000
+ autoScroll.stop();
1001
+ document.body.style.userSelect = previousUserSelect;
1002
+ document.body.style.webkitUserSelect = previousWebkitUserSelect;
1003
+ setMarqueeRect(null);
1004
+ };
1013
1005
  const onPointerMove = (moveEvent) => {
1014
1006
  updateSelection(moveEvent.clientX, moveEvent.clientY);
1007
+ // Only auto-scroll for an actual marquee drag, not a plain click
1008
+ // near an edge
1009
+ if (hasDragged) {
1010
+ autoScroll.update(moveEvent);
1011
+ }
1015
1012
  };
1016
1013
  (0, pointer_session_1.startCapturedPointerSession)({
1017
1014
  event,
@@ -1049,16 +1046,6 @@ const useTimelineMarqueeSelectableItem = (item, ref) => {
1049
1046
  }, [item, ref, registerMarqueeSelectableItem]);
1050
1047
  };
1051
1048
  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
1049
  const useTimelineRowSelection = (nodePathInfo) => {
1063
1050
  const { canSelect, isSelected, selectItem } = (0, exports.useTimelineSelection)();
1064
1051
  const selectableTimelineItemsRef = (0, react_1.useContext)(SelectableTimelineItemsContext);
@@ -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;