@remotion/studio 4.0.518 → 4.0.519

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 (140) hide show
  1. package/dist/components/AppLaunchButton.d.ts +16 -0
  2. package/dist/components/AppLaunchButton.js +90 -0
  3. package/dist/components/AssetSelector.js +7 -6
  4. package/dist/components/AssetSelectorItem.d.ts +12 -0
  5. package/dist/components/AssetSelectorItem.js +180 -62
  6. package/dist/components/Button.js +20 -7
  7. package/dist/components/Canvas.js +109 -78
  8. package/dist/components/CanvasOrLoading.js +7 -7
  9. package/dist/components/CodingAgentButton.d.ts +7 -0
  10. package/dist/components/CodingAgentButton.js +59 -0
  11. package/dist/components/CompositionContextButton.d.ts +1 -0
  12. package/dist/components/CompositionContextButton.js +6 -3
  13. package/dist/components/CompositionSelector.js +15 -10
  14. package/dist/components/CompositionSelectorItem.js +16 -23
  15. package/dist/components/ConfigureLicenseModal.js +4 -48
  16. package/dist/components/CurrentAsset.js +1 -1
  17. package/dist/components/ElementInstallConfirmation.d.ts +20 -7
  18. package/dist/components/ElementInstallConfirmation.js +325 -32
  19. package/dist/components/FixComputedValueModal.js +5 -131
  20. package/dist/components/InitialCompositionLoader.js +3 -2
  21. package/dist/components/InspectorOpenInEditor.js +48 -33
  22. package/dist/components/InspectorPanel/CompositionInspector.js +35 -3
  23. package/dist/components/InspectorPanel/CompositionInspectorHeader.js +22 -14
  24. package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +3 -1
  25. package/dist/components/InspectorPanel/SequenceInspectorHeader.d.ts +1 -1
  26. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +10 -5
  27. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +1 -1
  28. package/dist/components/InspectorPanel/common.js +1 -0
  29. package/dist/components/InspectorPanel/styles.js +1 -0
  30. package/dist/components/InspectorSequenceSection.js +8 -3
  31. package/dist/components/InspectorSourceLocation.js +5 -1
  32. package/dist/components/KnownBugs.d.ts +1 -1
  33. package/dist/components/KnownBugs.js +1 -1
  34. package/dist/components/LicenseExplanation.d.ts +2 -0
  35. package/dist/components/LicenseExplanation.js +63 -0
  36. package/dist/components/MenuToolbar.js +7 -1
  37. package/dist/components/Modals.js +1 -2
  38. package/dist/components/NewComposition/InputDragger.js +29 -2
  39. package/dist/components/NewComposition/NewCompDuration.js +1 -1
  40. package/dist/components/NewComposition/NewComposition.d.ts +23 -0
  41. package/dist/components/NewComposition/NewComposition.js +217 -80
  42. package/dist/components/{UpdateModal/OpenIssueButton.js → OpenIssueButton.js} +1 -1
  43. package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.js +2 -1
  44. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +21 -13
  45. package/dist/components/RenderQueue/actions.d.ts +1 -0
  46. package/dist/components/RenderQueue/actions.js +5 -1
  47. package/dist/components/SelectedOutlineCanvasRotation.js +27 -1
  48. package/dist/components/SelectedOutlineElement.js +2 -1
  49. package/dist/components/SelectedOutlineKeyboardControls.d.ts +2 -2
  50. package/dist/components/SelectedOutlineOverlay.d.ts +3 -1
  51. package/dist/components/SelectedOutlineOverlay.js +21 -26
  52. package/dist/components/SelectedOutlinePolygon.d.ts +1 -0
  53. package/dist/components/SelectedOutlinePolygon.js +12 -4
  54. package/dist/components/SelectedOutlineRenderer.js +88 -21
  55. package/dist/components/SettingsContext.js +2 -1
  56. package/dist/components/SettingsModal.d.ts +1 -1
  57. package/dist/components/SettingsModal.js +19 -3
  58. package/dist/components/SidebarRenderButton.d.ts +1 -0
  59. package/dist/components/SidebarRenderButton.js +14 -5
  60. package/dist/components/Timeline/SequencePropsObserver.js +29 -14
  61. package/dist/components/Timeline/TimelineKeyframeControls.js +3 -1
  62. package/dist/components/Timeline/TimelineRowChrome.js +4 -2
  63. package/dist/components/Timeline/TimelineSequence.js +40 -8
  64. package/dist/components/Timeline/TimelineSequenceItem.js +34 -1
  65. package/dist/components/Timeline/TimelineStack/get-stack.d.ts +1 -0
  66. package/dist/components/Timeline/TimelineStack/get-stack.js +35 -3
  67. package/dist/components/Timeline/duplicate-selected-timeline-item.js +23 -25
  68. package/dist/components/Timeline/get-sequence-context-menu-items.d.ts +6 -0
  69. package/dist/components/Timeline/get-sequence-context-menu-items.js +34 -1
  70. package/dist/components/Timeline/sequence-props-subscription-store.d.ts +2 -0
  71. package/dist/components/Timeline/sequence-props-subscription-store.js +22 -1
  72. package/dist/components/Timeline/use-sequence-props-subscription.js +7 -0
  73. package/dist/components/TimelineCombobox.js +1 -0
  74. package/dist/components/UpdateCheck.d.ts +0 -8
  75. package/dist/components/UpdateCheck.js +7 -54
  76. package/dist/components/UpdateStatusContext.d.ts +18 -0
  77. package/dist/components/UpdateStatusContext.js +74 -0
  78. package/dist/components/UpdatesSettings.d.ts +2 -0
  79. package/dist/components/UpdatesSettings.js +251 -0
  80. package/dist/components/WebMcp.js +3 -3
  81. package/dist/components/get-open-in-menu-items.d.ts +4 -0
  82. package/dist/components/get-open-in-menu-items.js +28 -24
  83. package/dist/components/root-composition-menu-items.d.ts +4 -1
  84. package/dist/components/root-composition-menu-items.js +38 -1
  85. package/dist/components/selected-outline-geometry.d.ts +21 -2
  86. package/dist/components/selected-outline-geometry.js +16 -5
  87. package/dist/components/selected-outline-measurement.d.ts +40 -1
  88. package/dist/components/selected-outline-measurement.js +239 -1
  89. package/dist/components/selected-outline-order.d.ts +12 -0
  90. package/dist/components/selected-outline-order.js +251 -0
  91. package/dist/components/selected-outline-types.d.ts +15 -2
  92. package/dist/components/selected-outline-uv.js +106 -3
  93. package/dist/components/use-configure-default-apps.d.ts +1 -0
  94. package/dist/components/use-configure-default-apps.js +24 -0
  95. package/dist/error-overlay/remotion-overlay/CodeFrame.js +5 -6
  96. package/dist/error-overlay/remotion-overlay/CopyStackTrace.js +1 -1
  97. package/dist/error-overlay/remotion-overlay/ErrorDisplay.js +47 -18
  98. package/dist/error-overlay/remotion-overlay/ErrorLoader.js +1 -1
  99. package/dist/error-overlay/remotion-overlay/ErrorTitle.js +5 -4
  100. package/dist/error-overlay/remotion-overlay/OpenInEditor.js +48 -76
  101. package/dist/error-overlay/remotion-overlay/SearchGitHubIssues.js +1 -1
  102. package/dist/error-overlay/remotion-overlay/ShortcutHint.js +2 -2
  103. package/dist/error-overlay/remotion-overlay/StackFrame.js +13 -8
  104. package/dist/error-overlay/remotion-overlay/Symbolicating.js +1 -1
  105. package/dist/esm/{chunk-7prjt5n5.js → chunk-1fkq5bfq.js} +15439 -11610
  106. package/dist/esm/chunk-6jf1natv.js +25 -0
  107. package/dist/esm/{chunk-4bxz1d3g.js → chunk-je0h1bgt.js} +1 -28
  108. package/dist/esm/chunk-m0jqdbkr.js +14571 -0
  109. package/dist/esm/index.mjs +0 -2
  110. package/dist/esm/internals.mjs +32140 -13755
  111. package/dist/esm/previewEntry.mjs +35408 -17021
  112. package/dist/esm/renderEntry.mjs +6 -3
  113. package/dist/helpers/can-show-updates.d.ts +5 -0
  114. package/dist/helpers/can-show-updates.js +7 -0
  115. package/dist/helpers/colors.d.ts +0 -3
  116. package/dist/helpers/colors.js +2 -5
  117. package/dist/helpers/create-folder-tree.d.ts +5 -0
  118. package/dist/helpers/create-folder-tree.js +24 -1
  119. package/dist/helpers/get-asset-metadata.js +1 -1
  120. package/dist/helpers/get-box-quads-polyfill-internals.d.ts +82 -0
  121. package/dist/helpers/get-box-quads-polyfill-internals.js +2403 -0
  122. package/dist/helpers/get-box-quads-ponyfill.d.ts +10 -0
  123. package/dist/helpers/get-box-quads-ponyfill.js +23 -0
  124. package/dist/helpers/get-git-menu-item.d.ts +5 -0
  125. package/dist/helpers/get-git-menu-item.js +15 -1
  126. package/dist/helpers/hoverable.js +10 -5
  127. package/dist/helpers/open-in-editor.js +51 -1
  128. package/dist/helpers/preview-server-events.js +3 -0
  129. package/dist/helpers/timeline-layout.d.ts +0 -1
  130. package/dist/helpers/timeline-layout.js +1 -5
  131. package/dist/helpers/url-state.d.ts +1 -0
  132. package/dist/helpers/url-state.js +12 -5
  133. package/dist/renderEntry.js +2 -0
  134. package/dist/state/folders.d.ts +3 -0
  135. package/dist/state/folders.js +40 -1
  136. package/dist/state/modals.d.ts +1 -6
  137. package/package.json +17 -14
  138. package/dist/components/UpdateModal/UpdateModal.d.ts +0 -6
  139. package/dist/components/UpdateModal/UpdateModal.js +0 -104
  140. /package/dist/components/{UpdateModal/OpenIssueButton.d.ts → OpenIssueButton.d.ts} +0 -0
