@remotion/studio 4.0.520 → 4.0.522

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 (117) hide show
  1. package/dist/api/shut-down-studio.d.ts +6 -0
  2. package/dist/api/shut-down-studio.js +23 -0
  3. package/dist/components/AudioWaveform.js +10 -6
  4. package/dist/components/Canvas.js +84 -12
  5. package/dist/components/CanvasIfSizeIsAvailable.js +7 -0
  6. package/dist/components/CaptionInspector.d.ts +1 -0
  7. package/dist/components/CaptionInspector.js +43 -2
  8. package/dist/components/CaptionTextEditor.js +1 -1
  9. package/dist/components/CompositionSelector.js +41 -30
  10. package/dist/components/CompositionSelectorItem.d.ts +7 -0
  11. package/dist/components/CompositionSelectorItem.js +343 -67
  12. package/dist/components/CopyButton.js +7 -14
  13. package/dist/components/Editor.js +6 -5
  14. package/dist/components/EditorContent.js +1 -1
  15. package/dist/components/ElementInstallConfirmation.js +77 -65
  16. package/dist/components/ElementLibraryModal.js +3 -1
  17. package/dist/components/FixComputedValueModal.js +20 -10
  18. package/dist/components/InlineCaptionInspector.js +37 -1
  19. package/dist/components/InspectorLocationCopy.js +10 -5
  20. package/dist/components/InspectorPanel/ElementLibraryButton.js +3 -18
  21. package/dist/components/InspectorSequenceSection.js +1 -4
  22. package/dist/components/Menu/MenuSubItem.js +1 -1
  23. package/dist/components/MenuBuildIndicator.js +7 -2
  24. package/dist/components/MenuCompositionName.js +62 -6
  25. package/dist/components/ModalContainer.d.ts +1 -0
  26. package/dist/components/ModalContainer.js +2 -2
  27. package/dist/components/ModalHeader.js +5 -1
  28. package/dist/components/QuickSwitcher/asset-search.d.ts +0 -1
  29. package/dist/components/QuickSwitcher/asset-search.js +1 -16
  30. package/dist/components/RenderButton.js +2 -2
  31. package/dist/components/RenderModal/CliCopyButton.js +13 -27
  32. package/dist/components/RenderModal/RenderStatusModal.js +7 -1
  33. package/dist/components/RenderModal/ServerRenderModal.js +1 -1
  34. package/dist/components/RenderModal/WebRenderModal.js +1 -1
  35. package/dist/components/RenderQueue/ClientRenderQueueProcessor.js +1 -1
  36. package/dist/components/RenderQueue/RenderQueueCopyToClipboard.js +7 -4
  37. package/dist/components/SettingsModal.js +8 -5
  38. package/dist/components/SidebarCollapserControls.js +11 -5
  39. package/dist/components/SkillsSettings.js +9 -5
  40. package/dist/components/Splitter/SplitterContainer.js +63 -10
  41. package/dist/components/Splitter/SplitterContext.d.ts +3 -0
  42. package/dist/components/Splitter/SplitterContext.js +5 -1
  43. package/dist/components/Splitter/SplitterElement.js +11 -2
  44. package/dist/components/Splitter/SplitterHandle.d.ts +1 -0
  45. package/dist/components/Splitter/SplitterHandle.js +55 -25
  46. package/dist/components/TimeValue.js +36 -7
  47. package/dist/components/Timeline/SubscribeToNodePaths.d.ts +2 -1
  48. package/dist/components/Timeline/SubscribeToNodePaths.js +2 -1
  49. package/dist/components/Timeline/Timeline.d.ts +1 -1
  50. package/dist/components/Timeline/Timeline.js +45 -22
  51. package/dist/components/Timeline/TimelineAssetField.d.ts +0 -1
  52. package/dist/components/Timeline/TimelineAssetField.js +16 -9
  53. package/dist/components/Timeline/TimelineCollapseToggle.js +1 -1
  54. package/dist/components/Timeline/TimelineDragHandler.js +9 -4
  55. package/dist/components/Timeline/TimelineFontWeightField.d.ts +11 -0
  56. package/dist/components/Timeline/TimelineFontWeightField.js +65 -0
  57. package/dist/components/Timeline/TimelineLayerChildren.d.ts +21 -0
  58. package/dist/components/Timeline/TimelineLayerChildren.js +129 -0
  59. package/dist/components/Timeline/TimelineNumberField.js +13 -5
  60. package/dist/components/Timeline/TimelinePinchZoom.js +6 -30
  61. package/dist/components/Timeline/TimelinePlayCursorSyncer.js +1 -7
  62. package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +4 -0
  63. package/dist/components/Timeline/TimelineSequence.js +113 -42
  64. package/dist/components/Timeline/TimelineSequenceItem.js +14 -2
  65. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +13 -3
  66. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +185 -126
  67. package/dist/components/Timeline/TimelineSlider.js +1 -4
  68. package/dist/components/Timeline/TimelineTickFormatProvider.d.ts +8 -0
  69. package/dist/components/Timeline/TimelineTickFormatProvider.js +16 -0
  70. package/dist/components/Timeline/TimelineTimeIndicators.js +7 -3
  71. package/dist/components/Timeline/TimelineVideoInfo.js +7 -3
  72. package/dist/components/Timeline/TimelineWidthProvider.js +2 -5
  73. package/dist/components/Timeline/TimelineZoomControls.js +20 -20
  74. package/dist/components/Timeline/get-sequence-split-menu-item.d.ts +11 -0
  75. package/dist/components/Timeline/get-sequence-split-menu-item.js +55 -0
  76. package/dist/components/Timeline/timeline-field-display-utils.js +1 -0
  77. package/dist/components/Timeline/use-sequence-props-subscription.d.ts +3 -2
  78. package/dist/components/Timeline/use-sequence-props-subscription.js +4 -10
  79. package/dist/components/TopPanel.js +3 -19
  80. package/dist/components/UpdateStatusContext.d.ts +5 -0
  81. package/dist/components/UpdateStatusContext.js +53 -2
  82. package/dist/components/UpdatesSettings.js +34 -9
  83. package/dist/components/WebMcp.js +26 -0
  84. package/dist/components/ZoomPersistor.js +6 -3
  85. package/dist/components/composition-menu-items.js +1 -1
  86. package/dist/components/composition-selector-drag-data.d.ts +27 -0
  87. package/dist/components/composition-selector-drag-data.js +80 -0
  88. package/dist/components/import-assets.d.ts +2 -1
  89. package/dist/components/import-assets.js +11 -1
  90. package/dist/components/parse-caption-file.d.ts +5 -0
  91. package/dist/components/parse-caption-file.js +63 -0
  92. package/dist/esm/{chunk-np6q13k5.js → chunk-3netyjd9.js} +7943 -6314
  93. package/dist/esm/index.mjs +23 -8
  94. package/dist/esm/internals.mjs +7965 -6336
  95. package/dist/esm/previewEntry.mjs +8007 -6378
  96. package/dist/esm/renderEntry.mjs +1 -1
  97. package/dist/helpers/copy-text.js +1 -2
  98. package/dist/helpers/get-preview-file-type.js +22 -3
  99. package/dist/helpers/inserted-element-selection.d.ts +2 -1
  100. package/dist/helpers/use-copy-feedback.d.ts +4 -0
  101. package/dist/helpers/use-copy-feedback.js +19 -0
  102. package/dist/helpers/use-menu-structure.js +2 -2
  103. package/dist/icons/copy.d.ts +5 -0
  104. package/dist/icons/copy.js +12 -0
  105. package/dist/index.d.ts +1 -0
  106. package/dist/index.js +3 -1
  107. package/dist/state/canvas-ref.d.ts +1 -0
  108. package/dist/state/canvas-ref.js +2 -1
  109. package/dist/state/modals.d.ts +0 -2
  110. package/dist/state/sidebar.d.ts +3 -0
  111. package/dist/state/sidebar.js +6 -1
  112. package/dist/state/timeline-zoom.d.ts +1 -1
  113. package/dist/state/timeline-zoom.js +3 -3
  114. package/dist/visual-controls/VisualControls.js +4 -0
  115. package/package.json +16 -16
  116. package/dist/helpers/use-max-media-duration.d.ts +0 -2
  117. package/dist/helpers/use-max-media-duration.js +0 -61
