@remotion/studio 4.0.472 → 4.0.474

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 (165) hide show
  1. package/dist/api/rename-static-file.d.ts +6 -0
  2. package/dist/api/rename-static-file.js +18 -0
  3. package/dist/components/AssetSelector.js +45 -4
  4. package/dist/components/AssetSelectorItem.js +177 -27
  5. package/dist/components/Canvas.js +131 -11
  6. package/dist/components/ConfirmationDialog-types.d.ts +8 -0
  7. package/dist/components/ConfirmationDialog-types.js +2 -0
  8. package/dist/components/ConfirmationDialog.d.ts +7 -0
  9. package/dist/components/ConfirmationDialog.js +103 -0
  10. package/dist/components/ContextMenu.d.ts +9 -1
  11. package/dist/components/ContextMenu.js +49 -5
  12. package/dist/components/CurrentAsset.d.ts +1 -0
  13. package/dist/components/CurrentAsset.js +13 -2
  14. package/dist/components/EditorContent.js +15 -2
  15. package/dist/components/EditorContexts.js +2 -1
  16. package/dist/components/EditorRuler/Ruler.js +2 -0
  17. package/dist/components/ExplorerPanel.d.ts +0 -4
  18. package/dist/components/ExplorerPanel.js +8 -4
  19. package/dist/components/ExplorerPanelRef.d.ts +4 -0
  20. package/dist/components/ExplorerPanelRef.js +5 -0
  21. package/dist/components/FilePreview.d.ts +1 -1
  22. package/dist/components/InitialCompositionLoader.d.ts +0 -1
  23. package/dist/components/InitialCompositionLoader.js +5 -27
  24. package/dist/components/Menu/MenuItem.js +7 -1
  25. package/dist/components/Menu/SubMenu.js +5 -1
  26. package/dist/components/Menu/portals.js +17 -8
  27. package/dist/components/MenuToolbar.js +5 -1
  28. package/dist/components/ModalContainer.js +6 -1
  29. package/dist/components/Modals.js +5 -2
  30. package/dist/components/NewComposition/ComboBox.js +8 -2
  31. package/dist/components/NewComposition/InputDragger.d.ts +1 -0
  32. package/dist/components/NewComposition/InputDragger.js +9 -6
  33. package/dist/components/NewComposition/RenameStaticFile.d.ts +4 -0
  34. package/dist/components/NewComposition/RenameStaticFile.js +118 -0
  35. package/dist/components/OptionsPanel.js +5 -1
  36. package/dist/components/OutlineToggle.d.ts +2 -0
  37. package/dist/components/OutlineToggle.js +20 -0
  38. package/dist/components/Preview.d.ts +0 -2
  39. package/dist/components/Preview.js +23 -33
  40. package/dist/components/PreviewToolbar.js +19 -6
  41. package/dist/components/RenderButton.js +8 -2
  42. package/dist/components/RenderPreview.js +2 -2
  43. package/dist/components/SelectedOutlineOverlay.d.ts +29 -3
  44. package/dist/components/SelectedOutlineOverlay.js +259 -80
  45. package/dist/components/ShowOutlinesProvider.d.ts +4 -0
  46. package/dist/components/ShowOutlinesProvider.js +24 -0
  47. package/dist/components/SizeSelector.js +3 -3
  48. package/dist/components/Splitter/SplitterHandle.js +2 -0
  49. package/dist/components/StaticFilePreview.js +2 -2
  50. package/dist/components/Timeline/KeyframeSettingsModal.d.ts +15 -0
  51. package/dist/components/Timeline/KeyframeSettingsModal.js +150 -0
  52. package/dist/components/Timeline/SequencePropsObserver.js +3 -3
  53. package/dist/components/Timeline/Timeline.js +3 -13
  54. package/dist/components/Timeline/TimelineClipboardKeybindings.d.ts +26 -3
  55. package/dist/components/Timeline/TimelineClipboardKeybindings.js +242 -25
  56. package/dist/components/Timeline/TimelineDeleteKeybindings.js +23 -11
  57. package/dist/components/Timeline/TimelineEffectItem.js +8 -7
  58. package/dist/components/Timeline/TimelineEffectPropItem.js +69 -19
  59. package/dist/components/Timeline/TimelineExpandedKeyframeRow.js +6 -1
  60. package/dist/components/Timeline/TimelineExpandedSection.js +5 -5
  61. package/dist/components/Timeline/TimelineKeyframeControls.js +13 -23
  62. package/dist/components/Timeline/TimelineKeyframeDiamond.js +24 -22
  63. package/dist/components/Timeline/TimelineKeyframeDiamondIcon.d.ts +6 -0
  64. package/dist/components/Timeline/TimelineKeyframeDiamondIcon.js +14 -0
  65. package/dist/components/Timeline/TimelineKeyframeDragState.d.ts +17 -0
  66. package/dist/components/Timeline/TimelineKeyframeDragState.js +39 -0
  67. package/dist/components/Timeline/TimelineKeyframeEasingLine.d.ts +9 -0
  68. package/dist/components/Timeline/TimelineKeyframeEasingLine.js +120 -0
  69. package/dist/components/Timeline/TimelineKeyframedValue.js +1 -1
  70. package/dist/components/Timeline/TimelineList.js +2 -2
  71. package/dist/components/Timeline/TimelineMediaInfo.d.ts +0 -13
  72. package/dist/components/Timeline/TimelineMediaInfo.js +8 -73
  73. package/dist/components/Timeline/TimelineNumberField.js +15 -7
  74. package/dist/components/Timeline/TimelineRotationField.js +17 -11
  75. package/dist/components/Timeline/TimelineScaleField.js +17 -13
  76. package/dist/components/Timeline/TimelineSelection.d.ts +15 -0
  77. package/dist/components/Timeline/TimelineSelection.js +26 -1
  78. package/dist/components/Timeline/TimelineSequence.js +6 -6
  79. package/dist/components/Timeline/TimelineSequenceItem.d.ts +1 -0
  80. package/dist/components/Timeline/TimelineSequenceItem.js +297 -36
  81. package/dist/components/Timeline/TimelineSequencePropItem.js +113 -48
  82. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +5 -5
  83. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +69 -70
  84. package/dist/components/Timeline/TimelineTranslateField.js +24 -19
  85. package/dist/components/Timeline/TimelineUvCoordinateField.js +18 -12
  86. package/dist/components/Timeline/apply-effect-response-to-prop-statuses.d.ts +5 -0
  87. package/dist/components/Timeline/apply-effect-response-to-prop-statuses.js +19 -0
  88. package/dist/components/Timeline/call-add-keyframe.d.ts +5 -5
  89. package/dist/components/Timeline/call-add-keyframe.js +6 -4
  90. package/dist/components/Timeline/call-delete-keyframe.d.ts +7 -7
  91. package/dist/components/Timeline/call-delete-keyframe.js +7 -7
  92. package/dist/components/Timeline/call-move-keyframe.d.ts +19 -0
  93. package/dist/components/Timeline/call-move-keyframe.js +71 -0
  94. package/dist/components/Timeline/call-update-keyframe-settings.d.ts +22 -0
  95. package/dist/components/Timeline/call-update-keyframe-settings.js +52 -0
  96. package/dist/components/Timeline/delete-selected-keyframe.d.ts +5 -5
  97. package/dist/components/Timeline/delete-selected-keyframe.js +5 -5
  98. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +10 -7
  99. package/dist/components/Timeline/delete-selected-timeline-item.js +37 -23
  100. package/dist/components/Timeline/duplicate-selected-timeline-item.d.ts +4 -2
  101. package/dist/components/Timeline/duplicate-selected-timeline-item.js +39 -34
  102. package/dist/components/Timeline/get-bounded-keyframe-drag-delta.d.ts +8 -0
  103. package/dist/components/Timeline/get-bounded-keyframe-drag-delta.js +12 -0
  104. package/dist/components/Timeline/get-keyframe-navigation.d.ts +2 -2
  105. package/dist/components/Timeline/get-keyframe-navigation.js +14 -6
  106. package/dist/components/Timeline/get-node-keyframes.d.ts +3 -3
  107. package/dist/components/Timeline/get-node-keyframes.js +4 -4
  108. package/dist/components/Timeline/get-timeline-easing-segments.d.ts +9 -0
  109. package/dist/components/Timeline/get-timeline-easing-segments.js +19 -0
  110. package/dist/components/Timeline/reset-selected-timeline-props.d.ts +7 -7
  111. package/dist/components/Timeline/reset-selected-timeline-props.js +13 -12
  112. package/dist/components/Timeline/save-effect-prop.d.ts +16 -5
  113. package/dist/components/Timeline/save-effect-prop.js +37 -19
  114. package/dist/components/Timeline/save-prop-queue.d.ts +4 -3
  115. package/dist/components/Timeline/save-prop-queue.js +6 -3
  116. package/dist/components/Timeline/save-sequence-prop.d.ts +5 -10
  117. package/dist/components/Timeline/save-sequence-prop.js +35 -32
  118. package/dist/components/Timeline/should-clear-selection-on-pointer-down.d.ts +3 -0
  119. package/dist/components/Timeline/should-clear-selection-on-pointer-down.js +7 -0
  120. package/dist/components/Timeline/timeline-asset-link.d.ts +13 -0
  121. package/dist/components/Timeline/timeline-asset-link.js +37 -0
  122. package/dist/components/Timeline/timeline-field-utils.d.ts +10 -0
  123. package/dist/components/Timeline/timeline-field-utils.js +26 -5
  124. package/dist/components/Timeline/timeline-translate-utils.d.ts +1 -1
  125. package/dist/components/Timeline/timeline-translate-utils.js +6 -4
  126. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +7 -7
  127. package/dist/components/Timeline/use-sequence-props-subscription.js +3 -3
  128. package/dist/components/Timeline/use-timeline-height.js +3 -3
  129. package/dist/components/Timeline/use-timeline-keyframe-drag.d.ts +10 -0
  130. package/dist/components/Timeline/use-timeline-keyframe-drag.js +380 -0
  131. package/dist/components/import-assets.d.ts +31 -0
  132. package/dist/components/import-assets.js +216 -17
  133. package/dist/components/load-canvas-content-from-url.d.ts +1 -0
  134. package/dist/components/load-canvas-content-from-url.js +9 -3
  135. package/dist/components/use-select-asset.d.ts +1 -0
  136. package/dist/components/use-select-asset.js +30 -0
  137. package/dist/error-overlay/error-origin.d.ts +3 -0
  138. package/dist/error-overlay/error-origin.js +42 -0
  139. package/dist/error-overlay/react-overlay/listen-to-runtime-errors.js +6 -2
  140. package/dist/error-overlay/remotion-overlay/ErrorLoader.js +38 -0
  141. package/dist/error-overlay/remotion-overlay/ShortcutHint.js +1 -1
  142. package/dist/error-overlay/remotion-overlay/log-studio-error.d.ts +3 -0
  143. package/dist/error-overlay/remotion-overlay/log-studio-error.js +27 -0
  144. package/dist/esm/{chunk-48grt472.js → chunk-xjvc8qen.js} +21838 -18862
  145. package/dist/esm/internals.mjs +21838 -18862
  146. package/dist/esm/previewEntry.mjs +21127 -18127
  147. package/dist/esm/renderEntry.mjs +1 -1
  148. package/dist/helpers/get-asset-metadata.js +2 -2
  149. package/dist/helpers/get-preview-file-type.d.ts +2 -0
  150. package/dist/helpers/get-preview-file-type.js +33 -0
  151. package/dist/helpers/install-required-package.d.ts +1 -0
  152. package/dist/helpers/install-required-package.js +39 -0
  153. package/dist/helpers/remote-asset-drag.d.ts +4 -0
  154. package/dist/helpers/remote-asset-drag.js +73 -0
  155. package/dist/helpers/timeline-layout.d.ts +6 -6
  156. package/dist/helpers/timeline-layout.js +5 -5
  157. package/dist/helpers/use-asset-drag-events.d.ts +5 -2
  158. package/dist/helpers/use-asset-drag-events.js +13 -2
  159. package/dist/hot-middleware-client/client.js +6 -0
  160. package/dist/state/editor-outlines.d.ts +8 -0
  161. package/dist/state/editor-outlines.js +18 -0
  162. package/dist/state/modals.d.ts +16 -2
  163. package/package.json +10 -10
  164. package/dist/helpers/detect-file-type.d.ts +0 -69
  165. package/dist/helpers/detect-file-type.js +0 -278
