@remotion/studio 4.0.442 → 4.0.444

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 (38) hide show
  1. package/dist/components/CanvasOrLoading.js +5 -0
  2. package/dist/components/Editor.js +10 -2
  3. package/dist/components/MenuBuildIndicator.js +58 -3
  4. package/dist/components/MenuCompositionName.d.ts +2 -0
  5. package/dist/components/MenuCompositionName.js +80 -0
  6. package/dist/components/RenderErrorContext.d.ts +4 -0
  7. package/dist/components/RenderErrorContext.js +7 -0
  8. package/dist/components/RenderModal/RenderModalJSONPropsEditor.js +7 -5
  9. package/dist/components/RenderModal/SchemaEditor/SchemaEditor.js +5 -1
  10. package/dist/components/RenderModal/SchemaEditor/SchemaErrorMessages.js +5 -3
  11. package/dist/components/Timeline/TimelineListItem.js +71 -8
  12. package/dist/components/Timeline/TimelineRotationField.js +11 -0
  13. package/dist/components/Timeline/TimelineSequence.js +1 -1
  14. package/dist/components/Timeline/TimelineStack/index.js +2 -1
  15. package/dist/components/Timeline/TimelineVideoInfo.d.ts +4 -0
  16. package/dist/components/Timeline/TimelineVideoInfo.js +32 -30
  17. package/dist/components/Timeline/use-sequence-props-subscription.d.ts +1 -1
  18. package/dist/components/Timeline/use-sequence-props-subscription.js +25 -6
  19. package/dist/error-overlay/react-overlay/listen-to-runtime-errors.js +1 -5
  20. package/dist/error-overlay/remotion-overlay/CopyStackTrace.d.ts +5 -0
  21. package/dist/error-overlay/remotion-overlay/CopyStackTrace.js +50 -0
  22. package/dist/error-overlay/remotion-overlay/ErrorDisplay.js +16 -13
  23. package/dist/error-overlay/remotion-overlay/MediaPlaybackErrorExplainer.d.ts +4 -0
  24. package/dist/error-overlay/remotion-overlay/MediaPlaybackErrorExplainer.js +87 -0
  25. package/dist/esm/{chunk-j8c13fkw.js → chunk-1zvzzrkf.js} +3589 -3290
  26. package/dist/esm/internals.mjs +3589 -3290
  27. package/dist/esm/previewEntry.mjs +3687 -3392
  28. package/dist/esm/renderEntry.mjs +1 -1
  29. package/dist/helpers/frame-database.d.ts +2 -2
  30. package/dist/helpers/frame-database.js +36 -25
  31. package/dist/helpers/timeline-layout.d.ts +4 -1
  32. package/dist/helpers/timeline-layout.js +10 -4
  33. package/dist/helpers/use-max-media-duration.js +1 -1
  34. package/package.json +9 -9
  35. package/dist/components/OpenEditorButton.d.ts +0 -3
  36. package/dist/components/OpenEditorButton.js +0 -67
  37. package/dist/error-overlay/remotion-overlay/CompositionIdsDropdown.d.ts +0 -5
  38. package/dist/error-overlay/remotion-overlay/CompositionIdsDropdown.js +0 -108
@@ -6,7 +6,7 @@ const remotion_1 = require("remotion");
6
6
  const client_id_1 = require("../../helpers/client-id");
7
7
  const timeline_layout_1 = require("../../helpers/timeline-layout");
8
8
  const call_api_1 = require("../call-api");
