@remotion/studio 4.0.526 → 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 (98) hide show
  1. package/dist/components/Canvas.js +88 -26
  2. package/dist/components/CanvasCaptureDropHandler.js +63 -0
  3. package/dist/components/CanvasOrLoading.js +10 -2
  4. package/dist/components/CompositionSelectorItem.js +1 -0
  5. package/dist/components/CurrentAsset.js +2 -1
  6. package/dist/components/InitialCompositionLoader.js +1 -1
  7. package/dist/components/InlineDropdown.js +26 -2
  8. package/dist/components/InlineEditableTitle.js +1 -0
  9. package/dist/components/InspectorPanel/CollapsibleInspectorSectionHeader.js +1 -0
  10. package/dist/components/InspectorPanel/CompositionInspector.js +3 -3
  11. package/dist/components/InspectorPanel/CompositionMetadata.js +4 -0
  12. package/dist/components/InspectorPanel/ElementLibraryButton.js +1 -0
  13. package/dist/components/InspectorPanel/MultiSequenceInspector.js +32 -1
  14. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +41 -1
  15. package/dist/components/InspectorPanel/common.js +1 -0
  16. package/dist/components/InspectorPanel/styles.js +2 -0
  17. package/dist/components/InspectorPanel/use-composition-actions.js +1 -0
  18. package/dist/components/InspectorSourceLocation.js +3 -0
  19. package/dist/components/MenuBuildIndicator.js +1 -0
  20. package/dist/components/NewComposition/CancelButton.js +1 -1
  21. package/dist/components/Preview.js +3 -0
  22. package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.js +1 -0
  23. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +1 -0
  24. package/dist/components/RadioButton.js +1 -0
  25. package/dist/components/RenderModal/DataEditor.js +4 -1
  26. package/dist/components/RenderQueue/CaptionQueueItem.js +5 -2
  27. package/dist/components/RenderQueue/CaptionQueueProcessor.js +35 -8
  28. package/dist/components/RenderQueue/VideoMattingQueueItem.js +1 -0
  29. package/dist/components/RenderQueue/caption-job-types.d.ts +6 -0
  30. package/dist/components/RenderQueue/index.js +1 -0
  31. package/dist/components/RendersTab.js +2 -0
  32. package/dist/components/SelectedOutlineSnapIndicators.d.ts +6 -0
  33. package/dist/components/SelectedOutlineSnapIndicators.js +16 -12
  34. package/dist/components/SequencePropsSubscriptionProvider.d.ts +3 -0
  35. package/dist/components/SequencePropsSubscriptionProvider.js +8 -6
  36. package/dist/components/Timeline/TimelineDeleteKeybindings.js +6 -9
  37. package/dist/components/Timeline/TimelineEffectItem.js +1 -0
  38. package/dist/components/Timeline/TimelineExpandArrowButton.js +1 -0
  39. package/dist/components/Timeline/TimelineExpandedRow.js +1 -0
  40. package/dist/components/Timeline/TimelineFieldLabel.js +1 -0
  41. package/dist/components/Timeline/TimelineKeyframeControls.js +1 -0
  42. package/dist/components/Timeline/TimelineSequence.js +26 -0
  43. package/dist/components/Timeline/TimelineSequenceFrame.js +1 -0
  44. package/dist/components/Timeline/TimelineSequenceItem.js +28 -0
  45. package/dist/components/Timeline/TimelineViewport.d.ts +1 -0
  46. package/dist/components/Timeline/TimelineViewport.js +10 -1
  47. package/dist/components/Timeline/delete-selected-timeline-item.js +2 -2
  48. package/dist/components/Timeline/get-sequence-context-menu-items.d.ts +3 -1
  49. package/dist/components/Timeline/get-sequence-context-menu-items.js +13 -1
  50. package/dist/components/Timeline/split-selected-timeline-item.d.ts +13 -10
  51. package/dist/components/Timeline/split-selected-timeline-item.js +58 -35
  52. package/dist/components/TimelineCombobox.js +1 -0
  53. package/dist/components/Transcription/TranscriptionModal.js +16 -11
  54. package/dist/components/Transcription/TranscriptionModalWithOptionalWhisper.js +1 -1
  55. package/dist/components/WebMcp.js +1 -0
  56. package/dist/components/composition-drop-preview.d.ts +9 -2
  57. package/dist/components/composition-drop-preview.js +7 -4
  58. package/dist/components/composition-menu-items.js +4 -4
  59. package/dist/components/delete-jsx-nodes-api.d.ts +2 -0
  60. package/dist/components/{delete-jsx-node-api.js → delete-jsx-nodes-api.js} +5 -5
  61. package/dist/components/get-open-in-menu-items.js +7 -7
  62. package/dist/components/keyboard-shortcuts.d.ts +4 -4
  63. package/dist/components/keyboard-shortcuts.js +3 -1
  64. package/dist/components/public-output-name.d.ts +1 -0
  65. package/dist/components/public-output-name.js +7 -3
  66. package/dist/esm/{CaptionQueueProcessor-k0yrm3dj.mjs → CaptionQueueProcessor-npa6szn1.mjs} +39 -8
  67. package/dist/esm/{LazyModels-nk7py0zt.mjs → LazyModels-nh3c8h9p.mjs} +4 -3
  68. package/dist/esm/{LazyModels-mtggyjye.mjs → LazyModels-rr5v8h5y.mjs} +4 -3
  69. package/dist/esm/{TranscriptionModal-ymnx1c7m.mjs → TranscriptionModal-79m5wgcj.mjs} +25 -17
  70. package/dist/esm/{VideoMattingModal-05vpczks.mjs → VideoMattingModal-31pew0xj.mjs} +9 -6
  71. package/dist/esm/index-21hxsfaa.mjs +239 -0
  72. package/dist/esm/{index-0gewwxse.mjs → index-4zen9prq.mjs} +2293 -2203
  73. package/dist/esm/index-5t2dwxsk.mjs +530 -0
  74. package/dist/esm/{index-5gd8k9yv.mjs → index-614tdz2q.mjs} +1 -1
  75. package/dist/esm/{index-cdy8v54v.mjs → index-9xxg6218.mjs} +20 -541
  76. package/dist/esm/{index-5bfxbpca.mjs → index-ac5550e7.mjs} +1 -1
  77. package/dist/esm/{index-eb5txqp6.mjs → index-e855w59j.mjs} +8 -86
  78. package/dist/esm/{index-4dsz9035.mjs → index-n5gmcvhz.mjs} +1 -1
  79. package/dist/esm/{index-bs39wngg.mjs → index-ppspzgn9.mjs} +3134 -2994
  80. package/dist/esm/{index-g7k2dvar.mjs → index-r0ejh5sy.mjs} +1 -1
  81. package/dist/esm/index-r1gr3j3a.mjs +80 -0
  82. package/dist/esm/{index-x40wwfmt.mjs → index-s7qa3xbw.mjs} +6 -4
  83. package/dist/esm/{index-f97r9e2g.mjs → index-vxwg66ar.mjs} +5 -3
  84. package/dist/esm/index.mjs +3 -2
  85. package/dist/esm/internals.mjs +10 -7
  86. package/dist/esm/previewEntry.mjs +10 -7
  87. package/dist/esm/{resolve-composition-component-location-bt2d6qxq.mjs → resolve-composition-component-location-qrp05g62.mjs} +1 -1
  88. package/dist/helpers/copy-text.js +1 -16
  89. package/dist/helpers/hoverable.js +2 -1
  90. package/dist/helpers/open-in-editor.js +1 -1
  91. package/dist/helpers/studio-runtime-config.d.ts +1 -1
  92. package/dist/helpers/use-keybinding.d.ts +1 -1
  93. package/dist/helpers/use-keyboard-shortcut-label.d.ts +2 -2
  94. package/dist/helpers/use-menu-structure.js +15 -9
  95. package/dist/state/modals.d.ts +5 -0
  96. package/dist/state/timeline-zoom.js +4 -0
  97. package/package.json +19 -19
  98. package/dist/components/delete-jsx-node-api.d.ts +0 -2
