@remotion/studio 4.0.525 → 4.0.527

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 (195) hide show
  1. package/dist/api/focus-default-props-path.js +7 -1
  2. package/dist/api/restart-studio.d.ts +1 -1
  3. package/dist/api/restart-studio.js +1 -1
  4. package/dist/components/AgentPrompt.d.ts +6 -0
  5. package/dist/components/AgentPrompt.js +107 -0
  6. package/dist/components/AssetFileIcon.js +2 -0
  7. package/dist/components/AssetSelectorItem.d.ts +1 -23
  8. package/dist/components/AssetSelectorItem.js +10 -200
  9. package/dist/components/Canvas.js +109 -44
  10. package/dist/components/CanvasCaptureDropHandler.js +63 -0
  11. package/dist/components/CanvasOrLoading.js +10 -2
  12. package/dist/components/CaptionInspector.js +9 -3
  13. package/dist/{error-overlay/remotion-overlay → components}/CodeFrame.d.ts +2 -0
  14. package/dist/components/CodeFrame.js +77 -0
  15. package/dist/components/CompositionSelectorItem.js +7 -17
  16. package/dist/components/CurrentAsset.js +6 -4
  17. package/dist/components/ElementInstallConfirmation.js +69 -38
  18. package/dist/components/FilePreview.js +4 -0
  19. package/dist/components/FixComputedValueModal.js +64 -96
  20. package/dist/components/GenerateWithAgentModal.d.ts +9 -0
  21. package/dist/components/GenerateWithAgentModal.js +39 -0
  22. package/dist/components/InitialCompositionLoader.js +1 -1
  23. package/dist/components/InlineDropdown.js +26 -2
  24. package/dist/components/InlineEditableTitle.js +3 -0
  25. package/dist/components/InspectorOpenInEditor.js +8 -4
  26. package/dist/components/InspectorPanel/CollapsibleInspectorSection.d.ts +7 -0
  27. package/dist/components/InspectorPanel/CollapsibleInspectorSection.js +14 -0
  28. package/dist/components/InspectorPanel/CollapsibleInspectorSectionHeader.d.ts +1 -1
  29. package/dist/components/InspectorPanel/CollapsibleInspectorSectionHeader.js +20 -8
  30. package/dist/components/InspectorPanel/CompositionInspector.js +32 -15
  31. package/dist/components/InspectorPanel/CompositionMetadata.js +7 -0
  32. package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +6 -12
  33. package/dist/components/InspectorPanel/ElementLibraryButton.js +2 -0
  34. package/dist/components/InspectorPanel/GuideInspector.js +2 -3
  35. package/dist/components/InspectorPanel/KeyframeSettings.js +5 -6
  36. package/dist/components/InspectorPanel/MultiSequenceInspector.js +34 -2
  37. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +45 -4
  38. package/dist/components/InspectorPanel/common.d.ts +4 -0
  39. package/dist/components/InspectorPanel/common.js +15 -2
  40. package/dist/components/InspectorPanel/styles.d.ts +0 -3
  41. package/dist/components/InspectorPanel/styles.js +3 -27
  42. package/dist/components/InspectorPanel/use-composition-actions.d.ts +2 -0
  43. package/dist/components/InspectorPanel/use-composition-actions.js +16 -0
  44. package/dist/components/InspectorPanel/use-inspector-section-expanded.d.ts +1 -0
  45. package/dist/components/InspectorPanel/use-inspector-section-expanded.js +21 -0
  46. package/dist/components/InspectorSequenceSection.js +44 -35
  47. package/dist/components/InspectorSourceLocation.js +4 -0
  48. package/dist/components/KeyboardShortcutsSettings.js +12 -4
  49. package/dist/components/LutPreview.d.ts +4 -0
  50. package/dist/components/LutPreview.js +192 -0
  51. package/dist/components/MenuBuildIndicator.js +1 -0
  52. package/dist/components/MenuCompositionName.js +4 -9
  53. package/dist/components/Modals.js +3 -6
  54. package/dist/components/ModelsSettings.js +15 -4
  55. package/dist/components/NewComposition/CancelButton.js +1 -1
  56. package/dist/components/Notifications/NotificationCenter.d.ts +0 -1
  57. package/dist/components/Notifications/NotificationCenter.js +1 -22
  58. package/dist/components/Preview.js +3 -0
  59. package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.js +1 -0
  60. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +1 -0
  61. package/dist/components/QuickSwitcher/QuickSwitcherResult.js +4 -9
  62. package/dist/components/RadioButton.js +1 -0
  63. package/dist/components/RenderModal/DataEditor.js +4 -1
  64. package/dist/components/RenderModal/SchemaEditor/scroll-to-default-props-path.d.ts +1 -0
  65. package/dist/components/RenderModal/SchemaEditor/scroll-to-default-props-path.js +2 -1
  66. package/dist/components/RenderModal/WebRenderModal.js +10 -2
  67. package/dist/components/RenderQueue/CaptionQueueItem.js +5 -2
  68. package/dist/components/RenderQueue/CaptionQueueProcessor.js +35 -8
  69. package/dist/components/RenderQueue/VideoMattingQueueItem.js +1 -0
  70. package/dist/components/RenderQueue/caption-job-types.d.ts +6 -0
  71. package/dist/components/RenderQueue/index.js +1 -0
  72. package/dist/components/RendersTab.js +4 -0
  73. package/dist/components/SelectedOutlineElement.js +6 -0
  74. package/dist/components/SelectedOutlineSnapIndicators.d.ts +6 -0
  75. package/dist/components/SelectedOutlineSnapIndicators.js +16 -12
  76. package/dist/components/SequencePropsSubscriptionProvider.d.ts +3 -0
  77. package/dist/components/SequencePropsSubscriptionProvider.js +8 -6
  78. package/dist/components/SettingsButton.js +11 -2
  79. package/dist/components/SettingsModal.d.ts +1 -2
  80. package/dist/components/SettingsModal.js +24 -6
  81. package/dist/components/SettingsModalFooter.js +17 -3
  82. package/dist/components/SkillsSettings.d.ts +5 -0
  83. package/dist/components/SkillsSettings.js +29 -26
  84. package/dist/components/Timeline/Timeline.js +10 -11
  85. package/dist/components/Timeline/TimelineAssetField.js +81 -51
  86. package/dist/components/Timeline/TimelineDeleteKeybindings.js +6 -9
  87. package/dist/components/Timeline/TimelineEffectItem.js +1 -0
  88. package/dist/components/Timeline/TimelineExpandArrowButton.js +1 -0
  89. package/dist/components/Timeline/TimelineExpandedRow.js +1 -0
  90. package/dist/components/Timeline/TimelineFieldLabel.js +1 -0
  91. package/dist/components/Timeline/TimelineHeightContainer.js +11 -1
  92. package/dist/components/Timeline/TimelineKeyframeControls.js +16 -1
  93. package/dist/components/Timeline/TimelineLayerChildren.d.ts +3 -3
  94. package/dist/components/Timeline/TimelineLayerChildren.js +11 -9
  95. package/dist/components/Timeline/TimelineLayerEye.d.ts +1 -1
  96. package/dist/components/Timeline/TimelineLayerEye.js +6 -3
  97. package/dist/components/Timeline/TimelineList.js +9 -3
  98. package/dist/components/Timeline/TimelineSchemaField.js +2 -6
  99. package/dist/components/Timeline/TimelineSelection.d.ts +14 -3
  100. package/dist/components/Timeline/TimelineSelection.js +91 -49
  101. package/dist/components/Timeline/TimelineSequence.js +28 -2
  102. package/dist/components/Timeline/TimelineSequenceFrame.js +1 -0
  103. package/dist/components/Timeline/TimelineSequenceItem.d.ts +2 -0
  104. package/dist/components/Timeline/TimelineSequenceItem.js +45 -13
  105. package/dist/components/Timeline/TimelineViewport.d.ts +1 -0
  106. package/dist/components/Timeline/TimelineViewport.js +10 -1
  107. package/dist/components/Timeline/TimelineVirtualization.d.ts +3 -3
  108. package/dist/components/Timeline/delete-selected-timeline-item.js +2 -2
  109. package/dist/components/Timeline/get-sequence-context-menu-items.d.ts +6 -2
  110. package/dist/components/Timeline/get-sequence-context-menu-items.js +143 -46
  111. package/dist/components/Timeline/normalize-font-weight-for-keyframe.d.ts +1 -0
  112. package/dist/components/Timeline/normalize-font-weight-for-keyframe.js +19 -0
  113. package/dist/components/Timeline/split-selected-timeline-item.d.ts +13 -10
  114. package/dist/components/Timeline/split-selected-timeline-item.js +58 -35
  115. package/dist/components/Timeline/timeline-display-groups.d.ts +9 -0
  116. package/dist/components/Timeline/timeline-display-groups.js +66 -0
  117. package/dist/components/Timeline/use-timeline-asset-drop.js +21 -21
  118. package/dist/components/Timeline/use-timeline-expanded-tree.d.ts +2 -1
  119. package/dist/components/Timeline/use-timeline-expanded-tree.js +1 -2
  120. package/dist/components/TimelineCombobox.js +1 -0
  121. package/dist/components/Transcription/TranscriptionModal.js +16 -11
  122. package/dist/components/Transcription/TranscriptionModalWithOptionalWhisper.js +1 -1
  123. package/dist/components/UpdateStatusContext.d.ts +2 -2
  124. package/dist/components/UpdateStatusContext.js +6 -7
  125. package/dist/components/UpdatesSettings.js +6 -6
  126. package/dist/components/WebMcp.js +41 -41
  127. package/dist/components/asset-context-menu.d.ts +32 -0
  128. package/dist/components/asset-context-menu.js +242 -0
  129. package/dist/components/composition-drop-preview.d.ts +9 -2
  130. package/dist/components/composition-drop-preview.js +7 -4
  131. package/dist/components/composition-menu-items.d.ts +4 -6
  132. package/dist/components/composition-menu-items.js +191 -75
  133. package/dist/components/delete-jsx-nodes-api.d.ts +2 -0
  134. package/dist/components/{delete-jsx-node-api.js → delete-jsx-nodes-api.js} +5 -5
  135. package/dist/components/get-open-in-menu-items.d.ts +6 -5
  136. package/dist/components/get-open-in-menu-items.js +22 -16
  137. package/dist/components/keyboard-shortcuts.d.ts +4 -4
  138. package/dist/components/keyboard-shortcuts.js +3 -1
  139. package/dist/components/public-output-name.d.ts +1 -0
  140. package/dist/components/public-output-name.js +7 -3
  141. package/dist/components/selected-outline-order.js +18 -12
  142. package/dist/components/use-open-in-menu-apps.d.ts +14 -0
  143. package/dist/components/use-open-in-menu-apps.js +33 -0
  144. package/dist/error-overlay/remotion-overlay/ErrorDisplay.js +2 -2
  145. package/dist/error-overlay/remotion-overlay/OpenInEditor.d.ts +1 -0
  146. package/dist/error-overlay/remotion-overlay/OpenInEditor.js +3 -3
  147. package/dist/error-overlay/remotion-overlay/StackFrame.d.ts +5 -1
  148. package/dist/error-overlay/remotion-overlay/StackFrame.js +26 -19
  149. package/dist/esm/{CaptionQueueProcessor-k0yrm3dj.mjs → CaptionQueueProcessor-npa6szn1.mjs} +39 -8
  150. package/dist/esm/{LazyModels-gfmpcy4h.mjs → LazyModels-nh3c8h9p.mjs} +4 -3
  151. package/dist/esm/{LazyModels-m1rf06wh.mjs → LazyModels-rr5v8h5y.mjs} +4 -3
  152. package/dist/esm/{TranscriptionModal-8pvrehg4.mjs → TranscriptionModal-79m5wgcj.mjs} +25 -17
  153. package/dist/esm/{VideoMattingModal-fefbzgka.mjs → VideoMattingModal-31pew0xj.mjs} +9 -6
  154. package/dist/esm/index-21hxsfaa.mjs +239 -0
  155. package/dist/esm/{index-s848rffx.mjs → index-4zen9prq.mjs} +5438 -4686
  156. package/dist/esm/index-5t2dwxsk.mjs +530 -0
  157. package/dist/esm/{index-vsxrxfpj.mjs → index-614tdz2q.mjs} +1 -1
  158. package/dist/esm/{index-0x13f28h.mjs → index-9xxg6218.mjs} +20 -541
  159. package/dist/esm/{index-hbezgbbq.mjs → index-ac5550e7.mjs} +1 -1
  160. package/dist/esm/{index-41kqns5c.mjs → index-e855w59j.mjs} +15 -92
  161. package/dist/esm/{index-tzxb8808.mjs → index-n5gmcvhz.mjs} +8 -8
  162. package/dist/esm/{index-ggqpre9v.mjs → index-ppspzgn9.mjs} +4963 -4178
  163. package/dist/esm/{index-jrw61pkj.mjs → index-r0ejh5sy.mjs} +1 -1
  164. package/dist/esm/index-r1gr3j3a.mjs +80 -0
  165. package/dist/esm/{index-mww32xc8.mjs → index-s7qa3xbw.mjs} +6 -4
  166. package/dist/esm/{index-1089795y.mjs → index-vxwg66ar.mjs} +7 -22
  167. package/dist/esm/index.mjs +13 -6
  168. package/dist/esm/internals.mjs +10 -7
  169. package/dist/esm/previewEntry.mjs +10 -7
  170. package/dist/esm/{resolve-composition-component-location-bt2d6qxq.mjs → resolve-composition-component-location-qrp05g62.mjs} +1 -1
  171. package/dist/helpers/client-id.d.ts +1 -0
  172. package/dist/helpers/client-id.js +8 -4
  173. package/dist/helpers/copy-text.js +1 -16
  174. package/dist/helpers/cube-lut.d.ts +12 -0
  175. package/dist/helpers/cube-lut.js +160 -0
  176. package/dist/helpers/get-preview-file-type.d.ts +1 -1
  177. package/dist/helpers/get-preview-file-type.js +3 -0
  178. package/dist/helpers/hoverable.js +2 -1
  179. package/dist/helpers/open-in-editor.d.ts +5 -2
  180. package/dist/helpers/open-in-editor.js +13 -5
  181. package/dist/helpers/settings-tab-availability.d.ts +14 -0
  182. package/dist/helpers/settings-tab-availability.js +35 -0
  183. package/dist/helpers/studio-runtime-config.d.ts +1 -1
  184. package/dist/helpers/use-keybinding.d.ts +1 -1
  185. package/dist/helpers/use-keyboard-shortcut-label.d.ts +2 -2
  186. package/dist/helpers/use-menu-structure.js +31 -21
  187. package/dist/icons/lut.d.ts +4 -0
  188. package/dist/icons/lut.js +6 -0
  189. package/dist/icons/sparkles.d.ts +4 -0
  190. package/dist/icons/sparkles.js +6 -0
  191. package/dist/state/modals.d.ts +17 -2
  192. package/dist/state/timeline-zoom.js +4 -0
  193. package/package.json +19 -19
  194. package/dist/components/delete-jsx-node-api.d.ts +0 -2
  195. package/dist/error-overlay/remotion-overlay/CodeFrame.js +0 -62
