@remotion/studio 4.0.471 → 4.0.473

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 (192) 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 +55 -5
  4. package/dist/components/AssetSelectorItem.js +153 -27
  5. package/dist/components/Canvas.js +147 -0
  6. package/dist/components/CompositionSelectorItem.d.ts +1 -0
  7. package/dist/components/CompositionSelectorItem.js +12 -4
  8. package/dist/components/ConfirmationDialog-types.d.ts +8 -0
  9. package/dist/components/ConfirmationDialog-types.js +2 -0
  10. package/dist/components/ConfirmationDialog.d.ts +7 -0
  11. package/dist/components/ConfirmationDialog.js +103 -0
  12. package/dist/components/ContextMenu.d.ts +9 -1
  13. package/dist/components/ContextMenu.js +99 -47
  14. package/dist/components/CurrentAsset.d.ts +1 -0
  15. package/dist/components/CurrentAsset.js +13 -2
  16. package/dist/components/Editor.js +14 -6
  17. package/dist/components/EditorContent.js +15 -2
  18. package/dist/components/EditorContexts.js +2 -1
  19. package/dist/components/EditorRuler/Ruler.js +2 -0
  20. package/dist/components/ExplorerPanel.d.ts +0 -4
  21. package/dist/components/ExplorerPanel.js +8 -4
  22. package/dist/components/ExplorerPanelRef.d.ts +4 -0
  23. package/dist/components/ExplorerPanelRef.js +5 -0
  24. package/dist/components/FilePreview.d.ts +1 -1
  25. package/dist/components/InitialCompositionLoader.d.ts +0 -1
  26. package/dist/components/InitialCompositionLoader.js +5 -27
  27. package/dist/components/Menu/MenuItem.js +7 -1
  28. package/dist/components/Menu/SubMenu.js +5 -1
  29. package/dist/components/Menu/portals.js +17 -8
  30. package/dist/components/MenuToolbar.js +5 -1
  31. package/dist/components/ModalContainer.js +6 -1
  32. package/dist/components/Modals.js +8 -2
  33. package/dist/components/NewComposition/CodemodFooter.js +2 -2
  34. package/dist/components/NewComposition/ComboBox.js +8 -2
  35. package/dist/components/NewComposition/DeleteFolder.d.ts +6 -0
  36. package/dist/components/NewComposition/DeleteFolder.js +39 -0
  37. package/dist/components/NewComposition/DeleteStaticFile.d.ts +4 -0
  38. package/dist/components/NewComposition/DeleteStaticFile.js +44 -0
  39. package/dist/components/NewComposition/RenameFolder.d.ts +6 -0
  40. package/dist/components/NewComposition/RenameFolder.js +60 -0
  41. package/dist/components/NewComposition/RenameStaticFile.d.ts +4 -0
  42. package/dist/components/NewComposition/RenameStaticFile.js +118 -0
  43. package/dist/components/OptionsPanel.js +5 -1
  44. package/dist/components/OutlineToggle.d.ts +2 -0
  45. package/dist/components/OutlineToggle.js +20 -0
  46. package/dist/components/Preview.d.ts +0 -2
  47. package/dist/components/Preview.js +23 -33
  48. package/dist/components/PreviewToolbar.js +19 -6
  49. package/dist/components/RenderButton.js +8 -2
  50. package/dist/components/RenderPreview.js +2 -2
  51. package/dist/components/SelectedOutlineOverlay.d.ts +105 -4
  52. package/dist/components/SelectedOutlineOverlay.js +578 -59
  53. package/dist/components/ShowOutlinesProvider.d.ts +4 -0
  54. package/dist/components/ShowOutlinesProvider.js +24 -0
  55. package/dist/components/SizeSelector.js +3 -3
  56. package/dist/components/Splitter/SplitterContainer.js +9 -0
  57. package/dist/components/Splitter/SplitterHandle.js +65 -70
  58. package/dist/components/StaticFilePreview.js +2 -2
  59. package/dist/components/Timeline/KeyframeSettingsModal.d.ts +15 -0
  60. package/dist/components/Timeline/KeyframeSettingsModal.js +150 -0
  61. package/dist/components/Timeline/Timeline.js +50 -15
  62. package/dist/components/Timeline/TimelineArrayField.d.ts +9 -0
  63. package/dist/components/Timeline/TimelineArrayField.js +210 -0
  64. package/dist/components/Timeline/TimelineBooleanField.d.ts +2 -2
  65. package/dist/components/Timeline/TimelineBooleanField.js +2 -2
  66. package/dist/components/Timeline/TimelineClipboardKeybindings.d.ts +43 -0
  67. package/dist/components/Timeline/TimelineClipboardKeybindings.js +479 -0
  68. package/dist/components/Timeline/TimelineColorField.d.ts +2 -2
  69. package/dist/components/Timeline/TimelineColorField.js +2 -8
  70. package/dist/components/Timeline/TimelineDeleteKeybindings.js +12 -2
  71. package/dist/components/Timeline/TimelineEffectItem.js +3 -2
  72. package/dist/components/Timeline/TimelineEffectPropItem.js +146 -26
  73. package/dist/components/Timeline/TimelineEnumField.d.ts +2 -2
  74. package/dist/components/Timeline/TimelineEnumField.js +3 -3
  75. package/dist/components/Timeline/TimelineKeyframeControls.d.ts +4 -3
  76. package/dist/components/Timeline/TimelineKeyframeControls.js +41 -37
  77. package/dist/components/Timeline/TimelineKeyframeDiamond.js +24 -21
  78. package/dist/components/Timeline/TimelineKeyframeDiamondIcon.d.ts +6 -0
  79. package/dist/components/Timeline/TimelineKeyframeDiamondIcon.js +14 -0
  80. package/dist/components/Timeline/TimelineKeyframeDragState.d.ts +17 -0
  81. package/dist/components/Timeline/TimelineKeyframeDragState.js +39 -0
  82. package/dist/components/Timeline/TimelineKeyframedValue.d.ts +7 -2
  83. package/dist/components/Timeline/TimelineKeyframedValue.js +22 -8
  84. package/dist/components/Timeline/TimelineLayerEye.d.ts +1 -0
  85. package/dist/components/Timeline/TimelineLayerEye.js +8 -3
  86. package/dist/components/Timeline/TimelineList.js +2 -2
  87. package/dist/components/Timeline/TimelineMediaInfo.d.ts +0 -13
  88. package/dist/components/Timeline/TimelineMediaInfo.js +8 -73
  89. package/dist/components/Timeline/TimelineNumberField.d.ts +2 -2
  90. package/dist/components/Timeline/TimelineNumberField.js +7 -11
  91. package/dist/components/Timeline/TimelinePrimitiveFieldValue.d.ts +17 -0
  92. package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +53 -0
  93. package/dist/components/Timeline/TimelineRotationField.d.ts +2 -2
  94. package/dist/components/Timeline/TimelineRotationField.js +41 -24
  95. package/dist/components/Timeline/TimelineRowChrome.js +8 -7
  96. package/dist/components/Timeline/TimelineScaleField.d.ts +20 -0
  97. package/dist/components/Timeline/TimelineScaleField.js +314 -0
  98. package/dist/components/Timeline/TimelineSchemaField.d.ts +3 -2
  99. package/dist/components/Timeline/TimelineSchemaField.js +8 -42
  100. package/dist/components/Timeline/TimelineSelection.js +3 -2
  101. package/dist/components/Timeline/TimelineSequence.d.ts +1 -0
  102. package/dist/components/Timeline/TimelineSequence.js +51 -10
  103. package/dist/components/Timeline/TimelineSequenceFrame.js +1 -0
  104. package/dist/components/Timeline/TimelineSequenceItem.d.ts +1 -0
  105. package/dist/components/Timeline/TimelineSequenceItem.js +282 -28
  106. package/dist/components/Timeline/TimelineSequencePropItem.js +161 -35
  107. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +58 -0
  108. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +525 -0
  109. package/dist/components/Timeline/TimelineTrack.js +1 -1
  110. package/dist/components/Timeline/TimelineTranslateField.d.ts +2 -2
  111. package/dist/components/Timeline/TimelineTranslateField.js +21 -25
  112. package/dist/components/Timeline/TimelineUvCoordinateField.d.ts +2 -2
  113. package/dist/components/Timeline/TimelineUvCoordinateField.js +20 -26
  114. package/dist/components/Timeline/apply-effect-response-to-code-values.d.ts +5 -0
  115. package/dist/components/Timeline/apply-effect-response-to-code-values.js +19 -0
  116. package/dist/components/Timeline/call-add-keyframe.js +4 -0
  117. package/dist/components/Timeline/call-move-keyframe.d.ts +19 -0
  118. package/dist/components/Timeline/call-move-keyframe.js +71 -0
  119. package/dist/components/Timeline/call-update-keyframe-settings.d.ts +22 -0
  120. package/dist/components/Timeline/call-update-keyframe-settings.js +52 -0
  121. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +7 -4
  122. package/dist/components/Timeline/delete-selected-timeline-item.js +33 -21
  123. package/dist/components/Timeline/duplicate-selected-timeline-item.d.ts +4 -2
  124. package/dist/components/Timeline/duplicate-selected-timeline-item.js +39 -34
  125. package/dist/components/Timeline/get-bounded-keyframe-drag-delta.d.ts +8 -0
  126. package/dist/components/Timeline/get-bounded-keyframe-drag-delta.js +12 -0
  127. package/dist/components/Timeline/get-keyframe-navigation.d.ts +2 -2
  128. package/dist/components/Timeline/get-keyframe-navigation.js +14 -6
  129. package/dist/components/Timeline/get-node-keyframes.d.ts +5 -2
  130. package/dist/components/Timeline/get-node-keyframes.js +38 -5
  131. package/dist/components/Timeline/get-timeline-keyframes.js +4 -4
  132. package/dist/components/Timeline/reset-selected-timeline-props.js +22 -8
  133. package/dist/components/Timeline/save-effect-prop.d.ts +14 -3
  134. package/dist/components/Timeline/save-effect-prop.js +36 -18
  135. package/dist/components/Timeline/save-prop-queue.d.ts +2 -1
  136. package/dist/components/Timeline/save-prop-queue.js +5 -2
  137. package/dist/components/Timeline/save-sequence-prop.d.ts +2 -7
  138. package/dist/components/Timeline/save-sequence-prop.js +33 -30
  139. package/dist/components/Timeline/should-clear-selection-on-pointer-down.d.ts +3 -0
  140. package/dist/components/Timeline/should-clear-selection-on-pointer-down.js +7 -0
  141. package/dist/components/Timeline/timeline-asset-link.d.ts +13 -0
  142. package/dist/components/Timeline/timeline-asset-link.js +37 -0
  143. package/dist/components/Timeline/timeline-field-utils.d.ts +1 -0
  144. package/dist/components/Timeline/timeline-field-utils.js +5 -1
  145. package/dist/components/Timeline/timeline-translate-utils.js +9 -2
  146. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +7 -0
  147. package/dist/components/Timeline/use-timeline-keyframe-drag.d.ts +10 -0
  148. package/dist/components/Timeline/use-timeline-keyframe-drag.js +378 -0
  149. package/dist/components/TopPanel.d.ts +1 -1
  150. package/dist/components/folder-menu-items.d.ts +12 -0
  151. package/dist/components/folder-menu-items.js +147 -0
  152. package/dist/components/import-assets.d.ts +22 -0
  153. package/dist/components/import-assets.js +294 -0
  154. package/dist/components/load-canvas-content-from-url.d.ts +1 -0
  155. package/dist/components/load-canvas-content-from-url.js +9 -3
  156. package/dist/components/use-select-asset.d.ts +1 -0
  157. package/dist/components/use-select-asset.js +30 -0
  158. package/dist/error-overlay/error-origin.d.ts +3 -0
  159. package/dist/error-overlay/error-origin.js +42 -0
  160. package/dist/error-overlay/react-overlay/listen-to-runtime-errors.js +6 -2
  161. package/dist/error-overlay/remotion-overlay/ErrorLoader.js +38 -0
  162. package/dist/error-overlay/remotion-overlay/ShortcutHint.js +1 -1
  163. package/dist/error-overlay/remotion-overlay/log-studio-error.d.ts +3 -0
  164. package/dist/error-overlay/remotion-overlay/log-studio-error.js +27 -0
  165. package/dist/esm/{chunk-z0z9d4r0.js → chunk-q0jkt0zq.js} +23062 -17350
  166. package/dist/esm/internals.mjs +23062 -17350
  167. package/dist/esm/previewEntry.mjs +22351 -16615
  168. package/dist/esm/renderEntry.mjs +1 -1
  169. package/dist/helpers/calculate-timeline.js +7 -3
  170. package/dist/helpers/create-folder-tree.js +1 -0
  171. package/dist/helpers/get-asset-metadata.js +2 -2
  172. package/dist/helpers/get-folder-id.d.ts +4 -0
  173. package/dist/helpers/get-folder-id.js +7 -0
  174. package/dist/helpers/get-preview-file-type.d.ts +2 -0
  175. package/dist/helpers/get-preview-file-type.js +33 -0
  176. package/dist/helpers/get-timeline-sequence-sort-key.d.ts +2 -0
  177. package/dist/helpers/install-required-package.d.ts +1 -0
  178. package/dist/helpers/install-required-package.js +39 -0
  179. package/dist/helpers/remote-asset-drag.d.ts +4 -0
  180. package/dist/helpers/remote-asset-drag.js +73 -0
  181. package/dist/helpers/timeline-layout.js +5 -1
  182. package/dist/helpers/use-asset-drag-events.d.ts +5 -2
  183. package/dist/helpers/use-asset-drag-events.js +13 -2
  184. package/dist/helpers/validate-folder-rename.d.ts +6 -0
  185. package/dist/helpers/validate-folder-rename.js +19 -0
  186. package/dist/hot-middleware-client/client.js +6 -0
  187. package/dist/state/editor-outlines.d.ts +8 -0
  188. package/dist/state/editor-outlines.js +18 -0
  189. package/dist/state/modals.d.ts +29 -2
  190. package/dist/state/scale-lock.d.ts +18 -0
  191. package/dist/state/scale-lock.js +59 -0
  192. package/package.json +10 -10