@@ -45,6 +45,7 @@ const layout_1 = require("./layout");
45
45
  const NotificationCenter_1 = require("./Notifications/NotificationCenter");
46
46
  const Preview_1 = require("./Preview");
47
47
  const ResetZoomButton_1 = require("./ResetZoomButton");
48
+ const SelectedOutlineSnapIndicators_1 = require("./SelectedOutlineSnapIndicators");
48
49
  const SvgImportDialog_1 = require("./SvgImportDialog");
49
50
  const imperative_state_1 = require("./Timeline/imperative-state");
50
51
  const use_resolved_stack_1 = require("./Timeline/use-resolved-stack");
@@ -143,7 +144,7 @@ const Canvas = ({ canvasContent, size }) => {
143
144
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.SetSelectedModalContext);
144
145
  const config = remotion_1.Internals.useUnsafeVideoConfig();
145
146
  const areRulersVisible = (0, use_is_ruler_visible_1.useIsRulerVisible)();
146
- const { editorShowGuides } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
147
+ const { editorShowGuides, guidesList } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
147
148
  const { editorSnapping } = (0, react_1.useContext)(editor_snapping_1.EditorSnappingContext);
148
149
  const { compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
149
150
  const { setCurrentAssetMetadata } = (0, react_1.useContext)(remotion_1.Internals.CompositionSetters);
@@ -873,36 +874,46 @@ const Canvas = ({ canvasContent, size }) => {
873
874
  }
874
875
  const metadata = getCanvasDragPreviewMetadata((_b = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.types) !== null && _b !== void 0 ? _b : []);
875
876
  if (((metadata === null || metadata === void 0 ? void 0 : metadata.type) !== 'composition' && (metadata === null || metadata === void 0 ? void 0 : metadata.type) !== 'element') ||
876
- metadata.width === undefined ||
877
- metadata.height === undefined) {
877
+ (metadata.type === 'composition' &&
878
+ (metadata.width === undefined || metadata.height === undefined))) {
878
879
  setCompositionDropPreview(null);
879
880
  return;
880
881
  }
881
- let dropPosition = getDropPosition({
882
- addFitPadding,
883
- clientX: event.clientX,
884
- clientY: event.clientY,
885
- contentDimensions,
886
- unbounded: metadata.type === 'composition',
887
- previewSize,
888
- size,
889
- });
882
+ const isFullscreenElement = metadata.type === 'element' &&
883
+ (metadata.width === undefined || metadata.height === undefined);
884
+ let dropPosition = isFullscreenElement
885
+ ? {
886
+ centerX: contentDimensions.width / 2,
887
+ centerY: contentDimensions.height / 2,
888
+ }
889
+ : getDropPosition({
890
+ addFitPadding,
891
+ clientX: event.clientX,
892
+ clientY: event.clientY,
893
+ contentDimensions,
894
+ unbounded: metadata.type === 'composition',
895
+ previewSize,
896
+ size,
897
+ });
890
898
  if (dropPosition === null) {
891
899
  setCompositionDropPreview(null);
892
900
  return;
893
901
  }
894
- const compositionDimensions = {
895
- width: metadata.width,
896
- height: metadata.height,
897
- };
898
- if (metadata.type === 'composition' &&
902
+ const compositionDimensions = metadata.width === undefined || metadata.height === undefined
903
+ ? contentDimensions
904
+ : { width: metadata.width, height: metadata.height };
905
+ let snapPoints = [];
906
+ if (!isFullscreenElement &&
899
907
  editorSnapping &&
900
908
  !event.metaKey &&
901
909
  !event.ctrlKey) {
902
- dropPosition = (0, composition_drop_preview_1.snapCompositionDropPosition)({
910
+ const snapped = (0, composition_drop_preview_1.snapCompositionDropPosition)({
903
911
  compositionDimensions,
904
912
  destinationDimensions: contentDimensions,
905
913
  dropPosition,
914
+ guides: editorShowGuides
915
+ ? guidesList.filter((guide) => guide.compositionId === currentCompositionId)
916
+ : [],
906
917
  scale: calculateCanvasScale({
907
918
  addFitPadding,
908
919
  canvasSize: size,
@@ -911,6 +922,8 @@ const Canvas = ({ canvasContent, size }) => {
911
922
  previewSize: previewSize.size,
912
923
  }),
913
924
  });
925
+ dropPosition = snapped.dropPosition;
926
+ snapPoints = snapped.snapPoints;
914
927
  }
915
928
  setCompositionDropPreview((currentPreview) => {
916
929
  if ((currentPreview === null || currentPreview === void 0 ? void 0 : currentPreview.compositionDimensions.width) ===
@@ -918,13 +931,17 @@ const Canvas = ({ canvasContent, size }) => {
918
931
  currentPreview.compositionDimensions.height ===
919
932
  compositionDimensions.height &&
920
933
  currentPreview.dropPosition.centerX === dropPosition.centerX &&
921
- currentPreview.dropPosition.centerY === dropPosition.centerY) {
934
+ currentPreview.dropPosition.centerY === dropPosition.centerY &&
935
+ currentPreview.snapPoints.length === snapPoints.length &&
936
+ snapPoints.every((snapPoint, index) => {
937
+ const currentPoint = currentPreview.snapPoints[index];
938
+ return (currentPoint.edge === snapPoint.edge &&
939
+ currentPoint.target.type === snapPoint.target.type &&
940
+ currentPoint.target.position === snapPoint.target.position);
941
+ })) {
922
942
  return currentPreview;
923
943
  }
924
- return {
925
- compositionDimensions,
926
- dropPosition,
927
- };
944
+ return { compositionDimensions, dropPosition, snapPoints };
928
945
  });
929
946
  }, [
930
947
  addFitPadding,
@@ -932,7 +949,10 @@ const Canvas = ({ canvasContent, size }) => {
932
949
  cannotAddSequence,
933
950
  canReceiveElementInstallRequest,
934
951
  contentDimensions,
952
+ currentCompositionId,
953
+ editorShowGuides,
935
954
  editorSnapping,
955
+ guidesList,
936
956
  isAddingAsset,
937
957
  previewSize,
938
958
  size,
@@ -1020,7 +1040,7 @@ const Canvas = ({ canvasContent, size }) => {
1020
1040
  size,
1021
1041
  });
1022
1042
  if (dropPosition !== null &&
1023
- isComposition &&
1043
+ ((metadata === null || metadata === void 0 ? void 0 : metadata.type) === 'composition' || (metadata === null || metadata === void 0 ? void 0 : metadata.type) === 'element') &&
1024
1044
  metadata.width !== undefined &&
1025
1045
  metadata.height !== undefined &&
1026
1046
  contentDimensions !== null &&
@@ -1035,6 +1055,9 @@ const Canvas = ({ canvasContent, size }) => {
1035
1055
  },
1036
1056
  destinationDimensions: contentDimensions,
1037
1057
  dropPosition,
1058
+ guides: editorShowGuides
1059
+ ? guidesList.filter((guide) => guide.compositionId === currentCompositionId)
1060
+ : [],
1038
1061
  scale: calculateCanvasScale({
1039
1062
  addFitPadding,
1040
1063
  canvasSize: size,
@@ -1042,7 +1065,7 @@ const Canvas = ({ canvasContent, size }) => {
1042
1065
  compositionWidth: contentDimensions.width,
1043
1066
  previewSize: previewSize.size,
1044
1067
  }),
1045
- });
1068
+ }).dropPosition;
1046
1069
  }
1047
1070
  await (0, handle_drop_1.handleDrop)({
1048
1071
  chooseSvgImportMode,
@@ -1070,7 +1093,9 @@ const Canvas = ({ canvasContent, size }) => {
1070
1093
  config,
1071
1094
  contentDimensions,
1072
1095
  currentCompositionId,
1096
+ editorShowGuides,
1073
1097
  editorSnapping,
1098
+ guidesList,
1074
1099
  isAddingAsset,
1075
1100
  previewSize,
1076
1101
  size,
@@ -1213,7 +1238,44 @@ const Canvas = ({ canvasContent, size }) => {
1213
1238
  zIndex: 1,
1214
1239
  };
1215
1240
  }, [compositionDropPreview, contentDimensions, previewSize, size]);
1241
+ const compositionDropSnapLines = (0, react_1.useMemo)(() => {
1242
+ if (compositionDropPreview === null ||
1243
+ compositionDropPreview.snapPoints.length === 0 ||
1244
+ contentDimensions === null ||
1245
+ contentDimensions === 'none') {
1246
+ return null;
1247
+ }
1248
+ const scale = calculateCanvasScale({
1249
+ addFitPadding,
1250
+ canvasSize: size,
1251
+ compositionHeight: contentDimensions.height,
1252
+ compositionWidth: contentDimensions.width,
1253
+ previewSize: previewSize.size,
1254
+ });
1255
+ const left = size.width / 2 -
1256
+ (contentDimensions.width * scale) / 2 -
1257
+ previewSize.translation.x;
1258
+ const top = size.height / 2 -
1259
+ (contentDimensions.height * scale) / 2 -
1260
+ previewSize.translation.y;
1261
+ return (jsx_runtime_1.jsx("svg", { "aria-hidden": "true", "data-testid": "canvas-drop-snap-lines", style: {
1262
+ position: 'absolute',
1263
+ left,
1264
+ top,
1265
+ width: contentDimensions.width * scale,
1266
+ height: contentDimensions.height * scale,
1267
+ pointerEvents: 'none',
1268
+ overflow: 'visible',
1269
+ zIndex: 2,
1270
+ }, children: jsx_runtime_1.jsx(SelectedOutlineSnapIndicators_1.SelectedOutlineSnapLines, { compositionHeight: contentDimensions.height, compositionWidth: contentDimensions.width, scale: scale, snapPoints: compositionDropPreview.snapPoints }) }));
1271
+ }, [
1272
+ addFitPadding,
1273
+ compositionDropPreview,
1274
+ contentDimensions,
1275
+ previewSize,
1276
+ size,
1277
+ ]);
1216
1278
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
1217
- jsx_runtime_1.jsxs("div", { ref: canvas_ref_1.canvasRef, style: getContainerStyle(editorZoomGestures), children: [size ? (jsx_runtime_1.jsx(Preview_1.VideoPreview, { canvasContent: canvasContent, contentDimensions: contentDimensions, canvasSize: size, assetMetadata: assetResolution, onRetryAssetMetadata: fetchMetadata })) : null, compositionDropPreviewStyle === null ? null : (jsx_runtime_1.jsx("div", { className: "css-reset", "data-testid": "composition-drop-preview", style: compositionDropPreviewStyle })), isFit ? null : (jsx_runtime_1.jsx("div", { style: resetZoom, className: "css-reset", children: jsx_runtime_1.jsx(ResetZoomButton_1.ResetZoomButton, { onClick: onReset }) })), editorShowGuides && canvasContent.type === 'composition' && (jsx_runtime_1.jsx(EditorGuides_1.default, { canvasSize: size, contentDimensions: contentDimensions, assetMetadata: assetResolution }))] }), areRulersVisible && (jsx_runtime_1.jsx(EditorRuler_1.EditorRulers, { canCreateGuides: canvasContent.type === 'composition', contentDimensions: contentDimensions, canvasSize: size, assetMetadata: assetResolution, containerRef: canvas_ref_1.canvasRef }))] }));
1279
+ jsx_runtime_1.jsxs("div", { ref: canvas_ref_1.canvasRef, style: getContainerStyle(editorZoomGestures), children: [size ? (jsx_runtime_1.jsx(Preview_1.VideoPreview, { canvasContent: canvasContent, contentDimensions: contentDimensions, canvasSize: size, assetMetadata: assetResolution, onRetryAssetMetadata: fetchMetadata })) : null, compositionDropPreviewStyle === null ? null : (jsx_runtime_1.jsx("div", { className: "css-reset", "data-testid": "composition-drop-preview", style: compositionDropPreviewStyle })), compositionDropSnapLines, isFit ? null : (jsx_runtime_1.jsx("div", { style: resetZoom, className: "css-reset", children: jsx_runtime_1.jsx(ResetZoomButton_1.ResetZoomButton, { onClick: onReset }) })), editorShowGuides && canvasContent.type === 'composition' && (jsx_runtime_1.jsx(EditorGuides_1.default, { canvasSize: size, contentDimensions: contentDimensions, assetMetadata: assetResolution }))] }), areRulersVisible && (jsx_runtime_1.jsx(EditorRuler_1.EditorRulers, { canCreateGuides: canvasContent.type === 'composition', contentDimensions: contentDimensions, canvasSize: size, assetMetadata: assetResolution, containerRef: canvas_ref_1.canvasRef }))] }));
1218
1280
  };