@@ -91,8 +91,10 @@ const TimelineRowChrome = ({ depth, eye, keyframeControls, arrow, children, styl
91
91
  }, [onSelect]);
92
92
  const onContextMenu = (0, react_1.useCallback)((e) => {
93
93
  e.stopPropagation();
94
- onSelect();
95
- }, [onSelect]);
94
+ if (!selected) {
95
+ onSelect();
96
+ }
97
+ }, [onSelect, selected]);
96
98
  const onDoubleClickIfNotInteractive = (0, react_1.useCallback)((e) => {
97
99
  const { target } = e;
98
100
  if (target instanceof Element &&
@@ -54,6 +54,7 @@ const delete_jsx_node_api_1 = require("../delete-jsx-node-api");
54
54
  const InitialCompositionLoader_1 = require("../InitialCompositionLoader");
55
55
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
56
56
  const use_select_asset_1 = require("../use-select-asset");
57
+ const delete_selected_timeline_item_1 = require("./delete-selected-timeline-item");
57
58
  const disable_sequence_interactivity_1 = require("./disable-sequence-interactivity");
58
59
  const duplicate_selected_timeline_item_1 = require("./duplicate-selected-timeline-item");
59
60
  const get_sequence_context_menu_items_1 = require("./get-sequence-context-menu-items");
@@ -117,7 +118,7 @@ const TimelineSequenceNegativeStartInner = ({ left, width, leftEdgeVisible, clip
117
118
  };
118
119
  const TimelineSequenceNegativeStart = react_1.default.memo(TimelineSequenceNegativeStartInner);
119
120
  const TimelineSequenceCurrentFrame = ({ s, displayDurationInFrames, premount, postmount, negativeStart, leftEdgeVisible, negativeStartClipped, style, children, nodePathInfo, sequenceFrameOffset, fromCanUpdate, frozenFrame, onMoveDragPointerDown, onPointerDownCapture, onDoubleClick, }) => {
120
- var _a, _b, _c, _d;
121
+ var _a, _b, _c;
121
122
  const ref = (0, react_1.useRef)(null);
122
123
  const { onSelect, selectable, selected, selectionItem } = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
123
124
  const containsSelection = (0, TimelineSelection_1.useTimelineRowContainsSelection)(nodePathInfo);
@@ -195,8 +196,8 @@ const TimelineSequenceCurrentFrame = ({ s, displayDurationInFrames, premount, po
195
196
  s.type !== 'video' &&
196
197
  s.type !== 'image' &&
197
198
  s.loopDisplay === undefined &&
198
- (isInRange || isPremounting || isPostmounting) ? (jsx_runtime_1.jsx("div", { style: {
199
- paddingLeft: 5 + ((_c = negativeStart === null || negativeStart === void 0 ? void 0 : negativeStart.width) !== null && _c !== void 0 ? _c : 0) + ((_d = premount === null || premount === void 0 ? void 0 : premount.width) !== null && _d !== void 0 ? _d : 0),
199
+ (frozenFrame !== null || isInRange || isPremounting || isPostmounting) ? (jsx_runtime_1.jsx("div", { style: {
200
+ paddingLeft: 5 + negativeStartEnd + ((_c = premount === null || premount === void 0 ? void 0 : premount.width) !== null && _c !== void 0 ? _c : 0),
200
201
  height: '100%',
201
202
  display: 'flex',
202
203
  alignItems: 'center',
@@ -279,7 +280,16 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
279
280
  const selectAsset = (0, use_select_asset_1.useSelectAsset)();
280
281
  const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
281
282
  const confirm = (0, ConfirmationDialog_1.useConfirmationDialog)();
282
- const { onSelect, selectable } = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
283
+ const { onSelect, selectable, selected } = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
284
+ const { selectedItems } = (0, TimelineSelection_1.useTimelineSelection)();
285
+ const selectedSequenceNodePathInfos = (0, react_1.useMemo)(() => {
286
+ if (!selected ||
287
+ selectedItems.length < 2 ||
288
+ selectedItems.some((item) => item.type !== 'sequence')) {
289
+ return null;
290
+ }
291
+ return selectedItems.flatMap((item) => item.type === 'sequence' ? [item.nodePathInfo] : []);
292
+ }, [selected, selectedItems]);
283
293
  const onSequenceDoubleClick = (0, react_1.useCallback)((e) => {
284
294
  if ((0, TimelineSelection_1.isTimelineSelectionModifierEvent)(e)) {
285
295
  e.stopPropagation();
@@ -332,6 +342,12 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
332
342
  }
333
343
  (0, duplicate_selected_timeline_item_1.duplicateSequencesFromSource)([nodePathInfo], confirm).catch(() => undefined);
334
344
  }, [confirm, duplicateDisabled, nodePathInfo, validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source]);
345
+ const onDuplicateSelectedSequences = (0, react_1.useCallback)(() => {
346
+ if (!previewInteractive || selectedSequenceNodePathInfos === null) {
347
+ return;
348
+ }
349
+ (0, duplicate_selected_timeline_item_1.duplicateSequencesFromSource)(selectedSequenceNodePathInfos, confirm).catch(() => undefined);
350
+ }, [confirm, previewInteractive, selectedSequenceNodePathInfos]);
335
351
  const onDeleteSequenceFromSource = (0, react_1.useCallback)(async () => {
336
352
  if (!(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source) || !nodePath || deleteDisabled) {
337
353
  return;
@@ -371,6 +387,12 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
371
387
  nodePathInfo,
372
388
  validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source,
373
389
  ]);
390
+ const onDeleteSelectedSequences = (0, react_1.useCallback)(() => {
391
+ if (!previewInteractive || selectedSequenceNodePathInfos === null) {
392
+ return;
393
+ }
394
+ (0, delete_selected_timeline_item_1.deleteSequencesFromSource)(selectedSequenceNodePathInfos, confirm).catch(() => undefined);
395
+ }, [confirm, previewInteractive, selectedSequenceNodePathInfos]);
374
396
  const onDisableSequenceInteractivity = (0, react_1.useCallback)(() => {
375
397
  if (disableInteractivityDisabled ||
376
398
  !nodePath ||
@@ -393,9 +415,17 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
393
415
  ]);
394
416
  const getContextMenuItems = (0, react_1.useCallback)(() => {
395
417
  var _a;
396
- if (selectable) {
418
+ if (selectable && !selected) {
397
419
  onSelect({ shiftKey: false, toggleKey: false });
398
420
  }
421
+ if (selectedSequenceNodePathInfos !== null) {
422
+ return (0, get_sequence_context_menu_items_1.getMultiSequenceContextMenuItems)({
423
+ deleteDisabled: !previewInteractive,
424
+ duplicateDisabled: !previewInteractive,
425
+ onDeleteSelectedSequences,
426
+ onDuplicateSelectedSequences,
427
+ });
428
+ }
399
429
  const freezeFrameMenuItem = (0, use_sequence_freeze_frame_menu_item_1.getSequenceFreezeFrameMenuItem)({
400
430
  clientId: previewInteractive && previewServerState.type === 'connected'
401
431
  ? previewServerState.clientId
@@ -454,8 +484,10 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
454
484
  nodePath,
455
485
  onSelect,
456
486
  onDeleteSequenceFromSource,
487
+ onDeleteSelectedSequences,
457
488
  onDisableSequenceInteractivity,
458
489
  onDuplicateSequenceFromSource,
490
+ onDuplicateSelectedSequences,
459
491
  openInCodingAgent,
460
492
  openInEditor,
461
493
  originalLocation,
@@ -465,6 +497,8 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
465
497
  s,
466
498
  selectAsset,
467
499
  selectable,
500
+ selected,
501
+ selectedSequenceNodePathInfos,
468
502
  sequenceFrameOffset,
469
503
  setPropStatuses,
470
504
  setSelectedModal,
@@ -543,9 +577,7 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
543
577
  ? colors_1.TIMELINE_AUDIO_GRADIENT
544
578
  : s.type === 'video'
545
579
  ? colors_1.TIMELINE_VIDEO_GRADIENT
546
- : s.type === 'image'
547
- ? colors_1.TIMELINE_IMAGE_GRADIENT
548
- : colors_1.BLUE,
580
+ : colors_1.BLUE,
549
581
  border: `${get_timeline_sequence_layout_1.SEQUENCE_BORDER_WIDTH}px solid ${colors_1.WHITE_ALPHA_20}`,
550
582
  borderLeftColor: (visibleLayout === null || visibleLayout === void 0 ? void 0 : visibleLayout.leftEdgeVisible) && !negativeStartClipped
551
583
  ? colors_1.WHITE_ALPHA_20
@@ -62,6 +62,7 @@ const NotificationCenter_1 = require("../Notifications/NotificationCenter");
62
62
  const reorder_sequence_api_1 = require("../reorder-sequence-api");
63
63
  const selected_outline_types_1 = require("../selected-outline-types");
64
64
  const use_select_asset_1 = require("../use-select-asset");
65
+ const delete_selected_timeline_item_1 = require("./delete-selected-timeline-item");
65
66
  const disable_sequence_interactivity_1 = require("./disable-sequence-interactivity");
66
67
  const duplicate_selected_timeline_item_1 = require("./duplicate-selected-timeline-item");
67
68
  const get_sequence_context_menu_items_1 = require("./get-sequence-context-menu-items");
@@ -195,6 +196,14 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
195
196
  const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
196
197
  const { onSelect, selectable, selected } = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
197
198
  const { selectItem, selectedItems } = (0, TimelineSelection_1.useTimelineSelection)();
199
+ const selectedSequenceNodePathInfos = (0, react_1.useMemo)(() => {
200
+ if (!selected ||
201
+ selectedItems.length < 2 ||
202
+ selectedItems.some((item) => item.type !== 'sequence')) {
203
+ return null;
204
+ }
205
+ return selectedItems.flatMap((item) => item.type === 'sequence' ? [item.nodePathInfo] : []);
206
+ }, [selected, selectedItems]);
198
207
  const containsSelection = (0, TimelineSelection_1.useTimelineRowContainsSelection)(nodePathInfo);
199
208
  const [effectDropHovered, setEffectDropHovered] = (0, react_1.useState)(false);
200
209
  const [isRenaming, setIsRenaming] = (0, react_1.useState)(false);
@@ -246,6 +255,12 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
246
255
  }
247
256
  (0, duplicate_selected_timeline_item_1.duplicateSequencesFromSource)([nodePathInfo], confirm).catch(() => undefined);
248
257
  }, [confirm, duplicateDisabled, nodePathInfo, validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source]);
258
+ const onDuplicateSelectedSequences = (0, react_1.useCallback)(() => {
259
+ if (!previewInteractive || selectedSequenceNodePathInfos === null) {
260
+ return;
261
+ }
262
+ (0, duplicate_selected_timeline_item_1.duplicateSequencesFromSource)(selectedSequenceNodePathInfos, confirm).catch(() => undefined);
263
+ }, [confirm, previewInteractive, selectedSequenceNodePathInfos]);
249
264
  const onDeleteSequenceFromSource = (0, react_1.useCallback)(async () => {
250
265
  if (deleteDisabled || !(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source) || !nodePath) {
251
266
  return;
@@ -285,6 +300,12 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
285
300
  validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source,
286
301
  nodePathInfo,
287
302
  ]);
303
+ const onDeleteSelectedSequences = (0, react_1.useCallback)(() => {
304
+ if (!previewInteractive || selectedSequenceNodePathInfos === null) {
305
+ return;
306
+ }
307
+ (0, delete_selected_timeline_item_1.deleteSequencesFromSource)(selectedSequenceNodePathInfos, confirm).catch(() => undefined);
308
+ }, [confirm, previewInteractive, selectedSequenceNodePathInfos]);
288
309
  const onDisableSequenceInteractivity = (0, react_1.useCallback)(() => {
289
310
  if (disableInteractivityDisabled ||
290
311
  !nodePath ||
@@ -693,9 +714,17 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
693
714
  }, [canRotate, nodePathInfo, selectItem, setManuallyEnabled]);
694
715
  const getContextMenuItems = (0, react_1.useCallback)(() => {
695
716
  var _a;
696
- if (selectable) {
717
+ if (selectable && !selected) {
697
718
  onSelect({ shiftKey: false, toggleKey: false });
698
719
  }
720
+ if (selectedSequenceNodePathInfos !== null) {
721
+ return (0, get_sequence_context_menu_items_1.getMultiSequenceContextMenuItems)({
722
+ deleteDisabled: !previewInteractive,
723
+ duplicateDisabled: !previewInteractive,
724
+ onDeleteSelectedSequences,
725
+ onDuplicateSelectedSequences,
726
+ });
727
+ }
699
728
  const freezeFrameMenuItem = (0, use_sequence_freeze_frame_menu_item_1.getSequenceFreezeFrameMenuItem)({
700
729
  clientId: previewInteractive && previewServerState.type === 'connected'
701
730
  ? previewServerState.clientId
@@ -835,8 +864,10 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
835
864
  onCrop,
836
865
  onRotate,
837
866
  onDeleteSequenceFromSource,
867
+ onDeleteSelectedSequences,
838
868
  onDisableSequenceInteractivity,
839
869
  onDuplicateSequenceFromSource,
870
+ onDuplicateSelectedSequences,
840
871
  onRenameSequence,
841
872
  onSelect,
842
873
  openInCodingAgent,
@@ -847,6 +878,8 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
847
878
  propStatusesForOverride,
848
879
  selectAsset,
849
880
  selectable,
881
+ selected,
882
+ selectedSequenceNodePathInfos,
850
883
  sequence,
851
884
  sequenceFrameOffset,
852
885
  setSelectedModal,
@@ -1 +1,2 @@
1
+ export declare const getSourceMapFilesForSource: (source: string) => Record<string, string> | null;
1
2
  export declare const getOriginalLocationFromStack: (stack: string, type: "sequence" | "visual-control") => Promise<import("../../../error-overlay/react-overlay/utils/get-source-map").OriginalPosition | null>;
@@ -1,16 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getOriginalLocationFromStack = void 0;
3
+ exports.getOriginalLocationFromStack = exports.getSourceMapFilesForSource = void 0;
4
4
  const trace_mapping_1 = require("@jridgewell/trace-mapping");
5
5
  const get_source_map_1 = require("../../../error-overlay/react-overlay/utils/get-source-map");
6
6
  const get_location_of_sequence_1 = require("../../../helpers/get-location-of-sequence");
7
7
  const traceMapCache = {};
8
8
  const traceMapPromises = {};
9
+ const traceMapsByOriginalSource = new Map();
10
+ const sourceMapFilesCache = new WeakMap();
9
11
  const browserStudioOriginalSourcePrefix = 'browser-studio-original://';
10
12
  const studioOriginalSourcePrefix = 'studio-original://';
11
- const getSourceMapCache = async (fileName) => {
13
+ const getSourceMapCache = (fileName) => {
12
14
  if (traceMapCache[fileName]) {
13
- return traceMapCache[fileName];
15
+ return Promise.resolve(traceMapCache[fileName]);
14
16
  }
15
17
  if (traceMapPromises[fileName]) {
16
18
  return traceMapPromises[fileName];
@@ -18,8 +20,16 @@ const getSourceMapCache = async (fileName) => {
18
20
  traceMapPromises[fileName] = fetch(`${fileName}.map`)
19
21
  .then((res) => res.json())
20
22
  .then((json) => {
23
+ var _a;
21
24
  const map = new trace_mapping_1.TraceMap(json);
22
25
  traceMapCache[fileName] = map;
26
+ for (let index = 0; index < map.sources.length; index++) {
27
+ const source = map.sources[index];
28
+ const content = (_a = map.sourcesContent) === null || _a === void 0 ? void 0 : _a[index];
29
+ if (source !== null && typeof content === 'string') {
30
+ traceMapsByOriginalSource.set(source, map);
31
+ }
32
+ }
23
33
  return map;
24
34
  })
25
35
  .finally(() => {
@@ -27,6 +37,28 @@ const getSourceMapCache = async (fileName) => {
27
37
  });
28
38
  return traceMapPromises[fileName];
29
39
  };
40
+ const getSourceMapFilesForSource = (source) => {
41
+ var _a;
42
+ const map = traceMapsByOriginalSource.get(source);
43
+ if (!map) {
44
+ return null;
45
+ }
46
+ const cached = sourceMapFilesCache.get(map);
47
+ if (cached) {
48
+ return cached;
49
+ }
50
+ const files = {};
51
+ for (let index = 0; index < map.sources.length; index++) {
52
+ const fileName = map.sources[index];
53
+ const content = (_a = map.sourcesContent) === null || _a === void 0 ? void 0 : _a[index];
54
+ if (fileName !== null && typeof content === 'string') {
55
+ files[fileName] = content;
56
+ }
57
+ }
58
+ sourceMapFilesCache.set(map, files);
59
+ return files;
60
+ };
61
+ exports.getSourceMapFilesForSource = getSourceMapFilesForSource;
30
62
  const getOriginalLocationFromStack = async (stack, type) => {
31
63
  const location = type === 'sequence'
32
64
  ? (0, get_location_of_sequence_1.getLocationOfSequence)(stack)
@@ -26,35 +26,33 @@ const confirmDuplicatingProgrammaticallyDuplicatedSequences = (nodePathInfos, co
26
26
  confirmLabel: 'Duplicate',
27
27
  });
28
28
  };
29
- const duplicateSequence = (nodePathInfo) => {
30
- const nodePath = nodePathInfo.sequenceSubscriptionKey;
31
- return (0, duplicate_jsx_node_api_1.duplicateJsxNode)({
32
- fileName: nodePath.absolutePath,
33
- nodePath: nodePath.nodePath,
34
- });
35
- };
36
- const duplicateSequencesFromSource = (nodePathInfos, confirm) => {
29
+ const duplicateSequencesFromSource = async (nodePathInfos, confirm) => {
37
30
  const programmaticallyDuplicated = nodePathInfos.filter((nodePathInfo) => nodePathInfo.numberOfSequencesWithThisNodePath > 1);
38
31
  const regular = nodePathInfos.filter((nodePathInfo) => nodePathInfo.numberOfSequencesWithThisNodePath <= 1);
39
- return confirmDuplicatingProgrammaticallyDuplicatedSequences(programmaticallyDuplicated, confirm).then((shouldDuplicateProgrammaticSequences) => {
40
- const toDuplicate = [...regular];
41
- if (shouldDuplicateProgrammaticSequences) {
42
- toDuplicate.push(...programmaticallyDuplicated);
32
+ const shouldDuplicateProgrammaticSequences = await confirmDuplicatingProgrammaticallyDuplicatedSequences(programmaticallyDuplicated, confirm);
33
+ const toDuplicate = [...regular];
34
+ if (shouldDuplicateProgrammaticSequences) {
35
+ toDuplicate.push(...programmaticallyDuplicated);
36
+ }
37
+ const nodes = toDuplicate.map((nodePathInfo) => {
38
+ const nodePath = nodePathInfo.sequenceSubscriptionKey;
39
+ return {
40
+ fileName: nodePath.absolutePath,
41
+ nodePath: nodePath.nodePath,
42
+ };
43
+ });
44
+ try {
45
+ if (nodes.length === 0) {
46
+ return;
43
47
  }
44
- if (toDuplicate.length === 0) {
45
- return Promise.resolve();
48
+ const result = await (0, duplicate_jsx_node_api_1.duplicateJsxNode)({ nodes });
49
+ if (!result.success) {
50
+ (0, NotificationCenter_1.showNotification)(result.reason, 4000);
46
51
  }
47
- return Promise.all(toDuplicate.map(duplicateSequence))
48
- .then((results) => {
49
- const failedResult = results.find((result) => !result.success);
50
- if (failedResult && !failedResult.success) {
51
- (0, NotificationCenter_1.showNotification)(failedResult.reason, 4000);
52
- }
53
- })
54
- .catch((err) => {
55
- (0, NotificationCenter_1.showNotification)(err.message, 4000);
56
- });
57
- });
52
+ }
53
+ catch (err) {
54
+ (0, NotificationCenter_1.showNotification)(err.message, 4000);
55
+ }
58
56
  };
59
57
  exports.duplicateSequencesFromSource = duplicateSequencesFromSource;
60
58
  const isDuplicatableSequenceRowSelection = (selection) => selection.type === 'sequence';
@@ -2,6 +2,12 @@ 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, }: {
6
+ readonly deleteDisabled: boolean;
7
+ readonly duplicateDisabled: boolean;
8
+ readonly onDeleteSelectedSequences: () => void;
9
+ readonly onDuplicateSelectedSequences: () => void;
10
+ }) => ComboboxValue[];
5
11
  export declare const getSequenceContextMenuItems: ({ assetLinkInfo, canOpenInEditor, deleteDisabled, disableInteractivityDisabled, duplicateDisabled, isProgrammaticallyDuplicated, includeSourceEditItems, codingAgentInfo, editorInfo, onConfigureApps, onDeleteSequenceFromSource, onDisableSequenceInteractivity, onDuplicateSequenceFromSource, openInCodingAgent, openInEditor, originalLocation, selectAsset, sequence, sourceActions, }: {
6
12
  readonly assetLinkInfo: TimelineAssetLinkInfo | null;
7
13
  readonly canOpenInEditor: boolean;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getSequenceContextMenuItems = void 0;
3
+ exports.getSequenceContextMenuItems = exports.getMultiSequenceContextMenuItems = 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_open_in_menu_items_1 = require("../get-open-in-menu-items");
@@ -27,6 +27,39 @@ const normalizeMenuDividers = (items) => {
27
27
  return normalized;
28
28
  };
29
29
  const interactiveSvgComponentIdentity = 'dev.remotion.remotion.Interactive.Svg';
30
+ const getMultiSequenceContextMenuItems = ({ deleteDisabled, duplicateDisabled, onDeleteSelectedSequences, onDuplicateSelectedSequences, }) => {
31
+ return [
32
+ {
33
+ type: 'item',
34
+ id: 'duplicate-selected-sequences',
35
+ keyHint: null,
36
+ label: 'Duplicate selected',
37
+ leftItem: null,
38
+ disabled: duplicateDisabled,
39
+ onClick: onDuplicateSelectedSequences,
40
+ quickSwitcherLabel: null,
41
+ subMenu: null,
42
+ value: 'duplicate-selected-sequences',
43
+ },
44
+ {
45
+ type: 'divider',
46
+ id: 'duplicate-delete-selected-sequences-divider',
47
+ },
48
+ {
49
+ type: 'item',
50
+ id: 'delete-selected-sequences',
51
+ keyHint: null,
52
+ label: 'Delete selected',
53
+ leftItem: null,
54
+ disabled: deleteDisabled,
55
+ onClick: onDeleteSelectedSequences,
56
+ quickSwitcherLabel: null,
57
+ subMenu: null,
58
+ value: 'delete-selected-sequences',
59
+ },
60
+ ];
61
+ };
62
+ exports.getMultiSequenceContextMenuItems = getMultiSequenceContextMenuItems;
30
63
  const getSequenceContextMenuItems = ({ assetLinkInfo, canOpenInEditor, deleteDisabled, disableInteractivityDisabled, duplicateDisabled, isProgrammaticallyDuplicated, includeSourceEditItems, codingAgentInfo, editorInfo, onConfigureApps, onDeleteSequenceFromSource, onDisableSequenceInteractivity, onDuplicateSequenceFromSource, openInCodingAgent, openInEditor, originalLocation, selectAsset, sequence, sourceActions = [], }) => {
31
64
  var _a, _b, _c;
32
65
  var _d, _e, _f;
@@ -2,6 +2,8 @@ import type { SequenceNodePath, InteractivitySchema, VideoConfigValues } from 'r
2
2
  import { subscribeToSequenceProps } from '../sequence-props-api';
3
3
  type SubscribeResult = Awaited<ReturnType<typeof subscribeToSequenceProps>>;
4
4
  type ApplyResult = (result: SubscribeResult) => void;
5
+ export declare const subscribeToSequencePropsRefresh: (overrideId: string, listener: () => void) => () => void;
6
+ export declare const refreshSequencePropsSubscription: (overrideId: string) => void;
5
7
  export declare const acquireSequencePropsSubscription: ({ fileName, line, column, schema, componentIdentity, effects, nodePath, clientId, applyOnce, applyEach, videoConfigValues, stack, }: {
6
8
  fileName: string;
7
9
  line: number;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.acquireSequencePropsSubscription = void 0;
3
+ exports.acquireSequencePropsSubscription = exports.refreshSequencePropsSubscription = exports.subscribeToSequencePropsRefresh = void 0;
4
4
  const studio_shared_1 = require("@remotion/studio-shared");
5
5
  const remotion_1 = require("remotion");
6
6
  const sequence_props_api_1 = require("../sequence-props-api");
@@ -8,6 +8,27 @@ const sequence_props_api_1 = require("../sequence-props-api");
8
8
  // resolve both the old and new JSX nodes to the same line and column.
9
9
  const makeKey = ({ fileName, line, column, componentIdentity, sequenceKeys, assetKeys, effectKeys, videoConfigValues, stack, }) => `${fileName}\0${line}\0${column}\0${componentIdentity !== null && componentIdentity !== void 0 ? componentIdentity : ''}\0${sequenceKeys.join('\0')}\0${assetKeys.join('\0')}\0${effectKeys.map((keys) => keys.join('\0')).join('\0\0')}\0${JSON.stringify(videoConfigValues)}\0${stack !== null && stack !== void 0 ? stack : ''}`;
10
10
  const entries = new Map();
11
+ const refreshListeners = new Map();
12
+ const subscribeToSequencePropsRefresh = (overrideId, listener) => {
13
+ var _a;
14
+ const listeners = (_a = refreshListeners.get(overrideId)) !== null && _a !== void 0 ? _a : new Set();
15
+ listeners.add(listener);
16
+ refreshListeners.set(overrideId, listeners);
17
+ return () => {
18
+ listeners.delete(listener);
19
+ if (listeners.size === 0) {
20
+ refreshListeners.delete(overrideId);
21
+ }
22
+ };
23
+ };
24
+ exports.subscribeToSequencePropsRefresh = subscribeToSequencePropsRefresh;
25
+ const refreshSequencePropsSubscription = (overrideId) => {
26
+ var _a;
27
+ for (const listener of (_a = refreshListeners.get(overrideId)) !== null && _a !== void 0 ? _a : []) {
28
+ listener();
29
+ }
30
+ };
31
+ exports.refreshSequencePropsSubscription = refreshSequencePropsSubscription;
11
32
  const acquireSequencePropsSubscription = ({ fileName, line, column, schema, componentIdentity, effects, nodePath, clientId, applyOnce, applyEach, videoConfigValues, stack, }) => {
12
33
  const sequenceKeys = (0, studio_shared_1.getAllSchemaKeys)(schema);
13
34
  const assetKeys = (0, studio_shared_1.getAssetSchemaKeys)(schema);
@@ -15,6 +15,7 @@ const useSequencePropsSubscription = ({ originalLocation, overrideId, componentI
15
15
  const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
16
16
  const { migrateExpandedTracksForSubscriptionKey } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksSetterContext);
17
17
  const { previewServerState: state } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
18
+ const [refreshToken, setRefreshToken] = (0, react_1.useState)(0);
18
19
  const previousNodePathRef = (0, react_1.useRef)(null);
19
20
  const overrideIdToNodePathMappingsRef = (0, react_1.useRef)(overrideIdToNodePathMappings);
20
21
  overrideIdToNodePathMappingsRef.current = overrideIdToNodePathMappings;
@@ -37,6 +38,11 @@ const useSequencePropsSubscription = ({ originalLocation, overrideId, componentI
37
38
  const locationSource = (_a = validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source) !== null && _a !== void 0 ? _a : null;
38
39
  const locationLine = (_b = validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.line) !== null && _b !== void 0 ? _b : null;
39
40
  const locationColumn = (_c = validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.column) !== null && _c !== void 0 ? _c : null;
41
+ (0, react_1.useEffect)(() => {
42
+ return (0, sequence_props_subscription_store_1.subscribeToSequencePropsRefresh)(overrideId, () => {
43
+ setRefreshToken((token) => token + 1);
44
+ });
45
+ }, [overrideId]);
40
46
  (0, react_1.useEffect)(() => {
41
47
  var _a, _b;
42
48
  if (!clientId ||
@@ -108,6 +114,7 @@ const useSequencePropsSubscription = ({ originalLocation, overrideId, componentI
108
114
  migrateExpandedTracksForSubscriptionKey,
109
115
  overrideId,
110
116
  preferMappedNodePath,
117
+ refreshToken,
111
118
  schema,
112
119
  setPropStatuses,
113
120
  setOverrideIdToNodePath,
@@ -18,6 +18,7 @@ const label = {
18
18
  overflow: 'hidden',
19
19
  textAlign: 'left',
20
20
  textOverflow: 'ellipsis',
21
+ userSelect: 'none',
21
22
  whiteSpace: 'nowrap',
22
23
  };
23
24
  const TimelineCombobox = ({ values, selectedId, title, labelWidth = 32, renderLeftItem, unhoveredIconColor = colors_1.LIGHT_TEXT, }) => {
@@ -1,9 +1 @@
1
- import type { GetRemotionSkillsInfoResponse, UpdateAvailableResponse } from '@remotion/studio-shared';
2
- export type UpdateInfo = UpdateAvailableResponse & Pick<GetRemotionSkillsInfoResponse, 'remotionUpgradeSkillAvailable'>;
3
- export type Bug = {
4
- title: string;
5
- description: string;
6
- link: string;
7
- versions: string[];
8
- };
9
1
  export declare const UpdateCheck: () => import("react/jsx-runtime").JSX.Element | null;
@@ -3,13 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.UpdateCheck = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
- const remotion_1 = require("remotion");
7
6
  const colors_1 = require("../helpers/colors");
8
7
  const modals_1 = require("../state/modals");
9
8
  const z_index_1 = require("../state/z-index");
10
9
  const InlineAction_1 = require("./InlineAction");
11
- const actions_1 = require("./RenderQueue/actions");
12
- const SettingsContext_1 = require("./SettingsContext");
10
+ const UpdateStatusContext_1 = require("./UpdateStatusContext");
13
11
  const buttonStyle = {
14
12
  appearance: 'none',
15
13
  border: 'none',
@@ -27,67 +25,22 @@ const updateIconContainer = {
27
25
  flexShrink: 0,
28
26
  };
29
27
  const UpdateCheck = () => {
30
- const [info, setInfo] = (0, react_1.useState)(null);
31
28
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.SetSelectedModalContext);
32
- const { remotionSkillsInfo } = (0, SettingsContext_1.useSettings)();
33
29
  const { tabIndex } = (0, z_index_1.useZIndex)();
34
- const [knownBugs, setKnownBugs] = (0, react_1.useState)(null);
30
+ const { info, knownBugs } = (0, UpdateStatusContext_1.useUpdateStatus)();
35
31
  const [hovered, setHovered] = (0, react_1.useState)(false);
36
32
  const hasBugfixesAvailable = (0, react_1.useMemo)(() => {
37
33
  return Boolean((info === null || info === void 0 ? void 0 : info.updateAvailable) && knownBugs && knownBugs.length > 0);
38
34
  }, [info === null || info === void 0 ? void 0 : info.updateAvailable, knownBugs]);
39
- const checkForUpdates = (0, react_1.useCallback)(() => {
40
- const controller = new AbortController();
41
- (0, actions_1.updateAvailable)(controller.signal)
42
- .then((d) => {
43
- setInfo(d);
44
- })
45
- .catch((err) => {
46
- if (err.message.includes('aborted')) {
47
- return;
48
- }
49
- // eslint-disable-next-line no-console
50
- console.log('Could not check for updates', err);
51
- });
52
- return controller;
53
- }, []);
54
- const checkForBugs = (0, react_1.useCallback)(() => {
55
- const controller = new AbortController();
56
- fetch(`https://bugs.remotion.dev/api/${remotion_1.VERSION}`, {
57
- signal: controller.signal,
58
- })
59
- .then(async (res) => {
60
- const body = await res.json();
61
- setKnownBugs(body.bugs);
62
- })
63
- .catch((err) => {
64
- if (err.message.includes('aborted')) {
65
- return;
66
- }
67
- // eslint-disable-next-line no-console
68
- console.log('Could not check for bugs in this version', err);
69
- });
70
- return controller;
71
- }, []);
72
- (0, react_1.useEffect)(() => {
73
- const abortUpdate = checkForUpdates();
74
- const abortBugs = checkForBugs();
75
- return () => {
76
- abortUpdate.abort();
77
- abortBugs.abort();
78
- };
79
- }, [checkForBugs, checkForUpdates]);
80
35
  const openModal = (0, react_1.useCallback)(() => {
81
36
  var _a;
37
+ var _b;
82
38
  setSelectedModal({
83
- type: 'update',
84
- info: {
85
- ...info,
86
- remotionUpgradeSkillAvailable: (_a = remotionSkillsInfo === null || remotionSkillsInfo === void 0 ? void 0 : remotionSkillsInfo.remotionUpgradeSkillAvailable) !== null && _a !== void 0 ? _a : false,
87
- },
88
- knownBugs: knownBugs,
39
+ type: 'settings',
40
+ initialTab: 'updates',
41
+ initialPublicLicenseKey: (_b = (_a = window.remotion_renderDefaults) === null || _a === void 0 ? void 0 : _a.publicLicenseKey) !== null && _b !== void 0 ? _b : null,
89
42
  });
90
- }, [info, knownBugs, remotionSkillsInfo, setSelectedModal]);
43
+ }, [setSelectedModal]);
91
44
  const dynButtonStyle = (0, react_1.useMemo)(() => {
92
45
  return {
93
46
  ...buttonStyle,
@@ -0,0 +1,18 @@
1
+ import type { UpdateAvailableResponse } from '@remotion/studio-shared';
2
+ import React from 'react';
3
+ export type Bug = {
4
+ title: string;
5
+ description: string;
6
+ link: string;
7
+ versions: string[];
8
+ };
9
+ type UpdateStatusContextValue = {
10
+ readonly error: string | null;
11
+ readonly info: UpdateAvailableResponse | null;
12
+ readonly knownBugs: Bug[] | null;
13
+ };
14
+ export declare const UpdateStatusProvider: React.FC<{
15
+ readonly children: React.ReactNode;
16
+ }>;
17
+ export declare const useUpdateStatus: () => UpdateStatusContextValue;
18
+ export {};