@@ -8,13 +8,17 @@ const remotion_1 = require("remotion");
8
8
  const no_react_1 = require("remotion/no-react");
9
9
  const client_id_1 = require("../../helpers/client-id");
10
10
  const format_file_location_1 = require("../../helpers/format-file-location");
11
+ const install_required_package_1 = require("../../helpers/install-required-package");
11
12
  const timeline_layout_1 = require("../../helpers/timeline-layout");
12
13
  const call_api_1 = require("../call-api");
14
+ const ConfirmationDialog_1 = require("../ConfirmationDialog");
13
15
  const ContextMenu_1 = require("../ContextMenu");
14
16
  const ExpandedTracksProvider_1 = require("../ExpandedTracksProvider");
15
17
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
18
+ const use_select_asset_1 = require("../use-select-asset");
16
19
  const duplicate_selected_timeline_item_1 = require("./duplicate-selected-timeline-item");
17
20
  const save_sequence_prop_1 = require("./save-sequence-prop");
21
+ const timeline_asset_link_1 = require("./timeline-asset-link");
18
22
  const TimelineExpandArrowButton_1 = require("./TimelineExpandArrowButton");
19
23
  const TimelineExpandedSection_1 = require("./TimelineExpandedSection");
20
24
  const TimelineItemStack_1 = require("./TimelineItemStack");
