@remotion/studio 4.0.521 → 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 (60) hide show
  1. package/dist/components/CanvasIfSizeIsAvailable.js +7 -0
  2. package/dist/components/CopyButton.js +7 -14
  3. package/dist/components/Editor.js +6 -5
  4. package/dist/components/EditorContent.js +1 -1
  5. package/dist/components/ElementInstallConfirmation.js +3 -1
  6. package/dist/components/FixComputedValueModal.js +20 -10
  7. package/dist/components/InspectorLocationCopy.js +10 -5
  8. package/dist/components/MenuBuildIndicator.js +7 -2
  9. package/dist/components/MenuCompositionName.js +62 -6
  10. package/dist/components/RenderModal/CliCopyButton.js +13 -27
  11. package/dist/components/RenderQueue/RenderQueueCopyToClipboard.js +7 -4
  12. package/dist/components/SidebarCollapserControls.js +11 -5
  13. package/dist/components/SkillsSettings.js +9 -5
  14. package/dist/components/Splitter/SplitterContainer.js +63 -10
  15. package/dist/components/Splitter/SplitterContext.d.ts +3 -0
  16. package/dist/components/Splitter/SplitterContext.js +5 -1
  17. package/dist/components/Splitter/SplitterElement.js +11 -2
  18. package/dist/components/Splitter/SplitterHandle.d.ts +1 -0
  19. package/dist/components/Splitter/SplitterHandle.js +55 -25
  20. package/dist/components/Timeline/SubscribeToNodePaths.d.ts +2 -1
  21. package/dist/components/Timeline/SubscribeToNodePaths.js +2 -1
  22. package/dist/components/Timeline/Timeline.js +15 -4
  23. package/dist/components/Timeline/TimelineDragHandler.js +9 -4
  24. package/dist/components/Timeline/TimelinePinchZoom.js +6 -30
  25. package/dist/components/Timeline/TimelinePlayCursorSyncer.js +1 -7
  26. package/dist/components/Timeline/TimelineSequence.js +77 -12
  27. package/dist/components/Timeline/TimelineSequenceItem.js +12 -1
  28. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +13 -3
  29. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +168 -121
  30. package/dist/components/Timeline/TimelineSlider.js +1 -4
  31. package/dist/components/Timeline/TimelineWidthProvider.js +2 -5
  32. package/dist/components/Timeline/TimelineZoomControls.js +20 -20
  33. package/dist/components/Timeline/get-sequence-split-menu-item.d.ts +11 -0
  34. package/dist/components/Timeline/get-sequence-split-menu-item.js +55 -0
  35. package/dist/components/Timeline/use-sequence-props-subscription.d.ts +3 -2
  36. package/dist/components/Timeline/use-sequence-props-subscription.js +4 -10
  37. package/dist/components/TopPanel.js +3 -19
  38. package/dist/components/UpdatesSettings.js +9 -5
  39. package/dist/components/ZoomPersistor.js +6 -3
  40. package/dist/components/composition-menu-items.js +1 -1
  41. package/dist/esm/{chunk-emw4k5b0.js → chunk-3netyjd9.js} +4917 -4651
  42. package/dist/esm/internals.mjs +4917 -4651
  43. package/dist/esm/previewEntry.mjs +4895 -4629
  44. package/dist/esm/renderEntry.mjs +1 -1
  45. package/dist/helpers/copy-text.js +1 -2
  46. package/dist/helpers/use-copy-feedback.d.ts +4 -0
  47. package/dist/helpers/use-copy-feedback.js +19 -0
  48. package/dist/icons/copy.d.ts +5 -0
  49. package/dist/icons/copy.js +12 -0
  50. package/dist/state/canvas-ref.d.ts +1 -0
  51. package/dist/state/canvas-ref.js +2 -1
  52. package/dist/state/sidebar.d.ts +3 -0
  53. package/dist/state/sidebar.js +6 -1
  54. package/dist/state/timeline-zoom.d.ts +1 -1
  55. package/dist/state/timeline-zoom.js +3 -3
  56. package/dist/visual-controls/VisualControls.js +4 -0
  57. package/package.json +15 -15
  58. package/dist/esm/chunk-vkrvnx2h.js +0 -99378
  59. package/dist/helpers/use-max-media-duration.d.ts +0 -2
  60. package/dist/helpers/use-max-media-duration.js +0 -61
@@ -5,9 +5,16 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
7
  const ruler_canvas_size_1 = require("../helpers/ruler-canvas-size");
