@remotion/studio 4.0.469 → 4.0.471

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 (101) hide show
  1. package/dist/Studio.js +1 -1
  2. package/dist/api/save-render-output.js +3 -12
  3. package/dist/components/AudioWaveform.js +19 -2
  4. package/dist/components/ContextMenu.d.ts +7 -2
  5. package/dist/components/ContextMenu.js +53 -9
  6. package/dist/components/EditorContent.js +5 -4
  7. package/dist/components/Menu/MenuItem.d.ts +1 -1
  8. package/dist/components/MenuBuildIndicator.js +0 -1
  9. package/dist/components/NewComposition/InputDragger.js +1 -0
  10. package/dist/components/Preview.js +6 -2
  11. package/dist/components/SelectedOutlineOverlay.d.ts +49 -0
  12. package/dist/components/SelectedOutlineOverlay.js +710 -0
  13. package/dist/components/Timeline/Timeline.js +102 -13
  14. package/dist/components/Timeline/TimelineDeleteKeybindings.d.ts +2 -0
  15. package/dist/components/Timeline/TimelineDeleteKeybindings.js +101 -0
  16. package/dist/components/Timeline/TimelineDragHandler.js +20 -244
  17. package/dist/components/Timeline/{TimelineEffectGroupRow.d.ts → TimelineEffectItem.d.ts} +1 -1
  18. package/dist/components/Timeline/TimelineEffectItem.js +323 -0
  19. package/dist/components/Timeline/{TimelineEffectFieldRow.d.ts → TimelineEffectPropItem.d.ts} +2 -1
  20. package/dist/components/Timeline/{TimelineEffectFieldRow.js → TimelineEffectPropItem.js} +97 -8
  21. package/dist/components/Timeline/TimelineExpandArrowButton.js +5 -1
  22. package/dist/components/Timeline/TimelineExpandedKeyframeRow.js +37 -5
  23. package/dist/components/Timeline/TimelineExpandedRow.d.ts +1 -0
  24. package/dist/components/Timeline/TimelineExpandedRow.js +9 -7
  25. package/dist/components/Timeline/TimelineExpandedSection.d.ts +1 -0
  26. package/dist/components/Timeline/TimelineExpandedSection.js +2 -2
  27. package/dist/components/Timeline/TimelineInOutDragHandler.d.ts +2 -0
  28. package/dist/components/Timeline/TimelineInOutDragHandler.js +324 -0
  29. package/dist/components/Timeline/TimelineInOutPointer.js +3 -1
  30. package/dist/components/Timeline/TimelineInOutPointerHandle.d.ts +1 -0
  31. package/dist/components/Timeline/TimelineInOutPointerHandle.js +5 -4
  32. package/dist/components/Timeline/TimelineKeyframeControls.d.ts +17 -0
  33. package/dist/components/Timeline/TimelineKeyframeControls.js +222 -0
  34. package/dist/components/Timeline/TimelineKeyframeDiamond.js +7 -6
  35. package/dist/components/Timeline/TimelineKeyframedValue.d.ts +8 -0
  36. package/dist/components/Timeline/TimelineKeyframedValue.js +36 -0
  37. package/dist/components/Timeline/TimelineList.js +3 -15
  38. package/dist/components/Timeline/TimelineRowChrome.d.ts +6 -1
  39. package/dist/components/Timeline/TimelineRowChrome.js +25 -7
  40. package/dist/components/Timeline/TimelineSelection.d.ts +53 -9
  41. package/dist/components/Timeline/TimelineSelection.js +305 -48
  42. package/dist/components/Timeline/TimelineSequence.d.ts +2 -0
  43. package/dist/components/Timeline/TimelineSequence.js +18 -6
  44. package/dist/components/Timeline/TimelineSequenceFrame.js +1 -0
  45. package/dist/components/Timeline/{TimelineListItem.d.ts → TimelineSequenceItem.d.ts} +2 -1
  46. package/dist/components/Timeline/{TimelineListItem.js → TimelineSequenceItem.js} +140 -34
  47. package/dist/components/Timeline/{TimelineFieldRow.d.ts → TimelineSequencePropItem.d.ts} +2 -1
  48. package/dist/components/Timeline/{TimelineFieldRow.js → TimelineSequencePropItem.js} +81 -5
  49. package/dist/components/Timeline/TimelineTimeIndicators.js +0 -1
  50. package/dist/components/Timeline/TimelineTrack.js +3 -1
  51. package/dist/components/Timeline/TimelineTranslateField.js +14 -22
  52. package/dist/components/Timeline/call-add-keyframe.d.ts +23 -0
  53. package/dist/components/Timeline/call-add-keyframe.js +54 -0
  54. package/dist/components/Timeline/call-delete-keyframe.d.ts +37 -0
  55. package/dist/components/Timeline/call-delete-keyframe.js +122 -0
  56. package/dist/components/Timeline/delete-selected-keyframe.d.ts +21 -0
  57. package/dist/components/Timeline/delete-selected-keyframe.js +92 -0
  58. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +17 -0
  59. package/dist/components/Timeline/delete-selected-timeline-item.js +178 -0
  60. package/dist/components/Timeline/duplicate-selected-timeline-item.d.ts +13 -0
  61. package/dist/components/Timeline/duplicate-selected-timeline-item.js +66 -0
  62. package/dist/components/Timeline/find-track-for-node-path-info.d.ts +7 -0
  63. package/dist/components/Timeline/find-track-for-node-path-info.js +13 -0
  64. package/dist/components/Timeline/get-keyframe-navigation.d.ts +9 -0
  65. package/dist/components/Timeline/get-keyframe-navigation.js +26 -0
  66. package/dist/components/Timeline/parse-keyframe-field-from-node-path.d.ts +8 -0
  67. package/dist/components/Timeline/parse-keyframe-field-from-node-path.js +26 -0
  68. package/dist/components/Timeline/reset-selected-timeline-props.d.ts +38 -0
  69. package/dist/components/Timeline/reset-selected-timeline-props.js +143 -0
  70. package/dist/components/Timeline/save-sequence-prop.d.ts +14 -2
  71. package/dist/components/Timeline/save-sequence-prop.js +42 -7
  72. package/dist/components/Timeline/sequence-props-subscription-store.d.ts +3 -2
  73. package/dist/components/Timeline/sequence-props-subscription-store.js +2 -1
  74. package/dist/components/Timeline/timeline-row-layout.d.ts +1 -0
  75. package/dist/components/Timeline/timeline-row-layout.js +2 -1
  76. package/dist/components/Timeline/timeline-scroll-logic.js +3 -3
  77. package/dist/components/Timeline/timeline-translate-utils.d.ts +2 -0
  78. package/dist/components/Timeline/timeline-translate-utils.js +20 -0
  79. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +10 -3
  80. package/dist/components/Timeline/use-sequence-props-subscription.js +2 -1
  81. package/dist/components/composition-menu-items.js +32 -1
  82. package/dist/error-overlay/remotion-overlay/OpenInEditor.js +0 -1
  83. package/dist/esm/{chunk-1mp51e0w.js → chunk-z0z9d4r0.js} +10422 -5958
  84. package/dist/esm/internals.mjs +10422 -5958
  85. package/dist/esm/previewEntry.mjs +10419 -5953
  86. package/dist/esm/renderEntry.mjs +3 -1
  87. package/dist/helpers/format-file-location.d.ts +9 -0
  88. package/dist/helpers/format-file-location.js +27 -0
  89. package/dist/helpers/get-box-quads-polyfill-internals.d.ts +82 -0
  90. package/dist/helpers/get-box-quads-polyfill-internals.js +2395 -0
  91. package/dist/helpers/get-box-quads-ponyfill.d.ts +10 -0
  92. package/dist/helpers/get-box-quads-ponyfill.js +23 -0
  93. package/dist/helpers/get-left-of-timeline-slider.js +1 -1
  94. package/dist/helpers/get-timeline-sequence-layout.js +10 -11
  95. package/dist/helpers/open-in-editor.d.ts +20 -2
  96. package/dist/helpers/open-in-editor.js +53 -30
  97. package/dist/helpers/use-menu-structure.js +8 -17
  98. package/dist/renderEntry.js +2 -2
  99. package/dist/state/z-index.js +5 -2
  100. package/package.json +10 -10
  101. package/dist/components/Timeline/TimelineEffectGroupRow.js +0 -153