1219
1281
  exports.Canvas = Canvas;
@@ -5,6 +5,7 @@ const react_1 = require("react");
5
5
  const modals_1 = require("../state/modals");
6
6
  const canvas_capture_drop_1 = require("./canvas-capture-drop");
7
7
  const drop_handler_data_1 = require("./drop-handler-data");
8
+ const canvasCaptureMessagePrefix = 'remotion-canvas-capture';
8
9
  const CanvasCaptureDropHandler = ({ readOnlyStudio }) => {
9
10
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.SetSelectedModalContext);
10
11
  const onDragOver = (0, react_1.useCallback)((event) => {
@@ -37,6 +38,68 @@ const CanvasCaptureDropHandler = ({ readOnlyStudio }) => {
37
38
  document.removeEventListener('drop', onDrop);
38
39
  };
39
40
  }, [onDragOver, onDrop]);
41
+ (0, react_1.useEffect)(() => {
42
+ if (readOnlyStudio) {
43
+ return;
44
+ }
45
+ const handoffWindow = window.remotion_browserStudio && window.parent !== window
46
+ ? window.parent
47
+ : window;
48
+ const captureId = new URL(handoffWindow.location.href).searchParams.get('canvas-capture');
49
+ if (!captureId) {
50
+ return;
51
+ }
52
+ let incoming = null;
53
+ const onMessage = async (event) => {
54
+ if (event.source !== handoffWindow ||
55
+ event.origin !== handoffWindow.location.origin ||
56
+ typeof event.data !== 'object' ||
57
+ event.data === null ||
58
+ event.data.captureId !== captureId) {
59
+ return;
60
+ }
61
+ if (event.data.type === `${canvasCaptureMessagePrefix}-start` &&
62
+ typeof event.data.filename === 'string' &&
63
+ typeof event.data.mimeType === 'string' &&
64
+ Number.isSafeInteger(event.data.chunks) &&
65
+ event.data.chunks >= 0) {
66
+ incoming = {
67
+ captureId,
68
+ filename: event.data.filename,
69
+ mimeType: event.data.mimeType,
70
+ chunks: Array.from({ length: event.data.chunks }, () => null),
71
+ };
72
+ return;
73
+ }
74
+ if (event.data.type === `${canvasCaptureMessagePrefix}-chunk` &&
75
+ incoming &&
76
+ Number.isSafeInteger(event.data.index) &&
77
+ event.data.index >= 0 &&
78
+ event.data.index < incoming.chunks.length &&
79
+ typeof event.data.data === 'string') {
80
+ const binary = atob(event.data.data);
81
+ const buffer = new ArrayBuffer(binary.length);
82
+ const bytes = new Uint8Array(buffer);
83
+ for (let index = 0; index < binary.length; index++) {
84
+ bytes[index] = binary.charCodeAt(index);
85
+ }
86
+ incoming.chunks[event.data.index] = buffer;
87
+ return;
88
+ }
89
+ if (event.data.type === `${canvasCaptureMessagePrefix}-complete` &&
90
+ incoming &&
91
+ incoming.chunks.every((chunk) => chunk !== null)) {
92
+ const file = new File(incoming.chunks, incoming.filename, {
93
+ type: incoming.mimeType,
94
+ });
95
+ incoming = null;
96
+ await (0, canvas_capture_drop_1.handleCanvasCaptureDrop)({ files: [file], setSelectedModal });
97
+ }
98
+ };
99
+ handoffWindow.addEventListener('message', onMessage);
100
+ handoffWindow.postMessage({ type: `${canvasCaptureMessagePrefix}-ready`, captureId }, handoffWindow.location.origin);
101
+ return () => handoffWindow.removeEventListener('message', onMessage);
102
+ }, [readOnlyStudio, setSelectedModal]);
40
103
  return null;