8
+ const canvas_ref_1 = require("../state/canvas-ref");
8
9
  const CanvasOrLoading_1 = require("./CanvasOrLoading");
9
10
  const use_is_ruler_visible_1 = require("./EditorRuler/use-is-ruler-visible");
11
+ const SplitterContext_1 = require("./Splitter/SplitterContext");
10
12
  const CanvasIfSizeIsAvailable = () => {
13
+ const layout = (0, react_1.useContext)(SplitterContext_1.SplitterLayoutContext);
14
+ const refreshCanvas = (0, react_1.useContext)(canvas_ref_1.RefreshCanvasSizeContext);
15
+ (0, react_1.useLayoutEffect)(() => {
16
+ refreshCanvas === null || refreshCanvas === void 0 ? void 0 : refreshCanvas();
17
+ }, [layout, refreshCanvas]);
11
18
  const rulersAreVisible = (0, use_is_ruler_visible_1.useIsRulerVisible)();
12
19
  const context = (0, react_1.useContext)(remotion_1.Internals.CurrentScaleContext);
13
20
  const sizeWithRulersApplied = (0, react_1.useMemo)(() => {
@@ -5,6 +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 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");
8
10
  const Button_1 = require("./Button");
9
11
  const layout_1 = require("./layout");
10
12
  const NotificationCenter_1 = require("./Notifications/NotificationCenter");
@@ -17,29 +19,20 @@ const buttonContainerStyle = {
17
19
  display: 'flex',
18
20
  minWidth: '114px',
19
21
  };
20
- const copyIcon = (jsx_runtime_1.jsx("svg", { "aria-hidden": "true", focusable: "false", "data-prefix": "far", "data-icon": "clipboard", className: "svg-inline--fa fa-clipboard fa-w-12", role: "img", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 384 512", style: iconStyle, children: jsx_runtime_1.jsx("path", { fill: colors_1.CURRENT_COLOR, d: "M336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 40c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm144 418c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V118c0-3.3 2.7-6 6-6h42v36c0 6.6 5.4 12 12 12h168c6.6 0 12-5.4 12-12v-36h42c3.3 0 6 2.7 6 6z" }) }));
21
22
  const labelStyle = {
22
23
  fontSize: 14,
23
24
  };
24
25
  const CopyButton = ({ textToCopy, label, labelWhenCopied }) => {
25
- const [copied, setCopied] = (0, react_1.useState)(false);
26
+ const { copied, markCopied } = (0, use_copy_feedback_1.useCopyFeedback)();
26
27
  const onClick = (0, react_1.useCallback)(() => {
27
28
  (0, copy_text_1.copyText)(textToCopy)
28
- .then(() => {
29
- setCopied(Date.now());
30
- })
29
+ .then(markCopied)
31
30
  .catch((err) => {
32
31
  (0, NotificationCenter_1.showNotification)(`Could not copy: ${err.message}`, 2000);
33
32
  });
34
- }, [textToCopy]);
35
- (0, react_1.useEffect)(() => {
36
- if (!copied) {
37
- return;
38
- }
39
- const to = setTimeout(() => setCopied(false), 2000);
40
- return () => clearTimeout(to);
41
- }, [copied]);
42
- return (jsx_runtime_1.jsxs(Button_1.Button, { onClick: onClick, buttonContainerStyle: buttonContainerStyle, children: [copyIcon, jsx_runtime_1.jsx(layout_1.Spacing, { x: 1.5 }), ' ', jsx_runtime_1.jsx("span", { style: labelStyle, children: copied ? labelWhenCopied : label })
33
+ }, [markCopied, textToCopy]);
34
+ return (jsx_runtime_1.jsxs(Button_1.Button, { onClick: onClick, buttonContainerStyle: buttonContainerStyle, children: [
35
+ jsx_runtime_1.jsx(copy_1.CopyIcon, { copied: copied, color: colors_1.CURRENT_COLOR, style: iconStyle }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1.5 }), ' ', jsx_runtime_1.jsx("span", { style: labelStyle, children: copied ? labelWhenCopied : label })
43
36
  ] }));
44
37
  };
45
38
  exports.CopyButton = CopyButton;
@@ -79,6 +79,7 @@ const CompositionListRenderMarker = () => {
79
79
  return null;
80
80
  };
81
81
  const Editor = ({ Root, readOnlyStudio }) => {
82
+ var _a;
82
83
  (0, client_id_1.useStudioConfigRevision)();
83
84
  const [drawElement, setDrawElement] = (0, react_1.useState)(null);
84
85
  const size = player_1.PlayerInternals.useElementSize(drawElement, {
@@ -111,11 +112,11 @@ const Editor = ({ Root, readOnlyStudio }) => {
111
112
  const compositionRenderErrorContextValue = (0, react_1.useMemo)(() => ({ setError: setRenderError, clearError }), [clearError]);
112
113
  const renderErrorContextValue = (0, react_1.useMemo)(() => ({ error: renderError }), [renderError]);
113
114
  return (jsx_runtime_1.jsx(z_index_1.HigherZIndex, { onEscape: noop_1.noop, onOutsideClick: noop_1.noop, children: jsx_runtime_1.jsx(timeline_zoom_1.TimelineZoomContext, { children: jsx_runtime_1.jsxs(SequencePropsSubscriptionProvider_1.SequencePropsSubscriptionProvider, { children: [
114
- jsx_runtime_1.jsxs(remotion_1.Internals.CurrentScaleContext.Provider, { value: value, children: [
115
- jsx_runtime_1.jsx(ForceSpecificCursor_1.ForceSpecificCursor, {}), jsx_runtime_1.jsx(CanvasCaptureDropHandler_1.CanvasCaptureDropHandler, { readOnlyStudio: readOnlyStudio }), jsx_runtime_1.jsx(scale_lock_1.ScaleLockProvider, { children: jsx_runtime_1.jsxs("div", { style: background, children: [
116
- jsx_runtime_1.jsx(remotion_1.Internals.CompositionRenderErrorContext.Provider, { value: compositionRenderErrorContextValue, children: canvasMounted ? (jsx_runtime_1.jsx(RootCompositionLoader, { Root: MemoRoot })) : null }), jsx_runtime_1.jsx(remotion_1.Internals.CanUseRemotionHooksProvider, { children: jsx_runtime_1.jsx(RenderErrorContext_1.RenderErrorContext.Provider, { value: renderErrorContextValue, children: jsx_runtime_1.jsx(EditorContent_1.EditorContent, { readOnlyStudio: readOnlyStudio, children: jsx_runtime_1.jsx(TopPanel_1.TopPanel, { drawRef: setDrawRef, bufferStateDelayInMilliseconds: (0, studio_runtime_config_1.getStudioBufferStateDelayInMilliseconds)(), onMounted: onMounted, readOnlyStudio: readOnlyStudio }) }) }) })
117
- ] }) })
118
- ] }), jsx_runtime_1.jsx(Modals_1.Modals, { readOnlyStudio: readOnlyStudio }), jsx_runtime_1.jsx(NotificationCenter_1.NotificationCenter, {})
115
+ jsx_runtime_1.jsx(canvas_ref_1.RefreshCanvasSizeContext.Provider, { value: (_a = size === null || size === void 0 ? void 0 : size.refresh) !== null && _a !== void 0 ? _a : null, children: jsx_runtime_1.jsxs(remotion_1.Internals.CurrentScaleContext.Provider, { value: value, children: [
116
+ jsx_runtime_1.jsx(ForceSpecificCursor_1.ForceSpecificCursor, {}), jsx_runtime_1.jsx(CanvasCaptureDropHandler_1.CanvasCaptureDropHandler, { readOnlyStudio: readOnlyStudio }), jsx_runtime_1.jsx(scale_lock_1.ScaleLockProvider, { children: jsx_runtime_1.jsxs("div", { style: background, children: [
117
+ jsx_runtime_1.jsx(remotion_1.Internals.CompositionRenderErrorContext.Provider, { value: compositionRenderErrorContextValue, children: canvasMounted ? (jsx_runtime_1.jsx(RootCompositionLoader, { Root: MemoRoot })) : null }), jsx_runtime_1.jsx(remotion_1.Internals.CanUseRemotionHooksProvider, { children: jsx_runtime_1.jsx(RenderErrorContext_1.RenderErrorContext.Provider, { value: renderErrorContextValue, children: jsx_runtime_1.jsx(EditorContent_1.EditorContent, { readOnlyStudio: readOnlyStudio, children: jsx_runtime_1.jsx(TopPanel_1.TopPanel, { drawRef: setDrawRef, bufferStateDelayInMilliseconds: (0, studio_runtime_config_1.getStudioBufferStateDelayInMilliseconds)(), onMounted: onMounted, readOnlyStudio: readOnlyStudio }) }) }) })
118
+ ] }) })
119
+ ] }) }), jsx_runtime_1.jsx(Modals_1.Modals, { readOnlyStudio: readOnlyStudio }), jsx_runtime_1.jsx(NotificationCenter_1.NotificationCenter, {})
119
120
  ] }) }) }));
120
121
  };
121
122
  exports.Editor = Editor;
@@ -41,7 +41,7 @@ const EditorContent = ({ readOnlyStudio, children }) => {
41
41
  (canvasContent.type === 'asset' &&
42
42
  (currentAssetMetadata === null || currentAssetMetadata === void 0 ? void 0 : currentAssetMetadata.asset) === canvasContent.asset));
43
43
  const content = (jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { orientation: "horizontal", id: "top-to-bottom", maxFlex: 0.9, minFlex: 0.2, defaultFlex: 0.75, maxFlexerSize: null, minFlexerSize: null, maxAntiFlexerSize: null, minAntiFlexerSize: null, children: [
44
- 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, {}) })
44
+ jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { sticky: null, type: "flexer", children: children }), jsx_runtime_1.jsx(SplitterHandle_1.SplitterHandle, { allowToCollapse: "none", onCollapse: noop, onCollapseDuringDrag: null }), 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, {}) })
45
45
  ] }));
46
46
  return (jsx_runtime_1.jsxs(TimelineSelection_1.TimelineSelectionProvider, { children: [
47
47
  jsx_runtime_1.jsx(WebMcp_1.WebMcp, {}), jsx_runtime_1.jsx(transform_3d_mode_1.Transform3DModeStateProvider, { children: jsx_runtime_1.jsxs(StudioClearSelectionArea, { children: [
@@ -283,7 +283,9 @@ const ElementInstallConfirmation = ({ state }) => {
283
283
  };
284
284
  const usesBrowserDependencyResolution = (0, browser_studio_operations_1.getBrowserStudioOperations)() !== null;
285
285
  const { currentZIndex } = (0, z_index_1.useZIndex)();
286
- const [mode, setMode] = (0, react_1.useState)(currentPlan === null ? 'new-composition' : 'current-composition');
286
+ const [mode, setMode] = (0, react_1.useState)(currentPlan === null || request.source.type === 'browser-studio-link'
287
+ ? 'new-composition'
288
+ : 'current-composition');
287
289
  const [submitting, setSubmitting] = (0, react_1.useState)(false);
288
290
  const inputRef = (0, react_1.useRef)(null);
289
291
  const currentDestinationRef = (0, react_1.useRef)(null);
@@ -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 copy_text_1 = require("../helpers/copy-text");
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 CodingAgentButton_1 = require("./CodingAgentButton");
10
11
  const InlineAction_1 = require("./InlineAction");
11
12
  const ModalFooter_1 = require("./ModalFooter");
@@ -63,23 +64,32 @@ const FixComputedValueModal = ({ state }) => {
63
64
  const prompt = `/remotion-interactivity ${state.context} make "${state.prop}" interactive`;
64
65
  const installCommand = 'npx remotion skills add';
65
66
  const hasCodingAgent = ((_a = codingAgentInfo === null || codingAgentInfo === void 0 ? void 0 : codingAgentInfo.installedCodingAgents.length) !== null && _a !== void 0 ? _a : 0) > 0;
67
+ const { copied: promptCopied, markCopied: markPromptCopied } = (0, use_copy_feedback_1.useCopyFeedback)();
68
+ const { copied: installCommandCopied, markCopied: markInstallCommandCopied } = (0, use_copy_feedback_1.useCopyFeedback)();
66
69
  const onCopyPrompt = (0, react_1.useCallback)(() => {
67
- (0, copy_text_1.copyText)(prompt).catch((err) => {
70
+ (0, copy_text_1.copyText)(prompt)
71
+ .then(markPromptCopied)
72
+ .catch((err) => {
68
73
  (0, NotificationCenter_1.showNotification)(`Could not copy: ${err.message}`, 2000);
69
74
  });
70
- }, [prompt]);
75
+ }, [markPromptCopied, prompt]);
71
76
  const onCopyInstallCommand = (0, react_1.useCallback)(() => {
72
- (0, copy_text_1.copyText)(installCommand).catch((err) => {
77
+ (0, copy_text_1.copyText)(installCommand)
78
+ .then(markInstallCommandCopied)
79
+ .catch((err) => {
73
80
  (0, NotificationCenter_1.showNotification)(`Could not copy: ${err.message}`, 2000);
74
81
  });
75
- }, [installCommand]);
76
- const renderCopyAction = (0, react_1.useCallback)((color) => {
77
- return jsx_runtime_1.jsx(clipboard_1.ClipboardIcon, { color: color, style: copyIcon });
78
- }, []);
82
+ }, [installCommand, markInstallCommandCopied]);
83
+ const renderPromptCopyAction = (0, react_1.useCallback)((color) => {
84
+ return jsx_runtime_1.jsx(copy_1.CopyIcon, { copied: promptCopied, color: color, style: copyIcon });
85
+ }, [promptCopied]);
86
+ const renderInstallCommandCopyAction = (0, react_1.useCallback)((color) => {
87
+ return (jsx_runtime_1.jsx(copy_1.CopyIcon, { copied: installCommandCopied, color: color, style: copyIcon }));
88
+ }, [installCommandCopied]);
79
89
  return (jsx_runtime_1.jsxs(DismissableModal_1.DismissableModal, { panelStyle: panelStyle, children: [
80
90
  jsx_runtime_1.jsx(ModalHeader_1.ModalHeader, { title: "Fix computed value" }), jsx_runtime_1.jsxs("div", { style: container, children: [state.remotionInteractivitySkillAvailable ? null : (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
81
91
  jsx_runtime_1.jsx("div", { style: text, children: "First, install the Remotion Agent Skills:" }), jsx_runtime_1.jsxs("div", { style: commandField, children: [
82
- jsx_runtime_1.jsx("pre", { style: code, children: installCommand }), jsx_runtime_1.jsx(InlineAction_1.InlineAction, { variant: null, onClick: onCopyInstallCommand, renderAction: renderCopyAction, title: "Copy command" })
92
+ jsx_runtime_1.jsx("pre", { style: code, children: installCommand }), jsx_runtime_1.jsx(InlineAction_1.InlineAction, { variant: null, onClick: onCopyInstallCommand, renderAction: renderInstallCommandCopyAction, title: "Copy command" })
83
93
  ] })
84
94
  ] })), jsx_runtime_1.jsx("div", { style: {
85
95
  ...text,
@@ -87,7 +97,7 @@ const FixComputedValueModal = ({ state }) => {
87
97
  }, children: state.remotionInteractivitySkillAvailable
88
98
  ? 'Paste this prompt into your coding agent to make this value editable in Studio:'
89
99
  : 'Then, paste this prompt into your coding agent:' }), jsx_runtime_1.jsxs("div", { style: commandField, children: [
90
- jsx_runtime_1.jsx("pre", { style: code, children: prompt }), jsx_runtime_1.jsx(InlineAction_1.InlineAction, { variant: null, onClick: onCopyPrompt, renderAction: renderCopyAction, title: "Copy prompt" })
100
+ jsx_runtime_1.jsx("pre", { style: code, children: prompt }), jsx_runtime_1.jsx(InlineAction_1.InlineAction, { variant: null, onClick: onCopyPrompt, renderAction: renderPromptCopyAction, title: "Copy prompt" })
91
101
  ] })
92
102
  ] }), hasCodingAgent ? (jsx_runtime_1.jsx(ModalFooter_1.ModalFooterContainer, { style: footer, children: jsx_runtime_1.jsx(CodingAgentButton_1.CodingAgentButton, { label: "Open in", prompt: prompt, size: "compact", style: null }) })) : null] }));
93
103
  };
@@ -4,7 +4,8 @@ exports.InspectorLocationCopy = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const format_file_location_1 = require("../helpers/format-file-location");
7
- const clipboard_1 = require("../icons/clipboard");
7
+ const use_copy_feedback_1 = require("../helpers/use-copy-feedback");
8
+ const copy_1 = require("../icons/copy");
8
9
  const InlineAction_1 = require("./InlineAction");
9
10
  const InspectorOpenInEditor_1 = require("./InspectorOpenInEditor");
10
11
  const NotificationCenter_1 = require("./Notifications/NotificationCenter");
@@ -38,6 +39,7 @@ const icon = {
38
39
  const InspectorLocationCopy = ({ children, location, name, openInEditorLocation }) => {
39
40
  const [hovered, setHovered] = (0, react_1.useState)(false);
40
41
  const [focusedWithin, setFocusedWithin] = (0, react_1.useState)(false);
42
+ const { copied, markCopied } = (0, use_copy_feedback_1.useCopyFeedback)();
41
43
  const contextForAgents = (0, react_1.useMemo)(() => {
42
44
  return (0, format_file_location_1.formatContextForAgents)({
43
45
  location,
@@ -46,17 +48,20 @@ const InspectorLocationCopy = ({ children, location, name, openInEditorLocation
46
48
  });
47
49
  }, [location, name]);
48
50
  const renderCopyAction = (0, react_1.useCallback)((color) => {
49
- return jsx_runtime_1.jsx(clipboard_1.ClipboardIcon, { style: icon, color: color });
50
- }, []);
51
+ return jsx_runtime_1.jsx(copy_1.CopyIcon, { copied: copied, style: icon, color: color });
52
+ }, [copied]);
51
53
  const onCopy = (0, react_1.useCallback)((event) => {
52
54
  event.stopPropagation();
53
55
  if (!contextForAgents) {
54
56
  return;
55
57
  }
56
- navigator.clipboard.writeText(contextForAgents).catch((err) => {
58
+ navigator.clipboard
59
+ .writeText(contextForAgents)
60
+ .then(markCopied)
61
+ .catch((err) => {
57
62
  (0, NotificationCenter_1.showNotification)(`Could not copy to clipboard: ${err.message}`, 2000);
58
63
  });
59
- }, [contextForAgents]);
64
+ }, [contextForAgents, markCopied]);
60
65
  const showAction = hovered || focusedWithin;
61
66
  return (jsx_runtime_1.jsxs("div", { "aria-label": "Inspector source location", role: "group", style: row, onPointerEnter: () => setHovered(true), onPointerLeave: () => setHovered(false), onFocus: () => setFocusedWithin(true), onBlur: () => setFocusedWithin(false), children: [
62
67
  jsx_runtime_1.jsx("div", { style: content, children: children }), contextForAgents || openInEditorLocation ? (jsx_runtime_1.jsxs("div", { style: {
@@ -10,7 +10,7 @@ const MenuCompositionName_1 = require("./MenuCompositionName");
10
10
  const Spinner_1 = require("./Spinner");
11
11
  const cwd = {
12
12
  fontSize: 13,
13
- opacity: 0.8,
13
+ color: colors_1.WHITE_ALPHA_80,
14
14
  display: 'flex',
15
15
  alignItems: 'center',
16
16
  justifyContent: 'center',
@@ -19,9 +19,14 @@ const cwd = {
19
19
  };
20
20
  const spinnerSize = 14;
21
21
  const spinner = {
22
+ opacity: 0.8,
22
23
  position: 'relative',
23
24
  width: spinnerSize,
24
25
  };
26
+ const openInEditor = {
27
+ display: 'flex',
28
+ opacity: 0.8,
29
+ };
25
30
  const noSpinner = {
26
31
  position: 'relative',
27
32
  width: spinnerSize,
@@ -48,7 +53,7 @@ const MenuBuildIndicator = ({ mobileLayout }) => {
48
53
  };
49
54
  }, []);
50
55
  return (jsx_runtime_1.jsxs("div", { style: cwd, title: window.remotion_cwd, children: [
51
- jsx_runtime_1.jsx(layout_1.Spacing, { x: mobileLayout ? 0.5 : 2 }), window.remotion_projectName, jsx_runtime_1.jsx(MenuCompositionName_1.MenuCompositionName, {}), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx(InspectorOpenInEditor_1.InspectorOpenInEditor, { location: folderLocation, locationType: "folder" }), mobileLayout ? null : jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), mobileLayout ? (isBuilding ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
56
+ jsx_runtime_1.jsx(layout_1.Spacing, { x: mobileLayout ? 0.5 : 2 }), window.remotion_projectName, jsx_runtime_1.jsx(MenuCompositionName_1.MenuCompositionName, {}), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("div", { style: openInEditor, children: jsx_runtime_1.jsx(InspectorOpenInEditor_1.InspectorOpenInEditor, { location: folderLocation, locationType: "folder" }) }), mobileLayout ? null : jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), mobileLayout ? (isBuilding ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
52
57
  jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx("div", { style: spinner, children: jsx_runtime_1.jsx(Spinner_1.Spinner, { duration: 0.5, size: spinnerSize, color: colors_1.WHITE_ALPHA_80 }) })
53
58
  ] })) : null) : isBuilding ? (jsx_runtime_1.jsx("div", { style: spinner, children: jsx_runtime_1.jsx(Spinner_1.Spinner, { duration: 0.5, size: spinnerSize, color: colors_1.WHITE_ALPHA_80 }) })) : (jsx_runtime_1.jsx("div", { style: noSpinner }))] }));
54
59
  };
@@ -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;
@@ -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;
@@ -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;
@@ -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" })