@@ -0,0 +1,323 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TimelineEffectItem = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const remotion_1 = require("remotion");
7
+ const client_id_1 = require("../../helpers/client-id");
8
+ const timeline_layout_1 = require("../../helpers/timeline-layout");
9
+ const call_api_1 = require("../call-api");
10
+ const ContextMenu_1 = require("../ContextMenu");
11
+ const NotificationCenter_1 = require("../Notifications/NotificationCenter");
12
+ const save_effect_prop_1 = require("./save-effect-prop");
13
+ const TimelineExpandArrowButton_1 = require("./TimelineExpandArrowButton");
14
+ const TimelineLayerEye_1 = require("./TimelineLayerEye");
15
+ const TimelineRowChrome_1 = require("./TimelineRowChrome");
16
+ const TimelineSelection_1 = require("./TimelineSelection");
17
+ const EFFECT_REORDER_MIME_TYPE = 'application/remotion-effect-reorder';
18
+ let currentEffectDrag = null;
19
+ const rowLabel = {
20
+ fontSize: 12,
21
+ color: 'rgba(255, 255, 255, 0.8)',
22
+ userSelect: 'none',
23
+ };
24
+ const rowStyle = {
25
+ height: timeline_layout_1.TREE_GROUP_ROW_HEIGHT,
26
+ cursor: 'default',
27
+ };
28
+ const reorderWrapper = {
29
+ position: 'relative',
30
+ };
31
+ const reorderLineBase = {
32
+ backgroundColor: '#0b84ff',
33
+ height: 2,
34
+ left: 0,
35
+ pointerEvents: 'none',
36
+ position: 'absolute',
37
+ right: 0,
38
+ zIndex: 1,
39
+ };
40
+ const hasEffectReorderDragType = (dataTransfer) => {
41
+ return Array.from(dataTransfer.types).includes(EFFECT_REORDER_MIME_TYPE);
42
+ };
43
+ const getEffectReorderDragData = (dataTransfer) => {
44
+ if (currentEffectDrag) {
45
+ return currentEffectDrag;
46
+ }
47
+ const value = dataTransfer.getData(EFFECT_REORDER_MIME_TYPE);
48
+ if (!value) {
49
+ return null;
50
+ }
51
+ try {
52
+ const parsed = JSON.parse(value);
53
+ if (typeof parsed.nodePathKey === 'string' &&
54
+ typeof parsed.effectIndex === 'number') {
55
+ return parsed;
56
+ }
57
+ }
58
+ catch (_a) {
59
+ return null;
60
+ }
61
+ return null;
62
+ };
63
+ const getDestinationIndex = ({ fromIndex, insertionIndex, }) => {
64
+ return insertionIndex > fromIndex ? insertionIndex - 1 : insertionIndex;
65
+ };
66
+ const TimelineEffectItem = ({ label, nodePathInfo, effectIndex, effectSchema, documentationLink, nodePath, validatedLocation, rowDepth, getIsExpanded, toggleTrack, }) => {
67
+ var _a;
68
+ var _b;
69
+ const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
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);
73
+ const selection = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
74
+ const [dropIndicator, setDropIndicator] = (0, react_1.useState)(null);
75
+ const effectStatus = (0, react_1.useMemo)(() => remotion_1.Internals.getEffectCodeValuesCtx({
76
+ codeValues,
77
+ nodePath,
78
+ effectIndex,
79
+ }), [codeValues, nodePath, effectIndex]);
80
+ const disabledStatus = effectStatus.type === 'can-update-effect'
81
+ ? ((_b = (_a = effectStatus.props) === null || _a === void 0 ? void 0 : _a.disabled) !== null && _b !== void 0 ? _b : null)
82
+ : null;
83
+ const isDisabled = (0, react_1.useMemo)(() => {
84
+ if (disabledStatus && disabledStatus.canUpdate) {
85
+ return Boolean(disabledStatus.codeValue);
86
+ }
87
+ return false;
88
+ }, [disabledStatus]);
89
+ const canToggle = previewConnected && disabledStatus !== null && disabledStatus.canUpdate;
90
+ const deleteDisabled = !previewConnected ||
91
+ effectStatus.type !== 'can-update-effect' ||
92
+ !validatedLocation.source;
93
+ const canReorder = TimelineSelection_1.SELECTION_ENABLED &&
94
+ previewConnected &&
95
+ effectStatus.type === 'can-update-effect' &&
96
+ Boolean(validatedLocation.source);
97
+ const nodePathKey = (0, react_1.useMemo)(() => remotion_1.Internals.makeSequencePropsSubscriptionKey(nodePath), [nodePath]);
98
+ const onDeleteEffectFromSource = (0, react_1.useCallback)(async () => {
99
+ if (deleteDisabled) {
100
+ return;
101
+ }
102
+ try {
103
+ const result = await (0, call_api_1.callApi)('/api/delete-effect', [
104
+ {
105
+ type: 'single-effect',
106
+ fileName: validatedLocation.source,
107
+ sequenceNodePath: nodePath,
108
+ effectIndex,
109
+ },
110
+ ]);
111
+ if (result.success) {
112
+ (0, NotificationCenter_1.showNotification)('Removed effect from source file', 2000);
113
+ }
114
+ else {
115
+ (0, NotificationCenter_1.showNotification)(result.reason, 4000);
116
+ }
117
+ }
118
+ catch (err) {
119
+ (0, NotificationCenter_1.showNotification)(err.message, 4000);
120
+ }
121
+ }, [deleteDisabled, effectIndex, nodePath, validatedLocation.source]);
122
+ const contextMenuValues = (0, react_1.useMemo)(() => {
123
+ if (!previewConnected) {
124
+ return [];
125
+ }
126
+ const items = [];
127
+ if (documentationLink) {
128
+ items.push({
129
+ type: 'item',
130
+ id: 'open-effect-docs',
131
+ keyHint: null,
132
+ label: 'Open effect docs',
133
+ leftItem: null,
134
+ disabled: false,
135
+ onClick: () => {
136
+ window.open(documentationLink, '_blank', 'noopener,noreferrer');
137
+ },
138
+ quickSwitcherLabel: null,
139
+ subMenu: null,
140
+ value: 'open-effect-docs',
141
+ });
142
+ items.push({
143
+ type: 'divider',
144
+ id: 'open-effect-docs-divider',
145
+ });
146
+ }
147
+ items.push({
148
+ type: 'item',
149
+ id: 'delete-effect',
150
+ keyHint: null,
151
+ label: 'Delete',
152
+ leftItem: null,
153
+ disabled: deleteDisabled,
154
+ onClick: () => {
155
+ if (deleteDisabled) {
156
+ return;
157
+ }
158
+ onDeleteEffectFromSource();
159
+ },
160
+ quickSwitcherLabel: null,
161
+ subMenu: null,
162
+ value: 'delete-effect',
163
+ });
164
+ return items;
165
+ }, [
166
+ deleteDisabled,
167
+ documentationLink,
168
+ onDeleteEffectFromSource,
169
+ previewConnected,
170
+ ]);
171
+ const onToggle = (0, react_1.useCallback)((type) => {
172
+ if (!canToggle || previewServerState.type !== 'connected') {
173
+ return;
174
+ }
175
+ const newValue = type !== 'enable';
176
+ const fieldSchema = effectSchema.disabled;
177
+ const defaultValue = fieldSchema && fieldSchema.type === 'boolean'
178
+ ? JSON.stringify(fieldSchema.default)
179
+ : null;
180
+ (0, save_effect_prop_1.saveEffectProp)({
181
+ fileName: validatedLocation.source,
182
+ nodePath,
183
+ effectIndex,
184
+ fieldKey: 'disabled',
185
+ value: newValue,
186
+ defaultValue,
187
+ schema: effectSchema,
188
+ setCodeValues,
189
+ clientId: previewServerState.clientId,
190
+ });
191
+ }, [
192
+ canToggle,
193
+ effectIndex,
194
+ effectSchema,
195
+ nodePath,
196
+ previewServerState,
197
+ setCodeValues,
198
+ validatedLocation.source,
199
+ ]);
200
+ const isExpanded = getIsExpanded(nodePathInfo);
201
+ const labelStyle = (0, react_1.useMemo)(() => {
202
+ return {
203
+ ...rowLabel,
204
+ ...(0, TimelineSelection_1.getTimelineSelectedLabelStyle)(selection.selected, true),
205
+ alignSelf: 'stretch',
206
+ alignItems: 'center',
207
+ color: (0, TimelineSelection_1.getTimelineColor)(selection.selected, true),
208
+ display: 'flex',
209
+ flex: 1,
210
+ minWidth: 0,
211
+ paddingRight: timeline_layout_1.EXPANDED_SECTION_PADDING_RIGHT,
212
+ };
213
+ }, [selection.selected]);
214
+ const getDropTarget = (0, react_1.useCallback)((e) => {
215
+ const dragData = getEffectReorderDragData(e.dataTransfer);
216
+ if (!dragData || dragData.nodePathKey !== nodePathKey) {
217
+ return null;
218
+ }
219
+ const rect = e.currentTarget.getBoundingClientRect();
220
+ const before = e.clientY < rect.top + rect.height / 2;
221
+ const insertionIndex = before ? effectIndex : effectIndex + 1;
222
+ const toIndex = getDestinationIndex({
223
+ fromIndex: dragData.effectIndex,
224
+ insertionIndex,
225
+ });
226
+ if (toIndex === dragData.effectIndex) {
227
+ return null;
228
+ }
229
+ return {
230
+ dragData,
231
+ toIndex,
232
+ indicator: before ? 'before' : 'after',
233
+ };
234
+ }, [effectIndex, nodePathKey]);
235
+ const onDragStart = (0, react_1.useCallback)((e) => {
236
+ if (!canReorder) {
237
+ e.preventDefault();
238
+ return;
239
+ }
240
+ const dragData = { nodePathKey, effectIndex };
241
+ currentEffectDrag = dragData;
242
+ e.dataTransfer.effectAllowed = 'move';
243
+ e.dataTransfer.setData(EFFECT_REORDER_MIME_TYPE, JSON.stringify(dragData));
244
+ e.stopPropagation();
245
+ }, [canReorder, effectIndex, nodePathKey]);
246
+ const onDragEnd = (0, react_1.useCallback)(() => {
247
+ currentEffectDrag = null;
248
+ setDropIndicator(null);
249
+ }, []);
250
+ const onDragOver = (0, react_1.useCallback)((e) => {
251
+ if (!canReorder || !hasEffectReorderDragType(e.dataTransfer)) {
252
+ return;
253
+ }
254
+ const dropTarget = getDropTarget(e);
255
+ if (!dropTarget) {
256
+ setDropIndicator(null);
257
+ return;
258
+ }
259
+ e.preventDefault();
260
+ e.stopPropagation();
261
+ e.dataTransfer.dropEffect = 'move';
262
+ setDropIndicator(dropTarget.indicator);
263
+ }, [canReorder, getDropTarget]);
264
+ const onDragLeave = (0, react_1.useCallback)((e) => {
265
+ if (e.currentTarget.contains(e.relatedTarget)) {
266
+ return;
267
+ }
268
+ setDropIndicator(null);
269
+ }, []);
270
+ const onDrop = (0, react_1.useCallback)(async (e) => {
271
+ if (!canReorder ||
272
+ previewServerState.type !== 'connected' ||
273
+ !validatedLocation.source) {
274
+ return;
275
+ }
276
+ const dropTarget = getDropTarget(e);
277
+ if (!dropTarget) {
278
+ setDropIndicator(null);
279
+ return;
280
+ }
281
+ e.preventDefault();
282
+ e.stopPropagation();
283
+ setDropIndicator(null);
284
+ currentEffectDrag = null;
285
+ try {
286
+ const result = await (0, call_api_1.callApi)('/api/reorder-effect', {
287
+ fileName: validatedLocation.source,
288
+ sequenceNodePath: nodePath,
289
+ fromIndex: dropTarget.dragData.effectIndex,
290
+ toIndex: dropTarget.toIndex,
291
+ clientId: previewServerState.clientId,
292
+ });
293
+ if (result.success) {
294
+ (0, NotificationCenter_1.showNotification)('Reordered effect', 2000);
295
+ }
296
+ else {
297
+ (0, NotificationCenter_1.showNotification)(result.reason, 4000);
298
+ }
299
+ }
300
+ catch (err) {
301
+ (0, NotificationCenter_1.showNotification)(err.message, 4000);
302
+ }
303
+ }, [
304
+ canReorder,
305
+ getDropTarget,
306
+ nodePath,
307
+ previewServerState,
308
+ validatedLocation.source,
309
+ ]);
310
+ const reorderLineStyle = (0, react_1.useMemo)(() => {
311
+ if (!dropIndicator) {
312
+ return null;
313
+ }
314
+ return {
315
+ ...reorderLineBase,
316
+ ...(dropIndicator === 'before' ? { top: -1 } : { bottom: -1 }),
317
+ };
318
+ }, [dropIndicator]);
319
+ const row = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: canToggle ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: "effect", hidden: isDisabled, onInvoked: onToggle })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowButton, { isExpanded: isExpanded, onClick: () => toggleTrack(nodePathInfo), label: `${label} section`, disabled: false }), style: rowStyle, selected: selection.selected, selectable: selection.selectable, onSelect: selection.onSelect, showSelectedBackground: true, containsSelection: false, outerHeight: null, children: jsx_runtime_1.jsx("span", { title: label, style: labelStyle, children: label }) }));
320
+ const draggableRow = canReorder ? (jsx_runtime_1.jsxs("div", { draggable: true, onDragStart: onDragStart, onDragEnd: onDragEnd, onDragOver: onDragOver, onDragLeave: onDragLeave, onDrop: onDrop, style: reorderWrapper, children: [reorderLineStyle ? jsx_runtime_1.jsx("div", { style: reorderLineStyle }) : null, row] })) : (row);
321
+ return previewConnected ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, onOpen: selection.selectable ? selection.onSelect : null, children: draggableRow })) : (draggableRow);
322
+ };
323
+ exports.TimelineEffectItem = TimelineEffectItem;
@@ -3,10 +3,11 @@ import type { SequencePropsSubscriptionKey } from 'remotion';
3
3
  import type { CodePosition } from '../../error-overlay/react-overlay/utils/get-source-map';