41
104
  };
42
105
  exports.CanvasCaptureDropHandler = CanvasCaptureDropHandler;
@@ -6,6 +6,7 @@ const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
7
  const ErrorLoader_1 = require("../error-overlay/remotion-overlay/ErrorLoader");
8
8
  const colors_1 = require("../helpers/colors");
9
+ const url_state_1 = require("../helpers/url-state");
9
10
  const composition_list_1 = require("../state/composition-list");
10
11
  const timeline_zoom_1 = require("../state/timeline-zoom");
11
12
  const Canvas_1 = require("./Canvas");
@@ -26,6 +27,10 @@ const container = {
26
27
  backgroundColor: colors_1.BACKGROUND,
27
28
  flexDirection: 'column',
28
29
  };
30
+ const welcomeLabel = {
31
+ ...RunningCalculateMetadata_1.loaderLabel,
32
+ textAlign: 'center',
33
+ };
29
34
  const CanvasOrLoading = ({ size }) => {
30
35
  const resolved = remotion_1.Internals.useResolvedVideoConfig(null);
31
36
  const { setZoom } = (0, react_1.useContext)(timeline_zoom_1.TimelineZoomCtx);
@@ -53,8 +58,11 @@ const CanvasOrLoading = ({ size }) => {
53
58
  if (compositionListState !== 'ready') {
54
59
  return null;
55
60
  }
56
- const compname = window.location.pathname.replace('/', '');
57
- return (jsx_runtime_1.jsx("div", { style: container, className: "css-reset", children: jsx_runtime_1.jsxs("div", { style: RunningCalculateMetadata_1.loaderLabel, children: ["Composition with ID ", compname, " not found."] }) }));
61
+ const route = (0, url_state_1.getRoute)();
62
+ if (route === '') {
63
+ return (jsx_runtime_1.jsx("div", { style: container, className: "css-reset", children: jsx_runtime_1.jsx("div", { style: welcomeLabel, children: "Select a composition to get started." }) }));
64
+ }
65
+ return (jsx_runtime_1.jsx("div", { style: container, className: "css-reset", children: jsx_runtime_1.jsxs("div", { style: RunningCalculateMetadata_1.loaderLabel, children: ["Composition with ID ", decodeURIComponent(route.substring(1)), " not found."] }) }));
58
66
  }
59
67
  const content = (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
60
68
  jsx_runtime_1.jsx(ZoomPersistor_1.ZoomPersistor, {}), jsx_runtime_1.jsx(Canvas_1.Canvas, { size: size, canvasContent: canvasContent }), (resolved === null || resolved === void 0 ? void 0 : resolved.type) === 'success-and-refreshing' ? (jsx_runtime_1.jsx(RefreshCompositionOverlay_1.RefreshCompositionOverlay, {})) : null] }));