@@ -37,6 +41,68 @@ const effectDropHighlight = {
37
41
  outline: '1px solid rgba(0, 155, 255, 0.75)',
38
42
  outlineOffset: -1,
39
43
  };
44
+ const SEQUENCE_REORDER_MIME_TYPE = 'application/remotion-sequence-reorder';
45
+ let currentSequenceDrag = null;
46
+ const sequenceReorderWrapper = {
47
+ position: 'relative',
48
+ };
49
+ const sequenceReorderLineBase = {
50
+ backgroundColor: '#0b84ff',
51
+ height: 2,
52
+ left: 0,
53
+ pointerEvents: 'none',
54
+ position: 'absolute',
55
+ right: 0,
56
+ zIndex: 1,
57
+ };
58
+ const sequenceReorderRejectionStyle = {
59
+ backgroundColor: 'rgba(0, 0, 0, 0.85)',
60
+ border: '1px solid rgba(255, 255, 255, 0.2)',
61
+ borderRadius: 4,
62
+ color: 'white',
63
+ fontSize: 11,
64
+ lineHeight: 1.2,
65
+ maxWidth: 260,
66
+ padding: '3px 6px',
67
+ pointerEvents: 'none',
68
+ position: 'absolute',
69
+ right: 6,
70
+ top: 2,
71
+ zIndex: 2,
72
+ };
73
+ const hasSequenceReorderDragType = (dataTransfer) => {
74
+ return Array.from(dataTransfer.types).includes(SEQUENCE_REORDER_MIME_TYPE);
75
+ };
76
+ const isSequenceReorderDrag = (dataTransfer) => {
77
+ return (currentSequenceDrag !== null || hasSequenceReorderDragType(dataTransfer));
78
+ };
79
+ const getSequenceReorderDragData = (dataTransfer) => {
80
+ if (currentSequenceDrag) {
81
+ return currentSequenceDrag;
82
+ }
83
+ const value = dataTransfer.getData(SEQUENCE_REORDER_MIME_TYPE);
84
+ if (!value) {
85
+ return null;
86
+ }
87
+ try {
88
+ const parsed = JSON.parse(value);
89
+ if (typeof parsed.nodePathKey === 'string' &&
90
+ typeof parsed.trackIndex === 'number' &&
91
+ (typeof parsed.parentId === 'string' || parsed.parentId === null) &&
92
+ typeof parsed.fileName === 'string' &&
93
+ parsed.nodePath &&
94
+ Array.isArray(parsed.nodePath.nodePath)) {
95
+ return parsed;
96
+ }
97
+ }
98
+ catch (_a) {
99
+ return null;
100
+ }
101
+ return null;
102
+ };
103
+ const getDestinationIndex = ({ fromIndex, insertionIndex, }) => {
104
+ return insertionIndex > fromIndex ? insertionIndex - 1 : insertionIndex;
105
+ };
40
106
  const hasEffectDragType = (dataTransfer) => {
41
107
  return Array.from(dataTransfer.types).some((type) => type === studio_shared_1.EFFECT_DRAG_MIME_TYPE ||
42
108
  type === 'application/json' ||
@@ -59,20 +125,22 @@ const getEffectDragData = (dataTransfer) => {
59
125
  }
60
126
  return null;
61
127
  };
62
- const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDisplayOffset }) => {
128
+ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDisplayOffset, trackIndex, }) => {
63
129
  var _a, _b;
64
- var _c;
130
+ var _c, _d;
65
131
  const nodePath = (_c = nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.sequenceSubscriptionKey) !== null && _c !== void 0 ? _c : null;
66
132
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
67
133
  const previewConnected = previewServerState.type === 'connected';
68
134
  const { getIsExpanded } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksGetterContext);
