@remotion/studio 4.0.496 → 4.0.497

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 (81) hide show
  1. package/dist/components/AudioWaveform.js +1 -11
  2. package/dist/components/Canvas.js +22 -203
  3. package/dist/components/CompositionSelectorItem.js +2 -10
  4. package/dist/components/InspectorPanel/AlignmentControls.js +2 -0
  5. package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +27 -2
  6. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +65 -8
  7. package/dist/components/InspectorPanel/use-composition-actions.js +6 -2
  8. package/dist/components/NewComposition/CodemodFooter.d.ts +1 -1
  9. package/dist/components/NewComposition/CodemodFooter.js +23 -4
  10. package/dist/components/NewComposition/InputDragger.d.ts +6 -0
  11. package/dist/components/NewComposition/InputDragger.js +12 -3
  12. package/dist/components/NewComposition/NewComposition.js +1 -1
  13. package/dist/components/NewComposition/use-rename-static-file.js +1 -1
  14. package/dist/components/SelectedOutlineElement.js +56 -88
  15. package/dist/components/SelectedOutlineOverlay.d.ts +1 -1
  16. package/dist/components/SelectedOutlineOverlay.js +9 -10
  17. package/dist/components/Timeline/Timeline.js +10 -3
  18. package/dist/components/Timeline/TimelineAssetDropIndicator.d.ts +2 -0
  19. package/dist/components/Timeline/TimelineAssetDropIndicator.js +37 -0
  20. package/dist/components/Timeline/TimelineClipboardKeybindings.js +1 -7
  21. package/dist/components/Timeline/TimelineScrollable.js +3 -2
  22. package/dist/components/Timeline/TimelineSelection.d.ts +4 -0
  23. package/dist/components/Timeline/TimelineSelection.js +40 -5
  24. package/dist/components/Timeline/TimelineSequence.js +20 -8
  25. package/dist/components/Timeline/TimelineSequenceFrame.js +2 -4
  26. package/dist/components/Timeline/TimelineSequenceItem.js +2 -0
  27. package/dist/components/Timeline/TimelineSequencePropItem.js +4 -0
  28. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +15 -3
  29. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +96 -18
  30. package/dist/components/Timeline/TimelineTimeIndicators.d.ts +16 -0
  31. package/dist/components/Timeline/TimelineTimeIndicators.js +154 -35
  32. package/dist/components/Timeline/TimelineTranslateField.js +2 -1
  33. package/dist/components/Timeline/TimelineVideoInfo.d.ts +1 -0
  34. package/dist/components/Timeline/TimelineVideoInfo.js +4 -1
  35. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +2 -0
  36. package/dist/components/Timeline/delete-selected-timeline-item.js +5 -4
  37. package/dist/components/Timeline/disable-sequence-interactivity.js +2 -0
  38. package/dist/components/Timeline/get-timeline-media-visualization-layout.d.ts +8 -0
  39. package/dist/components/Timeline/get-timeline-media-visualization-layout.js +10 -0
  40. package/dist/components/Timeline/get-timeline-video-info-widths.js +11 -3
  41. package/dist/components/Timeline/keyframe-clipboard.js +21 -5
  42. package/dist/components/Timeline/reset-selected-timeline-props.js +2 -0
  43. package/dist/components/Timeline/save-sequence-prop.d.ts +5 -3
  44. package/dist/components/Timeline/save-sequence-prop.js +43 -18
  45. package/dist/components/Timeline/should-clear-selection-on-pointer-down.d.ts +2 -0
  46. package/dist/components/Timeline/should-clear-selection-on-pointer-down.js +1 -1
  47. package/dist/components/Timeline/timeline-asset-drop-context.d.ts +1 -0
  48. package/dist/components/Timeline/timeline-asset-drop-context.js +5 -0
  49. package/dist/components/Timeline/timeline-scroll-logic.d.ts +7 -0
  50. package/dist/components/Timeline/timeline-scroll-logic.js +10 -1
  51. package/dist/components/Timeline/use-rename-sequence.js +2 -0
  52. package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.js +2 -0
  53. package/dist/components/Timeline/use-timeline-asset-drop.d.ts +1 -0
  54. package/dist/components/Timeline/use-timeline-asset-drop.js +168 -0
  55. package/dist/components/composition-menu-items.d.ts +15 -1
  56. package/dist/components/composition-menu-items.js +137 -107
  57. package/dist/components/drop-handler-data.d.ts +13 -0
  58. package/dist/components/drop-handler-data.js +117 -0
  59. package/dist/components/handle-drop.d.ts +13 -0
  60. package/dist/components/handle-drop.js +115 -0
  61. package/dist/components/import-assets.d.ts +26 -8
  62. package/dist/components/import-assets.js +161 -49
  63. package/dist/components/selected-outline-drag.d.ts +11 -1
  64. package/dist/components/selected-outline-drag.js +74 -1
  65. package/dist/esm/{chunk-0v4n7nkh.js → chunk-5wj95bdd.js} +4262 -3392
  66. package/dist/esm/internals.mjs +4262 -3392
  67. package/dist/esm/previewEntry.mjs +4464 -3594
  68. package/dist/esm/renderEntry.mjs +1 -1
  69. package/dist/helpers/is-video-with-last-frame-hold.d.ts +2 -0
  70. package/dist/helpers/is-video-with-last-frame-hold.js +9 -0
  71. package/dist/helpers/url-state.d.ts +1 -0
  72. package/dist/helpers/url-state.js +5 -1
  73. package/dist/helpers/use-max-media-duration.js +5 -3
  74. package/dist/helpers/use-menu-structure.js +2 -0
  75. package/dist/icons/duplicate.d.ts +5 -0
  76. package/dist/icons/duplicate.js +10 -0
  77. package/dist/icons/snowflake.d.ts +5 -0
  78. package/dist/icons/snowflake.js +10 -0
  79. package/dist/icons/trash.d.ts +5 -0
  80. package/dist/icons/trash.js +8 -0
  81. package/package.json +11 -11
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.prepareToPreserveTimelineCursor = exports.getScrollLeftToKeepCursorInPlace = exports.viewportClientXToScrollContentX = exports.getFrameFromX = exports.getFrameWhileScrollingRight = exports.getFrameIncrementFromWidth = exports.getScrollPositionForCursorOnRightEdge = exports.getScrollPositionForCursorOnLeftEdge = exports.scrollToTimelineXOffset = exports.ensureFrameIsInViewport = exports.isCursorInViewport = exports.getFrameWhileScrollingLeft = exports.canScrollTimelineIntoDirection = void 0;
3
+ exports.prepareToPreserveTimelineCursor = exports.getScrollLeftToKeepCursorInPlace = exports.viewportClientXToScrollContentX = exports.getFrameFromTimelineDrop = exports.getFrameFromX = exports.getFrameWhileScrollingRight = exports.getFrameIncrementFromWidth = exports.getScrollPositionForCursorOnRightEdge = exports.getScrollPositionForCursorOnLeftEdge = exports.scrollToTimelineXOffset = exports.ensureFrameIsInViewport = exports.isCursorInViewport = exports.getFrameWhileScrollingLeft = exports.canScrollTimelineIntoDirection = void 0;
4
4
  const remotion_1 = require("remotion");
