@remotion/studio 4.0.469 → 4.0.470

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 (90) 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.js +5 -1
  5. package/dist/components/EditorContent.js +5 -4
  6. package/dist/components/Menu/MenuItem.d.ts +1 -1
  7. package/dist/components/MenuBuildIndicator.js +0 -1
  8. package/dist/components/NewComposition/InputDragger.js +1 -0
  9. package/dist/components/Preview.js +4 -1
  10. package/dist/components/SelectedOutlineOverlay.d.ts +18 -0
  11. package/dist/components/SelectedOutlineOverlay.js +645 -0
  12. package/dist/components/Timeline/Timeline.js +27 -13
  13. package/dist/components/Timeline/TimelineDeleteKeybindings.d.ts +2 -0
  14. package/dist/components/Timeline/TimelineDeleteKeybindings.js +86 -0
  15. package/dist/components/Timeline/TimelineDragHandler.js +19 -244
  16. package/dist/components/Timeline/{TimelineEffectGroupRow.d.ts → TimelineEffectItem.d.ts} +1 -1
  17. package/dist/components/Timeline/{TimelineEffectGroupRow.js → TimelineEffectItem.js} +50 -33
  18. package/dist/components/Timeline/{TimelineEffectFieldRow.d.ts → TimelineEffectPropItem.d.ts} +2 -1
  19. package/dist/components/Timeline/{TimelineEffectFieldRow.js → TimelineEffectPropItem.js} +97 -8
  20. package/dist/components/Timeline/TimelineExpandArrowButton.js +5 -1
  21. package/dist/components/Timeline/TimelineExpandedKeyframeRow.js +37 -5
  22. package/dist/components/Timeline/TimelineExpandedRow.d.ts +1 -0
  23. package/dist/components/Timeline/TimelineExpandedRow.js +9 -7
  24. package/dist/components/Timeline/TimelineExpandedSection.d.ts +1 -0
  25. package/dist/components/Timeline/TimelineExpandedSection.js +2 -2
  26. package/dist/components/Timeline/TimelineInOutDragHandler.d.ts +2 -0
  27. package/dist/components/Timeline/TimelineInOutDragHandler.js +324 -0
  28. package/dist/components/Timeline/TimelineInOutPointer.js +3 -1
  29. package/dist/components/Timeline/TimelineInOutPointerHandle.d.ts +1 -0
  30. package/dist/components/Timeline/TimelineInOutPointerHandle.js +5 -4
  31. package/dist/components/Timeline/TimelineKeyframeControls.d.ts +17 -0
  32. package/dist/components/Timeline/TimelineKeyframeControls.js +217 -0
  33. package/dist/components/Timeline/TimelineKeyframeDiamond.js +7 -6
  34. package/dist/components/Timeline/TimelineKeyframedValue.d.ts +8 -0
  35. package/dist/components/Timeline/TimelineKeyframedValue.js +36 -0
  36. package/dist/components/Timeline/TimelineList.js +3 -15
  37. package/dist/components/Timeline/TimelineRowChrome.d.ts +3 -1
  38. package/dist/components/Timeline/TimelineRowChrome.js +23 -5
  39. package/dist/components/Timeline/TimelineSelection.d.ts +53 -9
  40. package/dist/components/Timeline/TimelineSelection.js +305 -48
  41. package/dist/components/Timeline/TimelineSequence.d.ts +2 -0
  42. package/dist/components/Timeline/TimelineSequence.js +18 -6
  43. package/dist/components/Timeline/TimelineSequenceFrame.js +1 -0
  44. package/dist/components/Timeline/{TimelineListItem.d.ts → TimelineSequenceItem.d.ts} +2 -1
  45. package/dist/components/Timeline/{TimelineListItem.js → TimelineSequenceItem.js} +49 -33
  46. package/dist/components/Timeline/{TimelineFieldRow.d.ts → TimelineSequencePropItem.d.ts} +2 -1
  47. package/dist/components/Timeline/{TimelineFieldRow.js → TimelineSequencePropItem.js} +81 -5
  48. package/dist/components/Timeline/TimelineTimeIndicators.js +0 -1
  49. package/dist/components/Timeline/TimelineTrack.js +3 -1
  50. package/dist/components/Timeline/TimelineTranslateField.js +14 -22
  51. package/dist/components/Timeline/call-add-keyframe.d.ts +23 -0
  52. package/dist/components/Timeline/call-add-keyframe.js +54 -0
  53. package/dist/components/Timeline/call-delete-keyframe.d.ts +21 -0
  54. package/dist/components/Timeline/call-delete-keyframe.js +50 -0
  55. package/dist/components/Timeline/delete-selected-keyframe.d.ts +11 -0
  56. package/dist/components/Timeline/delete-selected-keyframe.js +51 -0
  57. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +17 -0
  58. package/dist/components/Timeline/delete-selected-timeline-item.js +183 -0
  59. package/dist/components/Timeline/duplicate-selected-timeline-item.d.ts +13 -0
  60. package/dist/components/Timeline/duplicate-selected-timeline-item.js +66 -0
  61. package/dist/components/Timeline/find-track-for-node-path-info.d.ts +7 -0
  62. package/dist/components/Timeline/find-track-for-node-path-info.js +13 -0
  63. package/dist/components/Timeline/get-keyframe-navigation.d.ts +9 -0
  64. package/dist/components/Timeline/get-keyframe-navigation.js +26 -0
  65. package/dist/components/Timeline/parse-keyframe-field-from-node-path.d.ts +8 -0
  66. package/dist/components/Timeline/parse-keyframe-field-from-node-path.js +26 -0
  67. package/dist/components/Timeline/save-sequence-prop.d.ts +14 -2
  68. package/dist/components/Timeline/save-sequence-prop.js +42 -7
  69. package/dist/components/Timeline/timeline-row-layout.d.ts +1 -0
  70. package/dist/components/Timeline/timeline-row-layout.js +2 -1
  71. package/dist/components/Timeline/timeline-translate-utils.d.ts +2 -0
  72. package/dist/components/Timeline/timeline-translate-utils.js +20 -0
  73. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +10 -3
  74. package/dist/components/composition-menu-items.js +32 -1
  75. package/dist/error-overlay/remotion-overlay/OpenInEditor.js +0 -1
  76. package/dist/esm/{chunk-1mp51e0w.js → chunk-dny42qnq.js} +9896 -6174
  77. package/dist/esm/internals.mjs +9896 -6174
  78. package/dist/esm/previewEntry.mjs +9870 -6148
  79. package/dist/esm/renderEntry.mjs +3 -1
  80. package/dist/helpers/format-file-location.d.ts +9 -0
  81. package/dist/helpers/format-file-location.js +27 -0
  82. package/dist/helpers/get-box-quads-polyfill-internals.d.ts +82 -0
  83. package/dist/helpers/get-box-quads-polyfill-internals.js +2395 -0
  84. package/dist/helpers/get-box-quads-ponyfill.d.ts +10 -0
  85. package/dist/helpers/get-box-quads-ponyfill.js +23 -0
  86. package/dist/helpers/open-in-editor.d.ts +1 -1
  87. package/dist/helpers/open-in-editor.js +11 -26
  88. package/dist/helpers/use-menu-structure.js +8 -16
  89. package/dist/renderEntry.js +2 -2
  90. package/package.json +10 -10