69
135
  const { toggleTrack } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksSetterContext);
70
- const { codeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeCodeValuesContext);
71
- const { setCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
72
- const { setCanvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionSetters);
136
+ const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
137
+ const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
138
+ const selectAsset = (0, use_select_asset_1.useSelectAsset)();
73
139
  const { onSelect, selectable, selected } = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
74
140
  const containsSelection = (0, TimelineSelection_1.useTimelineRowContainsSelection)(nodePathInfo);
75
141
  const [effectDropHovered, setEffectDropHovered] = (0, react_1.useState)(false);
142
+ const [sequenceDropIndicator, setSequenceDropIndicator] = (0, react_1.useState)(null);
143
+ const [sequenceDropRejection, setSequenceDropRejection] = (0, react_1.useState)(null);
76
144
  const { canOpenInEditor, openInEditor, originalLocation } = (0, use_open_sequence_in_editor_1.useOpenSequenceInEditor)(sequence);
77
145
  const fileLocation = (0, react_1.useMemo)(() => (0, format_file_location_1.formatFileLocation)({
78
146
  location: originalLocation,
@@ -92,24 +160,35 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
92
160
  };
93
161
  }, [originalLocation]);
94
162
  const canDeleteFromSource = Boolean(nodePath && (validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source));
163
+ const nodePathKey = (0, react_1.useMemo)(() => nodePath ? remotion_1.Internals.makeSequencePropsSubscriptionKey(nodePath) : null, [nodePath]);
164
+ const parentId = (_d = sequence.parent) !== null && _d !== void 0 ? _d : null;
165
+ const canReorderSequence = TimelineSelection_1.SELECTION_ENABLED &&
166
+ previewConnected &&
167
+ Boolean(nodePath && nodePathKey && (validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source)) &&
168
+ (nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.numberOfSequencesWithThisNodePath) === 1;
169
+ const canHandleSequenceDrag = TimelineSelection_1.SELECTION_ENABLED && previewConnected;
170
+ const confirm = (0, ConfirmationDialog_1.useConfirmationDialog)();
95
171
  const deleteDisabled = (0, react_1.useMemo)(() => !previewConnected || !sequence.controls || !canDeleteFromSource, [previewConnected, sequence.controls, canDeleteFromSource]);
96
172
  const duplicateDisabled = deleteDisabled;
97
173
  const onDuplicateSequenceFromSource = (0, react_1.useCallback)(() => {
98
174
  if (!(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source) || !nodePathInfo) {
99
175
  return;
100
176
  }
101
- (0, duplicate_selected_timeline_item_1.duplicateSequencesFromSource)([nodePathInfo]).catch(() => undefined);
102
- }, [nodePathInfo, validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source]);
177
+ (0, duplicate_selected_timeline_item_1.duplicateSequencesFromSource)([nodePathInfo], confirm).catch(() => undefined);
178
+ }, [confirm, nodePathInfo, validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source]);
103
179
  const onDeleteSequenceFromSource = (0, react_1.useCallback)(async () => {
104
180
  if (!(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source) || !nodePath) {
105
181
  return;
106
182
  }
107
183
  if (nodePathInfo && nodePathInfo.numberOfSequencesWithThisNodePath > 1) {
108
- const message = 'This sequence is programmatically duplicated ' +
109
- nodePathInfo.numberOfSequencesWithThisNodePath +
110
- ' times in the code. Deleting removes all instances. Continue?';
111
- // eslint-disable-next-line no-alert -- native confirm before applying duplicate codemod in .map callbacks
112
- if (!window.confirm(message)) {
184
+ const shouldDelete = await confirm({
185
+ title: 'Delete sequence?',
186
+ message: 'This sequence is programmatically duplicated ' +
187
+ nodePathInfo.numberOfSequencesWithThisNodePath +
188
+ ' times in the code. Deleting removes all instances. Continue?',
189
+ confirmLabel: 'Delete',
190
+ });
191
+ if (!shouldDelete) {
113
192
  return;
114
193
  }
115
194
  }
@@ -132,13 +211,173 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
132
211
  catch (err) {
133
212
  (0, NotificationCenter_1.showNotification)(err.message, 4000);
134
213
  }
135
- }, [nodePath, validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source, nodePathInfo]);
214
+ }, [confirm, nodePath, validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source, nodePathInfo]);
215
+ const getSequenceDropTarget = (0, react_1.useCallback)((e) => {
216
+ const dragData = getSequenceReorderDragData(e.dataTransfer);
217
+ if (!dragData) {
218
+ return null;
219
+ }
220
+ if (!nodePath || !nodePathKey || !(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source)) {
221
+ return {
222
+ type: 'invalid',
223
+ reason: 'This sequence cannot be reordered from source.',
224
+ };
225
+ }
226
+ if (dragData.nodePathKey === nodePathKey) {
227
+ return {
228
+ type: 'invalid',
229
+ reason: 'Drop onto another sequence to reorder.',
230
+ };
231
+ }
232
+ if ((nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.numberOfSequencesWithThisNodePath) !== 1) {
233
+ return {
234
+ type: 'invalid',
235
+ reason: 'Programmatically duplicated sequences cannot be reordered.',
236
+ };
237
+ }
238
+ if (dragData.parentId !== parentId ||
239
+ dragData.fileName !== validatedLocation.source) {
240
+ return {
241
+ type: 'invalid',
242
+ reason: 'Sequences can only be reordered with direct JSX siblings.',
243
+ };
244
+ }
245
+ const rect = e.currentTarget.getBoundingClientRect();
246
+ const before = e.clientY < rect.top + rect.height / 2;
247
+ const insertionIndex = before ? trackIndex : trackIndex + 1;
248
+ const toIndex = getDestinationIndex({
249
+ fromIndex: dragData.trackIndex,
250
+ insertionIndex,
251
+ });
252
+ if (toIndex === dragData.trackIndex) {
253
+ return {
254
+ type: 'invalid',
255
+ reason: 'This sequence is already in that position.',
256
+ };
257
+ }
258
+ return {
259
+ type: 'valid',
260
+ dragData,
261
+ position: before ? 'before' : 'after',
262
+ };
263
+ }, [
264
+ nodePath,
265
+ nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.numberOfSequencesWithThisNodePath,
266
+ nodePathKey,
267
+ parentId,
268
+ trackIndex,
269
+ validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source,
270
+ ]);
271
+ const onSequenceDragStart = (0, react_1.useCallback)((e) => {
272
+ if (!canReorderSequence ||
273
+ !nodePath ||
274
+ !nodePathKey ||
275
+ !(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source)) {
276
+ e.preventDefault();
277
+ return;
278
+ }
279
+ const dragData = {
280
+ nodePath,
281
+ nodePathKey,
282
+ trackIndex,
283
+ parentId,
284
+ fileName: validatedLocation.source,
285
+ };
286
+ currentSequenceDrag = dragData;
287
+ e.dataTransfer.effectAllowed = 'move';
288
+ e.dataTransfer.setData(SEQUENCE_REORDER_MIME_TYPE, JSON.stringify(dragData));
289
+ e.stopPropagation();
290
+ }, [
291
+ canReorderSequence,
292
+ nodePath,
293
+ nodePathKey,
294
+ parentId,
295
+ trackIndex,
296
+ validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source,
297
+ ]);
298
+ const onSequenceDragEnd = (0, react_1.useCallback)(() => {
299
+ currentSequenceDrag = null;
300
+ setSequenceDropIndicator(null);
301
+ setSequenceDropRejection(null);
302
+ }, []);
303
+ const onSequenceDragOver = (0, react_1.useCallback)((e) => {
304
+ if (!hasSequenceReorderDragType(e.dataTransfer)) {
305
+ return;
306
+ }
307
+ const dropTarget = getSequenceDropTarget(e);
308
+ if (!dropTarget) {
309
+ setSequenceDropIndicator(null);
310
+ setSequenceDropRejection(null);
311
+ return;
312
+ }
313
+ if (dropTarget.type === 'invalid') {
314
+ setSequenceDropIndicator(null);
315
+ setSequenceDropRejection(dropTarget.reason);
316
+ e.dataTransfer.dropEffect = 'none';
317
+ return;
318
+ }
319
+ e.preventDefault();
320
+ e.stopPropagation();
321
+ e.dataTransfer.dropEffect = 'move';
322
+ setSequenceDropIndicator(dropTarget.position);
323
+ setSequenceDropRejection(null);
324
+ }, [getSequenceDropTarget]);
325
+ const onSequenceDragLeave = (0, react_1.useCallback)((e) => {
326
+ if (e.currentTarget.contains(e.relatedTarget)) {
327
+ return;
328
+ }
329
+ setSequenceDropIndicator(null);
330
+ setSequenceDropRejection(null);
331
+ }, []);
332
+ const onSequenceDrop = (0, react_1.useCallback)(async (e) => {
333
+ if (!canReorderSequence ||
334
+ previewServerState.type !== 'connected' ||
335
+ !nodePath ||
336
+ !(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source)) {
337
+ return;
338
+ }
339
+ const dropTarget = getSequenceDropTarget(e);
340
+ if (!dropTarget || dropTarget.type === 'invalid') {
341
+ setSequenceDropIndicator(null);
342
+ setSequenceDropRejection((dropTarget === null || dropTarget === void 0 ? void 0 : dropTarget.type) === 'invalid' ? dropTarget.reason : null);
343
+ return;
344
+ }
345
+ e.preventDefault();
346
+ e.stopPropagation();
347
+ setSequenceDropIndicator(null);
348
+ setSequenceDropRejection(null);
349
+ currentSequenceDrag = null;
350
+ try {
351
+ const result = await (0, call_api_1.callApi)('/api/reorder-sequence', {
352
+ fileName: validatedLocation.source,
353
+ sourceNodePath: dropTarget.dragData.nodePath,
354
+ targetNodePath: nodePath,
355
+ position: dropTarget.position,
356
+ clientId: previewServerState.clientId,
357
+ });
358
+ if (result.success) {
359
+ (0, NotificationCenter_1.showNotification)('Reordered sequence', 2000);
360
+ }
361
+ else {
362
+ (0, NotificationCenter_1.showNotification)(result.reason, 4000);
363
+ }
364
+ }
365
+ catch (err) {
366
+ (0, NotificationCenter_1.showNotification)(err.message, 4000);
367
+ }
368
+ }, [
369
+ canReorderSequence,
370
+ getSequenceDropTarget,
371
+ nodePath,
372
+ previewServerState,
373
+ validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source,
374
+ ]);
136
375
  const mediaSrc = sequence.type === 'audio' ||