5
5
  const timeline_layout_1 = require("../../helpers/timeline-layout");
6
6
  const timeline_refs_1 = require("./timeline-refs");
@@ -203,6 +203,15 @@ const getFrameFromX = ({ clientX, durationInFrames, width, extrapolate, }) => {
203
203
  return frame;
204
204
  };
205
205
  exports.getFrameFromX = getFrameFromX;
206
+ const getFrameFromTimelineDrop = ({ clientX, durationInFrames, scrollLeft, timelineLeft, timelineWidth, }) => {
207
+ return (0, exports.getFrameFromX)({
208
+ clientX: clientX - timelineLeft + scrollLeft,
209
+ durationInFrames,
210
+ width: timelineWidth,
211
+ extrapolate: 'clamp',
212
+ });
213
+ };
214
+ exports.getFrameFromTimelineDrop = getFrameFromTimelineDrop;
206
215
  /**
207
216
  * Horizontal position inside the scrollable timeline content (0 … scrollWidth)
208
217
  * for a viewport `clientX`, so pinch-anchoring matches the pointer (not a
@@ -76,6 +76,8 @@ const useRenameSequence = ({ clientId, nodePathInfo, sequence, validatedLocation
76
76
  return;
77
77
  }
78
78
  await (0, save_sequence_prop_1.saveSequenceProps)({
79
+ addedKeyframes: null,
80
+ movedKeyframes: null,
79
81
  changes: [
80
82
  {
81
83
  fileName: validatedLocation.source,
@@ -33,6 +33,8 @@ const useSequenceFreezeFrameMenuItem = ({ clientId, nodePath, propStatusesForOve
33
33
  const freezeFrame = Math.min(Math.max(0, rawFreezeFrame), maxFrame);
34
34
  const remove = isFrozen;
35
35
  (0, save_sequence_prop_1.saveSequenceProps)({
36
+ addedKeyframes: null,
37
+ movedKeyframes: null,
36
38
  changes: [
37
39
  {
38
40
  fileName: validatedSource,
@@ -0,0 +1 @@
1
+ export declare const useTimelineAssetDrop: () => number | null;
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useTimelineAssetDrop = void 0;
4
+ const react_1 = require("react");
5
+ const remotion_1 = require("remotion");
6
+ const client_id_1 = require("../../helpers/client-id");
7
+ const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
8
+ const open_in_editor_1 = require("../../helpers/open-in-editor");
9
+ const drop_handler_data_1 = require("../drop-handler-data");
10
+ const effect_drag_and_drop_1 = require("../effect-drag-and-drop");
11
+ const handle_drop_1 = require("../handle-drop");
12
+ const NotificationCenter_1 = require("../Notifications/NotificationCenter");
13
+ const SvgImportDialog_1 = require("../SvgImportDialog");
14
+ const timeline_refs_1 = require("./timeline-refs");
15
+ const timeline_scroll_logic_1 = require("./timeline-scroll-logic");
16
+ const use_resolved_stack_1 = require("./use-resolved-stack");
17
+ const isEventInsideElement = (event, element) => {
18
+ if (event.target instanceof Node && element.contains(event.target)) {
19
+ return true;
20
+ }
21
+ const rect = element.getBoundingClientRect();
22
+ return (event.clientX >= rect.left &&
23
+ event.clientX <= rect.right &&
24
+ event.clientY >= rect.top &&
25
+ event.clientY <= rect.bottom);
26
+ };
27
+ const useTimelineAssetDrop = () => {
28
+ var _a, _b;
29
+ const { canvasContent, compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
30
+ const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
31
+ const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
32
+ const chooseSvgImportMode = (0, SvgImportDialog_1.useSvgImportDialog)();
33
+ const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
34
+ const [isAddingAsset, setIsAddingAsset] = (0, react_1.useState)(false);
35
+ const [assetDropFrame, setAssetDropFrame] = (0, react_1.useState)(null);
36
+ const currentCompositionId = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition' ? canvasContent.compositionId : null;
37
+ const currentComposition = (0, react_1.useMemo)(() => {
38
+ var _a;
39
+ return ((_a = compositions.find((composition) => composition.id === currentCompositionId)) !== null && _a !== void 0 ? _a : null);
40
+ }, [compositions, currentCompositionId]);
41
+ const resolvedCompositionLocation = (0, use_resolved_stack_1.useResolvedStack)((_a = currentComposition === null || currentComposition === void 0 ? void 0 : currentComposition.stack) !== null && _a !== void 0 ? _a : null);
42
+ const compositionFile = (_b = resolvedCompositionLocation === null || resolvedCompositionLocation === void 0 ? void 0 : resolvedCompositionLocation.source) !== null && _b !== void 0 ? _b : null;
43
+ const compositionComponentInfo = (0, open_in_editor_1.useCachedCompositionComponentInfo)({
44
+ compositionFile,
45
+ compositionId: currentCompositionId,
46
+ });
47
+ const previewInteractive = previewServerState.type === 'connected' && interactivity_enabled_1.studioInteractivityEnabled;
48
+ const canInsertAsset = previewInteractive &&
49
+ !window.remotion_isReadOnlyStudio &&
50
+ (compositionComponentInfo === null || compositionComponentInfo === void 0 ? void 0 : compositionComponentInfo.canAddSequence) === true &&
51
+ currentCompositionId !== null &&
52
+ compositionFile !== null &&
53
+ videoConfig !== null &&
54
+ !isAddingAsset;
55
+ const getDropFrame = (0, react_1.useCallback)((event) => {
56
+ if (videoConfig === null) {
57
+ return null;
58
+ }
59
+ const scrollable = timeline_refs_1.scrollableRef.current;
60
+ return scrollable !== null && isEventInsideElement(event, scrollable)
61
+ ? (0, timeline_scroll_logic_1.getFrameFromTimelineDrop)({
62
+ clientX: event.clientX,
63
+ durationInFrames: videoConfig.durationInFrames,
64
+ scrollLeft: scrollable.scrollLeft,
65
+ timelineLeft: scrollable.getBoundingClientRect().left,
66
+ timelineWidth: scrollable.scrollWidth,
67
+ })
68
+ : timelinePosition;
69
+ }, [timelinePosition, videoConfig]);
70
+ const onAssetDragOver = (0, react_1.useCallback)((event) => {
71
+ const timeline = timeline_refs_1.timelineVerticalScroll.current;
72
+ const { dataTransfer } = event;
73
+ if (timeline === null ||
74
+ dataTransfer === null ||
75
+ !(0, drop_handler_data_1.isSupportedDropEvent)(event) ||
76
+ !isEventInsideElement(event, timeline)) {
77
+ setAssetDropFrame(null);
78
+ return;
79
+ }
80
+ event.preventDefault();
81
+ event.stopPropagation();
82
+ dataTransfer.dropEffect = canInsertAsset ? 'copy' : 'none';
83
+ const scrollable = timeline_refs_1.scrollableRef.current;
84
+ const shouldShowDropFrame = canInsertAsset &&
85
+ scrollable !== null &&
86
+ isEventInsideElement(event, scrollable);
87
+ setAssetDropFrame(shouldShowDropFrame ? getDropFrame(event) : null);
88
+ }, [canInsertAsset, getDropFrame]);
89
+ const onAssetDrop = (0, react_1.useCallback)(async (event) => {
90
+ setAssetDropFrame(null);
91
+ const timeline = timeline_refs_1.timelineVerticalScroll.current;
92
+ const { dataTransfer } = event;
93
+ if (timeline === null ||
94
+ dataTransfer === null ||
95
+ !(0, drop_handler_data_1.isSupportedDropEvent)(event) ||
96
+ !isEventInsideElement(event, timeline)) {
97
+ return;
98
+ }
99
+ if ((0, effect_drag_and_drop_1.getEffectDragData)(dataTransfer) !== null) {
100
+ event.preventDefault();
101
+ return;
102
+ }
103
+ event.preventDefault();
104
+ event.stopPropagation();
105
+ if (!canInsertAsset ||
106
+ currentCompositionId === null ||
107
+ compositionFile === null ||
108
+ videoConfig === null) {
109
+ if ((compositionComponentInfo === null || compositionComponentInfo === void 0 ? void 0 : compositionComponentInfo.canAddSequence) === false) {
110
+ (0, NotificationCenter_1.showNotification)('Cannot insert items into this composition component', 3000);
111
+ }
112
+ return;
113
+ }
114
+ const frame = getDropFrame(event);
115
+ if (frame === null) {
116
+ return;
117
+ }
118
+ setIsAddingAsset(true);
119
+ try {
120
+ await (0, handle_drop_1.handleDrop)({
121
+ chooseSvgImportMode,
122
+ compositionFile,
123
+ compositionId: currentCompositionId,
124
+ destinationDimensions: {
125
+ height: videoConfig.height,
126
+ width: videoConfig.width,
127
+ },
128
+ dropPosition: {
129
+ centerX: videoConfig.width / 2,
130
+ centerY: videoConfig.height / 2,
131
+ },
132
+ event,
133
+ fps: videoConfig.fps,
134
+ from: frame,
135
+ });
136
+ }
137
+ finally {
138
+ setIsAddingAsset(false);
139
+ }
140
+ }, [
141
+ canInsertAsset,
142
+ chooseSvgImportMode,
143
+ compositionComponentInfo === null || compositionComponentInfo === void 0 ? void 0 : compositionComponentInfo.canAddSequence,
144
+ compositionFile,
145
+ currentCompositionId,
146
+ getDropFrame,
147
+ videoConfig,
148
+ ]);
149
+ const clearAssetDropFrame = (0, react_1.useCallback)(() => {
150
+ setAssetDropFrame(null);
151
+ }, []);
152
+ (0, react_1.useEffect)(() => {
153
+ document.addEventListener('dragover', onAssetDragOver, { capture: true });
154
+ document.addEventListener('drop', onAssetDrop, { capture: true });
155
+ document.addEventListener('dragend', clearAssetDropFrame, { capture: true });
156
+ return () => {
157
+ document.removeEventListener('dragover', onAssetDragOver, {
158
+ capture: true,
159
+ });
160
+ document.removeEventListener('drop', onAssetDrop, { capture: true });
161
+ document.removeEventListener('dragend', clearAssetDropFrame, {
162
+ capture: true,
163
+ });
164
+ };
165
+ }, [clearAssetDropFrame, onAssetDragOver, onAssetDrop]);
166
+ return assetDropFrame;
167
+ };
168
+ exports.useTimelineAssetDrop = useTimelineAssetDrop;
@@ -2,11 +2,25 @@ import type { SetStateAction } from 'react';
2
2
  import type { ResolvedStackLocation } from 'remotion';
3
3
  import type { ModalState } from '../state/modals';
4
4
  import type { ComboboxValue } from './NewComposition/ComboBox';
5
- export declare const getCompositionMenuItems: ({ composition, connectionStatus, resolvedLocation, setSelectedModal, closeMenu, readOnlyStudio, }: {
5
+ export declare const getCompositionMenuItems: ({ composition, connectionStatus, resolvedLocation, setSelectedModal, closeMenu, readOnlyStudio, includeNewCompositionItem, includeCompositionManagementItems, }: {
6
6
  composition: import("remotion").AnyComposition | null;
7
7
  connectionStatus: "connected" | "disconnected" | "init";
8
8
  resolvedLocation: ResolvedStackLocation | null;
9
9
  setSelectedModal: (value: SetStateAction<ModalState | null>) => void;
10
10
  closeMenu: () => void;
11
11
  readOnlyStudio: boolean;
12
+ includeNewCompositionItem: boolean;
13
+ includeCompositionManagementItems: boolean;
14
+ }) => ComboboxValue[];
15
+ export declare const getCompositionContextMenuItems: (args: Omit<{
16
+ composition: import("remotion").AnyComposition | null;
17
+ connectionStatus: "connected" | "disconnected" | "init";
18
+ resolvedLocation: ResolvedStackLocation | null;
19
+ setSelectedModal: (value: SetStateAction<ModalState | null>) => void;
20
+ closeMenu: () => void;
21
+ readOnlyStudio: boolean;
22
+ includeNewCompositionItem: boolean;
23
+ includeCompositionManagementItems: boolean;
24
+ }, "includeCompositionManagementItems" | "includeNewCompositionItem"> & {
25
+ readonly includeCompositionManagementItems: boolean;
12
26
  }) => ComboboxValue[];
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getCompositionMenuItems = void 0;
3
+ exports.getCompositionContextMenuItems = exports.getCompositionMenuItems = 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 open_in_editor_1 = require("../helpers/open-in-editor");
7
7
  const NotificationCenter_1 = require("./Notifications/NotificationCenter");
8
- const getCompositionMenuItems = ({ composition, connectionStatus, resolvedLocation, setSelectedModal, closeMenu, readOnlyStudio, }) => {
8
+ const open_in_new_window_1 = require("./open-in-new-window");
9
+ const getCompositionMenuItems = ({ composition, connectionStatus, resolvedLocation, setSelectedModal, closeMenu, readOnlyStudio, includeNewCompositionItem, includeCompositionManagementItems, }) => {
9
10
  const editorName = window.remotion_editorName;
10
11
  const fileLocation = (0, format_file_location_1.formatFileLocation)({
11
12
  location: resolvedLocation,
@@ -19,7 +20,7 @@ const getCompositionMenuItems = ({ composition, connectionStatus, resolvedLocati
19
20
  ? {
20
21
  id: 'show-in-editor',
21
22
  keyHint: null,
22
- label: `Show composition in ${editorName}`,
23
+ label: `Open composition in ${editorName}`,
23
24
  leftItem: null,
24
25
  onClick: async () => {
25
26
  closeMenu();
@@ -33,13 +34,41 @@ const getCompositionMenuItems = ({ composition, connectionStatus, resolvedLocati
33
34
  (0, NotificationCenter_1.showNotification)(err.message, 2000);
34
35
  }
35
36
  },
36
- quickSwitcherLabel: `Show composition in ${editorName}`,
37
+ quickSwitcherLabel: `Open composition in ${editorName}`,
37
38
  subMenu: null,
38
39
  type: 'item',
39
40
  value: 'show-in-editor',
40
41
  disabled: showInEditorDisabled,
41
42
  }
42
43
  : null,
44
+ editorName
45
+ ? {
46
+ id: 'open-component-in-editor',
47
+ keyHint: null,
48
+ label: `Open component in ${editorName}`,
49
+ leftItem: null,
50
+ onClick: async () => {
51
+ closeMenu();
52
+ if (!composition || !(resolvedLocation === null || resolvedLocation === void 0 ? void 0 : resolvedLocation.source)) {
53
+ return;
54
+ }
55
+ try {
56
+ await (0, open_in_editor_1.openCompositionComponentInEditor)({
57
+ compositionFile: resolvedLocation.source,
58
+ compositionId: composition.id,
59
+ });
60
+ }
61
+ catch (err) {
62
+ (0, NotificationCenter_1.showNotification)(err.message, 2000);
63
+ }
64
+ },
65
+ quickSwitcherLabel: `Open composition component in ${editorName}`,
66
+ subMenu: null,
67
+ type: 'item',
68
+ value: 'open-component-in-editor',
69
+ disabled: openComponentInEditorDisabled,
70
+ }
71
+ : null,
43
72
  {
44
73
  id: 'copy-file-location',
45
74
  keyHint: null,
@@ -65,124 +94,105 @@ const getCompositionMenuItems = ({ composition, connectionStatus, resolvedLocati
65
94
  value: 'copy-file-location',
66
95
  disabled: copyFileLocationDisabled,
67
96
  },
68
- editorName
97
+ (editorName || fileLocation) &&
98
+ (includeNewCompositionItem || includeCompositionManagementItems)
69
99
  ? {
70
- id: 'open-component-in-editor',
100
+ type: 'divider',
101
+ id: 'show-in-editor-divider',
102
+ }
103
+ : null,
104
+ includeNewCompositionItem
105
+ ? {
106
+ id: 'new',
71
107
  keyHint: null,
72
- label: `Show component in ${editorName}`,
108
+ label: `New...`,
73
109
  leftItem: null,
74
- onClick: async () => {
110
+ onClick: () => {
75
111
  closeMenu();
76
- if (!composition || !(resolvedLocation === null || resolvedLocation === void 0 ? void 0 : resolvedLocation.source)) {
112
+ setSelectedModal({
113
+ type: 'new-comp',
114
+ folderName: null,
115
+ parentName: null,
116
+ stack: null,
117
+ });
118
+ },
119
+ quickSwitcherLabel: 'New composition...',
120
+ subMenu: null,
121
+ type: 'item',
122
+ value: 'new',
123
+ disabled: readOnlyStudio,
124
+ }
125
+ : null,
126
+ includeCompositionManagementItems
127
+ ? {
128
+ id: 'rename',
129
+ keyHint: null,
130
+ label: `Rename...`,
131
+ leftItem: null,
132
+ onClick: () => {
133
+ if (!composition) {
77
134
  return;
78
135
  }
79
- try {
80
- await (0, open_in_editor_1.openCompositionComponentInEditor)({
81
- compositionFile: resolvedLocation.source,
82
- compositionId: composition.id,
83
- });
84
- }
85
- catch (err) {
86
- (0, NotificationCenter_1.showNotification)(err.message, 2000);
136
+ closeMenu();
137
+ setSelectedModal({
138
+ type: 'rename-comp',
139
+ compositionId: composition.id,
140
+ });
141
+ },
142
+ quickSwitcherLabel: 'Rename composition...',
143
+ subMenu: null,
144
+ type: 'item',
145
+ value: 'rename',
146
+ disabled: !composition || readOnlyStudio,
147
+ }
148
+ : null,
149
+ includeCompositionManagementItems
150
+ ? {
151
+ id: 'duplicate',
152
+ keyHint: null,
153
+ label: `Duplicate...`,
154
+ leftItem: null,
155
+ onClick: () => {
156
+ if (!composition) {
157
+ return;
87
158
  }
159
+ closeMenu();
160
+ setSelectedModal({
161
+ type: 'duplicate-comp',
162
+ compositionId: composition.id,
163
+ compositionType: composition.durationInFrames === 1 ? 'still' : 'composition',
164
+ });
88
165
  },
89
- quickSwitcherLabel: `Show composition component in ${editorName}`,
166
+ quickSwitcherLabel: 'Duplicate composition...',
90
167
  subMenu: null,
91
168
  type: 'item',
92
- value: 'open-component-in-editor',
93
- disabled: openComponentInEditorDisabled,
169
+ value: 'duplicate',
170
+ disabled: !composition || readOnlyStudio,
94
171
  }
95
172
  : null,
96
- editorName || fileLocation
173
+ includeCompositionManagementItems
97
174
  ? {
98
- type: 'divider',
99
- id: 'show-in-editor-divider',
175
+ id: 'delete',
176
+ keyHint: null,
177
+ label: `Delete...`,
178
+ leftItem: null,
179
+ onClick: () => {
180
+ if (!composition) {
181
+ return;
182
+ }
183
+ closeMenu();
184
+ setSelectedModal({
185
+ type: 'delete-comp',
186
+ compositionId: composition.id,
187
+ });
188
+ },
189
+ quickSwitcherLabel: 'Delete composition...',
190
+ subMenu: null,
191
+ type: 'item',
192
+ value: 'delete',
193
+ disabled: !composition || readOnlyStudio,
100
194
  }
101
195
  : null,
102
- {
103
- id: 'new',
104
- keyHint: null,
105
- label: `New...`,
106
- leftItem: null,
107
- onClick: () => {
108
- closeMenu();
109
- setSelectedModal({
110
- type: 'new-comp',
111
- folderName: null,
112
- parentName: null,
113
- stack: null,
114
- });
115
- },
116
- quickSwitcherLabel: 'New composition...',
117
- subMenu: null,
118
- type: 'item',
119
- value: 'new',
120
- disabled: readOnlyStudio,
121
- },
122
- {
123
- id: 'rename',
124
- keyHint: null,
125
- label: `Rename...`,
126
- leftItem: null,
127
- onClick: () => {
128
- if (!composition) {
129
- return;
130
- }
131
- closeMenu();
132
- setSelectedModal({
133
- type: 'rename-comp',
134
- compositionId: composition.id,
135
- });
136
- },
137
- quickSwitcherLabel: 'Rename composition...',
138
- subMenu: null,
139
- type: 'item',
140
- value: 'rename',
141
- disabled: !composition || readOnlyStudio,
142
- },
143
- {
144
- id: 'duplicate',
145
- keyHint: null,
146
- label: `Duplicate...`,
147
- leftItem: null,
148
- onClick: () => {
149
- if (!composition) {
150
- return;
151
- }
152
- closeMenu();
153
- setSelectedModal({
154
- type: 'duplicate-comp',
155
- compositionId: composition.id,
156
- compositionType: composition.durationInFrames === 1 ? 'still' : 'composition',
157
- });
158
- },
159
- quickSwitcherLabel: 'Duplicate composition...',
160
- subMenu: null,
161
- type: 'item',
162
- value: 'duplicate',
163
- disabled: !composition || readOnlyStudio,
164
- },
165
- {
166
- id: 'delete',
167
- keyHint: null,
168
- label: `Delete...`,
169
- leftItem: null,
170
- onClick: () => {
171
- if (!composition) {
172
- return;
173
- }
174
- closeMenu();
175
- setSelectedModal({
176
- type: 'delete-comp',
177
- compositionId: composition.id,
178
- });
179
- },
180
- quickSwitcherLabel: 'Delete composition...',
181
- subMenu: null,
182
- type: 'item',
183
- value: 'delete',
184
- disabled: !composition || readOnlyStudio,
185
- },
186
196
  {
187
197
  type: 'divider',
188
198
  id: 'copy-id-divider',
@@ -215,3 +225,23 @@ const getCompositionMenuItems = ({ composition, connectionStatus, resolvedLocati
215
225
  ].filter(no_react_1.NoReactInternals.truthy);
216
226
  };
217
227
  exports.getCompositionMenuItems = getCompositionMenuItems;
228
+ const getCompositionContextMenuItems = (args) => {
229
+ if (args.composition === null) {
230
+ return (0, exports.getCompositionMenuItems)({
231
+ ...args,
232
+ includeNewCompositionItem: false,
233
+ });
234
+ }
235
+ return [
236
+ (0, open_in_new_window_1.getOpenInNewWindowMenuItem)(`/${args.composition.id}`),
237
+ {
238
+ type: 'divider',
239
+ id: 'open-in-new-window-divider',
240
+ },
241
+ ...(0, exports.getCompositionMenuItems)({
242
+ ...args,
243
+ includeNewCompositionItem: false,
244
+ }),
245
+ ];
246
+ };
247
+ exports.getCompositionContextMenuItems = getCompositionContextMenuItems;
@@ -0,0 +1,13 @@
1
+ import { type ComponentDragData, type CompositionDragData } from '@remotion/studio-shared';
2
+ export declare const isFileDragEvent: (event: DragEvent) => boolean;
3
+ export declare const isAssetDragEvent: (event: DragEvent) => boolean;
4
+ export declare const isComponentDragEvent: (event: DragEvent) => boolean;
5
+ export declare const isCompositionDragEvent: (event: DragEvent) => boolean;
6
+ export declare const isElementDragEvent: (event: DragEvent) => boolean;
7
+ export declare const isSfxDragEvent: (event: DragEvent) => boolean;
8
+ export declare const isRemoteAssetDragEvent: (event: DragEvent) => boolean;
9
+ export declare const isSupportedDropEvent: (event: DragEvent) => boolean;
10
+ export declare const getAssetDragPath: (event: DragEvent) => string | null;
11
+ export declare const getCompositionDragData: (event: DragEvent) => CompositionDragData | null;
12
+ export declare const getComponentDragData: (event: DragEvent) => ComponentDragData | null;
13
+ export declare const getSfxDragUrl: (event: DragEvent) => string | null;
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSfxDragUrl = exports.getComponentDragData = exports.getCompositionDragData = exports.getAssetDragPath = exports.isSupportedDropEvent = exports.isRemoteAssetDragEvent = exports.isSfxDragEvent = exports.isElementDragEvent = exports.isCompositionDragEvent = exports.isComponentDragEvent = exports.isAssetDragEvent = exports.isFileDragEvent = void 0;
4
+ const studio_shared_1 = require("@remotion/studio-shared");
5
+ const remote_asset_drag_1 = require("../helpers/remote-asset-drag");
6
+ const isFileDragEvent = (event) => {
7
+ var _a;
8
+ var _b;
9
+ return Array.from((_b = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.types) !== null && _b !== void 0 ? _b : []).includes('Files');
10
+ };
11
+ exports.isFileDragEvent = isFileDragEvent;
12
+ const isAssetDragEvent = (event) => {
13
+ var _a;
14
+ var _b;
15
+ return Array.from((_b = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.types) !== null && _b !== void 0 ? _b : []).includes(studio_shared_1.ASSET_DRAG_MIME_TYPE);
16
+ };
17
+ exports.isAssetDragEvent = isAssetDragEvent;
18
+ const isComponentDragEvent = (event) => {
19
+ var _a;
20
+ var _b;
21
+ return Array.from((_b = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.types) !== null && _b !== void 0 ? _b : []).includes(studio_shared_1.COMPONENT_DRAG_MIME_TYPE);
22
+ };
23
+ exports.isComponentDragEvent = isComponentDragEvent;
24
+ const isCompositionDragEvent = (event) => {
25
+ var _a;
26
+ var _b;
27
+ return Array.from((_b = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.types) !== null && _b !== void 0 ? _b : []).includes(studio_shared_1.COMPOSITION_DRAG_MIME_TYPE);
28
+ };
29
+ exports.isCompositionDragEvent = isCompositionDragEvent;
30
+ const isElementDragEvent = (event) => {
31
+ var _a;
32
+ var _b;
33
+ return Array.from((_b = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.types) !== null && _b !== void 0 ? _b : []).includes(studio_shared_1.ELEMENT_DRAG_MIME_TYPE);
34
+ };
35
+ exports.isElementDragEvent = isElementDragEvent;
36
+ const isSfxDragEvent = (event) => {
37
+ var _a;
38
+ var _b;
39
+ return Array.from((_b = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.types) !== null && _b !== void 0 ? _b : []).includes(studio_shared_1.SFX_DRAG_MIME_TYPE);
40
+ };
41
+ exports.isSfxDragEvent = isSfxDragEvent;
42
+ const isRemoteAssetDragEvent = (event) => {
43
+ return (!(0, exports.isFileDragEvent)(event) &&
44
+ !(0, exports.isAssetDragEvent)(event) &&
45
+ !(0, exports.isCompositionDragEvent)(event) &&
46
+ !(0, exports.isComponentDragEvent)(event) &&
47
+ !(0, exports.isElementDragEvent)(event) &&
48
+ !(0, exports.isSfxDragEvent)(event) &&
49
+ (0, remote_asset_drag_1.hasRemoteAssetDragData)(event.dataTransfer));
50
+ };
51
+ exports.isRemoteAssetDragEvent = isRemoteAssetDragEvent;
52
+ const isSupportedDropEvent = (event) => {
53
+ return ((0, exports.isFileDragEvent)(event) ||
54
+ (0, exports.isAssetDragEvent)(event) ||
55
+ (0, exports.isCompositionDragEvent)(event) ||
56
+ (0, exports.isComponentDragEvent)(event) ||
57
+ (0, exports.isElementDragEvent)(event) ||
58
+ (0, exports.isSfxDragEvent)(event) ||
59
+ (0, exports.isRemoteAssetDragEvent)(event));
60
+ };
61
+ exports.isSupportedDropEvent = isSupportedDropEvent;
62
+ const getAssetDragPath = (event) => {
63
+ var _a, _b;
64
+ var _c;
65
+ const value = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.getData(studio_shared_1.ASSET_DRAG_MIME_TYPE);
66
+ if (!value) {
67
+ return null;
68
+ }
69
+ return (_c = (_b = (0, studio_shared_1.parseAssetDragData)(value)) === null || _b === void 0 ? void 0 : _b.assetPath) !== null && _c !== void 0 ? _c : null;
70
+ };
71
+ exports.getAssetDragPath = getAssetDragPath;
72
+ const getCompositionDragData = (event) => {
73
+ var _a;
74
+ const value = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.getData(studio_shared_1.COMPOSITION_DRAG_MIME_TYPE);
75
+ if (!value) {
76
+ return null;
77
+ }
78
+ return (0, studio_shared_1.parseCompositionDragData)(value);
79
+ };
80
+ exports.getCompositionDragData = getCompositionDragData;
81
+ const getComponentDragData = (event) => {
82
+ var _a;
83
+ for (const type of [
84
+ studio_shared_1.COMPONENT_DRAG_MIME_TYPE,
85
+ 'application/json',
86
+ 'text/plain',
87
+ ]) {
88
+ const value = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.getData(type);
89
+ if (!value) {
90
+ continue;
91
+ }
92
+ const parsed = (0, studio_shared_1.parseComponentDragData)(value);
93
+ if (parsed) {
94
+ return parsed;
95
+ }
96
+ }
97
+ return null;
98
+ };
99
+ exports.getComponentDragData = getComponentDragData;
100
+ const getSfxDragUrl = (event) => {
101
+ const { dataTransfer } = event;
102
+ if (!dataTransfer) {
103
+ return null;
104
+ }
105
+ for (const type of [studio_shared_1.SFX_DRAG_MIME_TYPE, 'application/json', 'text/plain']) {
106
+ const value = dataTransfer.getData(type);
107
+ if (!value) {
108
+ continue;
109
+ }
110
+ const parsed = (0, studio_shared_1.parseSfxDragData)(value);
111
+ if (parsed) {
112
+ return parsed.sfx.url;
113
+ }
114
+ }
115
+ return null;
116
+ };
117
+ exports.getSfxDragUrl = getSfxDragUrl;