@@ -42,6 +42,7 @@ const itemStyle = {
42
42
  textAlign: 'left',
43
43
  height: layout_1.COMPACT_CONTROL_ROW_HEIGHT,
44
44
  userSelect: 'none',
45
+ WebkitUserSelect: 'none',
45
46
  };
46
47
  const labelStyle = {
47
48
  textAlign: 'left',
@@ -183,6 +183,7 @@ const AssetInfo = ({ assetName, contentSized = false, onAssetClick, readOnlyStud
183
183
  displayName: fileName,
184
184
  audioStreamIndex: null,
185
185
  requestInit: null,
186
+ target: null,
186
187
  });
187
188
  }, [fileName, mutationsDisabled, setSelectedModal, src]);
188
189
  const onTrackMatting = (0, react_1.useCallback)(() => {
@@ -250,7 +251,7 @@ const AssetInfo = ({ assetName, contentSized = false, onAssetClick, readOnlyStud
250
251
  : '4px 0', children: jsx_runtime_1.jsx(InlineEditableTitle_1.InlineEditableTitle, { value: fileName, canRename: canRename, getInitialSelection: use_rename_static_file_1.getStaticFileRenameSelection, onClick: onAssetClick, onCommit: onRename, size: contentSized ? 'default' : 'inspector', title: assetName }) }), fileDetails.length > 0 ? (jsx_runtime_1.jsx(CollapsibleInspectorSection_1.CollapsibleInspectorSection, { collapsible: true, label: "File", sectionId: "asset-file", children: jsx_runtime_1.jsx("div", { style: assetMetadataStyle, children: fileDetails.map((detail) => (jsx_runtime_1.jsx(common_1.InspectorDetailRow, { label: detail.label, children: jsx_runtime_1.jsx("span", { style: assetMetadataValueStyle, children: detail.value }) }, detail.label))) }) })) : null, mediaSections && mediaSections.video ? (jsx_runtime_1.jsx(CollapsibleInspectorSection_1.CollapsibleInspectorSection, { collapsible: true, label: "Video", sectionId: "asset-video", children: jsx_runtime_1.jsx("div", { style: assetMetadataStyle, children: mediaSections.video.map((detail) => (jsx_runtime_1.jsx(common_1.InspectorDetailRow, { label: detail.label, children: jsx_runtime_1.jsx("span", { style: assetMetadataValueStyle, children: detail.value }) }, detail.label))) }) })) : null, mediaSections && mediaSections.audio !== null ? (jsx_runtime_1.jsx(CollapsibleInspectorSection_1.CollapsibleInspectorSection, { collapsible: mediaSections.audio.length > 0, label: "Audio", sectionId: "asset-audio", children: mediaSections.audio.length === 0 ? (jsx_runtime_1.jsx("div", { style: assetEmptyStateStyle, children: "None" })) : (jsx_runtime_1.jsxs("div", { style: assetMetadataStyle, children: [mediaSections.audio.map((detail) => (jsx_runtime_1.jsx(common_1.InspectorDetailRow, { label: detail.label, children: jsx_runtime_1.jsx("span", { style: assetMetadataValueStyle, children: detail.value }) }, detail.label))), src ? (jsx_runtime_1.jsx(common_1.InspectorDetailRow, { label: "Average volume", children: jsx_runtime_1.jsx("span", { style: assetMetadataValueStyle, children: jsx_runtime_1.jsx(AssetAudioVolume_1.AssetAudioVolume, { src: (_d = volumeMetadata === null || volumeMetadata === void 0 ? void 0 : volumeMetadata.src) !== null && _d !== void 0 ? _d : null, waveformSampleRate: volumeMetadata
251
252
  ? Math.ceil(volumeMetadata.fps *
252
253
  get_timeline_max_zoom_1.TIMELINE_FRAME_WIDTH_AT_MAX_ZOOM)
253
- : null }, (_e = volumeMetadata === null || volumeMetadata === void 0 ? void 0 : volumeMetadata.src) !== null && _e !== void 0 ? _e : src) }) })) : null] })) })) : null, jsx_runtime_1.jsx(CollapsibleInspectorSection_1.CollapsibleInspectorSection, { collapsible: true, label: "Actions", sectionId: "asset-actions", children: jsx_runtime_1.jsxs(common_1.InspectorQuickActionsSection, { children: [fileManagerAvailable ? (jsx_runtime_1.jsxs(common_1.InspectorQuickAction, { disabled: fileManagerDisabled, onClick: onShowInFileManager, renderIcon: (color) => (jsx_runtime_1.jsx(folder_1.ExpandedFolderIcon, { color: color, style: quickActionIconStyle })), children: ["Show in ", fileManagerName] })) : null, src ? (jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: mutationsDisabled, onClick: onTranscribe, renderIcon: (color) => (jsx_runtime_1.jsx(transcription_1.TranscriptionIcon, { color: color, style: quickActionIconStyle })), children: "Transcribe" })) : null, fileType === 'video' ? (jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: mutationsDisabled, onClick: onTrackMatting, renderIcon: (color) => (jsx_runtime_1.jsx(separation_1.SeparationIcon, { color: color, style: quickActionIconStyle })), children: "Separate foreground" })) : null, src ? (jsx_runtime_1.jsxs(common_1.InspectorQuickAction, { disabled: false, onClick: onOpenConvert, renderIcon: (color) => (jsx_runtime_1.jsx(remotion_convert_1.RemotionConvertIcon, { color: color, style: quickActionIconStyle })), children: ["Convert",
254
+ : null }, (_e = volumeMetadata === null || volumeMetadata === void 0 ? void 0 : volumeMetadata.src) !== null && _e !== void 0 ? _e : src) }) })) : null] })) })) : null, jsx_runtime_1.jsx(CollapsibleInspectorSection_1.CollapsibleInspectorSection, { collapsible: true, label: "Actions", sectionId: "asset-actions", children: jsx_runtime_1.jsxs(common_1.InspectorQuickActionsSection, { children: [fileManagerAvailable ? (jsx_runtime_1.jsxs(common_1.InspectorQuickAction, { disabled: fileManagerDisabled, onClick: onShowInFileManager, renderIcon: (color) => (jsx_runtime_1.jsx(folder_1.ExpandedFolderIcon, { color: color, style: quickActionIconStyle })), children: ["Show in ", fileManagerName] })) : null, src && (mediaMetadata === null || mediaMetadata === void 0 ? void 0 : mediaMetadata.hasAudioTrack) !== false ? (jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: mutationsDisabled, onClick: onTranscribe, renderIcon: (color) => (jsx_runtime_1.jsx(transcription_1.TranscriptionIcon, { color: color, style: quickActionIconStyle })), children: "Transcribe" })) : null, fileType === 'video' ? (jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: mutationsDisabled, onClick: onTrackMatting, renderIcon: (color) => (jsx_runtime_1.jsx(separation_1.SeparationIcon, { color: color, style: quickActionIconStyle })), children: "Separate foreground" })) : null, src ? (jsx_runtime_1.jsxs(common_1.InspectorQuickAction, { disabled: false, onClick: onOpenConvert, renderIcon: (color) => (jsx_runtime_1.jsx(remotion_convert_1.RemotionConvertIcon, { color: color, style: quickActionIconStyle })), children: ["Convert",
254
255
  jsx_runtime_1.jsx("svg", { "aria-hidden": "true", viewBox: "0 0 16 16", style: convertArrowStyle, children: jsx_runtime_1.jsx("path", { d: "M4 12 12 4M6 4h6v6", fill: "none", stroke: colors_1.CURRENT_COLOR, strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "1.5" }) })
255
256
  ] })) : null, jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: mutationsDisabled, onClick: onDelete, renderIcon: (color) => (jsx_runtime_1.jsx(trash_1.TrashIcon, { color: color, style: quickActionIconStyle })), children: "Delete" })] }) })