@@ -4,26 +4,58 @@ exports.MenuCompositionName = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
+ const client_id_1 = require("../helpers/client-id");
7
8
  const colors_1 = require("../helpers/colors");
9
+ const hoverable_1 = require("../helpers/hoverable");
10
+ const noop_1 = require("../helpers/noop");
11
+ const modals_1 = require("../state/modals");
12
+ const composition_menu_items_1 = require("./composition-menu-items");
13
+ const ContextMenu_1 = require("./ContextMenu");
14
+ const InlineDropdown_1 = require("./InlineDropdown");
15
+ const use_resolved_stack_1 = require("./Timeline/use-resolved-stack");
16
+ const use_default_editor_info_1 = require("./use-default-editor-info");
8
17
  const baseStyle = {
9
- color: 'inherit',
18
+ cursor: 'default',
10
19
  textDecoration: 'none',
11
20
  fontSize: 'inherit',
12
21
  textUnderlineOffset: 2,
13
22
  whiteSpace: 'nowrap',
14
23
  };
24
+ const assetNameStyle = {
25
+ ...baseStyle,
26
+ color: colors_1.WHITE_ALPHA_80,
27
+ };
28
+ const contextMenuStyle = {
29
+ alignItems: 'center',
30
+ color: 'inherit',
31
+ display: 'flex',
32
+ fontFamily: 'inherit',
33
+ fontSize: 'inherit',
34
+ lineHeight: 'inherit',
35
+ };
15
36
  const compositionNameStyle = {
16
37
  ...baseStyle,
17
- cursor: 'default',
38
+ appearance: 'none',
39
+ border: 'none',
40
+ backgroundColor: colors_1.TRANSPARENT,
41
+ fontFamily: 'inherit',
42
+ fontSize: 13,
43
+ height: 'auto',
44
+ lineHeight: 1.5,
45
+ margin: 0,
46
+ padding: 0,
47
+ width: 'auto',
48
+ ...hoverable_1.NO_HOVER_BACKGROUND_STYLE,
18
49
  };
19
50
  const slashStyle = {
20
51
  color: colors_1.LIGHT_TEXT,
21
52
  marginInline: 4,
53
+ opacity: 0.8,
22
54
  position: 'relative',
23
55
  top: 1,
24
56
  };