@@ -1,23 +1,31 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.hasKeyframeAtSourceFrame = exports.getNextKeyframeDisplayFrame = exports.getPreviousKeyframeDisplayFrame = void 0;
4
- const getPreviousKeyframeDisplayFrame = (keyframes, currentDisplayFrame) => {
4
+ const isKeyframeInTimelineRange = (frame, durationInFrames) => {
5
+ return frame >= 0 && frame < durationInFrames;
6
+ };
7
+ const getPreviousKeyframeDisplayFrame = (keyframes, currentDisplayFrame, durationInFrames) => {
5
8
  let previous = null;
6
9
  for (const keyframe of keyframes) {
7
- if (keyframe.frame < currentDisplayFrame) {
10
+ if (isKeyframeInTimelineRange(keyframe.frame, durationInFrames) &&
11
+ keyframe.frame < currentDisplayFrame &&
12
+ (previous === null || keyframe.frame > previous)) {
8
13
  previous = keyframe.frame;
9
14
  }
10
15
  }
11
16
  return previous;
12
17
  };
13
18
  exports.getPreviousKeyframeDisplayFrame = getPreviousKeyframeDisplayFrame;
14
- const getNextKeyframeDisplayFrame = (keyframes, currentDisplayFrame) => {
19
+ const getNextKeyframeDisplayFrame = (keyframes, currentDisplayFrame, durationInFrames) => {
20
+ let next = null;
15
21
  for (const keyframe of keyframes) {
16
- if (keyframe.frame > currentDisplayFrame) {
17
- return keyframe.frame;
22
+ if (isKeyframeInTimelineRange(keyframe.frame, durationInFrames) &&
23
+ keyframe.frame > currentDisplayFrame &&
24
+ (next === null || keyframe.frame < next)) {
25
+ next = keyframe.frame;
18
26
  }
19
27
  }
20
- return null;
28
+ return next;
21
29
  };
22
30
  exports.getNextKeyframeDisplayFrame = getNextKeyframeDisplayFrame;
23
31
  const hasKeyframeAtSourceFrame = (keyframes, sourceFrame) => {
@@ -1,10 +1,13 @@
1
- import { type CodeValues, type SequencePropsSubscriptionKey } from 'remotion';
1
+ import { type CodeValues, type GetDragOverrides, type GetEffectDragOverrides, type SequencePropsSubscriptionKey } from 'remotion';
2
2
  import type { TimelineTreeNode } from '../../helpers/timeline-layout';
3
- export declare const getNodeKeyframes: ({ node, nodePath, codeValues, keyframeDisplayOffset, }: {
3
+ export declare const getNodeKeyframes: ({ node, nodePath, codeValues, keyframeDisplayOffset, getDragOverrides, getEffectDragOverrides, timelinePosition, }: {
4
4
  node: TimelineTreeNode;
5
5
  nodePath: SequencePropsSubscriptionKey;
6
6
  codeValues: CodeValues;
7
7
  keyframeDisplayOffset: number;
8
+ getDragOverrides: GetDragOverrides;
9
+ getEffectDragOverrides: GetEffectDragOverrides;
10
+ timelinePosition: number;
8
11
  }) => {
9
12
  frame: number;
10
13
  value: unknown;
@@ -3,21 +3,54 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getNodeKeyframes = void 0;
4
4
  const remotion_1 = require("remotion");
5
5
  const get_timeline_keyframes_1 = require("./get-timeline-keyframes");
6
- const getNodeKeyframes = ({ node, nodePath, codeValues, keyframeDisplayOffset, }) => {
6
+ const hasOverride = (overrides, key) => Object.prototype.hasOwnProperty.call(overrides, key);
7
+ const withDragOverrideKeyframe = ({ propStatus, keyframeDisplayOffset, timelinePosition, dragOverrideValue, hasDragOverride, }) => {
8
+ if ((dragOverrideValue === null || dragOverrideValue === void 0 ? void 0 : dragOverrideValue.type) === 'keyframed') {
9
+ return (0, get_timeline_keyframes_1.getTimelineKeyframes)(dragOverrideValue.status, keyframeDisplayOffset);
10
+ }
11
+ const keyframes = (0, get_timeline_keyframes_1.getTimelineKeyframes)(propStatus, keyframeDisplayOffset);
12
+ if (!hasDragOverride || (propStatus === null || propStatus === void 0 ? void 0 : propStatus.status) !== 'keyframed') {
13
+ return keyframes;
14
+ }
15
+ const dragKeyframe = {
16
+ frame: timelinePosition,
17
+ value: dragOverrideValue === null || dragOverrideValue === void 0 ? void 0 : dragOverrideValue.value,
18
+ };
19
+ const existingIndex = keyframes.findIndex((keyframe) => keyframe.frame === timelinePosition);
20
+ if (existingIndex !== -1) {
21
+ return keyframes.map((keyframe, index) => index === existingIndex ? dragKeyframe : keyframe);
22
+ }
23
+ return [...keyframes, dragKeyframe].sort((first, second) => first.frame - second.frame);
24
+ };
25
+ const getNodeKeyframes = ({ node, nodePath, codeValues, keyframeDisplayOffset, getDragOverrides, getEffectDragOverrides, timelinePosition, }) => {
7
26
  var _a, _b;
8
27
  if (node.kind !== 'field' || node.field === null) {
9
28
  return [];
10
29
  }
11
30
  if (node.field.kind === 'sequence-field') {
12
- return (0, get_timeline_keyframes_1.getTimelineKeyframes)((_a = remotion_1.Internals.getCodeValuesCtx(codeValues, nodePath)) === null || _a === void 0 ? void 0 : _a[node.field.key], keyframeDisplayOffset);
31
+ const dragOverrides = getDragOverrides(nodePath);
32
+ return withDragOverrideKeyframe({
33
+ propStatus: (_a = remotion_1.Internals.getCodeValuesCtx(codeValues, nodePath)) === null || _a === void 0 ? void 0 : _a[node.field.key],
34
+ keyframeDisplayOffset,
35
+ timelinePosition,
36
+ dragOverrideValue: dragOverrides[node.field.key],
37
+ hasDragOverride: hasOverride(dragOverrides, node.field.key),
38
+ });
13
39
  }
14
40
  const effectStatus = remotion_1.Internals.getEffectCodeValuesCtx({
15
41
  codeValues,
16
42
  nodePath,
17
43
  effectIndex: node.field.effectIndex,
18
44
  });
19
- return (0, get_timeline_keyframes_1.getTimelineKeyframes)(effectStatus.type === 'can-update-effect'
20
- ? (_b = effectStatus.props) === null || _b === void 0 ? void 0 : _b[node.field.key]
21
- : null, keyframeDisplayOffset);
45
+ const effectDragOverrides = getEffectDragOverrides(nodePath, node.field.effectIndex);
46
+ return withDragOverrideKeyframe({
47
+ propStatus: effectStatus.type === 'can-update-effect'
48
+ ? (_b = effectStatus.props) === null || _b === void 0 ? void 0 : _b[node.field.key]
49
+ : null,
50
+ keyframeDisplayOffset,
51
+ timelinePosition,
52
+ dragOverrideValue: effectDragOverrides[node.field.key],
53
+ hasDragOverride: hasOverride(effectDragOverrides, node.field.key),
54
+ });
22
55
  };
23
56
  exports.getNodeKeyframes = getNodeKeyframes;
@@ -2,17 +2,17 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getTimelineKeyframes = exports.getComputedStatusLabel = void 0;
4
4
  const getComputedStatusLabel = (propStatus) => {
5
- if (propStatus.reason === 'computed') {
5
+ if (propStatus.status === 'computed') {
6
6
  return 'computed';
7
7
  }
8
- return 'keyframed';
8
+ throw new Error(`Unsupported prop status: ${propStatus.status}`);
9
9
  };
10
10
  exports.getComputedStatusLabel = getComputedStatusLabel;
11
11
  const getTimelineKeyframes = (propStatus, keyframeDisplayOffset = 0) => {
12
- if (!propStatus || propStatus.canUpdate) {
12
+ if (!propStatus) {
13
13
  return [];
14
14
  }
15
- if (propStatus.reason === 'computed') {
15
+ if (propStatus.status !== 'keyframed') {
16
16
  return [];
17
17
  }
18
18
  const { keyframes } = propStatus;
@@ -9,6 +9,21 @@ const isPropResetSelection = (selection) => selection.type === 'sequence-prop' |
9
9
  selection.type === 'sequence-effect-prop';
10
10
  const isVisibleFieldSchema = (fieldSchema) => fieldSchema !== undefined && fieldSchema.type !== 'hidden';
11
11
  const isNonDefaultCodeValue = ({ codeValue, defaultValue, }) => JSON.stringify(codeValue !== null && codeValue !== void 0 ? codeValue : defaultValue) !== JSON.stringify(defaultValue);
12
+ const isResettablePropStatus = ({ propStatus, defaultValue, }) => {
13
+ if (!propStatus || propStatus.status === 'computed') {
14
+ return false;
15
+ }
16
+ if (defaultValue === undefined) {
17
+ return false;
18
+ }
19
+ if (propStatus.status === 'keyframed') {
20
+ return true;
21
+ }
22
+ return isNonDefaultCodeValue({
23
+ codeValue: propStatus.codeValue,
24
+ defaultValue,
25
+ });
26
+ };
12
27
  const getDefaultValue = (fieldSchema) => fieldSchema.default !== undefined
13
28
  ? JSON.stringify(fieldSchema.default)
14
29
  : null;
@@ -41,9 +56,8 @@ const getTimelinePropResetTargets = ({ selections, sequences, overrideIdsToNodeP
41
56
  const sequenceFieldSchema = sequence.controls.schema[selection.key];
42
57
  const sequencePropStatus = (_a = remotion_1.Internals.getCodeValuesCtx(codeValues, nodePath)) === null || _a === void 0 ? void 0 : _a[selection.key];
43
58
  if (!isVisibleFieldSchema(sequenceFieldSchema) ||
44
- !(sequencePropStatus === null || sequencePropStatus === void 0 ? void 0 : sequencePropStatus.canUpdate) ||
45
- !isNonDefaultCodeValue({
46
- codeValue: sequencePropStatus.codeValue,
59
+ !isResettablePropStatus({
60
+ propStatus: sequencePropStatus,
47
61
  defaultValue: sequenceFieldSchema.default,
48
62
  })) {
49
63
  continue;
@@ -71,9 +85,8 @@ const getTimelinePropResetTargets = ({ selections, sequences, overrideIdsToNodeP
71
85
  : null;
72
86
  if (!effect ||
73
87
  !isVisibleFieldSchema(fieldSchema) ||
74
- !(propStatus === null || propStatus === void 0 ? void 0 : propStatus.canUpdate) ||
75
- !isNonDefaultCodeValue({
76
- codeValue: propStatus.codeValue,
88
+ !isResettablePropStatus({
89
+ propStatus,
77
90
  defaultValue: fieldSchema.default,
78
91
  })) {
79
92
  continue;
@@ -119,14 +132,15 @@ const resetSelectedTimelineProps = ({ selections, sequences, overrideIdsToNodePa
119
132
  clientId,
120
133
  undoLabel: sequencePropTargets.length > 1
121
134
  ? 'Reset selected sequence props'
122
- : null,
135
+ : 'Reset sequence prop',
123
136
  redoLabel: sequencePropTargets.length > 1
124
137
  ? 'Reapply selected sequence props'
125
- : null,
138
+ : 'Reapply sequence prop',
126
139
  }));
127
140
  }
128
141
  for (const target of effectPropTargets) {
129
142
  resetPromises.push((0, save_effect_prop_1.saveEffectProp)({
143
+ type: 'value',
130
144
  fileName: target.fileName,
131
145
  nodePath: target.nodePath,
132
146
  effectIndex: target.effectIndex,
@@ -1,13 +1,24 @@
1
+ import { type EffectClipboardParam } from '@remotion/studio-shared';
1
2
  import type { SequencePropsSubscriptionKey, SequenceSchema } from 'remotion';
2
3
  import type { SetCodeValues } from './save-sequence-prop';
3
- export declare const saveEffectProp: ({ fileName, nodePath, effectIndex, fieldKey, value, defaultValue, schema, setCodeValues, clientId, }: {
4
+ type SaveEffectPropBase = {
4
5
  fileName: string;
5
6
  nodePath: SequencePropsSubscriptionKey;
6
7
  effectIndex: number;
7
8
  fieldKey: string;
8
- value: unknown;
9
9
  defaultValue: string | null;
10
10
  schema: SequenceSchema;
11
11
  setCodeValues: SetCodeValues;
12
12
  clientId: string;
13
- }) => Promise<void>;
13
+ };
14
+ type SaveEffectPropValue = SaveEffectPropBase & {
15
+ type: 'value';
16
+ value: unknown;
17
+ };
18
+ type SaveEffectPropEffectParam = SaveEffectPropBase & {
19
+ type: 'effect-param';
20
+ effectParam: EffectClipboardParam;
21
+ };
22
+ type SaveEffectPropInput = SaveEffectPropValue | SaveEffectPropEffectParam;
23
+ export declare const saveEffectProp: (input: SaveEffectPropInput) => Promise<void>;
24
+ export {};
@@ -3,28 +3,46 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.saveEffectProp = void 0;
4
4
  const studio_shared_1 = require("@remotion/studio-shared");
5
5
  const call_api_1 = require("../call-api");
6
+ const apply_effect_response_to_code_values_1 = require("./apply-effect-response-to-code-values");
6
7
  const save_prop_queue_1 = require("./save-prop-queue");
7
- const saveEffectProp = ({ fileName, nodePath, effectIndex, fieldKey, value, defaultValue, schema, setCodeValues, clientId, }) => {
8
+ const saveEffectProp = (input) => {
9
+ const { fileName, nodePath, effectIndex, fieldKey, defaultValue, schema, setCodeValues, clientId, } = input;
8
10
  return (0, save_prop_queue_1.enqueueSavePropChange)({
9
11
  nodePath,
10
12
  setCodeValues,
11
- applyOptimistic: (prev) => (0, studio_shared_1.optimisticUpdateForEffectCodeValues)({
12
- previous: prev,
13
- effectIndex,
14
- fieldKey,
15
- value,
16
- schema,
17
- }),
18
- apiCall: () => (0, call_api_1.callApi)('/api/save-effect-props', {
19
- fileName,
20
- sequenceNodePath: nodePath,
21
- effectIndex,
22
- key: fieldKey,
23
- value: JSON.stringify(value),
24
- defaultValue,
25
- schema,
26
- clientId,
27
- }),
13
+ applyOptimistic: (prev) => input.type === 'effect-param'
14
+ ? prev
15
+ : (0, studio_shared_1.optimisticUpdateForEffectCodeValues)({
16
+ previous: prev,
17
+ effectIndex,
18
+ fieldKey,
19
+ value: input.value,
20
+ schema,
21
+ }),
22
+ applyServerResponse: (prev, response) => (0, apply_effect_response_to_code_values_1.applyEffectResponseToCodeValues)({ previous: prev, response }),
23
+ apiCall: () => (0, call_api_1.callApi)('/api/save-effect-props', input.type === 'effect-param'
24
+ ? {
25
+ type: 'effect-param',
26
+ fileName,
27
+ sequenceNodePath: nodePath,
28
+ effectIndex,
29
+ key: fieldKey,
30
+ effectParam: input.effectParam,
31
+ defaultValue,
32
+ schema,
33
+ clientId,
34
+ }
35
+ : {
36
+ type: 'value',
37
+ fileName,
38
+ sequenceNodePath: nodePath,
39
+ effectIndex,
40
+ key: fieldKey,
41
+ value: JSON.stringify(input.value),
42
+ defaultValue,
43
+ schema,
44
+ clientId,
45
+ }),
28
46
  errorLabel: 'Could not save effect prop',
29
47
  });
30
48
  };
@@ -4,8 +4,9 @@ export type EnqueueSaveOptions<TResponse> = {
4
4
  nodePath: SequencePropsSubscriptionKey;
5
5
  setCodeValues: SetCodeValues;
6
6
  applyOptimistic: (prev: CanUpdateSequencePropsResponse) => CanUpdateSequencePropsResponse;
7
+ applyServerResponse?: (prev: CanUpdateSequencePropsResponse, response: TResponse) => CanUpdateSequencePropsResponse;
7
8
  apiCall: () => Promise<TResponse>;
8
9
  errorLabel: string;
9
10
  };
10
- export declare const enqueueSavePropChange: <TResponse>({ nodePath, setCodeValues, applyOptimistic, apiCall, errorLabel, }: EnqueueSaveOptions<TResponse>) => Promise<void>;
11
+ export declare const enqueueSavePropChange: <TResponse>({ nodePath, setCodeValues, applyOptimistic, applyServerResponse, apiCall, errorLabel, }: EnqueueSaveOptions<TResponse>) => Promise<void>;
11
12
  export {};
@@ -19,7 +19,7 @@ const dropQueue = (nodePath, q) => {
19
19
  queues.delete(key);
20
20
  }
21
21
  };
22
- const enqueueSavePropChange = ({ nodePath, setCodeValues, applyOptimistic, apiCall, errorLabel, }) => {
22
+ const enqueueSavePropChange = ({ nodePath, setCodeValues, applyOptimistic, applyServerResponse, apiCall, errorLabel, }) => {
23
23
  const q = getQueue(nodePath);
24
24
  if (q.cancelled) {
25
25
  return Promise.resolve();
@@ -33,12 +33,15 @@ const enqueueSavePropChange = ({ nodePath, setCodeValues, applyOptimistic, apiCa
33
33
  return;
34
34
  }
35
35
  try {
36
- await apiCall();
36
+ const response = await apiCall();
37
37
  if (myQueue.cancelled) {
38
38
  return;
39
39
  }
40
40
  // If nothing more is queued, reset baseline so the next round starts fresh.
41
41
  if (myQueue.chain === next) {
42
+ if (applyServerResponse) {
43
+ setCodeValues(nodePath, (prev) => applyServerResponse(prev, response));
44
+ }
42
45
  dropQueue(nodePath, myQueue);
43
46
  }
44
47
  }
@@ -12,13 +12,8 @@ type SaveSequencePropsOptions = {
12
12
  changes: SaveSequencePropChange[];
13
13
  setCodeValues: SetCodeValues;
14
14
  clientId: string;
15
- undoLabel: string | null;
16
- redoLabel: string | null;
17
- };
18
- type SaveSequencePropOptions = SaveSequencePropChange & {
19
- setCodeValues: SetCodeValues;
20
- clientId: string;
15
+ undoLabel: string;
16
+ redoLabel: string;
21
17
  };
22
18
  export declare const saveSequenceProps: ({ changes, setCodeValues, clientId, undoLabel, redoLabel, }: SaveSequencePropsOptions) => Promise<void>;
23
- export declare const saveSequenceProp: ({ fileName, nodePath, fieldKey, value, defaultValue, schema, setCodeValues, clientId, }: SaveSequencePropOptions) => Promise<void>;
24
19
  export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.saveSequenceProp = exports.saveSequenceProps = void 0;
3
+ exports.saveSequenceProps = void 0;
4
4
  const studio_shared_1 = require("@remotion/studio-shared");
5
5
  const call_api_1 = require("../call-api");
6
6
  const save_prop_queue_1 = require("./save-prop-queue");
@@ -8,6 +8,38 @@ const saveSequenceProps = ({ changes, setCodeValues, clientId, undoLabel, redoLa
8
8
  if (changes.length === 0) {
9
9
  return Promise.resolve();
10
10
  }
11
+ if (changes.length === 1) {
12
+ const change = changes[0];
13
+ if (change === undefined) {
14
+ throw new Error('Expected a sequence prop change');
15
+ }
16
+ return (0, save_prop_queue_1.enqueueSavePropChange)({
17
+ nodePath: change.nodePath,
18
+ setCodeValues,
19
+ applyOptimistic: (prev) => (0, studio_shared_1.optimisticUpdateForCodeValues)({
20
+ previous: prev,
21
+ fieldKey: change.fieldKey,
22
+ value: change.value,
23
+ schema: change.schema,
24
+ }),
25
+ apiCall: () => (0, call_api_1.callApi)('/api/save-sequence-props', {
26
+ edits: [
27
+ {
28
+ fileName: change.fileName,
29
+ nodePath: change.nodePath,
30
+ key: change.fieldKey,
31
+ value: JSON.stringify(change.value),
32
+ defaultValue: change.defaultValue,
33
+ schema: change.schema,
34
+ },
35
+ ],
36
+ clientId,
37
+ undoLabel,
38
+ redoLabel,
39
+ }),
40
+ errorLabel: 'Could not save sequence prop',
41
+ });
42
+ }
11
43
  for (const change of changes) {
12
44
  setCodeValues(change.nodePath, (prev) => (0, studio_shared_1.optimisticUpdateForCodeValues)({
13
45
  previous: prev,
@@ -33,32 +65,3 @@ const saveSequenceProps = ({ changes, setCodeValues, clientId, undoLabel, redoLa
33
65
  }).then(() => undefined);
34
66
  };
35
67
  exports.saveSequenceProps = saveSequenceProps;
36
- const saveSequenceProp = ({ fileName, nodePath, fieldKey, value, defaultValue, schema, setCodeValues, clientId, }) => {
37
- return (0, save_prop_queue_1.enqueueSavePropChange)({
38
- nodePath,
39
- setCodeValues,
40
- applyOptimistic: (prev) => (0, studio_shared_1.optimisticUpdateForCodeValues)({
41
- previous: prev,
42
- fieldKey,
43
- value,
44
- schema,
45
- }),
46
- apiCall: () => (0, call_api_1.callApi)('/api/save-sequence-props', {
47
- edits: [
48
- {
49
- fileName,
50
- nodePath,
51
- key: fieldKey,
52
- value: JSON.stringify(value),
53
- defaultValue,
54
- schema,
55
- },
56
- ],
57
- clientId,
58
- undoLabel: null,
59
- redoLabel: null,
60
- }),
61
- errorLabel: 'Could not save sequence prop',
62
- });
63
- };
64
- exports.saveSequenceProp = saveSequenceProp;
@@ -0,0 +1,3 @@
1
+ export declare const shouldClearSelectionOnPointerDown: (event: {
2
+ readonly button: number;
3
+ }) => boolean;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.shouldClearSelectionOnPointerDown = void 0;
4
+ const shouldClearSelectionOnPointerDown = (event) => {
5
+ return event.button === 0;
6
+ };
7
+ exports.shouldClearSelectionOnPointerDown = shouldClearSelectionOnPointerDown;
@@ -0,0 +1,13 @@
1
+ type LinkInfo = {
2
+ kind: 'local';
3
+ assetPath: string;
4
+ title: string;
5
+ } | {
6
+ kind: 'remote';
7
+ href: string;
8
+ title: string;
9
+ } | null;
10
+ export type TimelineAssetLinkInfo = Exclude<LinkInfo, null>;
11
+ export declare const getTimelineAssetLinkInfo: (src: string) => LinkInfo;
12
+ export declare const openTimelineAssetLink: (linkInfo: TimelineAssetLinkInfo, selectAsset: (asset: string) => void) => void;
13
+ export {};
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.openTimelineAssetLink = exports.getTimelineAssetLinkInfo = void 0;
4
+ const url_state_1 = require("../../helpers/url-state");
5
+ const getTimelineAssetLinkInfo = (src) => {
6
+ const staticBase = typeof window === 'undefined' ? null : window.remotion_staticBase;
7
+ if (staticBase && src.startsWith(staticBase + '/')) {
8
+ const assetPath = src.slice(staticBase.length + 1);
9
+ return {
10
+ kind: 'local',
11
+ assetPath: decodeURIComponent(assetPath),
12
+ title: decodeURIComponent(assetPath),
13
+ };
14
+ }
15
+ if (src.startsWith('http://') ||
16
+ src.startsWith('https://') ||
17
+ src.startsWith('//')) {
18
+ try {
19
+ const url = new URL(src.startsWith('//') ? 'https:' + src : src);
20
+ return { kind: 'remote', href: src, title: url.hostname };
21
+ }
22
+ catch (_a) {
23
+ return { kind: 'remote', href: src, title: src };
24
+ }
25
+ }
26
+ return null;
27
+ };
28
+ exports.getTimelineAssetLinkInfo = getTimelineAssetLinkInfo;
29
+ const openTimelineAssetLink = (linkInfo, selectAsset) => {
30
+ if (linkInfo.kind === 'local') {
31
+ selectAsset(linkInfo.assetPath);
32
+ (0, url_state_1.pushUrl)(`/assets/${linkInfo.assetPath}`);
33
+ return;
34
+ }
35
+ window.open(linkInfo.href, '_blank', 'noopener,noreferrer');
36
+ };
37
+ exports.openTimelineAssetLink = openTimelineAssetLink;
@@ -1,2 +1,3 @@
1
1
  export declare const getDecimalPlaces: (num: number) => number;
2
+ export declare const normalizeTimelineNumber: (value: number) => number;
2
3
  export declare const draggerStyle: React.CSSProperties;
@@ -1,12 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.draggerStyle = exports.getDecimalPlaces = void 0;
3
+ exports.draggerStyle = exports.normalizeTimelineNumber = exports.getDecimalPlaces = void 0;
4
4
  const getDecimalPlaces = (num) => {
5
5
  const str = String(num);
6
6
  const decimalIndex = str.indexOf('.');
7
7
  return decimalIndex === -1 ? 0 : str.length - decimalIndex - 1;
8
8
  };
9
9
  exports.getDecimalPlaces = getDecimalPlaces;
10
+ const normalizeTimelineNumber = (value) => {
11
+ return Math.round(value * 1000000) / 1000000;
12
+ };
13
+ exports.normalizeTimelineNumber = normalizeTimelineNumber;
10
14
  exports.draggerStyle = {
11
15
  width: 80,
12
16
  };
@@ -1,17 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.serializeTranslate = exports.parseTranslate = void 0;
4
+ const timeline_field_utils_1 = require("./timeline-field-utils");
4
5
  const PIXEL_PATTERN = /^(-?\d+(?:\.\d+)?)px(?:\s+(-?\d+(?:\.\d+)?)px)?$/;
6
+ const translateDecimalPlaces = 1;
5
7
  const parseTranslate = (value) => {
6
8
  const m = value.match(PIXEL_PATTERN);
7
9
  if (!m) {
8
10
  return [0, 0];
9
11
  }
10
- return [Number(m[1]), m[2] !== undefined ? Number(m[2]) : 0];
12
+ return [
13
+ (0, timeline_field_utils_1.normalizeTimelineNumber)(Number(m[1])),
14
+ m[2] !== undefined ? (0, timeline_field_utils_1.normalizeTimelineNumber)(Number(m[2])) : 0,
15
+ ];
11
16
  };
12
17
  exports.parseTranslate = parseTranslate;
13
18
  const formatTranslateCoordinate = (value) => {
14
- const rounded = Math.round(value * 1000) / 1000;
19
+ const normalized = (0, timeline_field_utils_1.normalizeTimelineNumber)(value);
20
+ const factor = 10 ** translateDecimalPlaces;
21
+ const rounded = Math.round(normalized * factor) / factor;
15
22
  return String(Object.is(rounded, -0) ? 0 : rounded);
16
23
  };
17
24
  const serializeTranslate = (x, y) => {
@@ -11,6 +11,7 @@ const useExpandedTrackKeyframeRows = ({ sequence, nodePathInfo, keyframeDisplayO
11
11
  const { getIsExpanded } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksGetterContext);
12
12
  const { codeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeCodeValuesContext);
13
13
  const { getDragOverrides, getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
14
+ const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
14
15
  const tree = (0, react_1.useMemo)(() => (0, timeline_layout_1.buildTimelineTree)({
15
16
  sequence,
16
17
  nodePathInfo,
@@ -38,14 +39,20 @@ const useExpandedTrackKeyframeRows = ({ sequence, nodePathInfo, keyframeDisplayO
38
39
  nodePath: nodePathInfo.sequenceSubscriptionKey,
39
40
  codeValues,
40
41
  keyframeDisplayOffset,
42
+ getDragOverrides,
43
+ getEffectDragOverrides,
44
+ timelinePosition,
41
45
  }),
42
46
  rowKey: (0, timeline_node_path_key_1.timelineNodePathInfoToKey)(node.nodePathInfo),
43
47
  nodePathInfo: node.nodePathInfo,
44
48
  })), [
45
49
  codeValues,
46
50
  flat,
51
+ getDragOverrides,
52
+ getEffectDragOverrides,
47
53
  keyframeDisplayOffset,
48
54
  nodePathInfo.sequenceSubscriptionKey,
55
+ timelinePosition,
49
56
  ]);
50
57
  return { rows, expandedHeight };
51
58
  };
@@ -0,0 +1,10 @@
1
+ import type React from 'react';
2
+ import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
3
+ import { type TimelineSelectionInteraction } from './TimelineSelection';
4
+ export declare const useTimelineKeyframeDrag: ({ frame, nodePathInfo, onSelect, selectable, selected, }: {
5
+ readonly frame: number;
6
+ readonly nodePathInfo: SequenceNodePathInfo;
7
+ readonly onSelect: (interaction?: TimelineSelectionInteraction | undefined) => void;
8
+ readonly selectable: boolean;
9
+ readonly selected: boolean;
10
+ }) => (e: React.PointerEvent<HTMLButtonElement>) => void;