256
257
  ] }));
@@ -95,7 +95,7 @@ const InitialCompositionLoader = () => {
95
95
  if (!compositionListIsReady) {
96
96
  return;
97
97
  }
98
- if (compositions.length > 0) {
98
+ if (compositions.length > 0 && !window.remotion_isReadOnlyStudio) {
99
99
  selectComposition(compositions[0], true);
100
100
  }
101
101
  else {
@@ -13,6 +13,7 @@ const mobile_layout_1 = require("../helpers/mobile-layout");
13
13
  const noop_1 = require("../helpers/noop");
14
14
  const z_index_1 = require("../state/z-index");
15
15
  const InlineAction_1 = require("./InlineAction");
16
+ const menu_tree_context_1 = require("./Menu/menu-tree-context");
16
17
  const portals_1 = require("./Menu/portals");
17
18
  const styles_1 = require("./Menu/styles");
18
19
  const MenuContent_1 = require("./NewComposition/MenuContent");
@@ -23,6 +24,7 @@ const container = {
23
24
  const InlineDropdown = ({ values, getItems, onOpenChange, unhoveredColor, ...props }) => {
24
25
  var _a, _b;
25
26
  const ref = (0, react_1.useRef)(null);
27
+ const [menuTreeId] = (0, react_1.useState)(menu_tree_context_1.getNextMenuTreeId);
26
28
  const [opened, setOpened] = (0, react_1.useState)({ type: 'not-open' });
27
29
  const { currentZIndex } = (0, z_index_1.useZIndex)();
28
30
  const size = player_1.PlayerInternals.useElementSize(ref, {
@@ -96,9 +98,31 @@ const InlineDropdown = ({ values, getItems, onOpenChange, unhoveredColor, ...pro
96
98
  setOpened({ type: 'not-open' });
97
99
  onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(false);
98
100
  }, [onOpenChange]);
101
+ (0, react_1.useEffect)(() => {
102
+ if (opened.type === 'not-open') {
103
+ return;
104
+ }
105
+ const dismissWithoutClickThrough = (event) => {
106
+ if (event.button !== 0) {
107
+ return;
108
+ }
109
+ const target = event.target;
110
+ if ((0, menu_tree_context_1.isNodeInMenuTree)(target, menuTreeId)) {
111
+ return;
112
+ }
113
+ event.preventDefault();
114
+ event.stopPropagation();
115
+ event.stopImmediatePropagation();
116
+ onHide();
117
+ };
118
+ window.addEventListener('pointerdown', dismissWithoutClickThrough, true);
119
+ return () => {
120
+ window.removeEventListener('pointerdown', dismissWithoutClickThrough, true);
121
+ };
122
+ }, [menuTreeId, onHide, opened.type]);
99
123
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
100
- jsx_runtime_1.jsx("div", { ref: ref, style: container, children: jsx_runtime_1.jsx(InlineAction_1.InlineAction, { onClick: onClick, unhoveredColor: opened.type === 'open' ? colors_1.WHITE : unhoveredColor, ...props }) }), portalStyle && opened.type === 'open'
101
- ? react_dom_1.default.createPortal(jsx_runtime_1.jsx("div", { style: styles_1.fullScreenOverlay, children: jsx_runtime_1.jsx("div", { style: styles_1.outerPortal, className: "css-reset", children: jsx_runtime_1.jsx(z_index_1.HigherZIndex, { onOutsideClick: onHide, onEscape: onHide, children: jsx_runtime_1.jsx("div", { style: portalStyle, children: jsx_runtime_1.jsx(MenuContent_1.MenuContent, { onNextMenu: noop_1.noop, onPreviousMenu: noop_1.noop, values: (_b = (_a = opened.values) !== null && _a !== void 0 ? _a : values) !== null && _b !== void 0 ? _b : [], onHide: onHide, leaveLeftSpace: true, preselectIndex: false, topItemCanBeUnselected: false, fixedHeight: null }) }) }) }) }), (0, portals_1.getPortal)(currentZIndex))
124
+ jsx_runtime_1.jsx("div", { ref: ref, style: container, children: jsx_runtime_1.jsx(InlineAction_1.InlineAction, { onClick: onClick, unhoveredColor: opened.type === 'open' ? colors_1.WHITE : unhoveredColor, ...props, "aria-expanded": opened.type === 'open' }) }), portalStyle && opened.type === 'open'
125
+ ? react_dom_1.default.createPortal(jsx_runtime_1.jsx("div", { style: styles_1.fullScreenOverlay, children: jsx_runtime_1.jsx("div", { style: styles_1.outerPortal, className: "css-reset", children: jsx_runtime_1.jsx(z_index_1.HigherZIndex, { onOutsideClick: onHide, onEscape: onHide, children: jsx_runtime_1.jsx("div", { "data-remotion-menu-tree-id": menuTreeId, style: portalStyle, onPointerDown: (event) => event.stopPropagation(), children: jsx_runtime_1.jsx(menu_tree_context_1.MenuTreeContext.Provider, { value: menuTreeId, children: jsx_runtime_1.jsx(MenuContent_1.MenuContent, { onNextMenu: noop_1.noop, onPreviousMenu: noop_1.noop, values: (_b = (_a = opened.values) !== null && _a !== void 0 ? _a : values) !== null && _b !== void 0 ? _b : [], onHide: onHide, leaveLeftSpace: true, preselectIndex: false, topItemCanBeUnselected: false, fixedHeight: null }) }) }) }) }) }), (0, portals_1.getPortal)(currentZIndex))
102
126
  : null] }));
103
127
  };
104
128
  exports.InlineDropdown = InlineDropdown;
@@ -36,6 +36,7 @@ const titleGridItem = {
36
36
  overflow: 'hidden',
37
37
  textOverflow: 'ellipsis',
38
38
  userSelect: 'none',
39
+ WebkitUserSelect: 'none',
39
40
  whiteSpace: 'nowrap',
40
41
  };
41
42
  const titleInput = {
@@ -19,6 +19,7 @@ const sectionTitle = {
19
19
  textAlign: 'left',
20
20
  textOverflow: 'ellipsis',
21
21
  userSelect: 'none',
22
+ WebkitUserSelect: 'none',
22
23
  whiteSpace: 'nowrap',
23
24
  };
24
25
  const staticSectionTitle = {
@@ -163,14 +163,14 @@ const CompositionDefaultPropsSection = ({ composition, currentDefaultProps, read
163
163
  defaultProps: currentDefaultProps,
164
164
  mode: defaultPropsMode,
165
165
  propsEditType: 'default-props',
166
- showCannotSaveDefaultPropsWarning: canShowDefaultPropsSection,
166
+ showCannotSaveDefaultPropsWarning: canShowDefaultPropsSection && !readOnlyStudio,
167
167
  });
168
- if (readOnlyStudio || !canShowDefaultPropsSection) {
168
+ if (!canShowDefaultPropsSection) {
169
169
  return null;
170
170
  }
171
171
  return (jsx_runtime_1.jsxs("div", { style: styles_1.compositionDefaultPropsSection, children: [
172
172
  jsx_runtime_1.jsx(common_1.InspectorSectionHeader, { children: jsx_runtime_1.jsx(CollapsibleInspectorSectionHeader_1.CollapsibleInspectorSectionHeader, { action: expanded ? (jsx_runtime_1.jsxs("div", { style: styles_1.sectionHeaderRow, children: [
173
- jsx_runtime_1.jsx(SegmentedControl_1.SegmentedControl, { items: defaultPropsModeItems, needsWrapping: false, size: "compact" }), defaultPropsWarnings.length > 0 ? (jsx_runtime_1.jsx(WarningIndicatorButton_1.WarningIndicatorButton, { setShowWarning: setShowWarning, showWarning: showWarning, warningCount: defaultPropsWarnings.length, size: "compact" })) : null] })) : null, expanded: expanded, label: "Default Props", onToggle: () => setExpanded(!expanded) }) }), jsx_runtime_1.jsxs(common_1.InspectorSectionBody, { expanded: expanded, children: [defaultPropsWarnings.length > 0 && showWarning ? (jsx_runtime_1.jsx("div", { style: styles_1.defaultPropsWarningContainer, children: jsx_runtime_1.jsx(common_1.InspectorDefaultPropsWarnings, { warnings: defaultPropsWarnings }) })) : null, jsx_runtime_1.jsx(DefaultPropsEditor_1.DefaultPropsEditor, { unresolvedComposition: composition, defaultProps: currentDefaultProps, setDefaultProps: setDefaultProps, propsEditType: "default-props", schemaErrorMode: "compact", layout: "inspector", mode: defaultPropsMode, onModeChange: setDefaultPropsMode, hideModeControls: canShowDefaultPropsSection, warnings: defaultPropsWarnings, showWarning: false, setShowWarning: setShowWarning, hideWarningButton: true }, composition.id)
173
+ jsx_runtime_1.jsx(SegmentedControl_1.SegmentedControl, { items: defaultPropsModeItems, needsWrapping: false, size: "compact" }), defaultPropsWarnings.length > 0 ? (jsx_runtime_1.jsx(WarningIndicatorButton_1.WarningIndicatorButton, { setShowWarning: setShowWarning, showWarning: showWarning, warningCount: defaultPropsWarnings.length, size: "compact" })) : null] })) : null, expanded: expanded, label: readOnlyStudio ? 'Props' : 'Default Props', onToggle: () => setExpanded(!expanded) }) }), jsx_runtime_1.jsxs(common_1.InspectorSectionBody, { expanded: expanded, children: [defaultPropsWarnings.length > 0 && showWarning ? (jsx_runtime_1.jsx("div", { style: styles_1.defaultPropsWarningContainer, children: jsx_runtime_1.jsx(common_1.InspectorDefaultPropsWarnings, { warnings: defaultPropsWarnings }) })) : null, jsx_runtime_1.jsx(DefaultPropsEditor_1.DefaultPropsEditor, { unresolvedComposition: composition, defaultProps: currentDefaultProps, setDefaultProps: setDefaultProps, propsEditType: "default-props", schemaErrorMode: "compact", layout: "inspector", mode: defaultPropsMode, onModeChange: setDefaultPropsMode, hideModeControls: canShowDefaultPropsSection, warnings: defaultPropsWarnings, showWarning: false, setShowWarning: setShowWarning, hideWarningButton: true }, composition.id)
174
174
  ] })
175
175
  ] }));