9
- const useSequencePropsSubscription = (sequence, originalLocation) => {
9
+ const useSequencePropsSubscription = (sequence, originalLocation, visualModeEnabled) => {
10
10
  var _a;
11
11
  var _b, _c, _d, _e;
12
12
  const { setCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeOverridesContext);
@@ -44,7 +44,12 @@ const useSequencePropsSubscription = (sequence, originalLocation) => {
44
44
  const currentLocationColumn = (0, react_1.useRef)(locationColumn);
45
45
  currentLocationColumn.current = locationColumn;
46
46
  const nodePathRef = (0, react_1.useRef)(null);
47
+ const [nodePath, setNodePath] = (0, react_1.useState)(null);
47
48
  const isMountedRef = (0, react_1.useRef)(true);
49
+ const setNodePathBoth = (0, react_1.useCallback)((next) => {
50
+ nodePathRef.current = next;
51
+ setNodePath(next);
52
+ }, []);
48
53
  (0, react_1.useEffect)(() => {
49
54
  isMountedRef.current = true;
50
55
  return () => {
@@ -52,12 +57,18 @@ const useSequencePropsSubscription = (sequence, originalLocation) => {
52
57
  };
53
58
  }, []);
54
59
  (0, react_1.useEffect)(() => {
60
+ if (!visualModeEnabled) {
61
+ setPropStatusesForSequence(null);
62
+ setNodePathBoth(null);
63
+ return;
64
+ }
55
65
  if (!clientId ||
56
66
  !locationSource ||
57
67
  !locationLine ||
58
68
  locationColumn === null ||
59
69
  !schemaKeysString) {
60
70
  setPropStatusesForSequence(null);
71
+ setNodePathBoth(null);
61
72
  return;
62
73
  }
63
74
  const keys = schemaKeysString.split(',');
@@ -75,16 +86,16 @@ const useSequencePropsSubscription = (sequence, originalLocation) => {
75
86
  return;
76
87
  }
77
88
  if (result.canUpdate) {
78
- nodePathRef.current = result.nodePath;
89
+ setNodePathBoth(result.nodePath);
79
90
  setPropStatusesForSequence(result.props);
80
91
  }
81
92
  else {
82
- nodePathRef.current = null;
93
+ setNodePathBoth(null);
83
94
  setPropStatusesForSequence(null);
84
95
  }
85
96
  })
86
97
  .catch((err) => {
87
- nodePathRef.current = null;
98
+ setNodePathBoth(null);
88
99
  remotion_1.Internals.Log.error(err);
89
100
  setPropStatusesForSequence(null);
90
101
  });
@@ -95,7 +106,7 @@ const useSequencePropsSubscription = (sequence, originalLocation) => {
95
106
  if (!isMountedRef.current) {
96
107
  setPropStatusesForSequence(null);
97
108
  }
98
- nodePathRef.current = null;
109
+ setNodePathBoth(null);
99
110
  if (currentNodePath) {
100
111
  (0, call_api_1.callApi)('/api/unsubscribe-from-sequence-props', {
101
112
  fileName: locationSource,
@@ -107,14 +118,19 @@ const useSequencePropsSubscription = (sequence, originalLocation) => {
107
118
  }
108
119
  };
109
120
  }, [
121
+ visualModeEnabled,
110
122
  clientId,
111
123
  locationSource,
112
124
  locationLine,
113
125
  locationColumn,
114
126
  schemaKeysString,
115
127
  setPropStatusesForSequence,
128
+ setNodePathBoth,
116
129
  ]);
117
130
  (0, react_1.useEffect)(() => {
131
+ if (!visualModeEnabled) {
132
+ return;
133
+ }
118
134
  if (!locationSource || !locationLine || locationColumn === null) {
119
135
  return;
120
136
  }
@@ -132,6 +148,7 @@ const useSequencePropsSubscription = (sequence, originalLocation) => {
132
148
  }
133
149
  else {
134
150
  setPropStatusesForSequence(null);
151
+ setNodePathBoth(null);
135
152
  }
136
153
  };
137
154
  const unsub = subscribeToEvent('sequence-props-updated', listener);
@@ -139,12 +156,14 @@ const useSequencePropsSubscription = (sequence, originalLocation) => {
139
156
  unsub();
140
157
  };
141
158
  }, [
159
+ visualModeEnabled,
142
160
  locationSource,
143
161
  locationLine,
144
162
  locationColumn,
145
163
  subscribeToEvent,
146
164
  setPropStatusesForSequence,
165
+ setNodePathBoth,
147
166
  ]);
148
- return nodePathRef.current;
167
+ return nodePath;
149
168
  };
150
169
  exports.useSequencePropsSubscription = useSequencePropsSubscription;
@@ -48,11 +48,7 @@ const crashWithFrames = (crash) => (error) => {
48
48
  function listenToRuntimeErrors(crash) {
49
49
  const crashWithFramesRunTime = crashWithFrames(crash);
50
50
  (0, unhandled_error_1.register)(window, (error) => {
51
- return crashWithFramesRunTime({
52
- message: error.message,
53
- stack: error.stack,
54
- name: error.name,
55
- });
51
+ return crashWithFramesRunTime(error);
56
52
  });
57
53
  (0, unhandled_rejection_1.register)(window, (error) => {
58
54
  return crashWithFramesRunTime(error);
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ export declare const CopyStackTrace: React.FC<{
3
+ readonly canHaveKeyboardShortcuts: boolean;
4
+ readonly errorText: string;
5
+ }>;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CopyStackTrace = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const Button_1 = require("../../components/Button");
7
+ const use_keybinding_1 = require("../../helpers/use-keybinding");
8
+ const ShortcutHint_1 = require("./ShortcutHint");
9
+ const CopyStackTrace = ({ canHaveKeyboardShortcuts, errorText }) => {
10
+ const [copyState, setCopyState] = (0, react_1.useState)('idle');
11
+ const handleCopyToClipboard = (0, react_1.useCallback)(() => {
12
+ navigator.clipboard
13
+ .writeText(errorText)
14
+ .then(() => {
15
+ setCopyState('copied');
16
+ setTimeout(() => setCopyState('idle'), 2000);
17
+ })
18
+ .catch(() => {
19
+ setCopyState('failed');
20
+ setTimeout(() => setCopyState('idle'), 2000);
21
+ });
22
+ }, [errorText]);
23
+ const { registerKeybinding } = (0, use_keybinding_1.useKeybinding)();
24
+ (0, react_1.useEffect)(() => {
25
+ if (!canHaveKeyboardShortcuts) {
26
+ return;
27
+ }
28
+ const { unregister } = registerKeybinding({
29
+ event: 'keydown',
30
+ key: 't',
31
+ callback: handleCopyToClipboard,
32
+ commandCtrlKey: true,
33
+ preventDefault: true,
34
+ triggerIfInputFieldFocused: false,
35
+ keepRegisteredWhenNotHighestContext: false,
36
+ });
37
+ return () => unregister();
38
+ }, [canHaveKeyboardShortcuts, handleCopyToClipboard, registerKeybinding]);
39
+ const label = (0, react_1.useMemo)(() => {
40
+ if (copyState === 'copied') {
41
+ return 'Copied!';
42
+ }
43
+ if (copyState === 'failed') {
44
+ return 'Failed!';
45
+ }
46
+ return 'Copy Stacktrace';
47
+ }, [copyState]);
48
+ return (jsx_runtime_1.jsxs(Button_1.Button, { onClick: handleCopyToClipboard, children: [label, ' ', copyState === 'idle' && canHaveKeyboardShortcuts ? (jsx_runtime_1.jsx(ShortcutHint_1.ShortcutHint, { cmdOrCtrl: true, keyToPress: "t" })) : null] }));
49
+ };
50
+ exports.CopyStackTrace = CopyStackTrace;
@@ -4,15 +4,16 @@ exports.ErrorDisplay = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const studio_shared_1 = require("@remotion/studio-shared");
6
6
  const react_1 = require("react");
7
+ const remotion_1 = require("remotion");
7
8
  const layout_1 = require("../../components/layout");
8
9
  const is_menu_item_1 = require("../../components/Menu/is-menu-item");
9
- const url_state_1 = require("../../helpers/url-state");
10
10
  const AskOnDiscord_1 = require("./AskOnDiscord");
11
11
  const CalculateMetadataErrorExplainer_1 = require("./CalculateMetadataErrorExplainer");
12
- const CompositionIdsDropdown_1 = require("./CompositionIdsDropdown");
12
+ const CopyStackTrace_1 = require("./CopyStackTrace");
13
13
  const ErrorTitle_1 = require("./ErrorTitle");
14
14
  const get_help_link_1 = require("./get-help-link");
15
15
  const HelpLink_1 = require("./HelpLink");
16
+ const MediaPlaybackErrorExplainer_1 = require("./MediaPlaybackErrorExplainer");
16
17
  const OpenInEditor_1 = require("./OpenInEditor");
17
18
  const Retry_1 = require("./Retry");
18
19
  const SearchGitHubIssues_1 = require("./SearchGitHubIssues");
@@ -27,8 +28,6 @@ const spacer = {
27
28
  display: 'inline-block',
28
29
  };
29
30
  const ErrorDisplay = ({ display, keyboardShortcuts, onRetry, canHaveDismissButton, calculateMetadata, }) => {
30
- var _a;
31
- const compositionIds = (_a = window === null || window === void 0 ? void 0 : window.remotion_seenCompositionIds) !== null && _a !== void 0 ? _a : [];
32
31
  const highestLineNumber = Math.max(...display.stackFrames
33
32
  .map((s) => s.originalScriptCode)
34
33
  .flat(1)
@@ -50,23 +49,27 @@ const ErrorDisplay = ({ display, keyboardShortcuts, onRetry, canHaveDismissButto
50
49
  }, [display.error]);
51
50
  const lineNumberWidth = String(highestLineNumber).length;
52
51
  const helpLink = (0, get_help_link_1.getHelpLink)(message);
53
- const getCurrentCompositionId = () => {
54
- var _a;
55
- const route = (0, url_state_1.getRoute)();
56
- const id = route.startsWith('/') ? route.slice(1) : route;
57
- return compositionIds.includes(id) ? id : ((_a = compositionIds[0]) !== null && _a !== void 0 ? _a : null);
58
- };
52
+ const errorTextForCopy = (0, react_1.useMemo)(() => {
53
+ const header = `${display.error.name}: ${message}`;
54
+ if (display.stackFrames.length > 0) {
55
+ const stackLines = display.stackFrames
56
+ .map((frame) => `at ${frame.originalFunctionName || '<anonymous>'} (${frame.originalFileName || 'unknown'}:${frame.originalLineNumber || '?'}:${frame.originalColumnNumber || '?'})`)
57
+ .join('\n');
58
+ return `${header}\n${stackLines}`;
59
+ }
60
+ return display.error.stack || header;
61
+ }, [display.stackFrames, display.error, message]);
59
62
  return (jsx_runtime_1.jsxs("div", { children: [
60
63
  jsx_runtime_1.jsx(ErrorTitle_1.ErrorTitle, { symbolicating: false, name: display.error.name, message: message, canHaveDismissButton: canHaveDismissButton }), helpLink ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
61
64
  jsx_runtime_1.jsx(HelpLink_1.HelpLink, { link: helpLink, canHaveKeyboardShortcuts: keyboardShortcuts }), jsx_runtime_1.jsx("div", { style: spacer })
62
65
  ] })) : null, display.stackFrames.length > 0 && window.remotion_editorName ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
63
66
  jsx_runtime_1.jsx(OpenInEditor_1.OpenInEditor, { canHaveKeyboardShortcuts: keyboardShortcuts, stack: display.stackFrames[0] }), jsx_runtime_1.jsx("div", { style: spacer })
64
- ] })) : null, compositionIds.length > 0 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
65
- jsx_runtime_1.jsx(CompositionIdsDropdown_1.CompositionIdsDropdown, { compositionIds: compositionIds, currentId: getCurrentCompositionId() }), jsx_runtime_1.jsx("div", { style: spacer })
66
- ] })) : null, jsx_runtime_1.jsx(SearchGitHubIssues_1.SearchGithubIssues, { canHaveKeyboardShortcuts: keyboardShortcuts, message: display.error.message }), jsx_runtime_1.jsx("div", { style: spacer }), jsx_runtime_1.jsx(AskOnDiscord_1.AskOnDiscord, { canHaveKeyboardShortcuts: keyboardShortcuts }), onRetry ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
67
+ ] })) : null, jsx_runtime_1.jsx(CopyStackTrace_1.CopyStackTrace, { canHaveKeyboardShortcuts: keyboardShortcuts, errorText: errorTextForCopy }), jsx_runtime_1.jsx("div", { style: spacer }), jsx_runtime_1.jsx(SearchGitHubIssues_1.SearchGithubIssues, { canHaveKeyboardShortcuts: keyboardShortcuts, message: display.error.message }), jsx_runtime_1.jsx("div", { style: spacer }), jsx_runtime_1.jsx(AskOnDiscord_1.AskOnDiscord, { canHaveKeyboardShortcuts: keyboardShortcuts }), onRetry ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
67
68
  jsx_runtime_1.jsx("div", { style: spacer }), jsx_runtime_1.jsx(Retry_1.RetryButton, { onClick: onRetry })