137
376
  sequence.type === 'video' ||
138
377
  sequence.type === 'image'
139
378
  ? sequence.src
140
379
  : null;
141
- const assetLinkInfo = (0, react_1.useMemo)(() => (mediaSrc ? (0, TimelineMediaInfo_1.getTimelineAssetLinkInfo)(mediaSrc) : null), [mediaSrc]);
380
+ const assetLinkInfo = (0, react_1.useMemo)(() => (mediaSrc ? (0, timeline_asset_link_1.getTimelineAssetLinkInfo)(mediaSrc) : null), [mediaSrc]);
142
381
  const contextMenuValues = (0, react_1.useMemo)(() => {
143
382
  if (!previewConnected) {
144
383
  return [];
@@ -211,7 +450,7 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
211
450
  leftItem: null,
212
451
  disabled: false,
213
452
  onClick: () => {
214
- (0, TimelineMediaInfo_1.openTimelineAssetLink)(assetLinkInfo, setCanvasContent);
453
+ (0, timeline_asset_link_1.openTimelineAssetLink)(assetLinkInfo, selectAsset);
215
454
  },
216
455
  quickSwitcherLabel: null,
217
456
  subMenu: null,
@@ -269,8 +508,8 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
269
508
  canOpenInEditor,
270
509
  openInEditor,
271
510
  previewConnected,
511
+ selectAsset,
272
512
  sequence,
273
- setCanvasContent,
274
513
  ]);
275
514
  const isExpanded = previewConnected && nodePathInfo !== null && getIsExpanded(nodePathInfo);
276
515
  const onToggleExpand = (0, react_1.useCallback)(() => {
@@ -290,26 +529,26 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
290
529
  e.stopPropagation();
291
530
  openInEditor();
292
531
  }, [canOpenInEditor, openInEditor]);
293
- const codeValuesForOverride = (0, react_1.useMemo)(() => {
532
+ const propStatusesForOverride = (0, react_1.useMemo)(() => {
294
533
  return nodePath
295
- ? remotion_1.Internals.getCodeValuesCtx(codeValues, nodePath)
534
+ ? remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePath)
296
535
  : undefined;
297
- }, [codeValues, nodePath]);
298
- const codeHiddenStatus = codeValuesForOverride === null || codeValuesForOverride === void 0 ? void 0 : codeValuesForOverride.hidden;
536
+ }, [propStatuses, nodePath]);
537
+ const codeHiddenStatus = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.hidden;
299
538
  const isItemHidden = (0, react_1.useMemo)(() => {
300
539
  var _a;
301
- const codeValue = codeHiddenStatus && codeHiddenStatus.status === 'static'
540
+ const propStatus = codeHiddenStatus && codeHiddenStatus.status === 'static'
302
541
  ? codeHiddenStatus.codeValue
303
542
  : undefined;
304
543
  const runtimeValue = (_a = sequence.controls) === null || _a === void 0 ? void 0 : _a.currentRuntimeValueDotNotation.hidden;
305
- const effective = (codeValue !== null && codeValue !== void 0 ? codeValue : runtimeValue);
544
+ const effective = (propStatus !== null && propStatus !== void 0 ? propStatus : runtimeValue);
306
545
  return effective !== null && effective !== void 0 ? effective : false;
307
546
  }, [codeHiddenStatus, (_a = sequence.controls) === null || _a === void 0 ? void 0 : _a.currentRuntimeValueDotNotation]);