package/dist/Studio.js CHANGED
@@ -17,7 +17,7 @@ const getServerDisconnectedDomElement = () => {
17
17
  };
18
18
  const StudioInner = ({ rootComponent, readOnly }) => {
19
19
  var _a, _b;
20
- return (jsx_runtime_1.jsx(remotion_1.Internals.CompositionManagerProvider, { onlyRenderComposition: null, currentCompositionMetadata: null, initialCompositions: [], initialCanvasContent: null, children: jsx_runtime_1.jsx(remotion_1.Internals.RemotionRootContexts, { frameState: null, audioEnabled: window.remotion_audioEnabled, videoEnabled: window.remotion_videoEnabled, logLevel: (_a = window.remotion_logLevel) !== null && _a !== void 0 ? _a : 'info', numberOfAudioTags: window.remotion_numberOfAudioTags, audioLatencyHint: (_b = window.remotion_audioLatencyHint) !== null && _b !== void 0 ? _b : 'playback', children: jsx_runtime_1.jsx(use_static_files_1.StaticFilesProvider, { children: jsx_runtime_1.jsx(ResolveCompositionConfigInStudio_1.ResolveCompositionConfigInStudio, { children: jsx_runtime_1.jsxs(EditorContexts_1.EditorContexts, { readOnlyStudio: readOnly, children: [
20
+ return (jsx_runtime_1.jsx(remotion_1.Internals.CompositionManagerProvider, { onlyRenderComposition: null, currentCompositionMetadata: null, initialCompositions: [], initialCanvasContent: null, children: jsx_runtime_1.jsx(remotion_1.Internals.RemotionRootContexts, { frameState: null, audioEnabled: window.remotion_audioEnabled, videoEnabled: window.remotion_videoEnabled, logLevel: (_a = window.remotion_logLevel) !== null && _a !== void 0 ? _a : 'info', numberOfAudioTags: window.remotion_numberOfAudioTags, audioLatencyHint: (_b = window.remotion_audioLatencyHint) !== null && _b !== void 0 ? _b : 'playback', previewSampleRate: window.remotion_previewSampleRate, children: jsx_runtime_1.jsx(use_static_files_1.StaticFilesProvider, { children: jsx_runtime_1.jsx(ResolveCompositionConfigInStudio_1.ResolveCompositionConfigInStudio, { children: jsx_runtime_1.jsxs(EditorContexts_1.EditorContexts, { readOnlyStudio: readOnly, children: [
21
21
  jsx_runtime_1.jsx(Editor_1.Editor, { readOnlyStudio: readOnly, Root: rootComponent }), readOnly
22
22
  ? null
23
23
  : (0, react_dom_1.createPortal)(jsx_runtime_1.jsx(ServerDisconnected_1.ServerDisconnected, {}), getServerDisconnectedDomElement())] }) }) }) }) }));
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.unregisterClientRender = exports.registerClientRender = exports.saveOutputFile = void 0;
4
+ const call_api_1 = require("../components/call-api");
4
5
  const throwIfNotOk = async (response) => {
5
6
  if (!response.ok) {
6
7
  try {
@@ -26,20 +27,10 @@ const saveOutputFile = async ({ blob, filePath, }) => {
26
27
  };
27
28
  exports.saveOutputFile = saveOutputFile;
28
29
  const registerClientRender = async (render) => {
29
- const response = await fetch('/api/register-client-render', {
30
- method: 'POST',
31
- headers: { 'Content-Type': 'application/json' },
32
- body: JSON.stringify(render),
33
- });
34
- await throwIfNotOk(response);
30
+ await (0, call_api_1.callApi)('/api/register-client-render', render);
35
31
  };
36
32
  exports.registerClientRender = registerClientRender;
37
33
  const unregisterClientRender = async (id) => {
38
- const response = await fetch('/api/unregister-client-render', {
39
- method: 'POST',
40
- headers: { 'Content-Type': 'application/json' },
41
- body: JSON.stringify({ id }),
42
- });
43
- await throwIfNotOk(response);
34
+ await (0, call_api_1.callApi)('/api/unregister-client-render', { id });
44
35
  };
45
36
  exports.unregisterClientRender = unregisterClientRender;
@@ -41,6 +41,9 @@ const errorMessage = {
41
41
  maxWidth: 450,
42
42
  opacity: 0.75,
43
43
  };
44
+ const getWaveformErrorMessage = () => {
45
+ return new Error('No waveform available. The audio could not be decoded or may not support CORS.');
46
+ };
44
47
  const waveformCanvasStyle = {
45
48
  pointerEvents: 'none',
46
49
  width: '100%',
@@ -121,6 +124,7 @@ const AudioWaveform = ({ src, height, startFrom, durationInFrames, visualization
121
124
  return;
122
125
  }
123
126
  const worker = (0, timeline_utils_1.makeAudioWaveformWorker)();
127
+ let workerFailed = false;
124
128
  waveformWorker.current = worker;
125
129
  worker.addEventListener('message', (event) => {
126
130
  if (event.data.type === 'error') {
@@ -130,6 +134,17 @@ const AudioWaveform = ({ src, height, startFrom, durationInFrames, visualization
130
134
  setError(new Error(event.data.message));
131
135
  }
132
136
  });
137
+ worker.addEventListener('error', (event) => {
138
+ event.preventDefault();
139
+ workerFailed = true;
140
+ if (worker !== waveformWorker.current) {
141
+ return;
142
+ }
143
+ worker.terminate();
144
+ waveformWorker.current = null;
145
+ hasTransferredCanvas.current = false;
146
+ setError(getWaveformErrorMessage());
147
+ });
133
148
  let offscreen;
134
149
  try {
135
150
  offscreen = canvasElement.transferControlToOffscreen();
@@ -146,7 +161,9 @@ const AudioWaveform = ({ src, height, startFrom, durationInFrames, visualization
146
161
  hasTransferredCanvas.current = true;
147
162
  worker.postMessage({ type: 'init', canvas: offscreen }, [offscreen]);
148
163
  return () => {
149
- worker.postMessage({ type: 'dispose' });
164
+ if (!workerFailed) {
165
+ worker.postMessage({ type: 'dispose' });
166
+ }
150
167
  worker.terminate();
151
168
  waveformWorker.current = null;
152
169
  hasTransferredCanvas.current = false;
@@ -277,7 +294,7 @@ const AudioWaveform = ({ src, height, startFrom, durationInFrames, visualization
277
294
  if (error) {
278
295
  // eslint-disable-next-line no-console
279
296
  console.error(error);
280
- return (jsx_runtime_1.jsx("div", { style: getContainerStyle(height), children: jsx_runtime_1.jsx("div", { style: errorMessage, children: "No waveform available. Audio might not support CORS." }) }));
297
+ return (jsx_runtime_1.jsx("div", { style: getContainerStyle(height), children: jsx_runtime_1.jsx("div", { style: errorMessage, children: "No waveform available. The audio could not be decoded or may not support CORS." }) }));
281
298
  }
282
299
  if (!canUseWorkerPath && !peaks) {
283
300
  return null;
@@ -92,9 +92,13 @@ const ContextMenu = ({ children, values, onOpen }) => {
92
92
  const onHide = (0, react_1.useCallback)(() => {
93
93
  setOpened({ type: 'not-open' });
94
94
  }, []);
95
+ // Prevent deselection of a selected item
96
+ const onPointerDown = (0, react_1.useCallback)((e) => {
97
+ e.stopPropagation();
98
+ }, []);
95
99
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
96
100
  jsx_runtime_1.jsx("div", { ref: ref, onContextMenu: () => false, style: style, children: children }), portalStyle
97
- ? react_dom_1.default.createPortal(jsx_runtime_1.jsx("div", { style: styles_1.fullScreenOverlay, children: jsx_runtime_1.jsx("div", { style: styles_1.outerPortal, className: "css-reset", children: jsx_runtime_1.jsx(z_index_1.HigherZIndex, { onOutsideClick: onHide, onEscape: onHide, children: jsx_runtime_1.jsx("div", { style: portalStyle, children: jsx_runtime_1.jsx(MenuContent_1.MenuContent, { onNextMenu: noop_1.noop, onPreviousMenu: noop_1.noop, values: values, onHide: onHide, leaveLeftSpace: true, preselectIndex: false, topItemCanBeUnselected: false, fixedHeight: null }) }) }) }) }), (0, portals_1.getPortal)(currentZIndex))
101
+ ? react_dom_1.default.createPortal(jsx_runtime_1.jsx("div", { style: styles_1.fullScreenOverlay, children: jsx_runtime_1.jsx("div", { style: styles_1.outerPortal, className: "css-reset", children: jsx_runtime_1.jsx(z_index_1.HigherZIndex, { onOutsideClick: onHide, onEscape: onHide, children: jsx_runtime_1.jsx("div", { style: portalStyle, onPointerDown: onPointerDown, children: jsx_runtime_1.jsx(MenuContent_1.MenuContent, { onNextMenu: noop_1.noop, onPreviousMenu: noop_1.noop, values: values, onHide: onHide, leaveLeftSpace: true, preselectIndex: false, topItemCanBeUnselected: false, fixedHeight: null }) }) }) }) }), (0, portals_1.getPortal)(currentZIndex))
98
102
  : null] }));
99
103
  };
100
104
  exports.ContextMenu = ContextMenu;
@@ -11,6 +11,7 @@ const SplitterElement_1 = require("./Splitter/SplitterElement");
11
11
  const SplitterHandle_1 = require("./Splitter/SplitterHandle");
12
12
  const Timeline_1 = require("./Timeline/Timeline");
13
13
  const TimelineEmptyState_1 = require("./Timeline/TimelineEmptyState");
14
+ const TimelineSelection_1 = require("./Timeline/TimelineSelection");
14
15
  const noop = () => undefined;
15
16
  const container = {
16
17
  display: 'flex',
@@ -21,10 +22,10 @@ const container = {
21
22
  const EditorContent = ({ readOnlyStudio, children }) => {
22
23
  const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
23
24
  const showTimeline = canvasContent !== null && canvasContent.type === 'composition';
24
- return (jsx_runtime_1.jsxs("div", { style: container, children: [
25
- jsx_runtime_1.jsx(InitialCompositionLoader_1.InitialCompositionLoader, {}), jsx_runtime_1.jsx(MenuToolbar_1.MenuToolbar, { readOnlyStudio: readOnlyStudio }), jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { orientation: "horizontal", id: "top-to-bottom", maxFlex: 0.9, minFlex: 0.2, defaultFlex: 0.75, children: [
26
- jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { sticky: null, type: "flexer", children: children }), jsx_runtime_1.jsx(SplitterHandle_1.SplitterHandle, { allowToCollapse: "none", onCollapse: noop }), jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { sticky: null, type: "anti-flexer", children: showTimeline ? jsx_runtime_1.jsx(Timeline_1.Timeline, {}) : jsx_runtime_1.jsx(TimelineEmptyState_1.TimelineEmptyState, {}) })
27
- ] })
25
+ const content = (jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { orientation: "horizontal", id: "top-to-bottom", maxFlex: 0.9, minFlex: 0.2, defaultFlex: 0.75, children: [
26
+ jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { sticky: null, type: "flexer", children: children }), jsx_runtime_1.jsx(SplitterHandle_1.SplitterHandle, { allowToCollapse: "none", onCollapse: noop }), jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { sticky: null, type: "anti-flexer", children: showTimeline ? jsx_runtime_1.jsx(Timeline_1.Timeline, {}) : jsx_runtime_1.jsx(TimelineEmptyState_1.TimelineEmptyState, {}) })
28
27
  ] }));
28
+ return (jsx_runtime_1.jsxs("div", { style: container, children: [
29
+ jsx_runtime_1.jsx(InitialCompositionLoader_1.InitialCompositionLoader, {}), jsx_runtime_1.jsx(MenuToolbar_1.MenuToolbar, { readOnlyStudio: readOnlyStudio }), showTimeline ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionProvider, { children: content })) : (content)] }));
29
30
  };
30
31
  exports.EditorContent = EditorContent;
@@ -1,7 +1,7 @@
1
1
  import type { SetStateAction } from 'react';
2
2
  import React from 'react';
3
3
  import type { ComboboxValue } from '../NewComposition/ComboBox';
4
- export type MenuId = 'remotion' | 'file' | 'view' | 'composition' | 'install' | 'tools' | 'help';
4
+ export type MenuId = 'remotion' | 'file' | 'view' | 'composition' | 'tools' | 'help';
5
5
  export type Menu = {
6
6
  id: MenuId;
7
7
  label: React.ReactNode;
@@ -56,7 +56,6 @@ const MenuBuildIndicator = () => {
56
56
  originalFunctionName: null,
57
57
  originalScriptCode: null,
58
58
  })
59
- .then((res) => res.json())
60
59
  .then(({ success }) => {
61
60
  if (!success) {
62
61
  (0, NotificationCenter_1.showNotification)(`Could not open ${window.remotion_editorName}`, 2000);
@@ -120,6 +120,7 @@ const InputDraggerForwardRefFn = ({ onValueChange, onValueChangeEnd, min: _min,
120
120
  return Math.ceil(val * factor) / factor;
121
121
  };
122
122
  const onPointerDown = (0, react_1.useCallback)((e) => {
123
+ e.stopPropagation();
123
124
  pointerDownRef.current = true;
124
125
  const target = e.currentTarget;
125
126
  const { pageX, pageY, button } = e;
@@ -11,6 +11,7 @@ const colors_1 = require("../helpers/colors");
11
11
  const checkerboard_1 = require("../state/checkerboard");
12
12
  const is_menu_item_1 = require("./Menu/is-menu-item");
13
13
  const RenderPreview_1 = require("./RenderPreview");
14
+ const SelectedOutlineOverlay_1 = require("./SelectedOutlineOverlay");
14
15
  const Spinner_1 = require("./Spinner");
15
16
  const StaticFilePreview_1 = require("./StaticFilePreview");
16
17
  const centeredContainer = {
@@ -146,7 +147,9 @@ const CompWhenItHasDimensions = ({ contentDimensions, canvasSize, canvasContent,
146
147
  if (canvasContent.type === 'output-blob') {
147
148
  return (jsx_runtime_1.jsx("div", { style: outer, children: jsx_runtime_1.jsx(RenderPreview_1.RenderPreview, { path: canvasContent.displayName, assetMetadata: assetMetadata, getBlob: canvasContent.getBlob }) }));
148
149
  }
149
- return (jsx_runtime_1.jsx("div", { style: outer, children: jsx_runtime_1.jsx(PortalContainer, { contentDimensions: contentDimensions, scale: scale, xCorrection: xCorrection, yCorrection: yCorrection }) }));
150
+ return (jsx_runtime_1.jsxs("div", { style: outer, children: [
151
+ jsx_runtime_1.jsx(PortalContainer, { contentDimensions: contentDimensions, scale: scale, xCorrection: xCorrection, yCorrection: yCorrection }), jsx_runtime_1.jsx(SelectedOutlineOverlay_1.SelectedOutlineOverlay, { scale: scale })
152
+ ] }));
150
153
  };
151
154
  const PortalContainer = ({ scale, xCorrection, yCorrection, contentDimensions }) => {
152
155
  const { checkerboard } = (0, react_1.useContext)(checkerboard_1.CheckerboardContext);
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import { type TimelineSelection } from './Timeline/TimelineSelection';
3
+ type OutlinePoint = {
4
+ readonly x: number;
5
+ readonly y: number;
6
+ };
7
+ type UvCoordinate = readonly [number, number];
8
+ export declare const getUvHandlePosition: (points: readonly [OutlinePoint, OutlinePoint, OutlinePoint, OutlinePoint], uv: UvCoordinate) => OutlinePoint;
9
+ export declare const getUvCoordinateForPoint: (points: readonly [OutlinePoint, OutlinePoint, OutlinePoint, OutlinePoint], point: OutlinePoint) => UvCoordinate;
10
+ type SelectedEffectFields = {
11
+ allFields: boolean;
12
+ fieldKeys: Set<string>;
13
+ };
14
+ export declare const getSelectedEffectFieldsBySequenceKey: (selectedItems: readonly TimelineSelection[]) => Map<string, Map<number, SelectedEffectFields>>;
15
+ export declare const SelectedOutlineOverlay: React.FC<{
16
+ readonly scale: number;
17
+ }>;
18
+ export {};