176
176
  };
@@ -31,6 +31,7 @@ const computedContainerStyle = {
31
31
  ...InputDragger_1.inputDraggerContainerStyle,
32
32
  textAlign: 'right',
33
33
  userSelect: 'none',
34
+ WebkitUserSelect: 'none',
34
35
  };
35
36
  const computedValueStyle = {
36
37
  color: colors_1.WHITE_ALPHA_40,
@@ -39,10 +40,12 @@ const computedValueStyle = {
39
40
  fontStyle: 'italic',
40
41
  lineHeight: '20px',
41
42
  userSelect: 'none',
43
+ WebkitUserSelect: 'none',
42
44
  };
43
45
  const metadataFormatterStyle = {
44
46
  fontSize: 13,
45
47
  userSelect: 'none',
48
+ WebkitUserSelect: 'none',
46
49
  };
47
50
  const metadataDraggerStyles = {
48
51
  durationInFrames: {
@@ -113,6 +116,7 @@ const metadataLabelText = {
113
116
  overflow: 'hidden',
114
117
  textOverflow: 'ellipsis',
115
118
  userSelect: 'none',
119
+ WebkitUserSelect: 'none',
116
120
  whiteSpace: 'nowrap',
117
121
  };
118
122
  const dimensionPresets = [
@@ -45,6 +45,7 @@ const elementLibraryDropdownLabelStyle = {
45
45
  textAlign: 'left',
46
46
  textOverflow: 'ellipsis',
47
47
  userSelect: 'none',
48
+ WebkitUserSelect: 'none',
48
49
  whiteSpace: 'nowrap',
49
50
  };
50
51
  const elementLibraryDropdownCaretStyle = {
@@ -7,11 +7,14 @@ const react_1 = require("react");
7
7
  const remotion_1 = require("remotion");
8
8
  const calculate_timeline_1 = require("../../helpers/calculate-timeline");
9
9
  const colors_1 = require("../../helpers/colors");
10
+ const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
10
11
  const timeline_layout_1 = require("../../helpers/timeline-layout");
12
+ const scissors_1 = require("../../icons/scissors");
11
13
  const InspectorInfoHeader_1 = require("../InspectorInfoHeader");
12
14
  const InspectorPanelLayout_1 = require("../InspectorPanelLayout");
13
15
  const layout_1 = require("../layout");
14
16
  const is_menu_item_1 = require("../Menu/is-menu-item");
17
+ const split_selected_timeline_item_1 = require("../Timeline/split-selected-timeline-item");
15
18
  const TimelineRowLayoutContext_1 = require("../Timeline/TimelineRowLayoutContext");
16
19
  const CollapsibleInspectorSection_1 = require("./CollapsibleInspectorSection");
17
20
  const common_1 = require("./common");
@@ -28,8 +31,14 @@ const selectionCountStyle = {
28
31
  textOverflow: 'ellipsis',
29
32
  whiteSpace: 'nowrap',
30
33
  };
34
+ const actionIconStyle = {
35
+ display: 'block',
36
+ height: 16,
37
+ width: 16,
38
+ };
31
39
  const MultiSequenceInspector = ({ selections, readOnlyStudio }) => {
32
40
  const { sequences } = (0, react_1.useContext)(remotion_1.Internals.SequenceManager);
41
+ const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
33
42
  const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
34
43
  const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
35
44
  const { getDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
@@ -93,11 +102,33 @@ const MultiSequenceInspector = ({ selections, readOnlyStudio }) => {
93
102
  });
94
103
  return ((_a = allFields[0]) !== null && _a !== void 0 ? _a : []).filter((field) => allFields.every((candidate) => candidate.some((other) => other.key === field.key && other.fieldSchema === field.fieldSchema)));
95
104
  }, [getDragOverrides, propStatuses, runtimeValues, targets]);
105
+ const canSplit = !readOnlyStudio && (0, interactivity_enabled_1.isStudioInteractivityEnabled)();
106
+ const onSplit = (0, react_1.useCallback)(() => {
107
+ var _a;
108
+ if (!canSplit) {
109
+ return;
110
+ }
111
+ (_a = (0, split_selected_timeline_item_1.splitSelectedTimelineItems)({
112
+ selections,
113
+ sequences,
114
+ overrideIdsToNodePaths: overrideIdToNodePathMappings,
115
+ propStatuses,
116
+ splitFrame: timelinePosition,
117
+ })) === null || _a === void 0 ? void 0 : _a.catch(() => undefined);
118
+ }, [
119
+ canSplit,
120
+ overrideIdToNodePathMappings,
121
+ propStatuses,
122
+ selections,
123
+ sequences,
124
+ timelinePosition,
125
+ ]);
96
126
  return (jsx_runtime_1.jsxs("div", { style: styles_1.scrollableContainer, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: [
97
127
  jsx_runtime_1.jsx(InspectorInfoHeader_1.InspectorInfoHeader, { padding: "4px 0", children: jsx_runtime_1.jsxs("div", { style: selectionCountStyle, children: [selections.length, " sequences selected"] }) }), jsx_runtime_1.jsx("div", { role: "separator", style: styles_1.sequenceHeaderDivider }), targets === null ? (jsx_runtime_1.jsx(common_1.InspectorMessage, { children: "Sequence controls unavailable" })) : fields.length === 0 ? (jsx_runtime_1.jsx(common_1.InspectorMessage, { children: "No shared controls" })) : (jsx_runtime_1.jsx(TimelineRowLayoutContext_1.TimelineRowLayoutContext.Provider, { value: TimelineRowLayoutContext_1.INSPECTOR_TIMELINE_ROW_LAYOUT, children: timeline_layout_1.SCHEMA_FIELD_GROUPS.map((group) => {
98
128
  const groupedFields = fields.filter((field) => field.group === group.id);
99
129
  return groupedFields.length === 0 ? null : (jsx_runtime_1.jsx(CollapsibleInspectorSection_1.CollapsibleInspectorSection, { collapsible: true, label: group.label, sectionId: `multi-sequence-${group.id}`, children: groupedFields.map((field) => (jsx_runtime_1.jsx(MultiSequenceField_1.MultiSequenceField, { field: field, targets: targets, readOnlyStudio: readOnlyStudio }, JSON.stringify(targets.map((target) => target.nodePath)) +
100
130
  field.key))) }, group.id));
101
- }) }))] }));
131
+ }) })), jsx_runtime_1.jsx(CollapsibleInspectorSection_1.CollapsibleInspectorSection, { collapsible: true, label: "Actions", sectionId: "multi-sequence-actions", children: jsx_runtime_1.jsx(common_1.InspectorQuickActionsSection, { children: jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: !canSplit, onClick: onSplit, title: canSplit ? undefined : 'Studio is read-only', renderIcon: (color) => (jsx_runtime_1.jsx(scissors_1.ScissorsIcon, { style: actionIconStyle, color: color })), children: "Split selected" }) }) })
132
+ ] }));
102
133
  };
103
134
  exports.MultiSequenceInspector = MultiSequenceInspector;