308
547
  const onToggleVisibility = (0, react_1.useCallback)((type) => {
309
548
  if (!sequence.controls ||
310
549
  !nodePath ||
311
550
  !validatedLocation ||
312
- !codeValuesForOverride ||
551
+ !propStatusesForOverride ||
313
552
  !codeHiddenStatus ||
314
553
  codeHiddenStatus.status !== 'static' ||
315
554
  previewServerState.type !== 'connected') {
@@ -321,23 +560,29 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
321
560
  const defaultValue = fieldSchema && fieldSchema.type === 'boolean'
322
561
  ? JSON.stringify(fieldSchema.default)
323
562
  : null;
324
- (0, save_sequence_prop_1.saveSequenceProp)({
325
- fileName: validatedLocation.source,
326
- nodePath,
327
- fieldKey: 'hidden',
328
- value: newValue,
329
- defaultValue,
330
- schema,
331
- setCodeValues,
563
+ (0, save_sequence_prop_1.saveSequenceProps)({
564
+ changes: [
565
+ {
566
+ fileName: validatedLocation.source,
567
+ nodePath,
568
+ fieldKey: 'hidden',
569
+ value: newValue,
570
+ defaultValue,
571
+ schema,
572
+ },
573
+ ],
574
+ setPropStatuses,
332
575
  clientId: previewServerState.clientId,
576
+ undoLabel: newValue ? 'Hide sequence' : 'Show sequence',
577
+ redoLabel: newValue ? 'Hide sequence again' : 'Show sequence again',
333
578
  });
334
579
  }, [
335
580
  codeHiddenStatus,
336
- codeValuesForOverride,
581
+ propStatusesForOverride,
337
582
  nodePath,
338
583
  previewServerState,
339
584
  sequence.controls,
340
- setCodeValues,
585
+ setPropStatuses,
341
586
  validatedLocation,
342
587
  ]);
343
588
  const outerHeight = (0, react_1.useMemo)(() => (0, timeline_layout_1.getTimelineLayerHeight)(sequence.type) + timeline_layout_1.TIMELINE_ITEM_BORDER_BOTTOM, [sequence.type]);
@@ -371,8 +616,19 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
371
616
  nodePath !== null &&
372
617
  validatedLocation !== null &&
373
618
  ((_b = sequence.controls) === null || _b === void 0 ? void 0 : _b.supportsEffects) === true;
619
+ const sequenceReorderLineStyle = (0, react_1.useMemo)(() => {
620
+ if (!sequenceDropIndicator) {
621
+ return null;
622
+ }
623
+ return {
624
+ ...sequenceReorderLineBase,
625
+ ...(sequenceDropIndicator === 'before' ? { top: -1 } : { bottom: -1 }),
626
+ };
627
+ }, [sequenceDropIndicator]);
374
628
  const onEffectDragOver = (0, react_1.useCallback)((e) => {
375
- if (!canDropEffect || !hasEffectDragType(e.dataTransfer)) {
629
+ if (!canDropEffect ||
630
+ isSequenceReorderDrag(e.dataTransfer) ||
631
+ !hasEffectDragType(e.dataTransfer)) {
376
632
  return;
377
633
  }
378
634
  e.preventDefault();
@@ -389,7 +645,9 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
389
645
  if (!canDropEffect ||
390
646
  previewServerState.type !== 'connected' ||
391
647
  nodePath === null ||
392
- validatedLocation === null) {
648
+ validatedLocation === null ||
649
+ isSequenceReorderDrag(e.dataTransfer) ||
650
+ !hasEffectDragType(e.dataTransfer)) {
393
651
  return;
394
652
  }
395
653
  e.preventDefault();
@@ -401,6 +659,8 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
401
659
  return;
402
660
  }
403
661
  try {
662
+ const requiredPackage = (0, studio_shared_1.getRequiredPackageForEffectImportPath)(dragData.effect.importPath);
663
+ await (0, install_required_package_1.installRequiredPackages)(requiredPackage ? [requiredPackage] : []);
404
664
  const result = await (0, call_api_1.callApi)('/api/add-effect', {
405
665
  fileName: validatedLocation.source,
406
666
  sequenceNodePath: nodePath,
@@ -425,7 +685,8 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
425
685
  : undefined, children: jsx_runtime_1.jsxs("div", { style: labelContainerStyle, children: [
426
686
  jsx_runtime_1.jsx(TimelineSequenceName_1.TimelineSequenceName, { sequence: sequence, selected: selected, containsSelection: containsSelection }), mediaSrc ? jsx_runtime_1.jsx(TimelineMediaInfo_1.TimelineMediaInfo, { src: mediaSrc }) : null, jsx_runtime_1.jsx(TimelineItemStack_1.TimelineItemStack, { originalLocation: originalLocation })
427
687
  ] }) }));
428
- return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [previewConnected ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, onOpen: selectable ? onSelect : null, children: trackRow })) : (trackRow), previewConnected &&
688
+ const draggableTrackRow = canHandleSequenceDrag ? (jsx_runtime_1.jsxs("div", { draggable: canReorderSequence, onDragStart: onSequenceDragStart, onDragEnd: onSequenceDragEnd, onDragOver: onSequenceDragOver, onDragLeave: onSequenceDragLeave, onDrop: onSequenceDrop, style: sequenceReorderWrapper, children: [sequenceReorderLineStyle ? (jsx_runtime_1.jsx("div", { style: sequenceReorderLineStyle })) : null, sequenceDropRejection ? (jsx_runtime_1.jsx("div", { style: sequenceReorderRejectionStyle, children: sequenceDropRejection })) : null, trackRow] })) : (trackRow);
689
+ return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [previewConnected ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, onOpen: selectable ? onSelect : null, children: draggableTrackRow })) : (draggableTrackRow), previewConnected &&
429
690
  isExpanded &&
430
691
  hasExpandableContent &&
431
692
  nodePathInfo &&