4
4
  import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
5
5
  import type { EffectSchemaFieldInfo } from '../../helpers/timeline-layout';
6
- export declare const TimelineEffectFieldRow: React.FC<{
6
+ export declare const TimelineEffectPropItem: React.FC<{
7
7
  readonly field: EffectSchemaFieldInfo;
8
8
  readonly validatedLocation: CodePosition;
9
9
  readonly rowDepth: number;
10
10
  readonly nodePath: SequencePropsSubscriptionKey;
11
11
  readonly nodePathInfo: SequenceNodePathInfo;
12
+ readonly keyframeDisplayOffset: number;
12
13
  }>;
@@ -1,23 +1,27 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TimelineEffectFieldRow = void 0;
3
+ exports.TimelineEffectPropItem = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const studio_shared_1 = require("@remotion/studio-shared");
6
6
  const react_1 = require("react");
7
7
  const remotion_1 = require("remotion");
8
8
  const client_id_1 = require("../../helpers/client-id");
9
9
  const call_api_1 = require("../call-api");
10
+ const ContextMenu_1 = require("../ContextMenu");
10
11
  const get_timeline_keyframes_1 = require("./get-timeline-keyframes");
12
+ const save_effect_prop_1 = require("./save-effect-prop");
11
13
  const save_prop_queue_1 = require("./save-prop-queue");
12
14
  const timeline_field_row_layout_1 = require("./timeline-field-row-layout");
13
15
  const TimelineExpandArrowButton_1 = require("./TimelineExpandArrowButton");
14
16
  const TimelineFieldLabel_1 = require("./TimelineFieldLabel");
17
+ const TimelineKeyframeControls_1 = require("./TimelineKeyframeControls");
18
+ const TimelineKeyframedValue_1 = require("./TimelineKeyframedValue");
15
19
  const TimelineLayerEye_1 = require("./TimelineLayerEye");
16
20
  const TimelineRowChrome_1 = require("./TimelineRowChrome");
17
21
  const TimelineSchemaField_1 = require("./TimelineSchemaField");
18
22
  const TimelineSelection_1 = require("./TimelineSelection");
19
23
  const fieldRowBase = {};
20
- const Value = ({ field, nodePath, validatedLocation }) => {
24
+ const Value = ({ field, nodePath, validatedLocation, keyframeDisplayOffset }) => {
21
25
  var _a;
22
26
  var _b;
23
27
  const { setEffectDragOverrides, clearEffectDragOverrides, setCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
@@ -124,8 +128,10 @@ const Value = ({ field, nodePath, validatedLocation }) => {
124
128
  throw new Error(`Unsupported effect status: ${effectStatus.reason}`);
125
129
  }
126
130
  if (propStatus === null || !propStatus.canUpdate) {
127
- if ((propStatus === null || propStatus === void 0 ? void 0 : propStatus.reason) === 'computed' ||
128
- (propStatus === null || propStatus === void 0 ? void 0 : propStatus.reason) === 'keyframed') {
131
+ if ((propStatus === null || propStatus === void 0 ? void 0 : propStatus.reason) === 'keyframed') {
132
+ return (jsx_runtime_1.jsx(TimelineKeyframedValue_1.TimelineKeyframedValue, { field: field, propStatus: propStatus, keyframeDisplayOffset: keyframeDisplayOffset }));
133
+ }
134
+ if ((propStatus === null || propStatus === void 0 ? void 0 : propStatus.reason) === 'computed') {
129
135
  return jsx_runtime_1.jsx(TimelineSchemaField_1.UnsupportedStatus, { label: (0, get_timeline_keyframes_1.getComputedStatusLabel)(propStatus) });
130
136
  }
131
137
  return null;
@@ -138,8 +144,13 @@ const Value = ({ field, nodePath, validatedLocation }) => {
138
144
  });
139
145
  return (jsx_runtime_1.jsx(TimelineSchemaField_1.TimelineFieldValue, { field: field, propStatus: propStatus, onSave: onSave, onDragValueChange: onDragValueChange, onDragEnd: onDragEnd, effectiveValue: effectiveValue }));
140
146
  };
141
- const TimelineEffectFieldRow = ({ field, validatedLocation, rowDepth, nodePath, nodePathInfo }) => {
147
+ const TimelineEffectPropItem = ({ field, validatedLocation, rowDepth, nodePath, nodePathInfo, keyframeDisplayOffset, }) => {
142
148
  var _a;
149
+ var _b, _c;
150
+ const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
151
+ const { setCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
152
+ const { codeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeCodeValuesContext);
153
+ const { getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
143
154
  const selection = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
144
155
  const style = (0, react_1.useMemo)(() => {
145
156
  return {
@@ -147,8 +158,86 @@ const TimelineEffectFieldRow = ({ field, validatedLocation, rowDepth, nodePath,
147
158
  height: field.rowHeight,
148
159
  };
149
160
  }, [field.rowHeight]);
150
- return (jsx_runtime_1.jsxs(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {}), arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {}), style: style, selected: selection.selected, selectable: selection.selectable, onSelect: selection.onSelect, showSelectedBackground: true, containsSelection: false, outerHeight: null, children: [
151
- jsx_runtime_1.jsx(TimelineFieldLabel_1.TimelineFieldLabel, { rowDepth: rowDepth, selected: selection.selected, label: (_a = field.description) !== null && _a !== void 0 ? _a : field.key }), jsx_runtime_1.jsx("div", { style: timeline_field_row_layout_1.timelineFieldValueColumnStyle, children: jsx_runtime_1.jsx(Value, { field: field, nodePath: nodePath, validatedLocation: validatedLocation }) })
161
+ const effectStatus = (0, react_1.useMemo)(() => remotion_1.Internals.getEffectCodeValuesCtx({
162
+ codeValues,
163
+ nodePath,
164
+ effectIndex: field.effectIndex,
165
+ }), [codeValues, nodePath, field.effectIndex]);
166
+ const propStatus = effectStatus.type === 'can-update-effect'
167
+ ? ((_b = (_a = effectStatus.props) === null || _a === void 0 ? void 0 : _a[field.key]) !== null && _b !== void 0 ? _b : null)
168
+ : null;
169
+ const dragOverrideValue = (0, react_1.useMemo)(() => {
170
+ const overrides = getEffectDragOverrides(nodePath, field.effectIndex);
171
+ return overrides[field.key];
172
+ }, [getEffectDragOverrides, nodePath, field.effectIndex, field.key]);
173
+ const keyframeControls = propStatus !== null &&
174
+ (0, TimelineKeyframeControls_1.shouldShowTimelineKeyframeControls)({
175
+ propStatus,
176
+ selected: selection.selected,
177
+ }) ? (jsx_runtime_1.jsx(TimelineKeyframeControls_1.TimelineKeyframeControls, { fieldKey: field.key, propStatus: propStatus, nodePath: nodePath, fileName: validatedLocation.source, keyframeDisplayOffset: keyframeDisplayOffset, defaultValue: field.fieldSchema.default, dragOverrideValue: dragOverrideValue, schema: field.effectSchema, effectIndex: field.effectIndex })) : null;
178
+ const isNonDefault = (0, react_1.useMemo)(() => {
179
+ var _a;
180
+ if (!propStatus || !propStatus.canUpdate) {
181
+ return false;
182
+ }
183
+ const effectiveCodeValue = (_a = propStatus.codeValue) !== null && _a !== void 0 ? _a : field.fieldSchema.default;
184
+ return (JSON.stringify(effectiveCodeValue) !==
185
+ JSON.stringify(field.fieldSchema.default));
186
+ }, [field.fieldSchema.default, propStatus]);
187
+ const canPerformReset = previewServerState.type === 'connected' &&
188
+ propStatus !== null &&
189
+ propStatus.canUpdate;
190
+ const onReset = (0, react_1.useCallback)(() => {
191
+ if (!canPerformReset ||
192
+ previewServerState.type !== 'connected' ||
193
+ !isNonDefault) {
194
+ return;
195
+ }
196
+ const defaultValue = field.fieldSchema.default !== undefined
197
+ ? JSON.stringify(field.fieldSchema.default)
198
+ : null;
199
+ (0, save_effect_prop_1.saveEffectProp)({
200
+ fileName: validatedLocation.source,
201
+ nodePath,
202
+ effectIndex: field.effectIndex,
203
+ fieldKey: field.key,
204
+ value: field.fieldSchema.default,
205
+ defaultValue,
206
+ schema: field.effectSchema,
207
+ setCodeValues,
208
+ clientId: previewServerState.clientId,
209
+ });
210
+ }, [
211
+ canPerformReset,
212
+ field.effectIndex,
213
+ field.effectSchema,
214
+ field.fieldSchema.default,
215
+ field.key,
216
+ isNonDefault,
217
+ nodePath,
218
+ previewServerState,
219
+ setCodeValues,
220
+ validatedLocation.source,
221
+ ]);
222
+ const contextMenuValues = (0, react_1.useMemo)(() => {
223
+ return [
224
+ {
225
+ type: 'item',
226
+ id: 'reset-effect-field',
227
+ keyHint: null,
228
+ label: 'Reset',
229
+ leftItem: null,
230
+ disabled: !canPerformReset,
231
+ onClick: onReset,
232
+ quickSwitcherLabel: null,
233
+ subMenu: null,
234
+ value: 'reset-effect-field',
235
+ },
236
+ ];
237
+ }, [canPerformReset, onReset]);
238
+ const row = (jsx_runtime_1.jsxs(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {}), keyframeControls: keyframeControls, arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {}), style: style, selected: selection.selected, selectable: selection.selectable, onSelect: selection.onSelect, showSelectedBackground: true, containsSelection: false, outerHeight: null, children: [
239
+ jsx_runtime_1.jsx(TimelineFieldLabel_1.TimelineFieldLabel, { rowDepth: rowDepth, selected: selection.selected, label: (_c = field.description) !== null && _c !== void 0 ? _c : field.key }), jsx_runtime_1.jsx("div", { style: timeline_field_row_layout_1.timelineFieldValueColumnStyle, children: jsx_runtime_1.jsx(Value, { field: field, nodePath: nodePath, validatedLocation: validatedLocation, keyframeDisplayOffset: keyframeDisplayOffset }) })
152
240
  ] }));
241
+ return (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, onOpen: selection.selectable ? selection.onSelect : null, children: row }));
153
242
  };
154
- exports.TimelineEffectFieldRow = TimelineEffectFieldRow;
243
+ exports.TimelineEffectPropItem = TimelineEffectPropItem;
@@ -21,6 +21,10 @@ const arrowButton = {
21
21
  outline: 'none',
22
22
  lineHeight: 1,
23
23
  };
24
+ const arrowSpacer = {
25
+ ...arrowButton,
26
+ cursor: 'default',
27
+ };
24
28
  const svgStyle = { display: 'block' };
25
29
  const TimelineExpandArrowButton = ({ isExpanded, onClick, label, disabled = false }) => {
26
30
  const style = (0, react_1.useMemo)(() => {
@@ -35,6 +39,6 @@ const TimelineExpandArrowButton = ({ isExpanded, onClick, label, disabled = fals
35
39
  };
36
40
  exports.TimelineExpandArrowButton = TimelineExpandArrowButton;
37
41
  const TimelineExpandArrowSpacer = () => {
38
- return jsx_runtime_1.jsx("div", { style: arrowButton });
42
+ return jsx_runtime_1.jsx("div", { style: arrowSpacer });
39
43
  };
40
44
  exports.TimelineExpandArrowSpacer = TimelineExpandArrowSpacer;
@@ -1,14 +1,45 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
5
35
  Object.defineProperty(exports, "__esModule", { value: true });
6
36
  exports.TimelineExpandedKeyframeRow = void 0;
7
37
  const jsx_runtime_1 = require("react/jsx-runtime");
8
- const react_1 = __importDefault(require("react"));
38
+ const react_1 = __importStar(require("react"));
9
39
  const timeline_layout_1 = require("../../helpers/timeline-layout");
10
40
  const TimelineKeyframeDiamond_1 = require("./TimelineKeyframeDiamond");
11
41
  const TimelineSelection_1 = require("./TimelineSelection");
42
+ const TimelineWidthProvider_1 = require("./TimelineWidthProvider");
12
43
  const row = {
13
44
  position: 'relative',
14
45
  };
@@ -16,8 +47,9 @@ const rowSeparator = {
16
47
  height: timeline_layout_1.TIMELINE_ITEM_BORDER_BOTTOM,
17
48
  };
18
49
  const TimelineExpandedKeyframeRowUnmemoized = ({ height, keyframes, nodePathInfo, showSeparator }) => {
50
+ const timelineWidth = (0, react_1.useContext)(TimelineWidthProvider_1.TimelineWidthContext);
19
51
  const { selected: rowSelected } = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
20
- return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [showSeparator ? jsx_runtime_1.jsx("div", { style: rowSeparator }) : null, jsx_runtime_1.jsxs("div", { style: { ...row, height }, children: [rowSelected ? (jsx_runtime_1.jsx("div", { style: TimelineSelection_1.TIMELINE_SELECTED_TRACK_HIGHLIGHT_STYLE })) : null, keyframes.map((keyframe) => (jsx_runtime_1.jsx(TimelineKeyframeDiamond_1.TimelineKeyframeDiamond, { frame: keyframe.frame, rowHeight: height, nodePathInfo: nodePathInfo }, keyframe.frame)))] })
52
+ return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [showSeparator ? jsx_runtime_1.jsx("div", { style: rowSeparator }) : null, jsx_runtime_1.jsxs("div", { style: { ...row, height }, children: [rowSelected && timelineWidth !== null ? (jsx_runtime_1.jsx("div", { style: (0, TimelineSelection_1.getTimelineSelectedTrackHighlightStyle)(timelineWidth) })) : null, keyframes.map((keyframe) => (jsx_runtime_1.jsx(TimelineKeyframeDiamond_1.TimelineKeyframeDiamond, { frame: keyframe.frame, rowHeight: height, nodePathInfo: nodePathInfo }, keyframe.frame)))] })
21
53
  ] }));
22
54
  };
23
55
  exports.TimelineExpandedKeyframeRow = react_1.default.memo(TimelineExpandedKeyframeRowUnmemoized);
@@ -13,4 +13,5 @@ export declare const TimelineExpandedRow: React.FC<{
13
13
  readonly validatedLocation: CodePosition;
14
14
  readonly nodePath: SequencePropsSubscriptionKey;
15
15
  readonly schema: SequenceSchema;
16
+ readonly keyframeDisplayOffset: number;
16
17
  }>;
@@ -8,19 +8,19 @@ const jsx_runtime_1 = require("react/jsx-runtime");
8
8
  const react_1 = __importDefault(require("react"));
9
9
  const timeline_layout_1 = require("../../helpers/timeline-layout");
10
10
  const timeline_row_layout_1 = require("./timeline-row-layout");
11
- const TimelineEffectFieldRow_1 = require("./TimelineEffectFieldRow");
12
- const TimelineEffectGroupRow_1 = require("./TimelineEffectGroupRow");
11
+ const TimelineEffectItem_1 = require("./TimelineEffectItem");
12
+ const TimelineEffectPropItem_1 = require("./TimelineEffectPropItem");
13
13
  const TimelineExpandArrowButton_1 = require("./TimelineExpandArrowButton");
14
- const TimelineFieldRow_1 = require("./TimelineFieldRow");
15
14
  const TimelineLayerEye_1 = require("./TimelineLayerEye");
16
15
  const TimelineRowChrome_1 = require("./TimelineRowChrome");
17
16
  const TimelineSelection_1 = require("./TimelineSelection");
17
+ const TimelineSequencePropItem_1 = require("./TimelineSequencePropItem");
18
18
  const rowLabel = {
19
19
  fontSize: 12,
20
20
  color: 'rgba(255, 255, 255, 0.8)',
21
21
  userSelect: 'none',
22
22
  };
23
- const TimelineExpandedRow = ({ node, depth, nestedDepth, getIsExpanded, toggleTrack, validatedLocation, nodePath, schema, }) => {
23
+ const TimelineExpandedRow = ({ node, depth, nestedDepth, getIsExpanded, toggleTrack, validatedLocation, nodePath, schema, keyframeDisplayOffset, }) => {
24
24
  const rowDepth = (0, timeline_row_layout_1.getExpandedRowDepth)({ nestedDepth, treeDepth: depth });
25
25
  const selection = (0, TimelineSelection_1.useTimelineRowSelection)(node.nodePathInfo);
26
26
  const labelStyle = react_1.default.useMemo(() => ({
@@ -36,7 +36,9 @@ const TimelineExpandedRow = ({ node, depth, nestedDepth, getIsExpanded, toggleTr
36
36
  }), [selection.selected]);
37
37
  if (node.kind === 'group') {
38
38
  if (node.effectInfo) {
39
- return (jsx_runtime_1.jsx(TimelineEffectGroupRow_1.TimelineEffectGroupRow, { label: node.label, nodePathInfo: node.nodePathInfo, effectIndex: node.effectInfo.effectIndex, effectSchema: node.effectInfo.effectSchema, documentationLink: node.effectInfo.documentationLink, nodePath: nodePath, validatedLocation: validatedLocation, rowDepth: rowDepth, getIsExpanded: getIsExpanded, toggleTrack: toggleTrack }));
39
+ return (
40
+ // A single effect
41
+ jsx_runtime_1.jsx(TimelineEffectItem_1.TimelineEffectItem, { label: node.label, nodePathInfo: node.nodePathInfo, effectIndex: node.effectInfo.effectIndex, effectSchema: node.effectInfo.effectSchema, documentationLink: node.effectInfo.documentationLink, nodePath: nodePath, validatedLocation: validatedLocation, rowDepth: rowDepth, getIsExpanded: getIsExpanded, toggleTrack: toggleTrack }));
40
42
  }
41
43
  // Group like "Effects"
42
44
  const isExpanded = getIsExpanded(node.nodePathInfo);
@@ -46,10 +48,10 @@ const TimelineExpandedRow = ({ node, depth, nestedDepth, getIsExpanded, toggleTr
46
48
  }
47
49
  if (node.field) {
48
50
  if (node.field.kind === 'effect-field') {
49
- return (jsx_runtime_1.jsx(TimelineEffectFieldRow_1.TimelineEffectFieldRow, { field: node.field, validatedLocation: validatedLocation, rowDepth: rowDepth, nodePath: nodePath, nodePathInfo: node.nodePathInfo }));
51
+ return (jsx_runtime_1.jsx(TimelineEffectPropItem_1.TimelineEffectPropItem, { field: node.field, validatedLocation: validatedLocation, rowDepth: rowDepth, nodePath: nodePath, nodePathInfo: node.nodePathInfo, keyframeDisplayOffset: keyframeDisplayOffset }));
50
52
  }
51
53
  if (node.field.kind === 'sequence-field') {
52
- return (jsx_runtime_1.jsx(TimelineFieldRow_1.TimelineFieldRow, { field: node.field, validatedLocation: validatedLocation, rowDepth: rowDepth, nodePath: nodePath, nodePathInfo: node.nodePathInfo, schema: schema }));
54
+ return (jsx_runtime_1.jsx(TimelineSequencePropItem_1.TimelineSequencePropItem, { field: node.field, validatedLocation: validatedLocation, rowDepth: rowDepth, nodePath: nodePath, nodePathInfo: node.nodePathInfo, schema: schema, keyframeDisplayOffset: keyframeDisplayOffset }));
53
55
  }
54
56
  throw new Error('Unexpected field kind: ' + JSON.stringify(node.field));
55
57
  }
@@ -7,4 +7,5 @@ export declare const TimelineExpandedSection: React.FC<{
7
7
  readonly validatedLocation: CodePosition;
8
8
  readonly nodePathInfo: SequenceNodePathInfo;
9
9
  readonly nestedDepth: number;
10
+ readonly keyframeDisplayOffset: number;
10
11
  }>;
@@ -53,7 +53,7 @@ const separator = {
53
53
  height: 0,
54
54
  borderBottom: `1px solid ${colors_1.TIMELINE_TRACK_SEPARATOR}`,
55
55
  };
56
- const TimelineExpandedSection = ({ sequence, validatedLocation, nodePathInfo, nestedDepth }) => {
56
+ const TimelineExpandedSection = ({ sequence, validatedLocation, nodePathInfo, nestedDepth, keyframeDisplayOffset, }) => {
57
57
  const { getIsExpanded } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksGetterContext);
58
58
  const { toggleTrack } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksSetterContext);
59
59
  const { codeValues: visualModeCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeCodeValuesContext);
@@ -89,7 +89,7 @@ const TimelineExpandedSection = ({ sequence, validatedLocation, nodePathInfo, ne
89
89
  return jsx_runtime_1.jsx("div", { style: style, children: "No schema" });
90
90
  }
91
91
  return (jsx_runtime_1.jsx("div", { style: style, children: flat.map(({ node, depth }, i) => {
92
- return (jsx_runtime_1.jsxs(react_1.default.Fragment, { children: [i > 0 ? jsx_runtime_1.jsx("div", { style: separator }) : null, jsx_runtime_1.jsx(TimelineExpandedRow_1.TimelineExpandedRow, { node: node, depth: depth, nestedDepth: nestedDepth, getIsExpanded: getIsExpanded, toggleTrack: toggleTrack, validatedLocation: validatedLocation, nodePath: nodePathInfo.sequenceSubscriptionKey, schema: schema })
92
+ return (jsx_runtime_1.jsxs(react_1.default.Fragment, { children: [i > 0 ? jsx_runtime_1.jsx("div", { style: separator }) : null, jsx_runtime_1.jsx(TimelineExpandedRow_1.TimelineExpandedRow, { node: node, depth: depth, nestedDepth: nestedDepth, getIsExpanded: getIsExpanded, toggleTrack: toggleTrack, validatedLocation: validatedLocation, nodePath: nodePathInfo.sequenceSubscriptionKey, schema: schema, keyframeDisplayOffset: keyframeDisplayOffset })
93
93
  ] }, JSON.stringify(node.nodePathInfo)));
94
94
  }) }));
95
95
  };
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare const TimelineInOutDragHandler: React.FC;