@@ -52,6 +52,7 @@ const AudioWaveform_1 = require("../AudioWaveform");
52
52
  const ConfirmationDialog_1 = require("../ConfirmationDialog");
53
53
  const ContextMenu_1 = require("../ContextMenu");
54
54
  const InitialCompositionLoader_1 = require("../InitialCompositionLoader");
55
+ const SequencePropsSubscriptionProvider_1 = require("../SequencePropsSubscriptionProvider");
55
56
  const use_select_asset_1 = require("../use-select-asset");
56
57
  const disable_sequence_interactivity_1 = require("./disable-sequence-interactivity");
57
58
  const duplicate_selected_timeline_item_1 = require("./duplicate-selected-timeline-item");
@@ -61,6 +62,7 @@ const get_timeline_media_start_frame_1 = require("./get-timeline-media-start-fra
61
62
  const get_timeline_sequence_visible_layout_1 = require("./get-timeline-sequence-visible-layout");
62
63
  const imperative_state_1 = require("./imperative-state");
63
64
  const LoopedTimelineIndicators_1 = require("./LoopedTimelineIndicators");
65
+ const split_selected_timeline_item_1 = require("./split-selected-timeline-item");
64
66
  const timeline_asset_link_1 = require("./timeline-asset-link");
65
67
  const TimelineImageInfo_1 = require("./TimelineImageInfo");
66
68
  const TimelineSelection_1 = require("./TimelineSelection");
@@ -242,6 +244,7 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
242
244
  var _f, _g, _h, _j, _k, _l, _m;
243
245
  const video = remotion_1.Internals.useVideo();
244
246
  const { sequences } = (0, react_1.useContext)(remotion_1.Internals.SequenceManager);
247
+ const overrideIdToNodePathMappingsRef = (0, react_1.useContext)(SequencePropsSubscriptionProvider_1.OverrideIdToNodePathMappingsRefContext);
245
248
  const renderWindow = (0, react_1.useContext)(TimelineViewport_1.TimelineViewportContext);
246
249
  const mediaDurationDragLimitsRegistry = (0, react_1.useContext)(TimelineSequenceRightEdgeDragHandle_1.TimelineSequenceMediaDurationDragLimitsContext);
247
250
  const dragAwareDoubleClick = (0, react_1.useMemo)(() => (0, drag_aware_double_click_1.createDragAwareDoubleClickTracker)(), []);
@@ -304,8 +307,7 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
304
307
  const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
305
308
  const confirm = (0, ConfirmationDialog_1.useConfirmationDialog)();
306
309
  const deleteTimelineItems = (0, use_delete_timeline_items_1.useDeleteTimelineItems)();
307
- const { onSelect, selectable, selected } = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
308
- const { selectedItems } = (0, TimelineSelection_1.useTimelineSelection)();
310
+ const { onSelect, selectable, selected, selectedItems } = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
309
311
  const selectedSequenceNodePathInfos = (0, react_1.useMemo)(() => {
310
312
  if (!selected ||
311
313
  selectedItems.length < 2 ||
@@ -378,6 +380,26 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
378
380
  }
379
381
  (0, duplicate_selected_timeline_item_1.duplicateSequencesFromSource)(selectedSequenceNodePathInfos, confirm).catch(() => undefined);
380
382
  }, [confirm, previewInteractive, selectedSequenceNodePathInfos]);
383
+ const onSplitSelectedSequences = (0, react_1.useCallback)(() => {
384
+ var _a;
385
+ if (!previewInteractive || selectedSequenceNodePathInfos === null) {
386
+ return;
387
+ }
388
+ (_a = (0, split_selected_timeline_item_1.splitSelectedTimelineItems)({
389
+ selections: selectedItems,
390
+ sequences,
391
+ overrideIdsToNodePaths: overrideIdToNodePathMappingsRef.current,
392
+ propStatuses,
393
+ splitFrame: (0, imperative_state_1.getCurrentFrame)(),
394
+ })) === null || _a === void 0 ? void 0 : _a.catch(() => undefined);
395
+ }, [
396
+ overrideIdToNodePathMappingsRef,
397
+ previewInteractive,
398
+ propStatuses,
399
+ selectedItems,
400
+ selectedSequenceNodePathInfos,
401
+ sequences,
402
+ ]);
381
403
  const onDeleteSequenceFromSource = (0, react_1.useCallback)(() => {
382
404
  if (!(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source) ||
383
405
  !nodePath ||
@@ -434,8 +456,10 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
434
456
  return (0, get_sequence_context_menu_items_1.getMultiSequenceContextMenuItems)({
435
457
  deleteDisabled: !previewInteractive,
436
458
  duplicateDisabled: !previewInteractive,
459
+ splitDisabled: !previewInteractive,
437
460
  onDeleteSelectedSequences,
438
461
  onDuplicateSelectedSequences,
462
+ onSplitSelectedSequences,
439
463
  });
440
464
  }
441
465
  const splitMenuItem = (0, get_sequence_split_menu_item_1.getSequenceSplitMenuItem)({
@@ -462,6 +486,7 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
462
486
  assetLinkInfo: mediaSrc ? (0, timeline_asset_link_1.getTimelineAssetLinkInfo)(mediaSrc) : null,
463
487
  canOpenInEditor,
464
488
  codingAgentInfo,
489
+ copyImageElement: null,
465
490
  deleteDisabled,
466
491
  disableInteractivityDisabled,
467
492
  duplicateDisabled,
@@ -513,6 +538,7 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
513
538
  onDisableSequenceInteractivity,
514
539
  onDuplicateSequenceFromSource,
515
540
  onDuplicateSelectedSequences,
541
+ onSplitSelectedSequences,
516
542
  openInCodingAgent,
517
543
  openInEditor,
518
544
  originalLocation,
@@ -15,6 +15,7 @@ const relativeFrameStyle = {
15
15
  whiteSpace: 'nowrap',
16
16
  pointerEvents: 'none',
17
17
  userSelect: 'none',
18
+ WebkitUserSelect: 'none',
18
19
  };
19
20
  const snowflakeStyle = {
20
21
  flexShrink: 0,
@@ -10,4 +10,6 @@ export declare const TimelineSequenceItem: React.NamedExoticComponent<{
10
10
  readonly keyframeDisplayOffset: number;
11
11
  readonly sequenceFrameOffset: number;
12
12
  readonly siblingIndex: number;
13
+ readonly numberOfHiddenDuplicates: number;
14
+ readonly showProvisionalVisibilityToggle: boolean;
13
15
  }>;
@@ -62,6 +62,7 @@ const layout_1 = require("../layout");
62
62
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
63
63
  const reorder_sequence_api_1 = require("../reorder-sequence-api");
64
64
  const selected_outline_types_1 = require("../selected-outline-types");
65
+ const SequencePropsSubscriptionProvider_1 = require("../SequencePropsSubscriptionProvider");
65
66
  const use_select_asset_1 = require("../use-select-asset");
66
67
  const disable_sequence_interactivity_1 = require("./disable-sequence-interactivity");
67
68
  const duplicate_selected_timeline_item_1 = require("./duplicate-selected-timeline-item");
@@ -69,6 +70,7 @@ const get_sequence_context_menu_items_1 = require("./get-sequence-context-menu-i
69
70
  const get_sequence_split_menu_item_1 = require("./get-sequence-split-menu-item");
70
71
  const imperative_state_1 = require("./imperative-state");
71
72
  const save_sequence_prop_1 = require("./save-sequence-prop");
73
+ const split_selected_timeline_item_1 = require("./split-selected-timeline-item");
72
74
  const timeline_asset_link_1 = require("./timeline-asset-link");
73
75
  const timeline_refs_1 = require("./timeline-refs");
74
76
  const timeline_scroll_logic_1 = require("./timeline-scroll-logic");
@@ -106,11 +108,12 @@ const effectDropHighlight = {
106
108
  outline: colors_1.BORDER_TIMELINE_DROP_BLUE,
107
109
  outlineOffset: -1,
108
110
  };
109
- const TimelineSequenceExpandArrowInner = ({ disabled, isExpanded, nodePathInfo, sequence }) => {
111
+ const TimelineSequenceExpandArrowInner = ({ disabled, isExpanded, nodePathInfo, selectedItems, sequence }) => {
110
112
  const { toggleTrack } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksSetterContext);
111
113
  const hasExpandableContent = (0, use_timeline_expanded_tree_1.useTimelineSequenceHasExpandableContent)({
112
114
  sequence,
113
115
  nodePathInfo,
116
+ selectedItems,
114
117
  });
115
118
  const onToggleExpand = (0, react_1.useCallback)(() => toggleTrack(nodePathInfo), [nodePathInfo, toggleTrack]);
116
119
  if (!hasExpandableContent) {
@@ -122,6 +125,7 @@ const areTimelineSequenceExpandArrowPropsEqual = (first, second) => {
122
125
  var _a, _b, _c, _d;
123
126
  return (first.disabled === second.disabled &&
124
127
  first.isExpanded === second.isExpanded &&
128
+ first.selectedItems === second.selectedItems &&
125
129
  ((_a = first.sequence.controls) === null || _a === void 0 ? void 0 : _a.schema) === ((_b = second.sequence.controls) === null || _b === void 0 ? void 0 : _b.schema) &&
126
130
  ((_c = first.sequence.controls) === null || _c === void 0 ? void 0 : _c.runtimeValues) ===
127
131
  ((_d = second.sequence.controls) === null || _d === void 0 ? void 0 : _d.runtimeValues) &&
@@ -169,10 +173,13 @@ const getSequencePointerDropTargetAtPoint = ({ clientX, clientY, }) => {
169
173
  return null;
170
174
  };
171
175
  const SEQUENCE_REORDER_POINTER_THRESHOLD = 3;
172
- const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions, nestedDepth, sequence, nodePathInfo, keyframeDisplayOffset, sequenceFrameOffset, siblingIndex, }) => {
176
+ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions, nestedDepth, sequence, nodePathInfo, keyframeDisplayOffset, sequenceFrameOffset, siblingIndex, numberOfHiddenDuplicates, showProvisionalVisibilityToggle, }) => {
173
177
  var _a, _b;
174
- var _c, _d, _e, _f;
178
+ var _c, _d, _e;
175
179
  const nodePath = (_c = nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.sequenceSubscriptionKey) !== null && _c !== void 0 ? _c : null;
180
+ const sequencesRef = (0, react_1.useContext)(remotion_1.Internals.SequenceManagerRefContext);
181
+ const overrideIdToNodePathMappingsRef = (0, react_1.useContext)(SequencePropsSubscriptionProvider_1.OverrideIdToNodePathMappingsRefContext);
182
+ const propStatusesRef = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesRefContext);
176
183
  const { hovered, onPointerEnter, onPointerLeave } = (0, timeline_sequence_hover_1.useTimelineSequenceHover)(nodePathInfo);
177
184
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
178
185
  const previewConnected = previewServerState.type === 'connected';
@@ -187,8 +194,7 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
187
194
  const assetContextMenu = (0, use_asset_timeline_context_menu_1.useAssetTimelineContextMenu)();
188
195
  const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
189
196
  const deleteTimelineItems = (0, use_delete_timeline_items_1.useDeleteTimelineItems)();
190
- const { onSelect, selectable, selected } = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
191
- const { selectItem, selectedItems } = (0, TimelineSelection_1.useTimelineSelection)();
197
+ const { onSelect, selectable, selected, selectedItems, selectItem } = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
192
198
  const selectedSequenceNodePathInfos = (0, react_1.useMemo)(() => {
193
199
  if (!selected ||
194
200
  selectedItems.length < 2 ||
@@ -229,17 +235,16 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
229
235
  const timelineDisplayName = sequence.displayName === '' && connectedCompositions.length === 1
230
236
  ? connectedCompositions[0].id
231
237
  : displayName;
232
- const numberOfHiddenDuplicates = Math.max(0, ((_d = nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.numberOfSequencesWithThisNodePath) !== null && _d !== void 0 ? _d : 1) - 1);
233
238
  const canDeleteFromSource = Boolean(nodePath && (validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source));
234
239
  const nodePathKey = (0, react_1.useMemo)(() => nodePath ? remotion_1.Internals.makeSequencePropsSubscriptionKey(nodePath) : null, [nodePath]);
235
- const parentId = (_e = sequence.parent) !== null && _e !== void 0 ? _e : null;
240
+ const parentId = (_d = sequence.parent) !== null && _d !== void 0 ? _d : null;
236
241
  const canReorderSequence = previewInteractive &&
237
242
  Boolean(nodePath && nodePathKey && (validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source)) &&
238
243
  (nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.numberOfSequencesWithThisNodePath) === 1;
239
244
  const canHandleSequenceDrag = previewInteractive;
240
245
  const confirm = (0, ConfirmationDialog_1.useConfirmationDialog)();
241
246
  const deleteDisabled = (0, react_1.useMemo)(() => !previewInteractive || !sequence.controls || !canDeleteFromSource, [previewInteractive, sequence.controls, canDeleteFromSource]);
242
- const isProgrammaticallyDuplicated = ((_f = nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.numberOfSequencesWithThisNodePath) !== null && _f !== void 0 ? _f : 1) > 1;
247
+ const isProgrammaticallyDuplicated = ((_e = nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.numberOfSequencesWithThisNodePath) !== null && _e !== void 0 ? _e : 1) > 1;
243
248
  const duplicateDisabled = deleteDisabled || isProgrammaticallyDuplicated;
244
249
  const disableInteractivityDisabled = !previewInteractive ||
245
250
  !sequence.showInTimeline ||
@@ -257,6 +262,26 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
257
262
  }
258
263
  (0, duplicate_selected_timeline_item_1.duplicateSequencesFromSource)(selectedSequenceNodePathInfos, confirm).catch(() => undefined);
259
264
  }, [confirm, previewInteractive, selectedSequenceNodePathInfos]);
265
+ const onSplitSelectedSequences = (0, react_1.useCallback)(() => {
266
+ var _a;
267
+ if (!previewInteractive || selectedSequenceNodePathInfos === null) {
268
+ return;
269
+ }
270
+ (_a = (0, split_selected_timeline_item_1.splitSelectedTimelineItems)({
271
+ selections: selectedItems,
272
+ sequences: sequencesRef.current,
273
+ overrideIdsToNodePaths: overrideIdToNodePathMappingsRef.current,
274
+ propStatuses: propStatusesRef.current,
275
+ splitFrame: (0, imperative_state_1.getCurrentFrame)(),
276
+ })) === null || _a === void 0 ? void 0 : _a.catch(() => undefined);
277
+ }, [
278
+ overrideIdToNodePathMappingsRef,
279
+ previewInteractive,
280
+ propStatusesRef,
281
+ selectedItems,
282
+ selectedSequenceNodePathInfos,
283
+ sequencesRef,
284
+ ]);
260
285
  const onDeleteSequenceFromSource = (0, react_1.useCallback)(() => {
261
286
  if (deleteDisabled ||
262
287
  !(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source) ||
@@ -641,6 +666,8 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
641
666
  codeHiddenStatus !== undefined &&
642
667
  codeHiddenStatus !== null &&
643
668
  codeHiddenStatus.status === 'static';
669
+ const showVisibilityToggle = canToggleVisibility ||
670
+ (previewInteractive && showProvisionalVisibilityToggle);
644
671
  const onSequenceDoubleClick = (0, react_1.useCallback)((e) => {
645
672
  if ((0, TimelineSelection_1.isTimelineSelectionModifierEvent)(e)) {
646
673
  e.stopPropagation();
@@ -704,7 +731,8 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
704
731
  return;
705
732
  }
706
733
  if (document.activeElement instanceof HTMLInputElement ||
707
- document.activeElement instanceof HTMLTextAreaElement) {
734
+ document.activeElement instanceof HTMLTextAreaElement ||
735
+ document.activeElement instanceof HTMLButtonElement) {
708
736
  return;
709
737
  }
710
738
  e.preventDefault();
@@ -803,8 +831,10 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
803
831
  return (0, get_sequence_context_menu_items_1.getMultiSequenceContextMenuItems)({
804
832
  deleteDisabled: !previewInteractive,
805
833
  duplicateDisabled: !previewInteractive,
834
+ splitDisabled: !previewInteractive,
806
835
  onDeleteSelectedSequences,
807
836
  onDuplicateSelectedSequences,
837
+ onSplitSelectedSequences,
808
838
  });
809
839
  }
810
840
  const splitMenuItem = (0, get_sequence_split_menu_item_1.getSequenceSplitMenuItem)({
@@ -831,6 +861,7 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
831
861
  assetLinkInfo: mediaSrc ? (0, timeline_asset_link_1.getTimelineAssetLinkInfo)(mediaSrc) : null,
832
862
  canOpenInEditor,
833
863
  codingAgentInfo,
864
+ copyImageElement: null,
834
865
  deleteDisabled,
835
866
  disableInteractivityDisabled,
836
867
  duplicateDisabled,
@@ -960,6 +991,7 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
960
991
  onDisableSequenceInteractivity,
961
992
  onDuplicateSequenceFromSource,
962
993
  onDuplicateSelectedSequences,
994
+ onSplitSelectedSequences,
963
995
  onRenameSequence,
964
996
  onSelect,
965
997
  openInCodingAgent,
@@ -1034,12 +1066,12 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
1034
1066
  clientId: previewServerState.clientId,
1035
1067
  });
1036
1068
  }, [canDropEffect, nodePath, previewServerState, validatedLocation]);
1037
- const trackRow = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: nestedDepth, eye: canToggleVisibility ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: sequence.type === 'audio' ? 'speaker' : 'eye', hidden: isItemHidden, onInvoked: onToggleVisibility })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: jsx_runtime_1.jsx(TimelineLayerChildren_1.TimelineLayerChildrenToggle, { sequence: sequence }), style: rowStyle, selected: selected, selectable: selectable, onSelect: onSelect, showSelectedBackground: true, containsSelection: containsSelection, hovered: hovered, outerHeight: outerHeight, onDragLeave: canDropEffect ? onEffectDragLeave : undefined, onDragOver: canDropEffect ? onEffectDragOver : undefined, onDrop: canDropEffect ? onEffectDrop : undefined, onDoubleClick: canHandleSequenceDoubleClick ? onSequenceDoubleClick : undefined, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, children: jsx_runtime_1.jsxs("div", { style: labelContainerStyle, children: [connectedCompositions.length > 0 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
1069
+ const trackRow = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: nestedDepth, eye: showVisibilityToggle ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: sequence.type === 'audio' ? 'speaker' : 'eye', hidden: isItemHidden, onInvoked: canToggleVisibility ? onToggleVisibility : null })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: jsx_runtime_1.jsx(TimelineLayerChildren_1.TimelineLayerChildrenToggle, { sequence: sequence }), style: rowStyle, selected: selected, selectable: selectable, onSelect: onSelect, showSelectedBackground: true, containsSelection: containsSelection, hovered: hovered, outerHeight: outerHeight, onDragLeave: canDropEffect ? onEffectDragLeave : undefined, onDragOver: canDropEffect ? onEffectDragOver : undefined, onDrop: canDropEffect ? onEffectDrop : undefined, onDoubleClick: canHandleSequenceDoubleClick ? onSequenceDoubleClick : undefined, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, children: jsx_runtime_1.jsxs("div", { style: labelContainerStyle, children: [connectedCompositions.length > 0 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
1038
1070
  jsx_runtime_1.jsx(CompositionOrStillIcon_1.CompositionOrStillIcon, { color: (0, TimelineSelection_1.getTimelineColor)(false, false), composition: connectedCompositions[0], style: connectedCompositionIconStyle }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 })
1039
- ] })) : null, jsx_runtime_1.jsx(TimelineSequenceName_1.TimelineSequenceName, { displayName: timelineDisplayName, fallbackDisplayName: fallbackDisplayName, selected: selected, containsSelection: containsSelection, editing: isRenaming, onCancelEditing: onCancelRenaming, onSaveName: onSaveName }), hasExpandableContent && nodePathInfo !== null ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
1040
- jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(TimelineSequenceExpandArrow, { disabled: !previewInteractive, isExpanded: isExpanded, nodePathInfo: nodePathInfo, sequence: sequence })
1041
- ] })) : null, numberOfHiddenDuplicates > 0 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
1071
+ ] })) : null, jsx_runtime_1.jsx(TimelineSequenceName_1.TimelineSequenceName, { displayName: timelineDisplayName, fallbackDisplayName: fallbackDisplayName, selected: selected, containsSelection: containsSelection, editing: isRenaming, onCancelEditing: onCancelRenaming, onSaveName: onSaveName }), numberOfHiddenDuplicates > 0 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
1042
1072
  jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(TimelineDuplicateCount_1.TimelineDuplicateCount, { count: numberOfHiddenDuplicates })