25
57
  const MenuCompositionName = () => {
26
- var _a;
58
+ var _a, _b;
27
59
  const { canvasContent, compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
28
60
  const composition = (0, react_1.useMemo)(() => {
29
61
  var _a;
@@ -33,12 +65,36 @@ const MenuCompositionName = () => {
33
65
  return ((_a = compositions.find((c) => c.id === canvasContent.compositionId)) !== null && _a !== void 0 ? _a : null);
34
66
  }, [canvasContent, compositions]);
35
67
  const asset = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'asset' ? canvasContent.asset : null;
68
+ const { setSelectedModal } = (0, react_1.useContext)(modals_1.SetSelectedModalContext);
69
+ const connectionStatus = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx)
70
+ .previewServerState.type;
71
+ const { defaultEditorId, defaultEditorName } = (0, use_default_editor_info_1.useEditorOpening)(connectionStatus === 'connected');
72
+ const resolvedLocation = (0, use_resolved_stack_1.useResolvedStack)((_a = composition === null || composition === void 0 ? void 0 : composition.stack) !== null && _a !== void 0 ? _a : null);
73
+ const getContextMenuItems = (0, react_1.useCallback)(() => {
74
+ return (0, composition_menu_items_1.getCompositionContextMenuItems)({
75
+ closeMenu: noop_1.noop,
76
+ composition,
77
+ connectionStatus,
78
+ editorId: defaultEditorId,
79
+ editorName: defaultEditorName,
80
+ includeCompositionManagementItems: true,
81
+ resolvedLocation,
82
+ setSelectedModal,
83
+ readOnlyStudio: window.remotion_isReadOnlyStudio,
84
+ });
85
+ }, [
86
+ composition,
87
+ connectionStatus,
88
+ defaultEditorId,
89
+ defaultEditorName,
90
+ resolvedLocation,
91
+ setSelectedModal,
92
+ ]);
36
93
  if (!composition && asset === null) {
37
94
  return null;
38
95
  }
39
- const name = (_a = composition === null || composition === void 0 ? void 0 : composition.id) !== null && _a !== void 0 ? _a : asset;
96
+ const name = (_b = composition === null || composition === void 0 ? void 0 : composition.id) !== null && _b !== void 0 ? _b : asset;
40
97
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
41
- jsx_runtime_1.jsx("span", { style: slashStyle, children: "/" }), jsx_runtime_1.jsx("span", { style: compositionNameStyle, children: name })
42
- ] }));
98
+ jsx_runtime_1.jsx("span", { style: slashStyle, children: "/" }), composition ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { getItems: getContextMenuItems, style: contextMenuStyle, children: jsx_runtime_1.jsx(InlineDropdown_1.InlineDropdown, { "aria-label": "Open composition menu", className: hoverable_1.FOCUS_VISIBLE_ONLY_CLASS_NAME, getItems: getContextMenuItems, hoveredColor: colors_1.WHITE, renderAction: () => composition.id, style: compositionNameStyle, title: "Open composition menu", unhoveredColor: colors_1.WHITE_ALPHA_80, variant: null }) })) : (jsx_runtime_1.jsx("span", { style: assetNameStyle, children: name }))] }));
43
99
  };
44
100
  exports.MenuCompositionName = MenuCompositionName;
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  export declare const getMaxModalWidth: (width: number) => string;
3
3
  export declare const getMaxModalHeight: (height: number) => string;