68
69
  ] })) : null, calculateMetadata ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
69
70
  jsx_runtime_1.jsx("br", {}), jsx_runtime_1.jsx(layout_1.Spacing, { y: 0.5 }), jsx_runtime_1.jsx(CalculateMetadataErrorExplainer_1.CalculateMetadataErrorExplainer, {})
71
+ ] })) : null, display.error instanceof remotion_1.MediaPlaybackError ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
72
+ jsx_runtime_1.jsx("br", {}), jsx_runtime_1.jsx(layout_1.Spacing, { y: 0.5 }), jsx_runtime_1.jsx(MediaPlaybackErrorExplainer_1.MediaPlaybackErrorExplainer, { src: display.error.src })
70
73
  ] })) : null, jsx_runtime_1.jsx("div", { style: stack, className: is_menu_item_1.HORIZONTAL_SCROLLBAR_CLASSNAME, children: display.stackFrames.map((s, i) => {
71
74
  return (jsx_runtime_1.jsx(StackFrame_1.StackElement
72
75
  // eslint-disable-next-line react/no-array-index-key
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ export declare const MediaPlaybackErrorExplainer: React.FC<{
3
+ readonly src: string;
4
+ }>;
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MediaPlaybackErrorExplainer = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const colors_1 = require("../../helpers/colors");
7
+ const container = {
8
+ borderRadius: 3,
9
+ color: 'white',
10
+ padding: 12,
11
+ backgroundColor: colors_1.BORDER_COLOR,
12
+ fontSize: 14,
13
+ fontFamily: 'sans-serif',
14
+ lineHeight: 1.5,
15
+ };
16
+ const codeStyle = {
17
+ backgroundColor: 'rgba(255,255,255,0.1)',
18
+ padding: '2px 5px',
19
+ borderRadius: 3,
20
+ fontFamily: 'monospace',
21
+ fontSize: 13,
22
+ };
23
+ const linkStyle = {
24
+ color: '#58a6ff',
25
+ };
26
+ const MediaPlaybackErrorExplainer = ({ src }) => {
27
+ const [result, setResult] = (0, react_1.useState)({ type: 'loading' });
28
+ (0, react_1.useEffect)(() => {
29
+ fetch(src, { method: 'HEAD' })
30
+ .then((res) => {
31
+ var _a;
32
+ if (res.status === 404) {
33
+ setResult({ type: 'not-found' });
34
+ }
35
+ else if (!res.ok) {
36
+ setResult({ type: 'other-error', statusCode: res.status });
37
+ }
38
+ else {
39
+ const contentType = (_a = res.headers.get('content-type')) !== null && _a !== void 0 ? _a : '';
40
+ if (contentType.includes('text/html') ||
41
+ contentType.includes('application/json')) {
42
+ setResult({ type: 'wrong-content-type', contentType });
43
+ }
44
+ else {
45
+ setResult({ type: 'ok' });
46
+ }
47
+ }
48
+ })
49
+ .catch(() => {
50
+ setResult({ type: 'fetch-error' });
51
+ });
52
+ }, [src]);
53
+ if (result.type === 'loading') {
54
+ return null;
55
+ }
56
+ if (result.type === 'not-found') {
57
+ return (jsx_runtime_1.jsxs("div", { style: container, children: ["The file ",
58
+ jsx_runtime_1.jsx("code", { style: codeStyle, children: src }),
59
+ " was not found (404).",
60
+ jsx_runtime_1.jsx("br", {}),
61
+ "If the file is in your ",
62
+ jsx_runtime_1.jsx("code", { style: codeStyle, children: "public/" }),
63
+ " folder, make sure to use", ' ', jsx_runtime_1.jsx("a", { style: linkStyle, href: "https://remotion.dev/docs/staticfile", target: "_blank", children: jsx_runtime_1.jsx("code", { style: codeStyle, children: "staticFile()" }) }), ' ', "to reference it.",
64
+ jsx_runtime_1.jsx("br", {}), jsx_runtime_1.jsx("a", { style: linkStyle, href: "https://remotion.dev/docs/media-playback-error", target: "_blank", children: "Learn more" })
65
+ ] }));
66
+ }
67
+ if (result.type === 'other-error') {
68
+ return (jsx_runtime_1.jsxs("div", { style: container, children: ["\u26A0\uFE0F Fetching ",
69
+ jsx_runtime_1.jsx("code", { style: codeStyle, children: src }),
70
+ " returned status code", ' ', result.statusCode, ".",
71
+ jsx_runtime_1.jsx("br", {}), jsx_runtime_1.jsx("a", { style: linkStyle, href: "https://remotion.dev/docs/media-playback-error", target: "_blank", children: "Learn more" })
72
+ ] }));
73
+ }
74
+ if (result.type === 'wrong-content-type') {
75
+ return (jsx_runtime_1.jsxs("div", { style: container, children: ["\u26A0\uFE0F Fetching ",
76
+ jsx_runtime_1.jsx("code", { style: codeStyle, children: src }),
77
+ " returned a", ' ', jsx_runtime_1.jsx("code", { style: codeStyle, children: result.contentType }),
78
+ " content type.",
79
+ jsx_runtime_1.jsx("br", {}),
80
+ "\uD83D\uDC49 If the file is in your ",
81
+ jsx_runtime_1.jsx("code", { style: codeStyle, children: "public/" }), ' ', "folder, make sure to use", ' ', jsx_runtime_1.jsx("a", { style: linkStyle, href: "https://remotion.dev/docs/staticfile", target: "_blank", children: jsx_runtime_1.jsx("code", { style: codeStyle, children: "staticFile()" }) }), ' ', "to reference it.",
82
+ jsx_runtime_1.jsx("br", {}), jsx_runtime_1.jsx("a", { style: linkStyle, href: "https://remotion.dev/docs/media-playback-error", target: "_blank", children: "Learn more" })
83
+ ] }));
84
+ }
85
+ return null;
86
+ };
87
+ exports.MediaPlaybackErrorExplainer = MediaPlaybackErrorExplainer;