@remotion/studio 4.0.472 → 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 (133) 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 +153 -27
  5. package/dist/components/Canvas.js +60 -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 +6 -2
  30. package/dist/components/NewComposition/ComboBox.js +8 -2
  31. package/dist/components/NewComposition/DeleteStaticFile.d.ts +4 -0
  32. package/dist/components/NewComposition/DeleteStaticFile.js +44 -0
  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 +24 -0
  44. package/dist/components/SelectedOutlineOverlay.js +190 -22
  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/Timeline.js +3 -13
  53. package/dist/components/Timeline/TimelineClipboardKeybindings.d.ts +25 -2
  54. package/dist/components/Timeline/TimelineClipboardKeybindings.js +234 -20
  55. package/dist/components/Timeline/TimelineDeleteKeybindings.js +12 -2
  56. package/dist/components/Timeline/TimelineEffectItem.js +1 -0
  57. package/dist/components/Timeline/TimelineEffectPropItem.js +52 -2
  58. package/dist/components/Timeline/TimelineKeyframeControls.js +5 -15
  59. package/dist/components/Timeline/TimelineKeyframeDiamond.js +24 -21
  60. package/dist/components/Timeline/TimelineKeyframeDiamondIcon.d.ts +6 -0
  61. package/dist/components/Timeline/TimelineKeyframeDiamondIcon.js +14 -0
  62. package/dist/components/Timeline/TimelineKeyframeDragState.d.ts +17 -0
  63. package/dist/components/Timeline/TimelineKeyframeDragState.js +39 -0
  64. package/dist/components/Timeline/TimelineList.js +2 -2
  65. package/dist/components/Timeline/TimelineMediaInfo.d.ts +0 -13
  66. package/dist/components/Timeline/TimelineMediaInfo.js +8 -73
  67. package/dist/components/Timeline/TimelineScaleField.js +1 -1
  68. package/dist/components/Timeline/TimelineSequenceItem.d.ts +1 -0
  69. package/dist/components/Timeline/TimelineSequenceItem.js +276 -22
  70. package/dist/components/Timeline/TimelineSequencePropItem.js +81 -16
  71. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +25 -28
  72. package/dist/components/Timeline/apply-effect-response-to-code-values.d.ts +5 -0
  73. package/dist/components/Timeline/apply-effect-response-to-code-values.js +19 -0
  74. package/dist/components/Timeline/call-add-keyframe.js +2 -0
  75. package/dist/components/Timeline/call-move-keyframe.d.ts +19 -0
  76. package/dist/components/Timeline/call-move-keyframe.js +71 -0
  77. package/dist/components/Timeline/call-update-keyframe-settings.d.ts +22 -0
  78. package/dist/components/Timeline/call-update-keyframe-settings.js +52 -0
  79. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +7 -4
  80. package/dist/components/Timeline/delete-selected-timeline-item.js +33 -21
  81. package/dist/components/Timeline/duplicate-selected-timeline-item.d.ts +4 -2
  82. package/dist/components/Timeline/duplicate-selected-timeline-item.js +39 -34
  83. package/dist/components/Timeline/get-bounded-keyframe-drag-delta.d.ts +8 -0
  84. package/dist/components/Timeline/get-bounded-keyframe-drag-delta.js +12 -0
  85. package/dist/components/Timeline/get-keyframe-navigation.d.ts +2 -2
  86. package/dist/components/Timeline/get-keyframe-navigation.js +14 -6
  87. package/dist/components/Timeline/reset-selected-timeline-props.js +3 -2
  88. package/dist/components/Timeline/save-effect-prop.d.ts +14 -3
  89. package/dist/components/Timeline/save-effect-prop.js +36 -18
  90. package/dist/components/Timeline/save-prop-queue.d.ts +2 -1
  91. package/dist/components/Timeline/save-prop-queue.js +5 -2
  92. package/dist/components/Timeline/save-sequence-prop.d.ts +2 -7
  93. package/dist/components/Timeline/save-sequence-prop.js +33 -30
  94. package/dist/components/Timeline/should-clear-selection-on-pointer-down.d.ts +3 -0
  95. package/dist/components/Timeline/should-clear-selection-on-pointer-down.js +7 -0
  96. package/dist/components/Timeline/timeline-asset-link.d.ts +13 -0
  97. package/dist/components/Timeline/timeline-asset-link.js +37 -0
  98. package/dist/components/Timeline/timeline-translate-utils.js +4 -1
  99. package/dist/components/Timeline/use-timeline-keyframe-drag.d.ts +10 -0
  100. package/dist/components/Timeline/use-timeline-keyframe-drag.js +378 -0
  101. package/dist/components/import-assets.d.ts +16 -0
  102. package/dist/components/import-assets.js +155 -18
  103. package/dist/components/load-canvas-content-from-url.d.ts +1 -0
  104. package/dist/components/load-canvas-content-from-url.js +9 -3
  105. package/dist/components/use-select-asset.d.ts +1 -0
  106. package/dist/components/use-select-asset.js +30 -0
  107. package/dist/error-overlay/error-origin.d.ts +3 -0
  108. package/dist/error-overlay/error-origin.js +42 -0
  109. package/dist/error-overlay/react-overlay/listen-to-runtime-errors.js +6 -2
  110. package/dist/error-overlay/remotion-overlay/ErrorLoader.js +38 -0
  111. package/dist/error-overlay/remotion-overlay/ShortcutHint.js +1 -1
  112. package/dist/error-overlay/remotion-overlay/log-studio-error.d.ts +3 -0
  113. package/dist/error-overlay/remotion-overlay/log-studio-error.js +27 -0
  114. package/dist/esm/{chunk-48grt472.js → chunk-q0jkt0zq.js} +21961 -19299
  115. package/dist/esm/internals.mjs +21961 -19299
  116. package/dist/esm/previewEntry.mjs +20600 -17914
  117. package/dist/esm/renderEntry.mjs +1 -1
  118. package/dist/helpers/get-asset-metadata.js +2 -2
  119. package/dist/helpers/get-preview-file-type.d.ts +2 -0
  120. package/dist/helpers/get-preview-file-type.js +33 -0
  121. package/dist/helpers/install-required-package.d.ts +1 -0
  122. package/dist/helpers/install-required-package.js +39 -0
  123. package/dist/helpers/remote-asset-drag.d.ts +4 -0
  124. package/dist/helpers/remote-asset-drag.js +73 -0
  125. package/dist/helpers/use-asset-drag-events.d.ts +5 -2
  126. package/dist/helpers/use-asset-drag-events.js +13 -2
  127. package/dist/hot-middleware-client/client.js +6 -0
  128. package/dist/state/editor-outlines.d.ts +8 -0
  129. package/dist/state/editor-outlines.js +18 -0
  130. package/dist/state/modals.d.ts +19 -2
  131. package/package.json +10 -10
  132. package/dist/helpers/detect-file-type.d.ts +0 -69
  133. package/dist/helpers/detect-file-type.js +0 -278
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.applyEffectResponseToCodeValues = void 0;
4
+ const applyEffectResponseToCodeValues = ({ previous, response, }) => {
5
+ if (!previous.canUpdate) {
6
+ return previous;
7
+ }
8
+ const targetIndex = previous.effects.findIndex((effect) => effect.effectIndex === response.effectIndex);
9
+ if (targetIndex === -1) {
10
+ return previous;
11
+ }
12
+ const effects = [...previous.effects];
13
+ effects[targetIndex] = response;
14
+ return {
15
+ ...previous,
16
+ effects,
17
+ };
18
+ };
19
+ exports.applyEffectResponseToCodeValues = applyEffectResponseToCodeValues;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.callAddEffectKeyframe = exports.callAddSequenceKeyframe = 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
8
  const callAddSequenceKeyframe = ({ fileName, nodePath, fieldKey, sourceFrame, value, schema, setCodeValues, clientId, }) => {
8
9
  return (0, save_prop_queue_1.enqueueSavePropChange)({
@@ -40,6 +41,7 @@ const callAddEffectKeyframe = ({ fileName, nodePath, effectIndex, fieldKey, sour
40
41
  value,
41
42
  schema,
42
43
  }),
44
+ applyServerResponse: (prev, response) => (0, apply_effect_response_to_code_values_1.applyEffectResponseToCodeValues)({ previous: prev, response }),
43
45
  apiCall: () => (0, call_api_1.callApi)('/api/add-effect-keyframe', {
44
46
  fileName,
45
47
  sequenceNodePath: nodePath,
@@ -0,0 +1,19 @@
1
+ import type { SequencePropsSubscriptionKey, SequenceSchema } from 'remotion';
2
+ import type { SetCodeValues } from './save-sequence-prop';
3
+ export type MoveSequenceKeyframeChange = {
4
+ fileName: string;
5
+ nodePath: SequencePropsSubscriptionKey;
6
+ fieldKey: string;
7
+ fromFrame: number;
8
+ toFrame: number;
9
+ schema: SequenceSchema;
10
+ };
11
+ export type MoveEffectKeyframeChange = MoveSequenceKeyframeChange & {
12
+ effectIndex: number;
13
+ };
14
+ export declare const callMoveKeyframes: ({ sequenceKeyframes, effectKeyframes, setCodeValues, clientId, }: {
15
+ sequenceKeyframes: MoveSequenceKeyframeChange[];
16
+ effectKeyframes: MoveEffectKeyframeChange[];
17
+ setCodeValues: SetCodeValues;
18
+ clientId: string;
19
+ }) => Promise<void>;
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.callMoveKeyframes = void 0;
4
+ const studio_shared_1 = require("@remotion/studio-shared");
5
+ const call_api_1 = require("../call-api");
6
+ const groupByNodePath = (keyframes) => {
7
+ var _a;
8
+ const groups = new Map();
9
+ for (const keyframe of keyframes) {
10
+ const key = JSON.stringify(keyframe.nodePath);
11
+ const group = (_a = groups.get(key)) !== null && _a !== void 0 ? _a : [];
12
+ group.push(keyframe);
13
+ groups.set(key, group);
14
+ }
15
+ return [...groups.values()];
16
+ };
17
+ const callMoveKeyframes = ({ sequenceKeyframes, effectKeyframes, setCodeValues, clientId, }) => {
18
+ if (sequenceKeyframes.length === 0 && effectKeyframes.length === 0) {
19
+ return Promise.resolve();
20
+ }
21
+ for (const keyframes of groupByNodePath(sequenceKeyframes)) {
22
+ const [firstKeyframe] = keyframes;
23
+ if (!firstKeyframe) {
24
+ continue;
25
+ }
26
+ setCodeValues(firstKeyframe.nodePath, (prev) => (0, studio_shared_1.optimisticMoveSequenceKeyframes)({
27
+ previous: prev,
28
+ keyframes: keyframes.map((keyframe) => ({
29
+ fieldKey: keyframe.fieldKey,
30
+ fromFrame: keyframe.fromFrame,
31
+ toFrame: keyframe.toFrame,
32
+ })),
33
+ }));
34
+ }
35
+ for (const keyframes of groupByNodePath(effectKeyframes)) {
36
+ const [firstKeyframe] = keyframes;
37
+ if (!firstKeyframe) {
38
+ continue;
39
+ }
40
+ setCodeValues(firstKeyframe.nodePath, (prev) => (0, studio_shared_1.optimisticMoveEffectKeyframes)({
41
+ previous: prev,
42
+ keyframes: keyframes.map((keyframe) => ({
43
+ effectIndex: keyframe.effectIndex,
44
+ fieldKey: keyframe.fieldKey,
45
+ fromFrame: keyframe.fromFrame,
46
+ toFrame: keyframe.toFrame,
47
+ })),
48
+ }));
49
+ }
50
+ return (0, call_api_1.callApi)('/api/move-keyframes', {
51
+ sequenceKeyframes: sequenceKeyframes.map((keyframe) => ({
52
+ fileName: keyframe.fileName,
53
+ nodePath: keyframe.nodePath,
54
+ key: keyframe.fieldKey,
55
+ fromFrame: keyframe.fromFrame,
56
+ toFrame: keyframe.toFrame,
57
+ schema: keyframe.schema,
58
+ })),
59
+ effectKeyframes: effectKeyframes.map((keyframe) => ({
60
+ fileName: keyframe.fileName,
61
+ sequenceNodePath: keyframe.nodePath,
62
+ effectIndex: keyframe.effectIndex,
63
+ key: keyframe.fieldKey,
64
+ fromFrame: keyframe.fromFrame,
65
+ toFrame: keyframe.toFrame,
66
+ schema: keyframe.schema,
67
+ })),
68
+ clientId,
69
+ }).then(() => undefined);
70
+ };
71
+ exports.callMoveKeyframes = callMoveKeyframes;
@@ -0,0 +1,22 @@
1
+ import { type KeyframeSettings } from '@remotion/studio-shared';
2
+ import type { SequencePropsSubscriptionKey, SequenceSchema } from 'remotion';
3
+ import type { SetCodeValues } from './save-sequence-prop';
4
+ export declare const callUpdateSequenceKeyframeSettings: ({ fileName, nodePath, fieldKey, settings, schema, setCodeValues, clientId, }: {
5
+ fileName: string;
6
+ nodePath: SequencePropsSubscriptionKey;
7
+ fieldKey: string;
8
+ settings: KeyframeSettings;
9
+ schema: SequenceSchema;
10
+ setCodeValues: SetCodeValues;
11
+ clientId: string;
12
+ }) => Promise<void>;
13
+ export declare const callUpdateEffectKeyframeSettings: ({ fileName, nodePath, effectIndex, fieldKey, settings, schema, setCodeValues, clientId, }: {
14
+ fileName: string;
15
+ nodePath: SequencePropsSubscriptionKey;
16
+ effectIndex: number;
17
+ fieldKey: string;
18
+ settings: KeyframeSettings;
19
+ schema: SequenceSchema;
20
+ setCodeValues: SetCodeValues;
21
+ clientId: string;
22
+ }) => Promise<void>;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.callUpdateEffectKeyframeSettings = exports.callUpdateSequenceKeyframeSettings = void 0;
4
+ const studio_shared_1 = require("@remotion/studio-shared");
5
+ const call_api_1 = require("../call-api");
6
+ const apply_effect_response_to_code_values_1 = require("./apply-effect-response-to-code-values");
7
+ const save_prop_queue_1 = require("./save-prop-queue");
8
+ const callUpdateSequenceKeyframeSettings = ({ fileName, nodePath, fieldKey, settings, schema, setCodeValues, clientId, }) => {
9
+ return (0, save_prop_queue_1.enqueueSavePropChange)({
10
+ nodePath,
11
+ setCodeValues,
12
+ applyOptimistic: (prev) => (0, studio_shared_1.optimisticUpdateSequenceKeyframeSettings)({
13
+ previous: prev,
14
+ fieldKey,
15
+ settings,
16
+ }),
17
+ apiCall: () => (0, call_api_1.callApi)('/api/update-sequence-keyframe-settings', {
18
+ fileName,
19
+ nodePath,
20
+ key: fieldKey,
21
+ settings,
22
+ schema,
23
+ clientId,
24
+ }),
25
+ errorLabel: 'Could not update keyframe settings',
26
+ });
27
+ };
28
+ exports.callUpdateSequenceKeyframeSettings = callUpdateSequenceKeyframeSettings;
29
+ const callUpdateEffectKeyframeSettings = ({ fileName, nodePath, effectIndex, fieldKey, settings, schema, setCodeValues, clientId, }) => {
30
+ return (0, save_prop_queue_1.enqueueSavePropChange)({
31
+ nodePath,
32
+ setCodeValues,
33
+ applyOptimistic: (prev) => (0, studio_shared_1.optimisticUpdateEffectKeyframeSettings)({
34
+ previous: prev,
35
+ effectIndex,
36
+ fieldKey,
37
+ settings,
38
+ }),
39
+ applyServerResponse: (prev, response) => (0, apply_effect_response_to_code_values_1.applyEffectResponseToCodeValues)({ previous: prev, response }),
40
+ apiCall: () => (0, call_api_1.callApi)('/api/update-effect-keyframe-settings', {
41
+ fileName,
42
+ sequenceNodePath: nodePath,
43
+ effectIndex,
44
+ key: fieldKey,
45
+ settings,
46
+ schema,
47
+ clientId,
48
+ }),
49
+ errorLabel: 'Could not update keyframe settings',
50
+ });
51
+ };
52
+ exports.callUpdateEffectKeyframeSettings = callUpdateEffectKeyframeSettings;
@@ -1,17 +1,20 @@
1
1
  import type { OverrideIdToNodePaths, TSequence } from 'remotion';
2
+ import type { ConfirmationDialogFunction } from '../ConfirmationDialog-types';
2
3
  import type { SetCodeValues } from './save-sequence-prop';
3
4
  import type { TimelineSelection } from './TimelineSelection';
4
- export declare const deleteSelectedTimelineItem: ({ selection, sequences, overrideIdsToNodePaths, setCodeValues, clientId, }: {
5
+ export declare const deleteSelectedTimelineItem: ({ selection, sequences, overrideIdsToNodePaths, setCodeValues, clientId, confirm, }: {
5
6
  selection: TimelineSelection;
6
7
  sequences: TSequence[];
7
8
  overrideIdsToNodePaths: OverrideIdToNodePaths;
8
9
  setCodeValues: SetCodeValues;
9
10
  clientId: string;
10
- }) => Promise<void> | null;
11
- export declare const deleteSelectedTimelineItems: ({ selections, sequences, overrideIdsToNodePaths, setCodeValues, clientId, }: {
11
+ confirm: ConfirmationDialogFunction;
12
+ }) => Promise<boolean> | null;
13
+ export declare const deleteSelectedTimelineItems: ({ selections, sequences, overrideIdsToNodePaths, setCodeValues, clientId, confirm, }: {
12
14
  selections: readonly TimelineSelection[];
13
15
  sequences: TSequence[];
14
16
  overrideIdsToNodePaths: OverrideIdToNodePaths;
15
17
  setCodeValues: SetCodeValues;
16
18
  clientId: string;
17
- }) => Promise<void> | null;
19
+ confirm: ConfirmationDialogFunction;
20
+ }) => Promise<boolean> | null;
@@ -4,27 +4,31 @@ exports.deleteSelectedTimelineItems = exports.deleteSelectedTimelineItem = void
4
4
  const call_api_1 = require("../call-api");
5
5
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
6
6
  const delete_selected_keyframe_1 = require("./delete-selected-keyframe");
7
- const confirmDeletingDuplicatedSequences = (nodePathInfos) => {
7
+ const confirmDeletingDuplicatedSequences = (nodePathInfos, confirm) => {
8
8
  const duplicatedNodePathInfos = nodePathInfos.filter((nodePathInfo) => nodePathInfo.numberOfSequencesWithThisNodePath > 1);
9
9
  if (duplicatedNodePathInfos.length === 0) {
10
- return true;
10
+ return Promise.resolve(true);
11
11
  }
12
12
  if (duplicatedNodePathInfos.length === 1) {
13
13
  const [nodePathInfo] = duplicatedNodePathInfos;
14
- const singleDuplicatedSequenceMessage = 'This sequence is programmatically duplicated ' +
15
- nodePathInfo.numberOfSequencesWithThisNodePath +
16
- ' times in the code. Deleting removes all instances. Continue?';
17
- // eslint-disable-next-line no-alert -- native confirm before deleting all instances of a duplicated sequence
18
- return window.confirm(singleDuplicatedSequenceMessage);
14
+ return confirm({
15
+ title: 'Delete sequence?',
16
+ message: 'This sequence is programmatically duplicated ' +
17
+ nodePathInfo.numberOfSequencesWithThisNodePath +
18
+ ' times in the code. Deleting removes all instances. Continue?',
19
+ confirmLabel: 'Delete',
20
+ });
19
21
  }
20
- const multipleDuplicatedSequencesMessage = duplicatedNodePathInfos.length +
21
- ' selected sequences are programmatically duplicated in the code. Deleting removes all instances. Continue?';
22
- // eslint-disable-next-line no-alert -- native confirm before deleting all instances of duplicated sequences
23
- return window.confirm(multipleDuplicatedSequencesMessage);
22
+ return confirm({
23
+ title: 'Delete sequences?',
24
+ message: duplicatedNodePathInfos.length +
25
+ ' selected sequences are programmatically duplicated in the code. Deleting removes all instances. Continue?',
26
+ confirmLabel: 'Delete',
27
+ });
24
28
  };
25
- const deleteSequences = (nodePathInfos) => {
26
- if (!confirmDeletingDuplicatedSequences(nodePathInfos)) {
27
- return Promise.resolve();
29
+ const deleteSequences = async (nodePathInfos, confirm) => {
30
+ if (!(await confirmDeletingDuplicatedSequences(nodePathInfos, confirm))) {
31
+ return false;
28
32
  }
29
33
  return (0, call_api_1.callApi)('/api/delete-jsx-node', {
30
34
  nodes: nodePathInfos.map((nodePathInfo) => {
@@ -44,14 +48,16 @@ const deleteSequences = (nodePathInfos) => {
44
48
  else {
45
49
  (0, NotificationCenter_1.showNotification)(result.reason, 4000);
46
50
  }
51
+ return true;
47
52
  })
48
53
  .catch((err) => {
49
54
  (0, NotificationCenter_1.showNotification)(err.message, 4000);
55
+ return true;
50
56
  });
51
57
  };
52
58
  const deleteEffects = (effects) => {
53
59
  if (effects.length === 0) {
54
- return Promise.resolve();
60
+ return Promise.resolve(false);
55
61
  }
56
62
  return (0, call_api_1.callApi)('/api/delete-effect', effects.map((effect) => {
57
63
  const nodePath = effect.nodePathInfo.sequenceSubscriptionKey;
@@ -80,14 +86,17 @@ const deleteEffects = (effects) => {
80
86
  else {
81
87
  (0, NotificationCenter_1.showNotification)(result.reason, 4000);
82
88
  }
89
+ return true;
83
90
  })
84
91
  .catch((err) => {
85
92
  (0, NotificationCenter_1.showNotification)(err.message, 4000);
93
+ return true;
86
94
  });
87
95
  };
88
- const deleteSelectedTimelineItem = ({ selection, sequences, overrideIdsToNodePaths, setCodeValues, clientId, }) => {
96
+ const deleteSelectedTimelineItem = ({ selection, sequences, overrideIdsToNodePaths, setCodeValues, clientId, confirm, }) => {
97
+ var _a;
89
98
  if (selection.type === 'keyframe') {
90
- return (0, delete_selected_keyframe_1.deleteSelectedKeyframe)({
99
+ const promise = (0, delete_selected_keyframe_1.deleteSelectedKeyframe)({
91
100
  nodePathInfo: selection.nodePathInfo,
92
101
  frame: selection.frame,
93
102
  sequences,
@@ -95,10 +104,11 @@ const deleteSelectedTimelineItem = ({ selection, sequences, overrideIdsToNodePat
95
104
  setCodeValues,
96
105
  clientId,
97
106
  });
107
+ return (_a = promise === null || promise === void 0 ? void 0 : promise.then(() => true)) !== null && _a !== void 0 ? _a : null;
98
108
  }
99
109
  switch (selection.type) {
100
110
  case 'sequence':
101
- return deleteSequences([selection.nodePathInfo]);
111
+ return deleteSequences([selection.nodePathInfo], confirm);
102
112
  case 'sequence-effect':
103
113
  return deleteEffects([
104
114
  {
@@ -134,7 +144,8 @@ const assertTimelineSelectionsHaveSameType = (selections) => {
134
144
  }
135
145
  }
136
146
  };
137
- const deleteSelectedTimelineItems = ({ selections, sequences, overrideIdsToNodePaths, setCodeValues, clientId, }) => {
147
+ const deleteSelectedTimelineItems = ({ selections, sequences, overrideIdsToNodePaths, setCodeValues, clientId, confirm, }) => {
148
+ var _a;
138
149
  const firstSelection = selections[0];
139
150
  if (!firstSelection) {
140
151
  return null;
@@ -144,7 +155,7 @@ const deleteSelectedTimelineItems = ({ selections, sequences, overrideIdsToNodeP
144
155
  case 'sequence':
145
156
  return deleteSequences(selections
146
157
  .filter(isSequenceRowSelection)
147
- .map((selection) => selection.nodePathInfo));
158
+ .map((selection) => selection.nodePathInfo), confirm);
148
159
  case 'sequence-effect':
149
160
  return deleteEffects(selections.filter(isSequenceEffectSelection).map((selection) => ({
150
161
  type: 'single-effect',
@@ -152,7 +163,7 @@ const deleteSelectedTimelineItems = ({ selections, sequences, overrideIdsToNodeP
152
163
  effectIndex: selection.i,
153
164
  })));
154
165
  case 'keyframe': {
155
- return (0, delete_selected_keyframe_1.deleteSelectedKeyframes)({
166
+ const promise = (0, delete_selected_keyframe_1.deleteSelectedKeyframes)({
156
167
  keyframes: selections.filter(isKeyframeSelection).map((selection) => ({
157
168
  nodePathInfo: selection.nodePathInfo,
158
169
  frame: selection.frame,
@@ -162,6 +173,7 @@ const deleteSelectedTimelineItems = ({ selections, sequences, overrideIdsToNodeP
162
173
  setCodeValues,
163
174
  clientId,
164
175
  });
176
+ return (_a = promise === null || promise === void 0 ? void 0 : promise.then(() => true)) !== null && _a !== void 0 ? _a : null;
165
177
  }
166
178
  case 'sequence-prop':
167
179
  case 'sequence-effect-prop':
@@ -1,6 +1,7 @@
1
1
  import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
2
+ import type { ConfirmationDialogFunction } from '../ConfirmationDialog-types';
2
3
  import type { TimelineSelection } from './TimelineSelection';
3
- export declare const duplicateSequencesFromSource: (nodePathInfos: readonly SequenceNodePathInfo[]) => Promise<void>;
4
+ export declare const duplicateSequencesFromSource: (nodePathInfos: readonly SequenceNodePathInfo[], confirm: ConfirmationDialogFunction) => Promise<void>;
4
5
  export declare const isDuplicatableSequenceRowSelection: (selection: TimelineSelection) => selection is {
5
6
  readonly nodePathInfo: SequenceNodePathInfo;
6
7
  } & {
@@ -8,6 +9,7 @@ export declare const isDuplicatableSequenceRowSelection: (selection: TimelineSel
8
9
  } & {
9
10
  type: "sequence";
10
11
  };
11
- export declare const duplicateSelectedTimelineItems: ({ selections, }: {
12
+ export declare const duplicateSelectedTimelineItems: ({ selections, confirm, }: {
12
13
  selections: readonly TimelineSelection[];
14
+ confirm: ConfirmationDialogFunction;
13
15
  }) => Promise<void> | null;
@@ -3,22 +3,26 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.duplicateSelectedTimelineItems = exports.isDuplicatableSequenceRowSelection = exports.duplicateSequencesFromSource = void 0;
4
4
  const call_api_1 = require("../call-api");
5
5
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
6
- const confirmDuplicatingProgrammaticallyDuplicatedSequences = (nodePathInfos) => {
6
+ const confirmDuplicatingProgrammaticallyDuplicatedSequences = (nodePathInfos, confirm) => {
7
7
  if (nodePathInfos.length === 0) {
8
- return true;
8
+ return Promise.resolve(true);
9
9
  }
10
10
  if (nodePathInfos.length === 1) {
11
11
  const [nodePathInfo] = nodePathInfos;
12
- const singleDuplicatedSequenceMessage = 'This sequence is programmatically duplicated ' +
13
- nodePathInfo.numberOfSequencesWithThisNodePath +
14
- ' times in the code. Duplicating inserts another copy. Continue?';
15
- // eslint-disable-next-line no-alert -- native confirm before applying duplicate codemod in .map callbacks
16
- return window.confirm(singleDuplicatedSequenceMessage);
12
+ return confirm({
13
+ title: 'Duplicate sequence?',
14
+ message: 'This sequence is programmatically duplicated ' +
15
+ nodePathInfo.numberOfSequencesWithThisNodePath +
16
+ ' times in the code. Duplicating inserts another copy. Continue?',
17
+ confirmLabel: 'Duplicate',
18
+ });
17
19
  }
18
- const multipleDuplicatedSequencesMessage = nodePathInfos.length +
19
- ' selected sequences are programmatically duplicated in the code. Duplicating inserts another copy of each. Continue?';
20
- // eslint-disable-next-line no-alert -- native confirm before applying duplicate codemod in .map callbacks
21
- return window.confirm(multipleDuplicatedSequencesMessage);
20
+ return confirm({
21
+ title: 'Duplicate sequences?',
22
+ message: nodePathInfos.length +
23
+ ' selected sequences are programmatically duplicated in the code. Duplicating inserts another copy of each. Continue?',
24
+ confirmLabel: 'Duplicate',
25
+ });
22
26
  };
23
27
  const duplicateSequence = (nodePathInfo) => {
24
28
  const nodePath = nodePathInfo.sequenceSubscriptionKey;
@@ -27,40 +31,41 @@ const duplicateSequence = (nodePathInfo) => {
27
31
  nodePath: nodePath.nodePath,
28
32
  });
29
33
  };
30
- const duplicateSequencesFromSource = (nodePathInfos) => {
34
+ const duplicateSequencesFromSource = (nodePathInfos, confirm) => {
31
35
  const programmaticallyDuplicated = nodePathInfos.filter((nodePathInfo) => nodePathInfo.numberOfSequencesWithThisNodePath > 1);
32
36
  const regular = nodePathInfos.filter((nodePathInfo) => nodePathInfo.numberOfSequencesWithThisNodePath <= 1);
33
- const toDuplicate = [...regular];
34
- if (programmaticallyDuplicated.length === 0 ||
35
- confirmDuplicatingProgrammaticallyDuplicatedSequences(programmaticallyDuplicated)) {
36
- toDuplicate.push(...programmaticallyDuplicated);
37
- }
38
- if (toDuplicate.length === 0) {
39
- return Promise.resolve();
40
- }
41
- return Promise.all(toDuplicate.map(duplicateSequence))
42
- .then((results) => {
43
- const failedResult = results.find((result) => !result.success);
44
- if (failedResult && !failedResult.success) {
45
- (0, NotificationCenter_1.showNotification)(failedResult.reason, 4000);
46
- return;
37
+ return confirmDuplicatingProgrammaticallyDuplicatedSequences(programmaticallyDuplicated, confirm).then((shouldDuplicateProgrammaticSequences) => {
38
+ const toDuplicate = [...regular];
39
+ if (shouldDuplicateProgrammaticSequences) {
40
+ toDuplicate.push(...programmaticallyDuplicated);
41
+ }
42
+ if (toDuplicate.length === 0) {
43
+ return Promise.resolve();
47
44
  }
48
- (0, NotificationCenter_1.showNotification)(toDuplicate.length === 1
49
- ? 'Duplicated sequence in source file'
50
- : 'Duplicated sequences in source files', 2000);
51
- })
52
- .catch((err) => {
53
- (0, NotificationCenter_1.showNotification)(err.message, 4000);
45
+ return Promise.all(toDuplicate.map(duplicateSequence))
46
+ .then((results) => {
47
+ const failedResult = results.find((result) => !result.success);
48
+ if (failedResult && !failedResult.success) {
49
+ (0, NotificationCenter_1.showNotification)(failedResult.reason, 4000);
50
+ return;
51
+ }
52
+ (0, NotificationCenter_1.showNotification)(toDuplicate.length === 1
53
+ ? 'Duplicated sequence in source file'
54
+ : 'Duplicated sequences in source files', 2000);
55
+ })
56
+ .catch((err) => {
57
+ (0, NotificationCenter_1.showNotification)(err.message, 4000);
58
+ });
54
59
  });
55
60
  };
56
61
  exports.duplicateSequencesFromSource = duplicateSequencesFromSource;
57
62
  const isDuplicatableSequenceRowSelection = (selection) => selection.type === 'sequence';
58
63
  exports.isDuplicatableSequenceRowSelection = isDuplicatableSequenceRowSelection;
59
- const duplicateSelectedTimelineItems = ({ selections, }) => {
64
+ const duplicateSelectedTimelineItems = ({ selections, confirm, }) => {
60
65
  const sequenceSelections = selections.filter(exports.isDuplicatableSequenceRowSelection);
61
66
  if (sequenceSelections.length === 0) {
62
67
  return null;
63
68
  }
64
- return (0, exports.duplicateSequencesFromSource)(sequenceSelections.map((selection) => selection.nodePathInfo));
69
+ return (0, exports.duplicateSequencesFromSource)(sequenceSelections.map((selection) => selection.nodePathInfo), confirm);
65
70
  };
66
71
  exports.duplicateSelectedTimelineItems = duplicateSelectedTimelineItems;
@@ -0,0 +1,8 @@
1
+ export type TimelineKeyframeDragBoundsTarget = {
2
+ readonly displayFrame: number;
3
+ };
4
+ export declare const getBoundedKeyframeDragDelta: ({ delta, durationInFrames, targets, }: {
5
+ readonly delta: number;
6
+ readonly durationInFrames: number;
7
+ readonly targets: readonly TimelineKeyframeDragBoundsTarget[];
8
+ }) => number;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getBoundedKeyframeDragDelta = void 0;
4
+ const getBoundedKeyframeDragDelta = ({ delta, durationInFrames, targets, }) => {
5
+ if (targets.length === 0 || durationInFrames <= 0) {
6
+ return 0;
7
+ }
8
+ const minDelta = Math.max(...targets.map((target) => -target.displayFrame));
9
+ const maxDelta = Math.min(...targets.map((target) => durationInFrames - 1 - target.displayFrame));
10
+ return Math.min(Math.max(delta, minDelta), maxDelta);
11
+ };
12
+ exports.getBoundedKeyframeDragDelta = getBoundedKeyframeDragDelta;
@@ -1,9 +1,9 @@
1
1
  export declare const getPreviousKeyframeDisplayFrame: (keyframes: readonly {
2
2
  frame: number;
3
- }[], currentDisplayFrame: number) => number | null;
3
+ }[], currentDisplayFrame: number, durationInFrames: number) => number | null;
4
4
  export declare const getNextKeyframeDisplayFrame: (keyframes: readonly {
5
5
  frame: number;
6
- }[], currentDisplayFrame: number) => number | null;
6
+ }[], currentDisplayFrame: number, durationInFrames: number) => number | null;
7
7
  export declare const hasKeyframeAtSourceFrame: (keyframes: readonly {
8
8
  frame: number;
9
9
  }[], sourceFrame: number) => boolean;
@@ -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) => {
@@ -132,14 +132,15 @@ const resetSelectedTimelineProps = ({ selections, sequences, overrideIdsToNodePa
132
132
  clientId,
133
133
  undoLabel: sequencePropTargets.length > 1
134
134
  ? 'Reset selected sequence props'
135
- : null,
135
+ : 'Reset sequence prop',
136
136
  redoLabel: sequencePropTargets.length > 1
137
137
  ? 'Reapply selected sequence props'
138
- : null,
138
+ : 'Reapply sequence prop',
139
139
  }));
140
140
  }
141
141
  for (const target of effectPropTargets) {
142
142
  resetPromises.push((0, save_effect_prop_1.saveEffectProp)({
143
+ type: 'value',
143
144
  fileName: target.fileName,
144
145
  nodePath: target.nodePath,
145
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 {};