@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
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TimelineClipboardKeybindings = exports.getSnapshotsFromSelection = exports.getPasteEffectsTarget = void 0;
3
+ exports.TimelineClipboardKeybindings = exports.getPasteEffectPropTarget = exports.getEffectPropClipboardDataFromSelection = exports.getSnapshotsFromSelection = exports.getPasteEffectsTarget = void 0;
4
4
  const studio_shared_1 = require("@remotion/studio-shared");
5
5
  const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
@@ -8,6 +8,8 @@ const client_id_1 = require("../../helpers/client-id");
8
8
  const use_keybinding_1 = require("../../helpers/use-keybinding");
9
9
  const call_api_1 = require("../call-api");
10
10
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
11
+ const find_track_for_node_path_info_1 = require("./find-track-for-node-path-info");
12
+ const save_effect_prop_1 = require("./save-effect-prop");
11
13
  const TimelineSelection_1 = require("./TimelineSelection");
12
14
  const makeClipboardText = (payload) => JSON.stringify(payload);
13
15
  const makeTargetKey = (nodePath) => {
@@ -17,6 +19,10 @@ const makeTargetKey = (nodePath) => {
17
19
  sequenceKeys: nodePath.sequenceKeys,
18
20
  });
19
21
  };
22
+ const isVisibleFieldSchema = (fieldSchema) => fieldSchema !== undefined && fieldSchema.type !== 'hidden';
23
+ const getDefaultValue = (fieldSchema) => fieldSchema.default !== undefined
24
+ ? JSON.stringify(fieldSchema.default)
25
+ : null;
20
26
  const getTargetSequenceNodePathInfo = (selection) => {
21
27
  if (selection.type === 'sequence' ||
22
28
  selection.type === 'sequence-effect' ||
@@ -61,35 +67,45 @@ exports.getPasteEffectsTarget = getPasteEffectsTarget;
61
67
  const isClipboardInterpolationFunction = (value) => {
62
68
  return (0, studio_shared_1.isKeyframeInterpolationFunction)(value);
63
69
  };
70
+ const effectPropStatusToClipboardParam = (prop) => {
71
+ if (prop.status === 'computed') {
72
+ return null;
73
+ }
74
+ if (prop.status === 'static') {
75
+ if (prop.codeValue === undefined) {
76
+ return null;
77
+ }
78
+ return {
79
+ type: 'static',
80
+ value: prop.codeValue,
81
+ };
82
+ }
83
+ if (!isClipboardInterpolationFunction(prop.interpolationFunction)) {
84
+ return null;
85
+ }
86
+ return {
87
+ type: 'keyframed',
88
+ interpolationFunction: prop.interpolationFunction,
89
+ keyframes: prop.keyframes,
90
+ easing: prop.easing,
91
+ clamping: prop.clamping,
92
+ ...(prop.posterize === undefined ? {} : { posterize: prop.posterize }),
93
+ };
94
+ };
64
95
  const effectStatusToSnapshot = (effect) => {
65
96
  if (effect.importPath === null) {
66
97
  return null;
67
98
  }
68
99
  const params = {};
69
100
  for (const [key, prop] of Object.entries(effect.props)) {
70
- if (prop.status === 'computed') {
71
- return null;
72
- }
73
- if (prop.status === 'static') {
74
- if (prop.codeValue !== undefined) {
75
- params[key] = {
76
- type: 'static',
77
- value: prop.codeValue,
78
- };
79
- }
101
+ if (prop.status === 'static' && prop.codeValue === undefined) {
80
102
  continue;
81
103
  }
82
- if (!isClipboardInterpolationFunction(prop.interpolationFunction)) {
104
+ const param = effectPropStatusToClipboardParam(prop);
105
+ if (param === null) {
83
106
  return null;
84
107
  }
85
- params[key] = {
86
- type: 'keyframed',
87
- interpolationFunction: prop.interpolationFunction,
88
- keyframes: prop.keyframes,
89
- easing: prop.easing,
90
- clamping: prop.clamping,
91
- ...(prop.posterize === undefined ? {} : { posterize: prop.posterize }),
92
- };
108
+ params[key] = param;
93
109
  }
94
110
  return {
95
111
  callee: effect.callee,
@@ -97,13 +113,13 @@ const effectStatusToSnapshot = (effect) => {
97
113
  params,
98
114
  };
99
115
  };
100
- const getSnapshotsFromSelection = ({ selection, codeValues, }) => {
116
+ const getSnapshotsFromSelection = ({ selection, propStatuses, }) => {
101
117
  if (selection.type !== 'sequence-effect' &&
102
118
  selection.type !== 'sequence-all-effects') {
103
119
  return null;
104
120
  }
105
121
  const { sequenceSubscriptionKey } = selection.nodePathInfo;
106
- const sequenceStatus = codeValues[remotion_1.Internals.makeSequencePropsSubscriptionKey(sequenceSubscriptionKey)];
122
+ const sequenceStatus = propStatuses[remotion_1.Internals.makeSequencePropsSubscriptionKey(sequenceSubscriptionKey)];
107
123
  if (!sequenceStatus || !sequenceStatus.canUpdate) {
108
124
  return null;
109
125
  }
@@ -127,12 +143,121 @@ const getSnapshotsFromSelection = ({ selection, codeValues, }) => {
127
143
  return snapshots;
128
144
  };
129
145
  exports.getSnapshotsFromSelection = getSnapshotsFromSelection;
146
+ const getEffectPropClipboardDataFromSelection = ({ selection, propStatuses, }) => {
147
+ if (selection.type !== 'sequence-effect-prop') {
148
+ return null;
149
+ }
150
+ const sequenceStatus = propStatuses[remotion_1.Internals.makeSequencePropsSubscriptionKey(selection.nodePathInfo.sequenceSubscriptionKey)];
151
+ if (!sequenceStatus || !sequenceStatus.canUpdate) {
152
+ return null;
153
+ }
154
+ const effect = sequenceStatus.effects.find((item) => item.effectIndex === selection.i);
155
+ if (!(effect === null || effect === void 0 ? void 0 : effect.canUpdate) || effect.importPath === null) {
156
+ return null;
157
+ }
158
+ const prop = effect.props[selection.key];
159
+ if (!prop) {
160
+ return null;
161
+ }
162
+ const param = effectPropStatusToClipboardParam(prop);
163
+ if (param === null) {
164
+ return null;
165
+ }
166
+ return {
167
+ type: 'effect-prop',
168
+ version: 1,
169
+ remotionClipboard: 'effect-prop',
170
+ effect: {
171
+ callee: effect.callee,
172
+ importPath: effect.importPath,
173
+ },
174
+ key: selection.key,
175
+ param,
176
+ };
177
+ };
178
+ exports.getEffectPropClipboardDataFromSelection = getEffectPropClipboardDataFromSelection;
179
+ const getPasteEffectPropTarget = ({ selectedItems, payload, propStatuses, sequences, overrideIdsToNodePaths, }) => {
180
+ var _a;
181
+ if (selectedItems.length === 0) {
182
+ return { type: 'none' };
183
+ }
184
+ if (selectedItems.length !== 1) {
185
+ return { type: 'multiple' };
186
+ }
187
+ const [selection] = selectedItems;
188
+ if (!selection) {
189
+ return { type: 'none' };
190
+ }
191
+ if (!selection.nodePathInfo.supportsEffects) {
192
+ return { type: 'unsupported' };
193
+ }
194
+ const target = selection.type === 'sequence-effect-prop'
195
+ ? {
196
+ effectIndex: selection.i,
197
+ fieldKey: selection.key,
198
+ }
199
+ : selection.type === 'sequence-effect'
200
+ ? {
201
+ effectIndex: selection.i,
202
+ fieldKey: payload.key,
203
+ }
204
+ : null;
205
+ if (target === null) {
206
+ return { type: 'none' };
207
+ }
208
+ if (selection.type === 'sequence-effect-prop' &&
209
+ selection.key !== payload.key) {
210
+ return { type: 'prop-mismatch' };
211
+ }
212
+ const track = (0, find_track_for_node_path_info_1.findTrackForNodePathInfo)({
213
+ sequences,
214
+ overrideIdsToNodePaths,
215
+ nodePathInfo: selection.nodePathInfo,
216
+ });
217
+ const sequence = (_a = track === null || track === void 0 ? void 0 : track.sequence) !== null && _a !== void 0 ? _a : null;
218
+ if (!sequence) {
219
+ return { type: 'none' };
220
+ }
221
+ const effect = sequence.effects[target.effectIndex];
222
+ const fieldSchema = effect === null || effect === void 0 ? void 0 : effect.schema[target.fieldKey];
223
+ if (!effect || !isVisibleFieldSchema(fieldSchema)) {
224
+ return { type: 'prop-mismatch' };
225
+ }
226
+ const sequenceStatus = propStatuses[remotion_1.Internals.makeSequencePropsSubscriptionKey(selection.nodePathInfo.sequenceSubscriptionKey)];
227
+ if (!(sequenceStatus === null || sequenceStatus === void 0 ? void 0 : sequenceStatus.canUpdate)) {
228
+ return { type: 'uncopyable' };
229
+ }
230
+ const effectStatus = sequenceStatus.effects.find((item) => item.effectIndex === target.effectIndex);
231
+ if (!(effectStatus === null || effectStatus === void 0 ? void 0 : effectStatus.canUpdate)) {
232
+ return { type: 'uncopyable' };
233
+ }
234
+ if (effectStatus.importPath !== payload.effect.importPath) {
235
+ return { type: 'effect-type-mismatch' };
236
+ }
237
+ const propStatus = effectStatus.props[target.fieldKey];
238
+ if (!propStatus || propStatus.status === 'computed') {
239
+ return { type: 'uncopyable' };
240
+ }
241
+ return {
242
+ type: 'valid',
243
+ fileName: selection.nodePathInfo.sequenceSubscriptionKey.absolutePath,
244
+ nodePath: selection.nodePathInfo.sequenceSubscriptionKey,
245
+ effectIndex: target.effectIndex,
246
+ fieldKey: target.fieldKey,
247
+ defaultValue: getDefaultValue(fieldSchema),
248
+ schema: effect.schema,
249
+ };
250
+ };
251
+ exports.getPasteEffectPropTarget = getPasteEffectPropTarget;
130
252
  const TimelineClipboardKeybindings = () => {
131
253
  const keybindings = (0, use_keybinding_1.useKeybinding)();
132
254
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
133
255
  const { canSelect } = (0, TimelineSelection_1.useTimelineSelection)();
134
256
  const currentSelection = (0, TimelineSelection_1.useCurrentTimelineSelectionStateAsRef)();
135
- const { codeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeCodeValuesContext);
257
+ const propStatusesRef = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesRefContext);
258
+ const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
259
+ const sequencesRef = (0, react_1.useContext)(remotion_1.Internals.SequenceManagerRefContext);
260
+ const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
136
261
  (0, react_1.useEffect)(() => {
137
262
  if (!canSelect || previewServerState.type !== 'connected') {
138
263
  return;
@@ -142,10 +267,37 @@ const TimelineClipboardKeybindings = () => {
142
267
  event: 'keydown',
143
268
  key: 'c',
144
269
  callback: (e) => {
270
+ var _a;
145
271
  const { selectedItems } = currentSelection.current;
272
+ const propStatuses = propStatusesRef.current;
146
273
  if (selectedItems.length === 0) {
147
274
  return;
148
275
  }
276
+ if (selectedItems.some((selection) => selection.type === 'sequence-effect-prop')) {
277
+ e.preventDefault();
278
+ if (selectedItems.length !== 1 ||
279
+ ((_a = selectedItems[0]) === null || _a === void 0 ? void 0 : _a.type) !== 'sequence-effect-prop') {
280
+ (0, NotificationCenter_1.showNotification)('Select one effect prop to copy its value', 3000);
281
+ return;
282
+ }
283
+ const payload = (0, exports.getEffectPropClipboardDataFromSelection)({
284
+ selection: selectedItems[0],
285
+ propStatuses,
286
+ });
287
+ if (payload === null) {
288
+ (0, NotificationCenter_1.showNotification)('Cannot copy effect prop because its value cannot be copied', 3000);
289
+ return;
290
+ }
291
+ navigator.clipboard
292
+ .writeText(makeClipboardText(payload))
293
+ .then(() => {
294
+ (0, NotificationCenter_1.showNotification)('Copied effect prop to clipboard', 1000);
295
+ })
296
+ .catch((err) => {
297
+ (0, NotificationCenter_1.showNotification)(`Could not copy effect prop: ${err.message}`, 2000);
298
+ });
299
+ return;
300
+ }
149
301
  const firstSelection = selectedItems[0];
150
302
  const type = firstSelection ? getCopyType(firstSelection) : null;
151
303
  if (type === null) {
@@ -159,7 +311,7 @@ const TimelineClipboardKeybindings = () => {
159
311
  const snapshots = selectedItems.flatMap((selection) => {
160
312
  const itemSnapshots = (0, exports.getSnapshotsFromSelection)({
161
313
  selection,
162
- codeValues,
314
+ propStatuses,
163
315
  });
164
316
  return itemSnapshots !== null && itemSnapshots !== void 0 ? itemSnapshots : [null];
165
317
  });
@@ -201,6 +353,68 @@ const TimelineClipboardKeybindings = () => {
201
353
  navigator.clipboard
202
354
  .readText()
203
355
  .then((text) => {
356
+ const propStatuses = propStatusesRef.current;
357
+ const sequences = sequencesRef.current;
358
+ const effectPropResult = (0, studio_shared_1.parseEffectPropClipboardDataResult)(text);
359
+ if (effectPropResult.status !== 'invalid') {
360
+ e.preventDefault();
361
+ if (effectPropResult.status === 'unsupported-version') {
362
+ (0, NotificationCenter_1.showNotification)('Cannot paste effect prop copied from a different Remotion Studio version', 4000);
363
+ return;
364
+ }
365
+ const effectPropTarget = (0, exports.getPasteEffectPropTarget)({
366
+ selectedItems,
367
+ payload: effectPropResult.data,
368
+ propStatuses,
369
+ sequences,
370
+ overrideIdsToNodePaths: overrideIdToNodePathMappings,
371
+ });
372
+ if (effectPropTarget.type !== 'valid') {
373
+ switch (effectPropTarget.type) {
374
+ case 'multiple':
375
+ (0, NotificationCenter_1.showNotification)('Select one target effect prop or effect to paste onto', 3000);
376
+ return;
377
+ case 'none':
378
+ (0, NotificationCenter_1.showNotification)('Select a matching effect prop or effect to paste onto', 3000);
379
+ return;
380
+ case 'unsupported':
381
+ (0, NotificationCenter_1.showNotification)('This sequence does not support effects', 3000);
382
+ return;
383
+ case 'effect-type-mismatch':
384
+ (0, NotificationCenter_1.showNotification)('Select an effect of the same type to paste this prop', 3000);
385
+ return;
386
+ case 'prop-mismatch':
387
+ (0, NotificationCenter_1.showNotification)('Select the same effect prop, or an effect with that prop', 3000);
388
+ return;
389
+ case 'uncopyable':
390
+ (0, NotificationCenter_1.showNotification)('Cannot paste onto an effect prop that cannot be updated', 3000);
391
+ return;
392
+ default:
393
+ throw new Error(`Unexpected paste target: ${effectPropTarget}`);
394
+ }
395
+ }
396
+ return (0, save_effect_prop_1.saveEffectProp)({
397
+ fileName: effectPropTarget.fileName,
398
+ nodePath: effectPropTarget.nodePath,
399
+ effectIndex: effectPropTarget.effectIndex,
400
+ fieldKey: effectPropTarget.fieldKey,
401
+ ...(effectPropResult.data.param.type === 'static'
402
+ ? {
403
+ type: 'value',
404
+ value: effectPropResult.data.param.value,
405
+ }
406
+ : {
407
+ type: 'effect-param',
408
+ effectParam: effectPropResult.data.param,
409
+ }),
410
+ defaultValue: effectPropTarget.defaultValue,
411
+ schema: effectPropTarget.schema,
412
+ setPropStatuses,
413
+ clientId,
414
+ }).then(() => {
415
+ (0, NotificationCenter_1.showNotification)('Pasted effect prop', 2000);
416
+ });
417
+ }
204
418
  const result = (0, studio_shared_1.parseEffectClipboardDataResult)(text);
205
419
  if (result.status === 'invalid') {
206
420
  return;
@@ -255,10 +469,13 @@ const TimelineClipboardKeybindings = () => {
255
469
  };
256
470
  }, [
257
471
  canSelect,
258
- codeValues,
259
472
  currentSelection,
260
473
  keybindings,
474
+ overrideIdToNodePathMappings,
475
+ propStatusesRef,
261
476
  previewServerState,
477
+ sequencesRef,
478
+ setPropStatuses,
262
479
  ]);
263
480
  return null;
264
481
  };
@@ -5,6 +5,7 @@ const react_1 = require("react");
5
5
  const remotion_1 = require("remotion");
6
6
  const client_id_1 = require("../../helpers/client-id");
7
7
  const use_keybinding_1 = require("../../helpers/use-keybinding");
8
+ const ConfirmationDialog_1 = require("../ConfirmationDialog");
8
9
  const delete_selected_timeline_item_1 = require("./delete-selected-timeline-item");
9
10
  const duplicate_selected_timeline_item_1 = require("./duplicate-selected-timeline-item");
10
11
  const reset_selected_timeline_props_1 = require("./reset-selected-timeline-props");
@@ -12,12 +13,13 @@ const TimelineSelection_1 = require("./TimelineSelection");
12
13
  const TimelineDeleteKeybindings = () => {
13
14
  const keybindings = (0, use_keybinding_1.useKeybinding)();
14
15
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
15
- const { sequences } = (0, react_1.useContext)(remotion_1.Internals.SequenceManager);
16
+ const sequencesRef = (0, react_1.useContext)(remotion_1.Internals.SequenceManagerRefContext);
16
17
  const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
17
- const { codeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeCodeValuesContext);
18
- const { setCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
18
+ const propStatusesRef = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesRefContext);
19
+ const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
19
20
  const { canSelect } = (0, TimelineSelection_1.useTimelineSelection)();
20
21
  const currentSelection = (0, TimelineSelection_1.useCurrentTimelineSelectionStateAsRef)();
22
+ const confirm = (0, ConfirmationDialog_1.useConfirmationDialog)();
21
23
  (0, react_1.useEffect)(() => {
22
24
  if (!canSelect || previewServerState.type !== 'connected') {
23
25
  return;
@@ -28,6 +30,8 @@ const TimelineDeleteKeybindings = () => {
28
30
  key: 'Backspace',
29
31
  callback: () => {
30
32
  const { selectedItems, clearSelection } = currentSelection.current;
33
+ const sequences = sequencesRef.current;
34
+ const propStatuses = propStatusesRef.current;
31
35
  if (selectedItems.length === 0) {
32
36
  return;
33
37
  }
@@ -35,8 +39,8 @@ const TimelineDeleteKeybindings = () => {
35
39
  selections: selectedItems,
36
40
  sequences,
37
41
  overrideIdsToNodePaths: overrideIdToNodePathMappings,
38
- codeValues,
39
- setCodeValues,
42
+ propStatuses,
43
+ setPropStatuses,
40
44
  clientId,
41
45
  });
42
46
  if (resetPromise !== null) {
@@ -47,14 +51,20 @@ const TimelineDeleteKeybindings = () => {
47
51
  selections: selectedItems,
48
52
  sequences,
49
53
  overrideIdsToNodePaths: overrideIdToNodePathMappings,
50
- setCodeValues,
54
+ setPropStatuses,
51
55
  clientId,
56
+ confirm,
52
57
  });
53
58
  if (deletePromise === null) {
54
59
  return;
55
60
  }
56
- clearSelection();
57
- deletePromise.catch(() => undefined);
61
+ deletePromise
62
+ .then((deleted) => {
63
+ if (deleted) {
64
+ clearSelection();
65
+ }
66
+ })
67
+ .catch(() => undefined);
58
68
  },
59
69
  commandCtrlKey: false,
60
70
  preventDefault: true,
@@ -71,6 +81,7 @@ const TimelineDeleteKeybindings = () => {
71
81
  }
72
82
  const duplicatePromise = (0, duplicate_selected_timeline_item_1.duplicateSelectedTimelineItems)({
73
83
  selections: selectedItems,
84
+ confirm,
74
85
  });
75
86
  if (duplicatePromise === null) {
76
87
  return;
@@ -88,13 +99,14 @@ const TimelineDeleteKeybindings = () => {
88
99
  };
89
100
  }, [
90
101
  canSelect,
91
- codeValues,
102
+ confirm,
92
103
  currentSelection,
93
104
  keybindings,
94
105
  overrideIdToNodePathMappings,
106
+ propStatusesRef,
95
107
  previewServerState,
96
- sequences,
97
- setCodeValues,
108
+ sequencesRef,
109
+ setPropStatuses,
98
110
  ]);
99
111
  return null;
100
112
  };
@@ -68,15 +68,15 @@ const TimelineEffectItem = ({ label, nodePathInfo, effectIndex, effectSchema, do
68
68
  var _b;
69
69
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
70
70
  const previewConnected = previewServerState.type === 'connected';
71
- const { codeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeCodeValuesContext);
72
- const { setCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
71
+ const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
72
+ const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
73
73
  const selection = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
74
74
  const [dropIndicator, setDropIndicator] = (0, react_1.useState)(null);
75
- const effectStatus = (0, react_1.useMemo)(() => remotion_1.Internals.getEffectCodeValuesCtx({
76
- codeValues,
75
+ const effectStatus = (0, react_1.useMemo)(() => remotion_1.Internals.getEffectPropStatusesCtx({
76
+ propStatuses,
77
77
  nodePath,
78
78
  effectIndex,
79
- }), [codeValues, nodePath, effectIndex]);
79
+ }), [propStatuses, nodePath, effectIndex]);
80
80
  const disabledStatus = effectStatus.type === 'can-update-effect'
81
81
  ? ((_b = (_a = effectStatus.props) === null || _a === void 0 ? void 0 : _a.disabled) !== null && _b !== void 0 ? _b : null)
82
82
  : null;
@@ -178,6 +178,7 @@ const TimelineEffectItem = ({ label, nodePathInfo, effectIndex, effectSchema, do
178
178
  ? JSON.stringify(fieldSchema.default)
179
179
  : null;
180
180
  (0, save_effect_prop_1.saveEffectProp)({
181
+ type: 'value',
181
182
  fileName: validatedLocation.source,
182
183
  nodePath,
183
184
  effectIndex,
@@ -185,7 +186,7 @@ const TimelineEffectItem = ({ label, nodePathInfo, effectIndex, effectSchema, do
185
186
  value: newValue,
186
187
  defaultValue,
187
188
  schema: effectSchema,
188
- setCodeValues,
189
+ setPropStatuses,
189
190
  clientId: previewServerState.clientId,
190
191
  });
191
192
  }, [
@@ -194,7 +195,7 @@ const TimelineEffectItem = ({ label, nodePathInfo, effectIndex, effectSchema, do
194
195
  effectSchema,
195
196
  nodePath,
196
197
  previewServerState,
197
- setCodeValues,
198
+ setPropStatuses,
198
199
  validatedLocation.source,
199
200
  ]);
200
201
  const isExpanded = getIsExpanded(nodePathInfo);