1073
+ ] })) : null, hasExpandableContent && nodePathInfo !== null ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
1074
+ jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(TimelineSequenceExpandArrow, { disabled: !previewInteractive, isExpanded: isExpanded, nodePathInfo: nodePathInfo, selectedItems: selectedItems, sequence: sequence })
1043
1075
  ] })) : null, mediaSrc ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
1044
1076
  jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }),
1045
1077
  " ",
@@ -4,6 +4,7 @@ type TimelineRenderWindow = {
4
4
  readonly width: number;
5
5
  };
6
6
  export declare const TimelineViewportContext: React.Context<TimelineRenderWindow | null>;
7
+ export declare const syncTimelineViewport: () => void;
7
8
  export declare const getTimelineRenderWindow: (scrollable: HTMLDivElement) => TimelineRenderWindow;
8
9
  export declare const TimelineViewportProvider: React.FC<{
9
10
  readonly children: React.ReactNode;
@@ -1,9 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TimelineViewportProvider = exports.getTimelineRenderWindow = exports.TimelineViewportContext = void 0;
3
+ exports.TimelineViewportProvider = exports.getTimelineRenderWindow = exports.syncTimelineViewport = exports.TimelineViewportContext = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  exports.TimelineViewportContext = (0, react_1.createContext)(null);
7
+ let updateTimelineViewport = null;
8
+ const syncTimelineViewport = () => {
9
+ updateTimelineViewport === null || updateTimelineViewport === void 0 ? void 0 : updateTimelineViewport();
10
+ };
11
+ exports.syncTimelineViewport = syncTimelineViewport;
7
12
  const getTimelineRenderWindow = (scrollable) => {
8
13
  const viewportWidth = scrollable.clientWidth;
9
14
  if (viewportWidth === 0) {
@@ -41,6 +46,7 @@ const TimelineViewportProvider = ({ children, scrollable }) => {
41
46
  (0, react_1.useLayoutEffect)(() => {
42
47
  let element = null;
43
48
  let resizeObserver = null;
49
+ updateTimelineViewport = update;
44
50
  const animationFrame = requestAnimationFrame(() => {
45
51
  element = scrollable.current;
46
52
  if (!element) {
@@ -52,6 +58,9 @@ const TimelineViewportProvider = ({ children, scrollable }) => {
52
58
  element.addEventListener('scroll', update);
53
59
  });
54
60
  return () => {
61
+ if (updateTimelineViewport === update) {
62
+ updateTimelineViewport = null;
63
+ }
55
64
  cancelAnimationFrame(animationFrame);
56
65
  resizeObserver === null || resizeObserver === void 0 ? void 0 : resizeObserver.disconnect();
57
66
  element === null || element === void 0 ? void 0 : element.removeEventListener('scroll', update);
@@ -1,10 +1,10 @@
1
1
  import { type VirtualItem } from '@tanstack/react-virtual';
2
2
  import React from 'react';
3
- import type { TimelineTrackData } from '../../helpers/get-timeline-sequence-sort-key';
3
+ import type { TimelineTrackWithDisplayGroup } from './timeline-display-groups';
4
4
  export type TimelineVirtualRow = {
5
5
  readonly afterDropLineOffset: number;
6
6
  readonly siblingIndex: number;
7
- readonly track: TimelineTrackData;
7
+ readonly track: TimelineTrackWithDisplayGroup;
8
8
  };
9
9
  type TimelineVirtualizationContextValue = {
10
10
  readonly rows: readonly TimelineVirtualRow[];
@@ -16,7 +16,7 @@ export declare const TimelineVirtualizationProvider: React.FC<{
16
16
  readonly children: React.ReactNode;
17
17
  readonly hasBeenCut: boolean;
18
18
  readonly isStill: boolean;
19
- readonly timeline: readonly TimelineTrackData[];
19
+ readonly timeline: readonly TimelineTrackWithDisplayGroup[];
20
20
  }>;
21
21
  export declare const useTimelineVirtualization: () => TimelineVirtualizationContextValue;
22
22
  export {};
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.deleteSelectedTimelineItems = exports.getTimelineSelectionAfterDeletingItems = exports.deleteSequencesFromSource = void 0;
4
4
  const remotion_1 = require("remotion");
5
5
  const browser_studio_operations_1 = require("../../helpers/browser-studio-operations");
6
- const delete_jsx_node_api_1 = require("../delete-jsx-node-api");
6
+ const delete_jsx_nodes_api_1 = require("../delete-jsx-nodes-api");
7
7
  const effect_operations_api_1 = require("../effect-operations-api");
8
8
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
9
9
  const delete_selected_keyframe_1 = require("./delete-selected-keyframe");
@@ -39,7 +39,7 @@ const deleteSequencesFromSource = async (nodePathInfos, confirm) => {
39
39
  if (!(await confirmDeletingDuplicatedSequences(nodePathInfos, confirm))) {
40
40
  return false;
41
41
  }
42
- return (0, delete_jsx_node_api_1.deleteJsxNode)({
42
+ return (0, delete_jsx_nodes_api_1.deleteJsxNodes)({
43
43
  nodes: nodePathInfos.map((nodePathInfo) => {
44
44
  const nodePath = nodePathInfo.sequenceSubscriptionKey;
45
45
  return {
@@ -2,15 +2,19 @@ import type { EditorPickerId, GetDefaultCodingAgentInfoResponse, GetDefaultEdito
2
2
  import type { ResolvedStackLocation, TSequence } from 'remotion';
3
3
  import type { ComboboxValue } from '../NewComposition/ComboBox';
4
4
  import type { TimelineAssetLinkInfo } from './timeline-asset-link';
5
- export declare const getMultiSequenceContextMenuItems: ({ deleteDisabled, duplicateDisabled, onDeleteSelectedSequences, onDuplicateSelectedSequences, }: {
5
+ export declare const findCopyableFrameElement: (element: Element | null) => Element | null;
6
+ export declare const getMultiSequenceContextMenuItems: ({ deleteDisabled, duplicateDisabled, splitDisabled, onDeleteSelectedSequences, onDuplicateSelectedSequences, onSplitSelectedSequences, }: {
6
7
  readonly deleteDisabled: boolean;
7
8
  readonly duplicateDisabled: boolean;
9
+ readonly splitDisabled: boolean;
8
10
  readonly onDeleteSelectedSequences: () => void;
9
11
  readonly onDuplicateSelectedSequences: () => void;
12
+ readonly onSplitSelectedSequences: () => void;
10
13
  }) => ComboboxValue[];
11
- export declare const getSequenceContextMenuItems: ({ assetLinkInfo, canOpenInEditor, deleteDisabled, disableInteractivityDisabled, duplicateDisabled, isProgrammaticallyDuplicated, includeSourceEditItems, codingAgentInfo, editorInfo, onConfigureApps, onDeleteSequenceFromSource, onDisableSequenceInteractivity, onDuplicateSequenceFromSource, openInCodingAgent, openInEditor, originalLocation, selectAsset, sequence, sourceActions, }: {
14
+ export declare const getSequenceContextMenuItems: ({ assetLinkInfo, canOpenInEditor, copyImageElement, deleteDisabled, disableInteractivityDisabled, duplicateDisabled, isProgrammaticallyDuplicated, includeSourceEditItems, codingAgentInfo, editorInfo, onConfigureApps, onDeleteSequenceFromSource, onDisableSequenceInteractivity, onDuplicateSequenceFromSource, openInCodingAgent, openInEditor, originalLocation, selectAsset, sequence, sourceActions, }: {
12
15
  readonly assetLinkInfo: TimelineAssetLinkInfo | null;
13
16
  readonly canOpenInEditor: boolean;
17
+ readonly copyImageElement: Element | null;
14
18
  readonly deleteDisabled: boolean;
15
19
  readonly disableInteractivityDisabled: boolean;
16
20
  readonly duplicateDisabled: boolean;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getSequenceContextMenuItems = exports.getMultiSequenceContextMenuItems = void 0;
3
+ exports.getSequenceContextMenuItems = exports.getMultiSequenceContextMenuItems = exports.findCopyableFrameElement = void 0;
4
4
  const no_react_1 = require("remotion/no-react");
5
5
  const format_file_location_1 = require("../../helpers/format-file-location");
6
6
  const get_git_menu_item_1 = require("../../helpers/get-git-menu-item");
@@ -28,7 +28,75 @@ const normalizeMenuDividers = (items) => {
28
28
  return normalized;
29
29
  };
30
30
  const interactiveSvgComponentIdentity = 'dev.remotion.remotion.Interactive.Svg';
31
- const getMultiSequenceContextMenuItems = ({ deleteDisabled, duplicateDisabled, onDeleteSelectedSequences, onDuplicateSelectedSequences, }) => {
31
+ const findCopyableFrameElement = (element) => {
32
+ var _a;
33
+ if ((element === null || element === void 0 ? void 0 : element.tagName) === 'CANVAS' || (element === null || element === void 0 ? void 0 : element.tagName) === 'VIDEO') {
34
+ return element;
35
+ }
36
+ return (_a = element === null || element === void 0 ? void 0 : element.querySelector('canvas, video')) !== null && _a !== void 0 ? _a : null;
37
+ };
38
+ exports.findCopyableFrameElement = findCopyableFrameElement;
39
+ const copyImageToClipboard = async (element) => {
40
+ let canvas;
41
+ if (element.tagName === 'CANVAS') {
42
+ const sourceCanvas = element;
43
+ canvas = document.createElement('canvas');
44
+ canvas.width = sourceCanvas.width;
45
+ canvas.height = sourceCanvas.height;
46
+ const context = canvas.getContext('2d');
47
+ if (!context) {
48
+ throw new Error('Could not create canvas context');
49
+ }
50
+ context.drawImage(sourceCanvas, 0, 0);
51
+ }
52
+ else if (element.tagName === 'IMG') {
53
+ const image = element;
54
+ if (image.naturalWidth === 0 || image.naturalHeight === 0) {
55
+ throw new Error('Image has not loaded');
56
+ }
57
+ canvas = document.createElement('canvas');
58
+ canvas.width = image.naturalWidth;
59
+ canvas.height = image.naturalHeight;
60
+ const context = canvas.getContext('2d');
61
+ if (!context) {
62
+ throw new Error('Could not create canvas context');
63
+ }
64
+ context.drawImage(image, 0, 0);
65
+ }
66
+ else if (element.tagName === 'VIDEO') {
67
+ const video = element;
68
+ if (video.videoWidth === 0 || video.videoHeight === 0) {
69
+ throw new Error('Video frame has not loaded');
70
+ }
71
+ canvas = document.createElement('canvas');
72
+ canvas.width = video.videoWidth;
73
+ canvas.height = video.videoHeight;
74
+ const context = canvas.getContext('2d');
75
+ if (!context) {
76
+ throw new Error('Could not create canvas context');
77
+ }
78
+ context.drawImage(video, 0, 0);
79
+ }
80
+ else {
81
+ throw new Error('Expected an image, video, or canvas element');
82
+ }
83
+ const blob = new Promise((resolve, reject) => {
84
+ canvas.toBlob((result) => {
85
+ if (result) {
86
+ resolve(result);
87
+ }
88
+ else {
89
+ reject(new Error('Could not convert image to PNG'));
90
+ }
91
+ }, 'image/png');
92
+ });
93
+ await navigator.clipboard.write([
94
+ new ClipboardItem({
95
+ 'image/png': blob,
96
+ }),
97
+ ]);
98
+ };
99
+ const getMultiSequenceContextMenuItems = ({ deleteDisabled, duplicateDisabled, splitDisabled, onDeleteSelectedSequences, onDuplicateSelectedSequences, onSplitSelectedSequences, }) => {
32
100
  return [
33
101
  {
34
102
  type: 'item',
@@ -42,6 +110,18 @@ const getMultiSequenceContextMenuItems = ({ deleteDisabled, duplicateDisabled, o
42
110
  subMenu: null,
43
111
  value: 'duplicate-selected-sequences',
44
112
  },
113
+ {
114
+ type: 'item',
115
+ id: 'split-selected-sequences',
116
+ keyHint: null,
117
+ label: 'Split selected at playhead',
118
+ leftItem: null,
119
+ disabled: splitDisabled,
120
+ onClick: onSplitSelectedSequences,
121
+ quickSwitcherLabel: null,
122
+ subMenu: null,
123
+ value: 'split-selected-sequences',
124
+ },
45
125
  {
46
126
  type: 'divider',
47
127
  id: 'duplicate-delete-selected-sequences-divider',
@@ -61,9 +141,9 @@ const getMultiSequenceContextMenuItems = ({ deleteDisabled, duplicateDisabled, o
61
141
  ];
62
142
  };
63
143
  exports.getMultiSequenceContextMenuItems = getMultiSequenceContextMenuItems;
64
- const getSequenceContextMenuItems = ({ assetLinkInfo, canOpenInEditor, deleteDisabled, disableInteractivityDisabled, duplicateDisabled, isProgrammaticallyDuplicated, includeSourceEditItems, codingAgentInfo, editorInfo, onConfigureApps, onDeleteSequenceFromSource, onDisableSequenceInteractivity, onDuplicateSequenceFromSource, openInCodingAgent, openInEditor, originalLocation, selectAsset, sequence, sourceActions = [], }) => {
144
+ const getSequenceContextMenuItems = ({ assetLinkInfo, canOpenInEditor, copyImageElement, deleteDisabled, disableInteractivityDisabled, duplicateDisabled, isProgrammaticallyDuplicated, includeSourceEditItems, codingAgentInfo, editorInfo, onConfigureApps, onDeleteSequenceFromSource, onDisableSequenceInteractivity, onDuplicateSequenceFromSource, openInCodingAgent, openInEditor, originalLocation, selectAsset, sequence, sourceActions = [], }) => {
65
145
  var _a, _b, _c;
66
- var _d, _e, _f;
146
+ var _d, _e;
67
147
  const isInteractiveSvg = ((_a = sequence.controls) === null || _a === void 0 ? void 0 : _a.componentIdentity) === interactiveSvgComponentIdentity;
68
148
  const installedEditors = (_d = editorInfo === null || editorInfo === void 0 ? void 0 : editorInfo.installedEditors) !== null && _d !== void 0 ? _d : [];
69
149
  const defaultEditorId = (0, use_default_editor_info_1.getPreferredEditorId)(editorInfo);
@@ -74,7 +154,7 @@ const getSequenceContextMenuItems = ({ assetLinkInfo, canOpenInEditor, deleteDis
74
154
  ? (0, get_git_menu_item_1.getGitSourceName)(window.remotion_gitSource)
75
155
  : null;
76
156
  const defaultOpenInName = defaultOpenInTarget === 'editor' ? editorName : gitSourceName;
77
- const defaultCodingAgent = codingAgentInfo === null || codingAgentInfo === void 0 ? void 0 : codingAgentInfo.installedCodingAgents.find((codingAgent) => codingAgent.id === codingAgentInfo.defaultCodingAgent);
157
+ const copyImageLabel = copyImageElement && sequence.type === 'image' ? 'Copy image' : 'Copy frame';
78
158
  const contextForAgents = (0, format_file_location_1.formatContextForAgents)({
79
159
  location: originalLocation,
80
160
  name: sequence.displayName || ((_b = sequence.controls) === null || _b === void 0 ? void 0 : _b.componentName) || null,
@@ -83,31 +163,34 @@ const getSequenceContextMenuItems = ({ assetLinkInfo, canOpenInEditor, deleteDis
83
163
  const openInCodingAgentWithContext = (codingAgentId, codingAgentName) => {
84
164
  openInCodingAgent(codingAgentId, codingAgentName, codingAgentId === 'copilot' ? null : contextForAgents);
85
165
  };
86
- const openInMenuItems = onConfigureApps
87
- ? (0, get_open_in_menu_items_1.getOpenInMenuItems)({
88
- codingAgentInfo,
89
- editorDisabled: !canOpenInEditor || !originalLocation,
90
- editorInfo,
91
- excludeCodingAgentId: (_f = defaultCodingAgent === null || defaultCodingAgent === void 0 ? void 0 : defaultCodingAgent.id) !== null && _f !== void 0 ? _f : null,
92
- excludeEditorId: defaultEditorId,
93
- fileManagerDisabled: !(originalLocation === null || originalLocation === void 0 ? void 0 : originalLocation.source),
94
- folder: false,
95
- location: originalLocation,
96
- onConfigureApps,
97
- onOpenInCodingAgent: openInCodingAgentWithContext,
98
- onOpenInEditor: openInEditor,
99
- onOpenInFileExplorer: () => {
100
- if (!(originalLocation === null || originalLocation === void 0 ? void 0 : originalLocation.source)) {
101
- return;
102
- }
103
- (0, actions_1.openInFileExplorer)({ directory: originalLocation.source }).catch((err) => {
104
- (0, NotificationCenter_1.showNotification)(`Could not open file: ${err.message}`, 2000);
105
- });
106
- },
107
- onOpenInGitClient: () => undefined,
108
- onOpenInTerminal: null,
109
- })
110
- : [];
166
+ const openInMenuItems = (0, get_open_in_menu_items_1.getOpenInMenuItems)({
167
+ canOpenDesktopApps: onConfigureApps !== null,
168
+ codingAgentInfo,
169
+ editorDisabled: !canOpenInEditor || !originalLocation,
170
+ editorInfo,
171
+ excludeCodingAgentId: null,
172
+ excludeEditorId: defaultEditorId,
173
+ excludeGitSource: defaultOpenInTarget === 'git-source',
174
+ fileManagerDisabled: !(originalLocation === null || originalLocation === void 0 ? void 0 : originalLocation.source),
175
+ folder: false,
176
+ gitSourceDisabled: !originalLocation,
177
+ onConfigureApps,
178
+ onOpenInCodingAgent: openInCodingAgentWithContext,
179
+ onOpenInEditor: openInEditor,
180
+ onOpenInFileExplorer: () => {
181
+ if (!(originalLocation === null || originalLocation === void 0 ? void 0 : originalLocation.source)) {
182
+ return;
183
+ }
184
+ (0, actions_1.openInFileExplorer)({ directory: originalLocation.source }).catch((err) => {
185
+ (0, NotificationCenter_1.showNotification)(`Could not open file: ${err.message}`, 2000);
186
+ });
187
+ },
188
+ onOpenInGitClient: () => undefined,
189
+ onOpenInGitSource: () => {
190
+ (0, get_git_menu_item_1.openGitSource)({ folder: false, location: originalLocation });
191
+ },
192
+ onOpenInTerminal: null,
193
+ });
111
194
  const items = [
112
195
  defaultOpenInTarget && defaultOpenInName
113
196
  ? {
@@ -133,21 +216,7 @@ const getSequenceContextMenuItems = ({ assetLinkInfo, canOpenInEditor, deleteDis
133
216
  : 'open-in-git-source',
134
217
  }
135
218
  : null,
136
- defaultCodingAgent
137
- ? {
138
- type: 'item',
139
- id: 'open-in-default-coding-agent',
140
- keyHint: null,
141
- label: `Open in ${defaultCodingAgent.nameWithType}`,
142
- leftItem: null,
143
- disabled: false,
144
- onClick: () => openInCodingAgentWithContext(defaultCodingAgent.id, defaultCodingAgent.nameWithType),
145
- quickSwitcherLabel: null,
146
- subMenu: null,
147
- value: 'open-in-default-coding-agent',
148
- }
149
- : null,
150
- onConfigureApps
219
+ openInMenuItems.length > 0
151
220
  ? {
152
221
  type: 'item',
153
222
  id: 'open-in-another-app',
@@ -182,7 +251,35 @@ const getSequenceContextMenuItems = ({ assetLinkInfo, canOpenInEditor, deleteDis
182
251
  value: 'show-asset',
183
252
  }
184
253
  : null,
185
- assetLinkInfo
254
+ copyImageElement
255
+ ? {
256
+ type: 'divider',
257
+ id: 'copy-image-divider',
258
+ }
259
+ : null,
260
+ copyImageElement
261
+ ? {
262
+ type: 'item',
263
+ id: copyImageLabel === 'Copy image' ? 'copy-image' : 'copy-frame',
264
+ keyHint: null,
265
+ label: copyImageLabel,
266
+ leftItem: null,
267
+ disabled: false,
268
+ onClick: () => {
269
+ copyImageToClipboard(copyImageElement)
270
+ .then(() => {
271
+ (0, NotificationCenter_1.showNotification)(`Copied ${copyImageLabel === 'Copy image' ? 'image' : 'frame'} to clipboard`, 1000);
272
+ })
273
+ .catch((err) => {
274
+ (0, NotificationCenter_1.showNotification)(`Could not copy ${copyImageLabel === 'Copy image' ? 'image' : 'frame'}: ${err.message}`, 2000);
275
+ });
276
+ },
277
+ quickSwitcherLabel: null,
278
+ subMenu: null,
279
+ value: copyImageLabel === 'Copy image' ? 'copy-image' : 'copy-frame',
280
+ }
281
+ : null,
282
+ assetLinkInfo || copyImageElement
186
283
  ? {
187
284
  type: 'divider',
188
285
  id: 'sequence-link-divider',
@@ -0,0 +1 @@
1
+ export declare const normalizeFontWeightForKeyframe: (value: unknown) => number | null;