4
4
  export declare const ModalContainer: React.FC<{
5
+ readonly ariaLabelledBy?: string;
5
6
  readonly onEscape: () => void;
6
7
  readonly onOutsideClick: () => void;
7
8
  readonly children: React.ReactNode;
@@ -29,11 +29,11 @@ const panel = {
29
29
  color: colors_1.WHITE,
30
30
  margin: 'auto',
31
31
  };
32
- const ModalContainer = ({ children, onEscape, onOutsideClick, noZIndex, panelStyle }) => {
32
+ const ModalContainer = ({ ariaLabelledBy, children, onEscape, onOutsideClick, noZIndex, panelStyle, }) => {
33
33
  const onPointerDown = (0, react_1.useCallback)((e) => {
34
34
  // Prevent deselection of currently selected items
35
35
  e.stopPropagation();
36
36
  }, []);
37
- return (jsx_runtime_1.jsx("div", { className: "css-reset", style: backgroundOverlay, role: "dialog", "aria-modal": "true", onPointerDown: onPointerDown, children: jsx_runtime_1.jsx(z_index_1.HigherZIndex, { disabled: noZIndex, onOutsideClick: onOutsideClick, onEscape: onEscape, children: jsx_runtime_1.jsx("div", { style: { ...panel, ...panelStyle }, children: children }) }) }));
37
+ return (jsx_runtime_1.jsx("div", { "aria-labelledby": ariaLabelledBy !== null && ariaLabelledBy !== void 0 ? ariaLabelledBy : undefined, "aria-modal": "true", className: "css-reset", role: "dialog", style: backgroundOverlay, onPointerDown: onPointerDown, children: jsx_runtime_1.jsx(z_index_1.HigherZIndex, { disabled: noZIndex, onOutsideClick: onOutsideClick, onEscape: onEscape, children: jsx_runtime_1.jsx("div", { style: { ...panel, ...panelStyle }, children: children }) }) }));
38
38
  };
39
39
  exports.ModalContainer = ModalContainer;
@@ -16,8 +16,12 @@ const container = {
16
16
  borderBottom: colors_1.BORDER_BLACK,
17
17
  };
18
18
  const titleStyle = {
19
- fontSize: 14,
20
19
  color: colors_1.WHITE,
20
+ fontSize: 14,
21
+ minWidth: 0,
22
+ overflow: 'hidden',
23
+ textOverflow: 'ellipsis',
24
+ whiteSpace: 'nowrap',
21
25
  };
22
26
  const icon = {
23
27
  height: 20,
@@ -6,4 +6,3 @@ export declare const filterAssetsByType: ({ assets, query, }: {
6
6
  readonly assets: StaticFile[];
7
7
  readonly query: string;
8
8
  };
9
- export declare const getAssetSearchQueryForComponent: (componentIdentity: string | null) => string;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getAssetSearchQueryForComponent = exports.filterAssetsByType = void 0;
3
+ exports.filterAssetsByType = void 0;
4
4
  const get_preview_file_type_1 = require("../../helpers/get-preview-file-type");
5
5
  const typeFilterRegex = /(^|\s)type:([^\s]+)/gi;
6
6
  const filterAssetsByType = ({ assets, query, }) => {
@@ -26,18 +26,3 @@ const filterAssetsByType = ({ assets, query, }) => {
26
26
  };
27
27
  };
28
28
  exports.filterAssetsByType = filterAssetsByType;
29
- const componentAssetTypes = {
30
- 'dev.remotion.media.Audio': 'audio',
31
- 'dev.remotion.media.Video': 'video',
32
- 'dev.remotion.remotion.AnimatedImage': 'image',
33
- 'dev.remotion.remotion.CanvasImage': 'image',
34
- 'dev.remotion.remotion.Img': 'image',
35
- };
36
- const getAssetSearchQueryForComponent = (componentIdentity) => {
37
- if (componentIdentity === null) {
38
- return '';
39
- }
40
- const assetType = componentAssetTypes[componentIdentity];
41
- return assetType ? `type:${assetType} ` : '';
42
- };
43
- exports.getAssetSearchQueryForComponent = getAssetSearchQueryForComponent;
@@ -282,7 +282,7 @@ const RenderButtonInner = ({ readOnlyStudio, size: controlSize = 'default', narr
282
282
  {
283
283
  type: 'item',
284
284
  id: 'client-render',
285
- label: 'Render on web',
285
+ label: 'Render in browser',
286
286
  value: 'client-render',
287
287
  onClick: () => handleRenderTypeChange('client-render'),
288
288
  keyHint: null,
@@ -336,7 +336,7 @@ const RenderButtonInner = ({ readOnlyStudio, size: controlSize = 'default', narr
336
336
  ? 'Render'
337
337
  : renderType === 'render-command'
338
338
  ? 'Render via CLI'
339
- : 'Render on web';
339
+ : 'Render in browser';
340
340
  const showRenderLabel = !narrow || renderType !== 'server-render';
341
341
  const segments = (0, react_1.useMemo)(() => {
342
342
  return [
@@ -4,20 +4,15 @@ exports.CliCopyButton = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const colors_1 = require("../../helpers/colors");
7
- const clipboard_1 = require("../../icons/clipboard");
7
+ const copy_text_1 = require("../../helpers/copy-text");
8
+ const use_copy_feedback_1 = require("../../helpers/use-copy-feedback");
9
+ const copy_1 = require("../../icons/copy");
10
+ const NotificationCenter_1 = require("../Notifications/NotificationCenter");
8
11
  const svgStyle = {
9
12
  width: 16,
10
13
  height: 16,
11
14
  verticalAlign: 'sub',
12
15
  };
13
- const copiedStyle = {
14
- fontSize: '14px',
15
- minHeight: '30px',
16
- minWidth: '30px',
17
- display: 'flex',
18
- alignItems: 'center',
19
- justifyContent: 'center',
20
- };
21
16
  const buttonStyle = {
22
17
  width: '30px',
23
18
  height: '30px',
@@ -28,33 +23,24 @@ const buttonStyle = {
28
23
  justifyContent: 'center',
29
24
  };
30
25
  const CliCopyButton = ({ valueToCopy, }) => {
31
- const [copied, setCopied] = (0, react_1.useState)(false);
26
+ const { copied, markCopied } = (0, use_copy_feedback_1.useCopyFeedback)();
32
27
  const [hovered, setHovered] = (0, react_1.useState)(false);
33
28
  const fillColor = (0, react_1.useMemo)(() => {
34
29
  return hovered ? colors_1.WHITE : colors_1.LIGHT_TEXT;
35
30
  }, [hovered]);
36
- const clipboardIcon = jsx_runtime_1.jsx(clipboard_1.ClipboardIcon, { color: fillColor, style: svgStyle });
37
- const checkSvg = (jsx_runtime_1.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 448 512", style: svgStyle, children: jsx_runtime_1.jsx("path", { fill: fillColor, d: "M438.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L160 338.7 393.4 105.4c12.5-12.5 32.8-12.5 45.3 0z" }) }));
31
+ const copyIcon = (jsx_runtime_1.jsx(copy_1.CopyIcon, { copied: copied, color: fillColor, style: svgStyle }));
38
32
  const onPointerEnter = (0, react_1.useCallback)(() => {
39
33
  setHovered(true);
40
34
  }, []);
41
35
  const onPointerLeave = (0, react_1.useCallback)(() => {
42
36
  setHovered(false);
43
37
  }, []);
44
- (0, react_1.useEffect)(() => {
45
- if (!copied) {
46
- return;
47
- }
48
- const handleClear = () => {
49
- setCopied(false);
50
- setHovered(false);
51
- };
52
- const to = setTimeout(() => handleClear(), 2000);
53
- return () => clearTimeout(to);
54
- }, [copied]);
55
- return copied ? (jsx_runtime_1.jsx("span", { style: copiedStyle, children: checkSvg })) : (jsx_runtime_1.jsx("button", { type: "button", onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, style: buttonStyle, onClick: () => {
56
- navigator.clipboard.writeText(valueToCopy);
57
- setCopied(true);
58
- }, children: clipboardIcon }));
38
+ return (jsx_runtime_1.jsx("button", { type: "button", onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, style: buttonStyle, onClick: () => {
39
+ (0, copy_text_1.copyText)(valueToCopy)
40
+ .then(markCopied)
41
+ .catch((err) => {
42
+ (0, NotificationCenter_1.showNotification)(`Could not copy: ${err.message}`, 2000);
43
+ });
44
+ }, children: copyIcon }));
59
45
  };
60
46
  exports.CliCopyButton = CliCopyButton;
@@ -41,6 +41,7 @@ const buttonRow = {
41
41
  justifyContent: 'flex-end',
42
42
  };
43
43
  const RenderStatusModal = ({ jobId, }) => {
44
+ var _a;
44
45
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.SetSelectedModalContext);
45
46
  const { jobs, removeClientJob, cancelClientJob } = (0, react_1.useContext)(context_1.RenderQueueContext);
46
47
  const job = jobs.find((j) => j.id === jobId);
@@ -88,9 +89,14 @@ const RenderStatusModal = ({ jobId, }) => {
88
89
  if (job.status === 'idle') {
89
90
  throw new Error('should not have rendered this modal');
90
91
  }
92
+ const errorDetails = job.status === 'failed'
93
+ ? ((_a = job.error.stack) === null || _a === void 0 ? void 0 : _a.split('\n')[0].includes(job.error.message))
94
+ ? job.error.stack
95
+ : [job.error.message, job.error.stack].filter(Boolean).join('\n')
96
+ : null;
91
97
  return (jsx_runtime_1.jsxs(ModalContainer_1.ModalContainer, { onOutsideClick: onQuit, onEscape: onQuit, children: [
92
98
  jsx_runtime_1.jsx(ModalHeader_1.ModalHeader, { title: `Render ${job.compositionId}` }), jsx_runtime_1.jsxs("div", { style: container, children: [job.status === 'failed' ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
93
- jsx_runtime_1.jsx("p", { children: "The render failed because of the following error:" }), jsx_runtime_1.jsx("div", { className: is_menu_item_1.HORIZONTAL_SCROLLBAR_CLASSNAME, style: codeBlock, children: job.error.stack })
99
+ jsx_runtime_1.jsx("p", { children: "The render failed because of the following error:" }), jsx_runtime_1.jsx("div", { className: is_menu_item_1.HORIZONTAL_SCROLLBAR_CLASSNAME, style: codeBlock, children: errorDetails })
94
100
  ] })) : null, (job.status === 'done' || job.status === 'running') &&
95
101
  (isClientJob ? (jsx_runtime_1.jsx(ClientRenderProgress_1.ClientRenderProgress, { job: job })) : (jsx_runtime_1.jsx(GuiRenderStatus_1.GuiRenderStatus, { job: job }))), jsx_runtime_1.jsx("div", { style: spacer }), jsx_runtime_1.jsxs("div", { style: buttonRow, children: [job.status === 'running' ? (jsx_runtime_1.jsx(Button_1.Button, { onClick: onClickOnCancel, children: "Cancel render" })) : (jsx_runtime_1.jsx(Button_1.Button, { onClick: onClickOnRemove, children: "Remove render" })), jsx_runtime_1.jsx(layout_1.Flex, {}), job.status === 'failed' ? (jsx_runtime_1.jsx(Button_1.Button, { onClick: onRetry, children: "Retry" })) : null, jsx_runtime_1.jsx("div", { style: spacer }), jsx_runtime_1.jsx(Button_1.Button, { onClick: onQuit, children: "Close" })
96
102
  ] })
@@ -981,7 +981,7 @@ const RenderModal = ({ readOnlyStudio, initialFrame, initialVideoImageFormat, in
981
981
  });
982
982
  }, [availablePixelFormats, pixelFormat]);
983
983
  return (jsx_runtime_1.jsxs("div", { style: render_modals_1.outerModalStyle, children: [
984
- jsx_runtime_1.jsx(ModalHeader_1.ModalHeader, { title: `Render ${resolvedComposition.id}` }), jsx_runtime_1.jsxs("div", { style: render_modals_1.container, children: [
984
+ jsx_runtime_1.jsx(ModalHeader_1.ModalHeader, { title: `Render ${resolvedComposition.id} ${readOnlyStudio ? 'via CLI' : 'on the server'}` }), jsx_runtime_1.jsxs("div", { style: render_modals_1.container, children: [
985
985
  jsx_runtime_1.jsx(SegmentedControl_1.SegmentedControl, { items: renderTabOptions, needsWrapping: false }), jsx_runtime_1.jsx("div", { style: render_modals_1.flexer }), jsx_runtime_1.jsxs(Button_1.Button, { autoFocus: true, onClick: trigger, disabled: renderDisabled, style: {
986
986
  ...render_modals_1.buttonStyle,
987
987
  backgroundColor: outnameValidation.valid ? colors_1.BLUE : colors_1.BLUE_DISABLED,
@@ -416,7 +416,7 @@ const WebRenderModal = ({ initialFrame, defaultProps, inFrameMark, outFrameMark,
416
416
  pageResponsiveness,
417
417
  ]);
418
418
  return (jsx_runtime_1.jsxs("div", { style: render_modals_1.outerModalStyle, children: [
419
- jsx_runtime_1.jsx(ModalHeader_1.ModalHeader, { title: `Render ${resolvedComposition.id}` }), jsx_runtime_1.jsxs("div", { style: render_modals_1.container, children: [
419
+ jsx_runtime_1.jsx(ModalHeader_1.ModalHeader, { title: `Render ${resolvedComposition.id} in the browser` }), jsx_runtime_1.jsxs("div", { style: render_modals_1.container, children: [
420
420
  jsx_runtime_1.jsx(SegmentedControl_1.SegmentedControl, { items: renderTabOptions, needsWrapping: false }), jsx_runtime_1.jsx("div", { style: render_modals_1.flexer }), jsx_runtime_1.jsxs(Button_1.Button, { autoFocus: true, onClick: onAddToQueue, style: render_modals_1.buttonStyle, disabled: !outnameValidation.valid, children: ["Render ", renderMode, jsx_runtime_1.jsx(ShortcutHint_1.ShortcutHint, { keyToPress: "\u21B5", cmdOrCtrl: true })
421
421
  ] })
422
422
  ] }), jsx_runtime_1.jsxs("div", { style: render_modals_1.horizontalLayout, children: [
@@ -85,7 +85,7 @@ const ClientRenderQueueProcessor = () => {
85
85
  progress: progress.progress,
86
86
  });
87
87
  },
88
- outputTarget: 'web-fs',
88
+ outputTarget: null,
89
89
  licenseKey: (_c = job.licenseKey) !== null && _c !== void 0 ? _c : undefined,
90
90
  pageResponsiveness: job.pageResponsiveness,
91
91
  allowHtmlInCanvas: job.allowHtmlInCanvas,
@@ -5,7 +5,8 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const colors_1 = require("../../helpers/colors");
7
7
  const get_asset_metadata_1 = require("../../helpers/get-asset-metadata");
8
- const clipboard_1 = require("../../icons/clipboard");
8
+ const use_copy_feedback_1 = require("../../helpers/use-copy-feedback");
9
+ const copy_1 = require("../../icons/copy");
9
10
  const InlineAction_1 = require("../InlineAction");
10
11
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
11
12
  const revealIconStyle = {
@@ -29,9 +30,10 @@ const supportsCopyingToClipboard = (job) => {
29
30
  };
30
31
  exports.supportsCopyingToClipboard = supportsCopyingToClipboard;
31
32
  const RenderQueueCopyToClipboard = ({ job }) => {
33
+ const { copied, markCopied } = (0, use_copy_feedback_1.useCopyFeedback)();
32
34
  const renderCopyAction = (0, react_1.useCallback)((color) => {
33
- return jsx_runtime_1.jsx(clipboard_1.ClipboardIcon, { style: revealIconStyle, color: color });
34
- }, []);
35
+ return jsx_runtime_1.jsx(copy_1.CopyIcon, { copied: copied, style: revealIconStyle, color: color });
36
+ }, [copied]);
35
37
  const onClick = (0, react_1.useCallback)(async (e) => {
36
38
  e.stopPropagation();
37
39
  try {
@@ -47,12 +49,13 @@ const RenderQueueCopyToClipboard = ({ job }) => {
47
49
  [contentType]: blob,
48
50
  }),
49
51
  ]);
52
+ markCopied();
50
53
  (0, NotificationCenter_1.showNotification)('Copied to clipboard!', 1000);
51
54
  }
52
55
  catch (err) {
53
56
  (0, NotificationCenter_1.showNotification)(`Could not copy to clipboard: ${err.message}`, 2000);
54
57
  }
55
- }, [job.outName]);
58
+ }, [job.outName, markCopied]);
56
59
  return (jsx_runtime_1.jsx(InlineAction_1.InlineAction, { variant: null, title: "Copy to clipboard", renderAction: renderCopyAction, onClick: onClick }));
57
60
  };
58
61
  exports.RenderQueueCopyToClipboard = RenderQueueCopyToClipboard;
@@ -30,6 +30,7 @@ const SkillsSettings_1 = require("./SkillsSettings");
30
30
  const StudioSettings_1 = require("./StudioSettings");
31
31
  const vertical_1 = require("./Tabs/vertical");
32
32
  const UpdatesSettings_1 = require("./UpdatesSettings");
33
+ const UpdateStatusContext_1 = require("./UpdateStatusContext");
33
34
  const hiddenPanel = {
34
35
  display: 'none',
35
36
  };
@@ -64,11 +65,13 @@ const SettingsModal = ({ initialPublicLicenseKey, initialTab }) => {
64
65
  const { setPublicLicenseKey } = (0, SettingsContext_1.useSettings)();
65
66
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
66
67
  const isBrowserStudio = (0, browser_studio_operations_1.getBrowserStudioOperations)() !== null;
67
- const showUpdates = (0, can_show_updates_1.canShowUpdates)({
68
- connectionStatus: previewServerState.type,
69
- isBrowserStudio,
70
- readOnlyStudio: window.remotion_isReadOnlyStudio,
71
- });
68
+ const { upgradeState } = (0, UpdateStatusContext_1.useUpdateStatus)();
69
+ const showUpdates = upgradeState !== 'idle' ||
70
+ (0, can_show_updates_1.canShowUpdates)({
71
+ connectionStatus: previewServerState.type,
72
+ isBrowserStudio,
73
+ readOnlyStudio: window.remotion_isReadOnlyStudio,
74
+ });
72
75
  const packageManager = window.remotion_packageManager === 'unknown'
73
76
  ? null
74
77
  : window.remotion_packageManager;
@@ -19,7 +19,7 @@ const style = {
19
19
  position: 'relative',
20
20
  };
21
21
  const SidebarCollapserControl = ({ side }) => {
22
- const { setSidebarCollapsedState, sidebarCollapsedStateRight } = (0, react_1.useContext)(sidebar_1.SidebarContext);
22
+ const { setSidebarCollapsedState, sidebarCollapsedStateRight, sidebarCollapsedDuringDrag, } = (0, react_1.useContext)(sidebar_1.SidebarContext);
23
23
  const keybindings = (0, use_keybinding_1.useKeybinding)();
24
24
  const leftSidebarStatus = (0, TopPanel_1.useResponsiveSidebarStatus)();
25
25
  const leftIcon = (0, react_1.useCallback)((color) => {
@@ -27,9 +27,12 @@ const SidebarCollapserControl = ({ side }) => {
27
27
  width: '35%',
28
28
  height: '100%',
29
29
  borderRight: '1px solid ' + color,
30
- background: leftSidebarStatus === 'expanded' ? color : colors_1.TRANSPARENT,
30
+ background: leftSidebarStatus === 'expanded' &&
31
+ sidebarCollapsedDuringDrag !== 'left'
32
+ ? color
33
+ : colors_1.TRANSPARENT,
31
34
  };
32
- }, [leftSidebarStatus]);
35
+ }, [leftSidebarStatus, sidebarCollapsedDuringDrag]);
33
36
  const rightIcon = (0, react_1.useCallback)((color) => {
34
37
  return {
35
38
  width: '35%',
@@ -37,9 +40,12 @@ const SidebarCollapserControl = ({ side }) => {
37
40
  right: 0,
38
41
  position: 'absolute',
39
42
  borderLeft: '1px solid ' + color,
40
- background: sidebarCollapsedStateRight === 'expanded' ? color : colors_1.TRANSPARENT,
43
+ background: sidebarCollapsedStateRight === 'expanded' &&
44
+ sidebarCollapsedDuringDrag !== 'right'
45
+ ? color
46
+ : colors_1.TRANSPARENT,
41
47
  };
42
- }, [sidebarCollapsedStateRight]);
48
+ }, [sidebarCollapsedStateRight, sidebarCollapsedDuringDrag]);
43
49
  const toggleLeft = (0, react_1.useCallback)(() => {
44
50
  setSidebarCollapsedState({
45
51
  left: (s) => {
@@ -5,8 +5,9 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const colors_1 = require("../helpers/colors");
7
7
  const copy_text_1 = require("../helpers/copy-text");
8
+ const use_copy_feedback_1 = require("../helpers/use-copy-feedback");
8
9
  const check_circle_filled_1 = require("../icons/check-circle-filled");
9
- const clipboard_1 = require("../icons/clipboard");
10
+ const copy_1 = require("../icons/copy");
10
11
  const minus_1 = require("../icons/minus");
11
12
  const InlineAction_1 = require("./InlineAction");
12
13
  const ValidationMessage_1 = require("./NewComposition/ValidationMessage");
@@ -94,19 +95,22 @@ const loading = {
94
95
  const SkillsSettings = () => {
95
96
  var _a;
96
97
  const { error, remotionSkillsInfo } = (0, SettingsContext_1.useSettings)();
98
+ const { copied, markCopied } = (0, use_copy_feedback_1.useCopyFeedback)();
97
99
  const installedSkills = (0, react_1.useMemo)(() => {
98
100
  var _a;
99
101
  return ((_a = remotionSkillsInfo === null || remotionSkillsInfo === void 0 ? void 0 : remotionSkillsInfo.skills.filter(({ installedGlobally, installedInProject }) => installedGlobally || installedInProject).length) !== null && _a !== void 0 ? _a : 0);
100
102
  }, [remotionSkillsInfo]);
101
103
  const missingSkills = ((_a = remotionSkillsInfo === null || remotionSkillsInfo === void 0 ? void 0 : remotionSkillsInfo.skills.length) !== null && _a !== void 0 ? _a : 0) - installedSkills;
102
104
  const onCopy = (0, react_1.useCallback)(() => {
103
- (0, copy_text_1.copyText)(INSTALL_COMMAND).catch((err) => {
105
+ (0, copy_text_1.copyText)(INSTALL_COMMAND)
106
+ .then(markCopied)
107
+ .catch((err) => {
104
108
  (0, NotificationCenter_1.showNotification)(`Could not copy: ${err.message}`, 2000);
105
109
  });
106
- }, []);
110
+ }, [markCopied]);
107
111
  const renderCopyAction = (0, react_1.useCallback)((color) => {
108
- return jsx_runtime_1.jsx(clipboard_1.ClipboardIcon, { color: color, style: copyIcon });
109
- }, []);
112
+ return jsx_runtime_1.jsx(copy_1.CopyIcon, { copied: copied, color: color, style: copyIcon });
113
+ }, [copied]);
110
114
  return (jsx_runtime_1.jsxs("div", { style: container, children: [remotionSkillsInfo === null && error === null ? (jsx_runtime_1.jsx("p", { style: loading, children: "Checking installed skills..." })) : null, remotionSkillsInfo === null && error ? (jsx_runtime_1.jsx("div", { style: { marginTop: 14 }, children: jsx_runtime_1.jsx(ValidationMessage_1.ValidationMessage, { message: error, align: "flex-start", type: "error" }) })) : null, missingSkills > 0 ? (jsx_runtime_1.jsxs("div", { children: [
111
115
  jsx_runtime_1.jsx("p", { style: description, children: "Not all skills are installed. Run this command in the project directory, then reload Studio and restart your coding agent." }), jsx_runtime_1.jsxs("div", { style: commandField, children: [
112
116
  jsx_runtime_1.jsx("pre", { style: command, children: INSTALL_COMMAND }), jsx_runtime_1.jsx(InlineAction_1.InlineAction, { variant: null, onClick: onCopy, renderAction: renderCopyAction, title: "Copy install command" })
@@ -1,9 +1,42 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.SplitterContainer = exports.containerColumn = void 0;
4
37
  const jsx_runtime_1 = require("react/jsx-runtime");
5
38
  const player_1 = require("@remotion/player");
6
- const react_1 = require("react");
39
+ const react_1 = __importStar(require("react"));
7
40
  const timeline_1 = require("../../state/timeline");
8
41
  const SplitterContext_1 = require("./SplitterContext");
9
42
  const SplitterHandle_1 = require("./SplitterHandle");
@@ -21,8 +54,10 @@ exports.containerColumn = {
21
54
  height: 0,
22
55
  };
23
56
  const SplitterContainer = ({ orientation, children, defaultFlex, maxFlex, minFlex, maxFlexerSize, minFlexerSize, maxAntiFlexerSize, minAntiFlexerSize, id, }) => {
57
+ const parentLayout = (0, react_1.useContext)(SplitterContext_1.SplitterLayoutContext);
24
58
  const [initialTimelineFlex, persistFlex] = (0, timeline_1.useTimelineFlex)(id);
25
59
  const [flexValue, setFlexValue] = (0, react_1.useState)(initialTimelineFlex !== null && initialTimelineFlex !== void 0 ? initialTimelineFlex : defaultFlex);
60
+ const [collapsedDuringDrag, setCollapsedDuringDrag] = (0, react_1.useState)(null);
26
61
  const ref = (0, react_1.useRef)(null);
27
62
  const isDragging = (0, react_1.useRef)(false);
28
63
  const size = player_1.PlayerInternals.useElementSize(ref, {
@@ -46,6 +81,8 @@ const SplitterContainer = ({ orientation, children, defaultFlex, maxFlex, minFle
46
81
  const value = (0, react_1.useMemo)(() => {
47
82
  return {
48
83
  flexValue: effectiveFlexValue,
84
+ collapsedDuringDrag,
85
+ setCollapsedDuringDrag,
49
86
  ref,
50
87
  setFlexValue,
51
88
  isDragging,
@@ -62,6 +99,7 @@ const SplitterContainer = ({ orientation, children, defaultFlex, maxFlex, minFle
62
99
  };
63
100
  }, [
64
101
  defaultFlex,
102
+ collapsedDuringDrag,
65
103
  effectiveFlexValue,
66
104
  id,
67
105
  maxFlex,
@@ -74,14 +112,29 @@ const SplitterContainer = ({ orientation, children, defaultFlex, maxFlex, minFle
74
112
  persistFlex,
75
113
  ref,
76
114
  ]);
77
- (0, react_1.useEffect)(() => {
78
- const frame = requestAnimationFrame(() => {
79
- player_1.PlayerInternals.updateAllElementsSizes();
80
- });
81
- return () => {
82
- cancelAnimationFrame(frame);
83
- };
84
- });
85
- return (jsx_runtime_1.jsx(SplitterContext_1.SplitterContext.Provider, { value: value, children: jsx_runtime_1.jsx("div", { ref: ref, style: orientation === 'horizontal' ? exports.containerColumn : containerRow, children: children }) }));
115
+ const childCount = react_1.default.Children.toArray(children).length;
116
+ const layout = (0, react_1.useMemo)(() => ({
117
+ parentLayout,
118
+ effectiveFlexValue,
119
+ collapsedDuringDrag,
120
+ orientation,
121
+ width: size === null || size === void 0 ? void 0 : size.width,
122
+ height: size === null || size === void 0 ? void 0 : size.height,
123
+ childCount,
124
+ }), [
125
+ parentLayout,
126
+ effectiveFlexValue,
127
+ collapsedDuringDrag,
128
+ orientation,
129
+ size === null || size === void 0 ? void 0 : size.width,
130
+ size === null || size === void 0 ? void 0 : size.height,
131
+ childCount,
132
+ ]);
133
+ const refreshSize = size === null || size === void 0 ? void 0 : size.refresh;
134
+ (0, react_1.useLayoutEffect)(() => {
135
+ // Remeasure this splitter when its own or an ancestor's layout changes.
136
+ refreshSize === null || refreshSize === void 0 ? void 0 : refreshSize();
137
+ }, [layout, refreshSize]);
138
+ return (jsx_runtime_1.jsx(SplitterContext_1.SplitterLayoutContext.Provider, { value: layout, children: jsx_runtime_1.jsx(SplitterContext_1.SplitterContext.Provider, { value: value, children: jsx_runtime_1.jsx("div", { ref: ref, style: orientation === 'horizontal' ? exports.containerColumn : containerRow, children: children }) }) }));
86
139
  };
87
140
  exports.SplitterContainer = SplitterContainer;
@@ -6,6 +6,8 @@ export type SplitterDragState = false | {
6
6
  export type SplitterOrientation = 'horizontal' | 'vertical';
7
7
  export type TSplitterContext = {
8
8
  flexValue: number;
9
+ collapsedDuringDrag: 'left' | 'right' | null;
10
+ setCollapsedDuringDrag: (side: 'left' | 'right' | null) => void;
9
11
  setFlexValue: React.Dispatch<React.SetStateAction<number>>;
10
12
  orientation: SplitterOrientation;
11
13
  ref: React.RefObject<HTMLDivElement | null>;
@@ -36,4 +38,5 @@ export declare const getClampedSplitterFlex: ({ flexValue, ...bounds }: Pick<TSp
36
38
  readonly flexValue: number;
37
39
  }) => number;
38
40
  export declare const SplitterContext: React.Context<TSplitterContext>;
41
+ export declare const SplitterLayoutContext: React.Context<object | null>;
39
42
  export {};
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.SplitterContext = exports.getClampedSplitterFlex = exports.getSplitterFlexBounds = void 0;
6
+ exports.SplitterLayoutContext = exports.SplitterContext = exports.getClampedSplitterFlex = exports.getSplitterFlexBounds = void 0;
7
7
  const react_1 = __importDefault(require("react"));
8
8
  const getSplitterFlexBounds = ({ availableSize, maxAntiFlexerSize, maxFlex, maxFlexerSize, minAntiFlexerSize, minFlex, minFlexerSize, }) => {
9
9
  if (availableSize === null || availableSize <= 0) {
@@ -21,6 +21,8 @@ const getClampedSplitterFlex = ({ flexValue, ...bounds }) => {
21
21
  exports.getClampedSplitterFlex = getClampedSplitterFlex;
22
22
  exports.SplitterContext = react_1.default.createContext({
23
23
  flexValue: 1,
24
+ collapsedDuringDrag: null,
25
+ setCollapsedDuringDrag: () => undefined,
24
26
  ref: { current: null },
25
27
  setFlexValue: () => undefined,
26
28
  isDragging: { current: false },
@@ -35,3 +37,5 @@ exports.SplitterContext = react_1.default.createContext({
35
37
  id: '--',
36
38
  persistFlex: () => undefined,
37
39
  });
40
+ // Propagate layout changes only through the affected splitter subtree.
41
+ exports.SplitterLayoutContext = react_1.default.createContext(null);