@remotion/studio 4.0.524 → 4.0.525

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 (135) hide show
  1. package/dist/components/ActionTooltip.d.ts +2 -0
  2. package/dist/components/ActionTooltip.js +14 -4
  3. package/dist/components/AppLaunchButton.js +2 -0
  4. package/dist/components/AssetSelectorModal.d.ts +6 -0
  5. package/dist/components/AssetSelectorModal.js +174 -0
  6. package/dist/components/Canvas.js +15 -1
  7. package/dist/components/CheckboardToggle.js +2 -1
  8. package/dist/components/ColorPicker/AlphaSlider.js +1 -1
  9. package/dist/components/ColorPicker/HueSlider.js +1 -1
  10. package/dist/components/ColorPicker/SaturationValueArea.js +1 -1
  11. package/dist/components/CompositionSelector.js +1 -0
  12. package/dist/components/CompositionSelectorItem.js +1 -0
  13. package/dist/components/EditorGuides/Guide.js +1 -1
  14. package/dist/components/ElementInstallConfirmation.js +31 -23
  15. package/dist/components/FullscreenToggle.js +1 -1
  16. package/dist/components/GlobalKeybindings.js +14 -0
  17. package/dist/components/InspectorLocationCopy.js +1 -1
  18. package/dist/components/InspectorOpenInEditor.d.ts +1 -0
  19. package/dist/components/InspectorOpenInEditor.js +18 -15
  20. package/dist/components/InspectorPanel/CompositionInspectorHeader.js +6 -7
  21. package/dist/components/InspectorPanel/CompositionMetadata.js +1 -0
  22. package/dist/components/InspectorPanel/ElementLibraryButton.js +1 -0
  23. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +4 -12
  24. package/dist/components/InspectorSequenceSection.js +18 -9
  25. package/dist/components/LoopToggle.js +2 -1
  26. package/dist/components/Menu/MenuItem.js +1 -2
  27. package/dist/components/MenuBuildIndicator.js +1 -1
  28. package/dist/components/Modals.js +2 -1
  29. package/dist/components/MuteToggle.js +2 -1
  30. package/dist/components/NewComposition/CodemodFooter.js +1 -0
  31. package/dist/components/NewComposition/DeleteComposition.js +42 -6
  32. package/dist/components/NewComposition/DeleteFolder.js +1 -0
  33. package/dist/components/NewComposition/DuplicateComposition.js +5 -0
  34. package/dist/components/NewComposition/InputDragger.js +2 -2
  35. package/dist/components/NewComposition/NewFolder.js +29 -2
  36. package/dist/components/NewComposition/RenameFolder.js +1 -0
  37. package/dist/components/NewComposition/duplicate-composition-api.d.ts +3 -2
  38. package/dist/components/NewComposition/duplicate-composition-api.js +9 -2
  39. package/dist/components/Notifications/NotificationCenter.d.ts +1 -0
  40. package/dist/components/Notifications/NotificationCenter.js +22 -1
  41. package/dist/components/OutlineToggle.js +2 -1
  42. package/dist/components/PlayPause.js +1 -1
  43. package/dist/components/Preview.js +0 -3
  44. package/dist/components/PreviewToolbar.js +3 -6
  45. package/dist/components/PreviewToolbarOverflowButton.js +2 -1
  46. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +1 -1
  47. package/dist/components/RenderButton.js +40 -4
  48. package/dist/components/RenderModal/WebRenderModalBasic.js +1 -1
  49. package/dist/components/RenderModal/render-modals.js +3 -0
  50. package/dist/components/RenderQueue/RenderQueueCopyToClipboard.js +1 -1
  51. package/dist/components/RenderQueue/RenderQueueItemCancelButton.js +1 -1
  52. package/dist/components/RenderQueue/actions.d.ts +2 -1
  53. package/dist/components/RenderQueue/actions.js +2 -1
  54. package/dist/components/RulersAndGuidesToggle.js +2 -1
  55. package/dist/components/SegmentedButton.d.ts +1 -0
  56. package/dist/components/SegmentedButton.js +9 -3
  57. package/dist/components/SelectedOutlineElement.js +16 -6
  58. package/dist/components/SelectedOutlinePolygon.js +4 -2
  59. package/dist/components/SettingsContext.d.ts +8 -0
  60. package/dist/components/SettingsContext.js +57 -2
  61. package/dist/components/SettingsModal.js +4 -1
  62. package/dist/components/SettingsModalFooter.js +1 -1
  63. package/dist/components/SidebarCollapserControls.js +1 -1
  64. package/dist/components/SkillsSettings.js +35 -4
  65. package/dist/components/SnappingToggle.js +2 -1
  66. package/dist/components/Splitter/SplitterHandle.js +1 -2
  67. package/dist/components/Tabs/vertical.d.ts +1 -1
  68. package/dist/components/Tabs/vertical.js +16 -2
  69. package/dist/components/Timeline/EasingEditorModal.js +2 -2
  70. package/dist/components/Timeline/TimelineAssetField.js +148 -9
  71. package/dist/components/Timeline/TimelineDragHandler.js +1 -2
  72. package/dist/components/Timeline/TimelineEffectItem.d.ts +1 -0
  73. package/dist/components/Timeline/TimelineEffectItem.js +2 -2
  74. package/dist/components/Timeline/TimelineEffectPropItem.d.ts +1 -0
  75. package/dist/components/Timeline/TimelineEffectPropItem.js +2 -2
  76. package/dist/components/Timeline/TimelineExpandedRow.js +2 -2
  77. package/dist/components/Timeline/TimelineInOutDragHandler.js +1 -2
  78. package/dist/components/Timeline/TimelineSchemaField.js +8 -1
  79. package/dist/components/Timeline/TimelineSelection.d.ts +3 -1
  80. package/dist/components/Timeline/TimelineSelection.js +32 -5
  81. package/dist/components/Timeline/TimelineSequence.js +6 -6
  82. package/dist/components/Timeline/TimelineSequenceItem.js +12 -10
  83. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +3 -12
  84. package/dist/components/Timeline/TimelineTranslateField.js +25 -12
  85. package/dist/components/Timeline/TimelineZoomControls.js +1 -1
  86. package/dist/components/Timeline/get-sequence-context-menu-items.js +22 -6
  87. package/dist/components/Timeline/timeline-field-display-utils.js +4 -2
  88. package/dist/components/Timeline/timeline-translate-utils.d.ts +17 -0
  89. package/dist/components/Timeline/timeline-translate-utils.js +53 -12
  90. package/dist/components/Timeline/use-open-sequence-in-apps.d.ts +2 -0
  91. package/dist/components/Timeline/use-open-sequence-in-apps.js +17 -0
  92. package/dist/components/Timeline/use-timeline-asset-drop.js +17 -3
  93. package/dist/components/Timeline/use-timeline-keyframe-drag.js +4 -4
  94. package/dist/components/TimelineCombobox.js +1 -0
  95. package/dist/components/UndoRedoButtons.js +11 -0
  96. package/dist/components/composition-menu-items.js +56 -2
  97. package/dist/components/folder-menu-items.js +44 -0
  98. package/dist/components/get-open-in-menu-items.js +1 -1
  99. package/dist/components/import-assets.d.ts +24 -1
  100. package/dist/components/import-assets.js +3 -1
  101. package/dist/components/keyboard-shortcuts.d.ts +4 -4
  102. package/dist/components/keyboard-shortcuts.js +5 -0
  103. package/dist/esm/{LazyModels-hc33szyn.mjs → LazyModels-gfmpcy4h.mjs} +3 -3
  104. package/dist/esm/{LazyModels-sg40rjw6.mjs → LazyModels-m1rf06wh.mjs} +3 -3
  105. package/dist/esm/{TranscriptionModal-3ctnxpt6.mjs → TranscriptionModal-8pvrehg4.mjs} +6 -6
  106. package/dist/esm/{VideoMattingModal-b0r7e60n.mjs → VideoMattingModal-fefbzgka.mjs} +6 -6
  107. package/dist/esm/{index-yfrysr5f.mjs → index-0x13f28h.mjs} +17 -3
  108. package/dist/esm/{index-q2epbw93.mjs → index-1089795y.mjs} +2 -2
  109. package/dist/esm/{index-9qtvmwtx.mjs → index-41kqns5c.mjs} +4 -2
  110. package/dist/esm/{index-c37kme2v.mjs → index-ggqpre9v.mjs} +2202 -1719
  111. package/dist/esm/{index-wbmp5srk.mjs → index-hbezgbbq.mjs} +1 -1
  112. package/dist/esm/{index-2j3d1g81.mjs → index-jrw61pkj.mjs} +1 -1
  113. package/dist/esm/{index-1b9skrrd.mjs → index-mww32xc8.mjs} +3 -3
  114. package/dist/esm/{index-er3mh6em.mjs → index-s848rffx.mjs} +7123 -6588
  115. package/dist/esm/{index-q5xv20xx.mjs → index-tzxb8808.mjs} +1 -1
  116. package/dist/esm/{index-e3zwf3e7.mjs → index-vsxrxfpj.mjs} +1 -1
  117. package/dist/esm/index.mjs +2 -2
  118. package/dist/esm/internals.mjs +7 -7
  119. package/dist/esm/previewEntry.mjs +7 -7
  120. package/dist/helpers/get-git-menu-item.d.ts +4 -0
  121. package/dist/helpers/get-git-menu-item.js +8 -1
  122. package/dist/helpers/get-sequence-double-click-action.d.ts +3 -3
  123. package/dist/helpers/get-sequence-double-click-action.js +2 -2
  124. package/dist/helpers/pointer-session.d.ts +1 -0
  125. package/dist/helpers/pointer-session.js +10 -1
  126. package/dist/helpers/studio-runtime-config.d.ts +1 -1
  127. package/dist/helpers/use-create-composition.js +5 -0
  128. package/dist/helpers/use-keybinding.d.ts +1 -1
  129. package/dist/helpers/use-keyboard-shortcut-label.d.ts +2 -2
  130. package/dist/helpers/use-media-metadata.js +5 -1
  131. package/dist/helpers/use-menu-structure.js +5 -1
  132. package/dist/helpers/use-rename-composition.js +6 -1
  133. package/dist/state/modals.d.ts +13 -1
  134. package/dist/state/z-index.js +1 -3
  135. package/package.json +19 -19
@@ -3,14 +3,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.duplicateComposition = void 0;
4
4
  const browser_studio_operations_1 = require("../../helpers/browser-studio-operations");
5
5
  const actions_1 = require("../RenderQueue/actions");
6
- const duplicateComposition = ({ codemod, dryRun, signal, symbolicatedStack, }) => {
6
+ const duplicateComposition = ({ codemod, dryRun, signal, symbolicatedStack, undoRedoNavigation, }) => {
7
7
  const browserStudioOperations = (0, browser_studio_operations_1.getBrowserStudioOperations)();
8
8
  if (browserStudioOperations === null) {
9
- return (0, actions_1.applyCodemod)({ codemod, dryRun, signal, symbolicatedStack }).then((result) => (result.success ? result : { ...result, stack: '' }));
9
+ return (0, actions_1.applyCodemod)({
10
+ codemod,
11
+ dryRun,
12
+ signal,
13
+ symbolicatedStack,
14
+ undoRedoNavigation,
15
+ }).then((result) => (result.success ? result : { ...result, stack: '' }));
10
16
  }
11
17
  return browserStudioOperations.duplicateComposition({
12
18
  codemod,
13
19
  dryRun,
20
+ undoRedoNavigation,
14
21
  });
15
22
  };
16
23
  exports.duplicateComposition = duplicateComposition;
@@ -4,5 +4,6 @@ type CreatedNotification = {
4
4
  replaceContent: (newContent: React.ReactNode, durationInMs: number | null) => void;
5
5
  };
6
6
  export declare const showNotification: (content: React.ReactNode, durationInMs: number | null) => CreatedNotification;
7
+ export declare const showCannotAddSequenceDropNotification: () => void;
7
8
  export declare const NotificationCenter: React.FC;
8
9
  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.NotificationCenter = exports.showNotification = void 0;
6
+ exports.NotificationCenter = exports.showCannotAddSequenceDropNotification = exports.showNotification = void 0;
7
7
  const jsx_runtime_1 = require("react/jsx-runtime");
8
8
  const react_1 = require("react");
9
9
  const react_dom_1 = __importDefault(require("react-dom"));
@@ -32,6 +32,27 @@ const showNotification = (content, durationInMs) => {
32
32
  });
33
33
  };
34
34
  exports.showNotification = showNotification;
35
+ const CANNOT_ADD_SEQUENCE_DROP_NOTIFICATION = 'Cannot insert this item: This composition component cannot accept a new <Sequence>.';
36
+ const CANNOT_ADD_SEQUENCE_NOTIFICATION_DURATION = 3000;
37
+ let cannotAddSequenceNotification = null;
38
+ let cannotAddSequenceDismissTimeout = null;
39
+ const showCannotAddSequenceDropNotification = () => {
40
+ if (cannotAddSequenceNotification === null) {
41
+ cannotAddSequenceNotification = (0, exports.showNotification)(CANNOT_ADD_SEQUENCE_DROP_NOTIFICATION, null);
42
+ }
43
+ else {
44
+ cannotAddSequenceNotification.replaceContent(CANNOT_ADD_SEQUENCE_DROP_NOTIFICATION, null);
45
+ }
46
+ if (cannotAddSequenceDismissTimeout !== null) {
47
+ clearTimeout(cannotAddSequenceDismissTimeout);
48
+ }
49
+ cannotAddSequenceDismissTimeout = setTimeout(() => {
50
+ cannotAddSequenceNotification === null || cannotAddSequenceNotification === void 0 ? void 0 : cannotAddSequenceNotification.dismiss();
51
+ cannotAddSequenceNotification = null;
52
+ cannotAddSequenceDismissTimeout = null;
53
+ }, CANNOT_ADD_SEQUENCE_NOTIFICATION_DURATION);
54
+ };
55
+ exports.showCannotAddSequenceDropNotification = showCannotAddSequenceDropNotification;
35
56
  const NotificationCenter = () => {
36
57
  const [notifications, setNotifications] = (0, react_1.useState)([]);
37
58
  const { currentZIndex } = (0, z_index_1.useZIndex)();
@@ -9,6 +9,7 @@ const use_keyboard_shortcut_label_1 = require("../helpers/use-keyboard-shortcut-
9
9
  const editor_outlines_1 = require("../state/editor-outlines");
10
10
  const ActionTooltip_1 = require("./ActionTooltip");
11
11
  const ControlButton_1 = require("./ControlButton");
12
+ const buttonStyle = { width: 26 };
12
13
  const OutlineToggle = () => {
13
14
  const { editorShowOutlines, setEditorShowOutlines } = (0, react_1.useContext)(editor_outlines_1.EditorShowOutlinesContext);
14
15
  const onClick = (0, react_1.useCallback)(() => {
@@ -20,7 +21,7 @@ const OutlineToggle = () => {
20
21
  const accessibilityLabel = editorShowOutlines
21
22
  ? 'Hide outlines'
22
23
  : 'Show outlines';
23
- return (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: accessibilityLabel, shortcut: shortcutsDisabled ? null : shortcut, delay: 800, dismissOnClick: false, children: jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: "", "aria-label": accessibilityLabel, "aria-keyshortcuts": shortcutsDisabled ? undefined : ariaShortcut || undefined, "aria-pressed": editorShowOutlines, onClick: onClick, children: (color) => {
24
+ return (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "Outlines", shortcut: shortcutsDisabled ? null : shortcut, delay: 800, dismissOnClick: false, children: jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: "", "aria-label": accessibilityLabel, "aria-keyshortcuts": shortcutsDisabled ? undefined : ariaShortcut || undefined, "aria-pressed": editorShowOutlines, onClick: onClick, style: buttonStyle, children: (color) => {
24
25
  const iconColor = editorShowOutlines ? colors_1.BLUE : color;
25
26
  return (jsx_runtime_1.jsxs("svg", { style: { width: 17, height: 17 }, viewBox: "0 0 512 512", fill: "none", "aria-hidden": "true", focusable: "false", children: [
26
27
  jsx_runtime_1.jsx("path", { d: "M64 64H448V448H64V64Z", stroke: iconColor, strokeWidth: "36" }), [
@@ -235,6 +235,6 @@ const PlayPauseInner = ({ playbackRate, loop, bufferStateDelayInMilliseconds, mu
235
235
  };
236
236
  }, [bufferStateDelayInMilliseconds, emitter]);
237
237
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
238
- jsx_runtime_1.jsx(PlaybackManager, { loop: loop, playbackRate: playbackRate, muted: muted, inFrame: inFrame, outFrame: outFrame, getCurrentFrame: getCurrentFrame }), hideNavigationControls ? null : (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "Go to beginning", shortcut: jumpToBeginningShortcut, delay: 800, dismissOnClick: true, children: jsx_runtime_1.jsx(ControlButton_1.ControlButton, { "aria-label": "Go to beginning", "aria-keyshortcuts": jumpToBeginningAriaShortcut || undefined, title: "", disabled: !videoConfig, onClick: jumpToStart, children: (color) => jsx_runtime_1.jsx(jump_to_start_1.JumpToStart, { style: backStyle, color: color }) }) })), hideNavigationControls ? null : (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "Go back 1 frame", shortcut: "\u2190", delay: 800, dismissOnClick: true, children: jsx_runtime_1.jsx(ControlButton_1.ControlButton, { "aria-label": "Go back 1 frame", "aria-keyshortcuts": "ArrowLeft", title: "", disabled: !videoConfig, onClick: oneFrameBack, children: (color) => jsx_runtime_1.jsx(step_back_1.StepBack, { style: forwardBackStyle, color: color }) }) })), jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: playing ? 'Pause' : 'Play', shortcut: playPauseShortcut, delay: 800, dismissOnClick: false, children: jsx_runtime_1.jsx(ControlButton_1.ControlButton, { "aria-label": playing ? 'Pause' : 'Play', "aria-keyshortcuts": playPauseAriaShortcut || undefined, title: "", onClick: playing ? pause : play, disabled: !videoConfig, children: (color) => playing ? (showBufferIndicator ? (jsx_runtime_1.jsx(player_1.PlayerInternals.BufferingIndicator, { type: "studio", color: color })) : (jsx_runtime_1.jsx(pause_1.Pause, { style: iconButton, color: color }))) : (jsx_runtime_1.jsx(play_1.Play, { style: iconButton, color: color })) }) }), hideNavigationControls ? null : (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "Go forward 1 frame", shortcut: "\u2192", delay: 800, dismissOnClick: true, children: jsx_runtime_1.jsx(ControlButton_1.ControlButton, { "aria-label": "Go forward 1 frame", "aria-keyshortcuts": "ArrowRight", title: "", disabled: !videoConfig, onClick: oneFrameForward, children: (color) => jsx_runtime_1.jsx(step_forward_1.StepForward, { style: forwardBackStyle, color: color }) }) }))] }));
238
+ jsx_runtime_1.jsx(PlaybackManager, { loop: loop, playbackRate: playbackRate, muted: muted, inFrame: inFrame, outFrame: outFrame, getCurrentFrame: getCurrentFrame }), hideNavigationControls ? null : (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "Go to beginning", shortcut: jumpToBeginningShortcut, delay: 800, dismissOnClick: true, children: jsx_runtime_1.jsx(ControlButton_1.ControlButton, { "aria-label": "Go to beginning", "aria-keyshortcuts": jumpToBeginningAriaShortcut || undefined, title: "", disabled: !videoConfig, onClick: jumpToStart, children: (color) => jsx_runtime_1.jsx(jump_to_start_1.JumpToStart, { style: backStyle, color: color }) }) })), hideNavigationControls ? null : (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "Previous frame", shortcut: "\u2190", delay: 800, dismissOnClick: true, children: jsx_runtime_1.jsx(ControlButton_1.ControlButton, { "aria-label": "Go back 1 frame", "aria-keyshortcuts": "ArrowLeft", title: "", disabled: !videoConfig, onClick: oneFrameBack, children: (color) => jsx_runtime_1.jsx(step_back_1.StepBack, { style: forwardBackStyle, color: color }) }) })), jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: playing ? 'Pause' : 'Play', shortcut: playPauseShortcut, delay: 800, dismissOnClick: false, children: jsx_runtime_1.jsx(ControlButton_1.ControlButton, { "aria-label": playing ? 'Pause' : 'Play', "aria-keyshortcuts": playPauseAriaShortcut || undefined, title: "", onClick: playing ? pause : play, disabled: !videoConfig, children: (color) => playing ? (showBufferIndicator ? (jsx_runtime_1.jsx(player_1.PlayerInternals.BufferingIndicator, { type: "studio", color: color })) : (jsx_runtime_1.jsx(pause_1.Pause, { style: iconButton, color: color }))) : (jsx_runtime_1.jsx(play_1.Play, { style: iconButton, color: color })) }) }), hideNavigationControls ? null : (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "Next frame", shortcut: "\u2192", delay: 800, dismissOnClick: true, children: jsx_runtime_1.jsx(ControlButton_1.ControlButton, { "aria-label": "Go forward 1 frame", "aria-keyshortcuts": "ArrowRight", title: "", disabled: !videoConfig, onClick: oneFrameForward, children: (color) => jsx_runtime_1.jsx(step_forward_1.StepForward, { style: forwardBackStyle, color: color }) }) }))] }));
239
239
  };
240
240
  exports.PlayPause = react_1.default.memo(PlayPauseInner);
@@ -47,9 +47,6 @@ const PIXEL_GRID_MIN_SCALE = 4;
47
47
  const containerStyle = (options) => {
48
48
  return {
49
49
  transform: `scale(${options.scale})`,
50
- // Avoid the background bleeding through opaque compositions at fractional
51
- // scales due to Chromium compositing the child and background together.
52
- willChange: 'transform',
53
50
  marginLeft: options.xCorrection,
54
51
  marginTop: options.yCorrection,
55
52
  width: options.width,
@@ -91,13 +91,10 @@ const PreviewToolbar = ({ readOnlyStudio, bufferStateDelayInMilliseconds }) => {
91
91
  ] })) : null, isMobileLayout ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
92
92
  jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(PreviewToolbarOverflowButton_1.PreviewToolbarOverflowButton, { showFullscreen: Boolean(canvasContent && isFullscreenSupported), showPlaybackRate: isVideoComposition, showLoop: isVideoComposition, showCanvasViewControls: showCanvasViewControls, showCompositionControls: showCompositionControls, playbackRate: playbackRate, setPlaybackRate: setPlaybackRate, loop: loop, setLoop: setLoop }) }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1.5 })
93
93
  ] })) : null, isVideoComposition && isMobileLayout ? (jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(MuteToggle_1.MuteToggle, { muted: playerMuted, setMuted: setPlayerMuted }) })) : null] }), jsx_runtime_1.jsx(layout_1.Flex, {}), isVideoComposition && isMobileLayout ? (jsx_runtime_1.jsx("div", { style: centeredPlayButton, children: playPause })) : null, isVideoComposition && !isMobileLayout ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
94
- jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }), playPause, jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }), jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(LoopToggle_1.LoopToggle, { loop: loop, setLoop: setLoop }) }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.75 }), jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(MuteToggle_1.MuteToggle, { muted: playerMuted, setMuted: setPlayerMuted }) }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }), jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(TimelineInOutToggle_1.TimelineInOutPointToggle, {}) }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 })
95
- ] })) : null, showCanvasViewControls ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [isMobileLayout ? null : (jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(CheckboardToggle_1.CheckboardToggle, {}) })), isMobileLayout ? null : jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.25 }), isMobileLayout || !showCompositionControls ? null : (jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(OutlineToggle_1.OutlineToggle, {}) })), isMobileLayout ? null : (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [showCompositionControls ? jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.25 }) : null, jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(RulersAndGuidesToggle_1.RulersAndGuidesToggle, { showGuides: showCompositionControls }) })
96
- ] })), readOnlyStudio ||
94
+ jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }), playPause, jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }), jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(LoopToggle_1.LoopToggle, { loop: loop, setLoop: setLoop }) }), jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(MuteToggle_1.MuteToggle, { muted: playerMuted, setMuted: setPlayerMuted }) }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }), jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(TimelineInOutToggle_1.TimelineInOutPointToggle, {}) }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 })
95
+ ] })) : null, showCanvasViewControls ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [isMobileLayout ? null : (jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(CheckboardToggle_1.CheckboardToggle, {}) })), isMobileLayout || !showCompositionControls ? null : (jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(OutlineToggle_1.OutlineToggle, {}) })), isMobileLayout ? null : (jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(RulersAndGuidesToggle_1.RulersAndGuidesToggle, { showGuides: showCompositionControls }) })), readOnlyStudio ||
97
96
  isMobileLayout ||
98
- !showCompositionControls ? null : (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
99
- jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.25 }), jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(SnappingToggle_1.SnappingToggle, {}) })
100
- ] }))] })) : null, jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }), canvasContent && isFullscreenSupported ? (jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(FullscreenToggle_1.FullScreenToggle, { hidden: isMobileLayout }) })) : null, jsx_runtime_1.jsx(layout_1.Flex, {}), jsx_runtime_1.jsxs("div", { style: sideContainer, children: [
97
+ !showCompositionControls ? null : (jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(SnappingToggle_1.SnappingToggle, {}) }))] })) : null, jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }), canvasContent && isFullscreenSupported ? (jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(FullscreenToggle_1.FullScreenToggle, { hidden: isMobileLayout }) })) : null, jsx_runtime_1.jsx(layout_1.Flex, {}), jsx_runtime_1.jsxs("div", { style: sideContainer, children: [
101
98
  jsx_runtime_1.jsx(layout_1.Flex, {}), isMobileLayout ? null : jsx_runtime_1.jsx(FpsCounter_1.FpsCounter, { playbackSpeed: playbackRate }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }), jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(RenderButton_1.RenderButton, { readOnlyStudio: readOnlyStudio, size: "compact", narrow: isMobileLayout }) }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1.5 })
102
99
  ] }), jsx_runtime_1.jsx(PlaybackKeyboardShortcutsManager_1.PlaybackKeyboardShortcutsManager, { setPlaybackRate: setPlaybackRate, setMuted: setPlayerMuted, setLoop: setLoop }), jsx_runtime_1.jsx(PlaybackRatePersistor_1.PlaybackRatePersistor, {})
103
100
  ] }));
@@ -12,6 +12,7 @@ const checkerboard_1 = require("../state/checkerboard");
12
12
  const editor_guides_1 = require("../state/editor-guides");
13
13
  const editor_outlines_1 = require("../state/editor-outlines");
14
14
  const editor_rulers_1 = require("../state/editor-rulers");
15
+ const ActionTooltip_1 = require("./ActionTooltip");
15
16
  const InlineDropdown_1 = require("./InlineDropdown");
16
17
  const LoopToggle_1 = require("./LoopToggle");
17
18
  const PlaybackRateSelector_1 = require("./PlaybackRateSelector");
@@ -193,6 +194,6 @@ const PreviewToolbarOverflowButton = ({ showFullscreen, showPlaybackRate, showLo
193
194
  if (values.length === 0) {
194
195
  return null;
195
196
  }
196
- return (jsx_runtime_1.jsx(InlineDropdown_1.InlineDropdown, { variant: null, renderAction: renderAction, values: values, title: "More actions", unhoveredColor: colors_1.WHITE_ALPHA_80 }));
197
+ return (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "View options", shortcut: null, delay: 800, dismissOnClick: true, children: jsx_runtime_1.jsx(InlineDropdown_1.InlineDropdown, { variant: null, renderAction: renderAction, values: values, title: "More actions", unhoveredColor: colors_1.WHITE_ALPHA_80 }) }));
197
198
  };
198
199
  exports.PreviewToolbarOverflowButton = PreviewToolbarOverflowButton;
@@ -195,7 +195,7 @@ const QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio
195
195
  return [
196
196
  {
197
197
  id: 'select-file',
198
- title: 'Select file...',
198
+ title: 'Import file...',
199
199
  type: 'select-file',
200
200
  onSelected: () => {
201
201
  assetSelection.onSelectFile();
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.RenderButton = void 0;
37
37
  const jsx_runtime_1 = require("react/jsx-runtime");
38
38
  const player_1 = require("@remotion/player");
39
+ const studio_shared_1 = require("@remotion/studio-shared");
39
40
  const react_1 = __importStar(require("react"));
40
41
  const remotion_1 = require("remotion");
41
42
  const browser_studio_operations_1 = require("../helpers/browser-studio-operations");
@@ -47,7 +48,9 @@ const caret_1 = require("../icons/caret");
47
48
  const render_1 = require("../icons/render");
48
49
  const in_out_1 = require("../state/in-out");
49
50
  const modals_1 = require("../state/modals");
51
+ const call_api_1 = require("./call-api");
50
52
  const layout_1 = require("./layout");
53
+ const NotificationCenter_1 = require("./Notifications/NotificationCenter");
51
54
  const SegmentedButton_1 = require("./SegmentedButton");
52
55
  const segmentedButtonStyle = {
53
56
  height: 28,
@@ -215,7 +218,7 @@ const RenderButtonInner = ({ readOnlyStudio, size: controlSize = 'default', narr
215
218
  renderDefaults: defaults,
216
219
  });
217
220
  }, [video, setSelectedModal, props, inFrame, outFrame, getCurrentFrame]);
218
- const openClientRenderModal = (0, react_1.useCallback)(() => {
221
+ const openClientRenderModal = (0, react_1.useCallback)(async () => {
219
222
  var _a;
220
223
  if (!video) {
221
224
  return null;
@@ -224,6 +227,28 @@ const RenderButtonInner = ({ readOnlyStudio, size: controlSize = 'default', narr
224
227
  if (!defaults) {
225
228
  throw new TypeError('Expected defaults');
226
229
  }
230
+ if (!readOnlyStudio && !isBrowserStudio) {
231
+ let onReconciliation = null;
232
+ const nextReconciliation = new Promise((resolve) => {
233
+ onReconciliation = resolve;
234
+ window.addEventListener(studio_shared_1.REACT_REFRESH_FINISHED_EVENT, onReconciliation, { once: true });
235
+ });
236
+ try {
237
+ const { didInvalidate } = await (0, call_api_1.callApi)('/api/invalidate-bundle', {});
238
+ if (didInvalidate) {
239
+ await nextReconciliation;
240
+ }
241
+ }
242
+ catch (error) {
243
+ (0, NotificationCenter_1.showNotification)(`Could not prepare client-side render: ${error.message}`, 4000);
244
+ return null;
245
+ }
246
+ finally {
247
+ if (onReconciliation) {
248
+ window.removeEventListener(studio_shared_1.REACT_REFRESH_FINISHED_EVENT, onReconciliation);
249
+ }
250
+ }
251
+ }
227
252
  setSelectedModal({
228
253
  type: 'web-render',
229
254
  compositionId: video.id,
@@ -249,7 +274,16 @@ const RenderButtonInner = ({ readOnlyStudio, size: controlSize = 'default', narr
249
274
  initialAllowHtmlInCanvas: defaults.allowHtmlInCanvas,
250
275
  initialPageResponsiveness: 'medium',
251
276
  });
252
- }, [video, setSelectedModal, props, inFrame, outFrame, getCurrentFrame]);
277
+ }, [
278
+ video,
279
+ readOnlyStudio,
280
+ isBrowserStudio,
281
+ setSelectedModal,
282
+ props,
283
+ inFrame,
284
+ outFrame,
285
+ getCurrentFrame,
286
+ ]);
253
287
  const onClick = (0, react_1.useCallback)(() => {
254
288
  if (renderType === 'render-command') {
255
289
  openServerRenderModal(true);
@@ -361,7 +395,8 @@ const RenderButtonInner = ({ readOnlyStudio, size: controlSize = 'default', narr
361
395
  style: controlSize === 'compact'
362
396
  ? compactMainSegmentStyle
363
397
  : defaultMainSegmentStyle,
364
- title: tooltip,
398
+ title: showRenderLabel ? tooltip : null,
399
+ tooltipLabel: showRenderLabel ? null : renderLabel,
365
400
  type: 'action',
366
401
  },
367
402
  {
@@ -378,6 +413,7 @@ const RenderButtonInner = ({ readOnlyStudio, size: controlSize = 'default', narr
378
413
  ? compactDropdownSegmentStyle
379
414
  : defaultDropdownSegmentStyle,
380
415
  title: 'Select render type',
416
+ tooltipLabel: null,
381
417
  type: 'menu',
382
418
  values: dropdownValues,
383
419
  },
@@ -396,7 +432,7 @@ const RenderButtonInner = ({ readOnlyStudio, size: controlSize = 'default', narr
396
432
  return null;
397
433
  }
398
434
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
399
- jsx_runtime_1.jsx("button", { style: { display: 'none' }, id: "render-modal-button-server", disabled: !canServerRender, onClick: () => openServerRenderModal(false), type: "button" }), ' ', jsx_runtime_1.jsx("button", { style: { display: 'none' }, id: "render-modal-button-client", onClick: openClientRenderModal, type: "button" }), jsx_runtime_1.jsx("button", { style: { display: 'none' }, id: "render-modal-button-command", onClick: () => openServerRenderModal(true), type: "button" }), jsx_runtime_1.jsx(SegmentedButton_1.SegmentedButton, { segments: segments, style: segmentedButtonStyle, title: tooltip })
435
+ jsx_runtime_1.jsx("button", { style: { display: 'none' }, id: "render-modal-button-server", disabled: !canServerRender, onClick: () => openServerRenderModal(false), type: "button" }), ' ', jsx_runtime_1.jsx("button", { style: { display: 'none' }, id: "render-modal-button-client", onClick: openClientRenderModal, type: "button" }), jsx_runtime_1.jsx("button", { style: { display: 'none' }, id: "render-modal-button-command", onClick: () => openServerRenderModal(true), type: "button" }), jsx_runtime_1.jsx(SegmentedButton_1.SegmentedButton, { segments: segments, style: segmentedButtonStyle, title: showRenderLabel ? tooltip : null })
400
436
  ] }));
401
437
  };
402
438
  exports.RenderButton = react_1.default.memo(RenderButtonInner);
@@ -121,7 +121,7 @@ const WebRenderModalBasic = ({ renderMode, resolvedComposition, imageFormat, set
121
121
  jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(OptionExplainerBubble_1.WebRendererOptionExplainerBubble, { apiName: "codec", id: "videoCodecOption" })
122
122
  ] }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsx(ComboBox_1.Combobox, { values: codecOptions, selectedId: effectiveVideoCodec, title: "Codec" }) })
123
123
  ] })) : null, jsx_runtime_1.jsx(FrameRangeSetting_1.FrameRangeSetting, { durationInFrames: resolvedComposition.durationInFrames, startFrame: startFrame !== null && startFrame !== void 0 ? startFrame : 0, endFrame: endFrame !== null && endFrame !== void 0 ? endFrame : resolvedComposition.durationInFrames - 1, setStartFrame: setStartFrame, setEndFrame: setEndFrame })
124
- ] })), jsx_runtime_1.jsx(RenderModalOutputName_1.RenderModalOutputName, { ariaLabel: null, existingOutputPath: null, existence: false, inputStyle: layout_2.input, outName: outName, onValueChange: onOutNameChange, validationMessage: validationMessage, label: window.remotion_isReadOnlyStudio ? 'Download name' : 'Output name' }), jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [
124
+ ] })), jsx_runtime_1.jsx(RenderModalOutputName_1.RenderModalOutputName, { ariaLabel: window.remotion_isReadOnlyStudio ? 'Download name' : 'Output name', existingOutputPath: null, existence: false, inputStyle: layout_2.input, outName: outName, onValueChange: onOutNameChange, validationMessage: validationMessage, label: window.remotion_isReadOnlyStudio ? 'Download name' : 'Output name' }), jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [
125
125
  jsx_runtime_1.jsxs("div", { style: layout_2.label, children: ["Log Level ",
126
126
  jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(OptionExplainerBubble_1.WebRendererOptionExplainerBubble, { apiName: "logLevel", id: "logLevelOption" })
127
127
  ] }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsx(ComboBox_1.Combobox, { values: logLevelOptions, selectedId: logLevel, title: "Log Level" }) })
@@ -33,9 +33,12 @@ exports.horizontalLayout = {
33
33
  };
34
34
  exports.leftSidebar = {
35
35
  flexShrink: 0,
36
+ display: 'flex',
37
+ flexDirection: 'column',
36
38
  padding: 6,
37
39
  };
38
40
  exports.horizontalTab = {
41
+ flex: 'none',
39
42
  width: 150,
40
43
  display: 'flex',
41
44
  flexDirection: 'row',
@@ -57,6 +57,6 @@ const RenderQueueCopyToClipboard = ({ job }) => {
57
57
  (0, NotificationCenter_1.showNotification)(`Could not copy to clipboard: ${err.message}`, 2000);
58
58
  }
59
59
  }, [job.outName, markCopied]);
60
- return (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "Copy to clipboard", shortcut: null, delay: 800, dismissOnClick: true, children: jsx_runtime_1.jsx(InlineAction_1.InlineAction, { "aria-label": "Copy to clipboard", variant: null, renderAction: renderCopyAction, onClick: onClick }) }));
60
+ return (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "Copy", shortcut: null, delay: 800, dismissOnClick: true, children: jsx_runtime_1.jsx(InlineAction_1.InlineAction, { "aria-label": "Copy to clipboard", variant: null, renderAction: renderCopyAction, onClick: onClick }) }));
61
61
  };
62
62
  exports.RenderQueueCopyToClipboard = RenderQueueCopyToClipboard;
@@ -31,6 +31,6 @@ const RenderQueueCancelButton = ({ job }) => {
31
31
  const renderAction = (0, react_1.useCallback)((color) => {
32
32
  return (jsx_runtime_1.jsx("svg", { style: icon, xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 512 512", children: jsx_runtime_1.jsx("path", { fill: color, d: "M367.2 412.5L99.5 144.8C77.1 176.1 64 214.5 64 256c0 106 86 192 192 192c41.5 0 79.9-13.1 111.2-35.5zm45.3-45.3C434.9 335.9 448 297.5 448 256c0-106-86-192-192-192c-41.5 0-79.9 13.1-111.2 35.5L412.5 367.2zM512 256c0 141.4-114.6 256-256 256S0 397.4 0 256S114.6 0 256 0S512 114.6 512 256z" }) }));
33
33
  }, [icon]);
34
- return (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "Cancel render", shortcut: null, delay: 800, dismissOnClick: true, children: jsx_runtime_1.jsx(InlineAction_1.InlineAction, { "aria-label": "Cancel render", renderAction: renderAction, onClick: onClick, variant: null }) }));
34
+ return (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "Cancel", shortcut: null, delay: 800, dismissOnClick: true, children: jsx_runtime_1.jsx(InlineAction_1.InlineAction, { "aria-label": "Cancel render", renderAction: renderAction, onClick: onClick, variant: null }) }));
35
35
  };
36
36
  exports.RenderQueueCancelButton = RenderQueueCancelButton;
@@ -100,11 +100,12 @@ export declare const subscribeToFileExistenceWatcher: ({ file, clientId, }: {
100
100
  export declare const openInFileExplorer: ({ directory }: {
101
101
  directory: string;
102
102
  }) => Promise<void>;
103
- export declare const applyCodemod: ({ codemod, dryRun, symbolicatedStack, signal, }: {
103
+ export declare const applyCodemod: ({ codemod, dryRun, symbolicatedStack, signal, undoRedoNavigation, }: {
104
104
  codemod: RecastCodemod;
105
105
  dryRun: boolean;
106
106
  symbolicatedStack: import("@remotion/studio-shared").SymbolicatedStackFrame | null;
107
107
  signal: AbortSignal;
108
+ undoRedoNavigation: import("@remotion/studio-shared").UndoRedoNavigation | null;
108
109
  }) => Promise<import("@remotion/studio-shared").ApplyCodemodResponse>;
109
110
  export declare const removeRenderJob: (job: RenderJob) => Promise<undefined>;
110
111
  export declare const cancelRenderJob: (job: RenderJob) => Promise<import("@remotion/studio-shared").CancelRenderResponse>;
@@ -137,11 +137,12 @@ const openInFileExplorer = ({ directory }) => {
137
137
  return (0, call_api_1.callApi)('/api/open-in-file-explorer', body);
138
138
  };
139
139
  exports.openInFileExplorer = openInFileExplorer;
140
- const applyCodemod = ({ codemod, dryRun, symbolicatedStack, signal, }) => {
140
+ const applyCodemod = ({ codemod, dryRun, symbolicatedStack, signal, undoRedoNavigation, }) => {
141
141
  const body = {
142
142
  codemod,
143
143
  dryRun,
144
144
  symbolicatedStack,
145
+ undoRedoNavigation,
145
146
  };
146
147
  const browserStudioOperations = (0, browser_studio_operations_1.getBrowserStudioOperations)();
147
148
  if (browserStudioOperations !== null) {
@@ -10,6 +10,7 @@ const editor_guides_1 = require("../state/editor-guides");
10
10
  const editor_rulers_1 = require("../state/editor-rulers");
11
11
  const ActionTooltip_1 = require("./ActionTooltip");
12
12
  const ControlButton_1 = require("./ControlButton");
13
+ const buttonStyle = { width: 26 };
13
14
  const RulersAndGuidesToggle = ({ showGuides }) => {
14
15
  const { editorShowGuides, setEditorShowGuides } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
15
16
  const { editorShowRulers, setEditorShowRulers } = (0, react_1.useContext)(editor_rulers_1.EditorShowRulersContext);
@@ -35,6 +36,6 @@ const RulersAndGuidesToggle = ({ showGuides }) => {
35
36
  : editorShowRulers
36
37
  ? 'Hide rulers'
37
38
  : 'Show rulers';
38
- return (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: accessibilityLabel, shortcut: shortcutsDisabled ? null : shortcut, delay: 800, dismissOnClick: false, children: jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: "", "aria-label": accessibilityLabel, "aria-keyshortcuts": shortcutsDisabled ? undefined : ariaShortcut || undefined, "aria-pressed": rulersOrGuidesAreVisible, onClick: onClick, children: (color) => (jsx_runtime_1.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 576 512", style: { width: 18, height: 18 }, "aria-hidden": "true", focusable: "false", children: jsx_runtime_1.jsx("path", { fill: rulersOrGuidesAreVisible ? colors_1.BLUE : color, d: "M525.9 154.2L186.5 493.6c-6.2 6.2-16.4 6.2-22.6 0L50.7 380.5c-6.2-6.2-6.2-16.4 0-22.6l33.9-33.9 56.6 56.6c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6l-56.6-56.6 39.6-39.6 33.9 33.9c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6l-33.9-33.9 39.6-39.6 56.6 56.6c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6l-56.6-56.6 39.6-39.6 33.9 33.9c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6l-33.9-33.9 39.6-39.6 56.6 56.6c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6l-56.6-56.6 33.9-33.9c6.2-6.2 16.4-6.2 22.6 0L525.9 131.5c6.2 6.2 6.2 16.4 0 22.6zM73.3 289.9L28.1 335.2c-18.7 18.7-18.7 49.1 0 67.9L141.2 516.2c18.7 18.7 49.1 18.7 67.9 0L548.5 176.8c18.7-18.7 18.7-49.1 0-67.9L435.4-4.2C416.6-23 386.2-23 367.5-4.2 77.1 286.2 140.3 223 73.3 289.9z" }) })) }) }));
39
+ return (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: showGuides ? 'Rulers and Guides' : 'Rulers', shortcut: shortcutsDisabled ? null : shortcut, delay: 800, dismissOnClick: false, children: jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: "", "aria-label": accessibilityLabel, "aria-keyshortcuts": shortcutsDisabled ? undefined : ariaShortcut || undefined, "aria-pressed": rulersOrGuidesAreVisible, onClick: onClick, style: buttonStyle, children: (color) => (jsx_runtime_1.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 576 512", style: { width: 18, height: 18 }, "aria-hidden": "true", focusable: "false", children: jsx_runtime_1.jsx("path", { fill: rulersOrGuidesAreVisible ? colors_1.BLUE : color, d: "M525.9 154.2L186.5 493.6c-6.2 6.2-16.4 6.2-22.6 0L50.7 380.5c-6.2-6.2-6.2-16.4 0-22.6l33.9-33.9 56.6 56.6c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6l-56.6-56.6 39.6-39.6 33.9 33.9c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6l-33.9-33.9 39.6-39.6 56.6 56.6c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6l-56.6-56.6 39.6-39.6 33.9 33.9c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6l-33.9-33.9 39.6-39.6 56.6 56.6c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6l-56.6-56.6 33.9-33.9c6.2-6.2 16.4-6.2 22.6 0L525.9 131.5c6.2 6.2 6.2 16.4 0 22.6zM73.3 289.9L28.1 335.2c-18.7 18.7-18.7 49.1 0 67.9L141.2 516.2c18.7 18.7 49.1 18.7 67.9 0L548.5 176.8c18.7-18.7 18.7-49.1 0-67.9L435.4-4.2C416.6-23 386.2-23 367.5-4.2 77.1 286.2 140.3 223 73.3 289.9z" }) })) }) }));
39
40
  };
40
41
  exports.RulersAndGuidesToggle = RulersAndGuidesToggle;
@@ -9,6 +9,7 @@ type SegmentedButtonSegmentCommon = {
9
9
  readonly segmentId: string;
10
10
  readonly style: React.CSSProperties | null;
11
11
  readonly title: string | null;
12
+ readonly tooltipLabel: string | null;
12
13
  };
13
14
  export type SegmentedButtonSegment = SegmentedButtonSegmentCommon & ({
14
15
  readonly onClick: React.MouseEventHandler<HTMLButtonElement>;
@@ -13,6 +13,7 @@ const hoverable_1 = require("../helpers/hoverable");
13
13
  const mobile_layout_1 = require("../helpers/mobile-layout");
14
14
  const noop_1 = require("../helpers/noop");
15
15
  const z_index_1 = require("../state/z-index");
16
+ const ActionTooltip_1 = require("./ActionTooltip");
16
17
  const is_menu_item_1 = require("./Menu/is-menu-item");
17
18
  const portals_1 = require("./Menu/portals");
18
19
  const styles_1 = require("./Menu/styles");
@@ -46,6 +47,7 @@ const segmentStyle = {
46
47
  padding: '0 6px',
47
48
  whiteSpace: 'nowrap',
48
49
  };
50
+ const tooltipTriggerStyle = { height: '100%' };
49
51
  const getSegmentBorderRadius = ({ index, segmentCount, }) => {
50
52
  if (segmentCount === 1) {
51
53
  return SEGMENTED_BUTTON_BORDER_RADIUS;
@@ -106,7 +108,11 @@ const SegmentedButtonAction = ({ index, segment, segmentCount }) => {
106
108
  (_a = segment.onPointerDown) === null || _a === void 0 ? void 0 : _a.call(segment, event);
107
109
  preventPointerFocus(event);
108
110
  }, [segment]);
109
- return (jsx_runtime_1.jsx("button", { "aria-label": segment.ariaLabel, className: `${hoverable_1.HOVERABLE_CLASS_NAME} ${hoverable_1.FOCUS_VISIBLE_ONLY_CLASS_NAME}`, disabled: segment.disabled, id: (_a = segment.buttonId) !== null && _a !== void 0 ? _a : undefined, onClick: onClick, onMouseDown: preventMouseFocus, onPointerDown: onPointerDown, style: style, tabIndex: tabIndex, title: (_b = segment.title) !== null && _b !== void 0 ? _b : undefined, type: "button", children: segment.renderContent(colors_1.CURRENT_COLOR) }));
111
+ const button = (jsx_runtime_1.jsx("button", { "aria-label": segment.ariaLabel, className: `${hoverable_1.HOVERABLE_CLASS_NAME} ${hoverable_1.FOCUS_VISIBLE_ONLY_CLASS_NAME}`, disabled: segment.disabled, id: (_a = segment.buttonId) !== null && _a !== void 0 ? _a : undefined, onClick: onClick, onMouseDown: preventMouseFocus, onPointerDown: onPointerDown, style: style, tabIndex: tabIndex, title: (_b = segment.title) !== null && _b !== void 0 ? _b : undefined, type: "button", children: segment.renderContent(colors_1.CURRENT_COLOR) }));
112
+ if (segment.tooltipLabel === null) {
113
+ return button;
114
+ }
115
+ return (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: segment.tooltipLabel, shortcut: null, delay: 800, dismissOnClick: true, triggerStyle: tooltipTriggerStyle, children: button }));
110
116
  };
111
117
  const SegmentedButtonMenu = ({ index, segment, segmentCount }) => {
112
118
  var _a, _b;
@@ -208,8 +214,8 @@ const SegmentedButtonMenu = ({ index, segment, segmentCount }) => {
208
214
  ...segment.style,
209
215
  };
210
216
  }, [index, opened, segment, segmentCount]);
211
- return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
212
- jsx_runtime_1.jsx("button", { ref: ref, "aria-expanded": opened, "aria-haspopup": "menu", "aria-label": segment.ariaLabel, className: `${hoverable_1.HOVERABLE_CLASS_NAME} ${hoverable_1.FOCUS_VISIBLE_ONLY_CLASS_NAME} ${is_menu_item_1.MENU_INITIATOR_CLASSNAME}`, disabled: segment.disabled, id: (_a = segment.buttonId) !== null && _a !== void 0 ? _a : undefined, onClick: onClick, onMouseDown: preventMouseFocus, onPointerDown: onPointerDown, style: style, tabIndex: tabIndex, title: (_b = segment.title) !== null && _b !== void 0 ? _b : undefined, type: "button", children: segment.renderContent(colors_1.CURRENT_COLOR) }), portalStyle
217
+ const button = (jsx_runtime_1.jsx("button", { ref: ref, "aria-expanded": opened, "aria-haspopup": "menu", "aria-label": segment.ariaLabel, className: `${hoverable_1.HOVERABLE_CLASS_NAME} ${hoverable_1.FOCUS_VISIBLE_ONLY_CLASS_NAME} ${is_menu_item_1.MENU_INITIATOR_CLASSNAME}`, disabled: segment.disabled, id: (_a = segment.buttonId) !== null && _a !== void 0 ? _a : undefined, onClick: onClick, onMouseDown: preventMouseFocus, onPointerDown: onPointerDown, style: style, tabIndex: tabIndex, title: (_b = segment.title) !== null && _b !== void 0 ? _b : undefined, type: "button", children: segment.renderContent(colors_1.CURRENT_COLOR) }));
218
+ return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [segment.tooltipLabel === null ? (button) : (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: segment.tooltipLabel, shortcut: null, delay: 800, dismissOnClick: true, triggerStyle: tooltipTriggerStyle, children: button })), portalStyle
213
219
  ? react_dom_1.default.createPortal(jsx_runtime_1.jsx("div", { style: styles_1.fullScreenOverlay, onPointerDown: (event) => event.stopPropagation(), children: jsx_runtime_1.jsx("div", { style: styles_1.outerPortal, className: "css-reset", children: jsx_runtime_1.jsx(z_index_1.HigherZIndex, { onOutsideClick: onOutsideClick, onEscape: onHide, children: jsx_runtime_1.jsx("div", { style: portalStyle, children: jsx_runtime_1.jsx(MenuContent_1.MenuContent, { fixedHeight: Math.max(spaceToBottom, spaceToTop), leaveLeftSpace: segment.leaveLeftSpace, onHide: onHide, onNextMenu: noop_1.noop, onPreviousMenu: noop_1.noop, preselectIndex: segment.selectedId === null
214
220
  ? false
215
221
  : segment.values.findIndex((value) => value.id === segment.selectedId), topItemCanBeUnselected: false, values: segment.values }) }) }) }) }), (0, portals_1.getPortal)(currentZIndex))
@@ -39,6 +39,7 @@ const react_1 = __importStar(require("react"));
39
39
  const remotion_1 = require("remotion");
40
40
  const client_id_1 = require("../helpers/client-id");
41
41
  const get_connected_compositions_1 = require("../helpers/get-connected-compositions");
42
+ const get_git_menu_item_1 = require("../helpers/get-git-menu-item");
42
43
  const get_sequence_double_click_action_1 = require("../helpers/get-sequence-double-click-action");
43
44
  const interactivity_enabled_1 = require("../helpers/interactivity-enabled");
44
45
  const open_in_editor_1 = require("../helpers/open-in-editor");
@@ -65,6 +66,9 @@ const SelectedOutlineElementUnmemoized = ({ compositionHeight, compositionWidth,
65
66
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
66
67
  const { canConfigureApps, canOpenInEditor: editorAvailable, defaultEditorId, editorInfo, } = (0, use_default_editor_info_1.useEditorOpening)(previewServerState.type === 'connected');
67
68
  const codingAgentInfo = (0, use_default_editor_info_1.useDefaultCodingAgentInfo)(canConfigureApps);
69
+ const defaultOpenInTarget = (0, get_git_menu_item_1.getDefaultOpenInTarget)({
70
+ canOpenInEditor: editorAvailable,
71
+ });
68
72
  const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
69
73
  const updateResolvedStackTrace = (0, react_1.useContext)(remotion_1.Internals.SequenceStackTracesUpdateContext);
70
74
  const confirm = (0, ConfirmationDialog_1.useConfirmationDialog)();
@@ -100,7 +104,7 @@ const SelectedOutlineElementUnmemoized = ({ compositionHeight, compositionWidth,
100
104
  });
101
105
  const action = (0, get_sequence_double_click_action_1.getSequenceDoubleClickAction)({
102
106
  button,
103
- canOpenInEditor: editorAvailable,
107
+ canOpenSource: defaultOpenInTarget !== null,
104
108
  numberOfConnectedCompositions: connectedCompositions.length,
105
109
  sequenceWasDragged,
106
110
  });
@@ -111,21 +115,27 @@ const SelectedOutlineElementUnmemoized = ({ compositionHeight, compositionWidth,
111
115
  selectComposition(connectedCompositions[0], true);
112
116
  return true;
113
117
  }
114
- const openTargetInEditor = async () => {
118
+ const openTargetSource = async () => {
115
119
  const originalLocation = await resolveOriginalLocation(doubleClickTarget);
116
- if (originalLocation === null || defaultEditorId === null) {
120
+ if (originalLocation === null) {
121
+ return;
122
+ }
123
+ if (defaultOpenInTarget === 'editor' && defaultEditorId !== null) {
124
+ await (0, open_in_editor_1.openOriginalPositionInEditor)(originalLocation, defaultEditorId);
117
125
  return;
118
126
  }
119
- await (0, open_in_editor_1.openOriginalPositionInEditor)(originalLocation, defaultEditorId);
127
+ if (defaultOpenInTarget === 'git-source') {
128
+ (0, get_git_menu_item_1.openGitSource)({ folder: false, location: originalLocation });
129
+ }
120
130
  };
121
- openTargetInEditor().catch((err) => {
131
+ openTargetSource().catch((err) => {
122
132
  (0, NotificationCenter_1.showNotification)(err.message, 2000);
123
133
  });
124
134
  return true;
125
135
  }, [
126
136
  compositions,
127
137
  defaultEditorId,
128
- editorAvailable,
138
+ defaultOpenInTarget,
129
139
  resolveOriginalLocation,
130
140
  selectComposition,
131
141
  ]);
@@ -262,7 +262,7 @@ const SelectedOutlinePolygonUnmemoized = ({ compositionHeight, compositionWidth,
262
262
  axisLocked = nextAxisLocked;
263
263
  updateDragOverrides();
264
264
  };
265
- const onPointerUp = (reason) => {
265
+ const onPointerUp = (reason, endEvent) => {
266
266
  dragAwareDoubleClick.endPointerGesture(dragStarted);
267
267
  window.removeEventListener('keydown', onKeyChange);
268
268
  window.removeEventListener('keyup', onKeyChange);
@@ -277,7 +277,9 @@ const SelectedOutlinePolygonUnmemoized = ({ compositionHeight, compositionWidth,
277
277
  });
278
278
  if (changes.length === 0) {
279
279
  (0, selected_outline_drag_1.clearSelectedOutlineDragOverrides)({ clearDragOverrides, dragStates });
280
- if (deferSelection && !dragStarted && reason === 'pointerup') {
280
+ if (deferSelection &&
281
+ !dragStarted &&
282
+ (0, pointer_session_1.isPointerSessionRelease)(reason, endEvent)) {
281
283
  onSelect(target.selection, interaction);
282
284
  }
283
285
  return;
@@ -1,5 +1,9 @@
1
1
  import type { GetDefaultCodingAgentInfoResponse, GetDefaultEditorInfoResponse, GetRemotionSkillsInfoResponse, RenderDefaults, StudioRuntimeConfig } from '@remotion/studio-shared';
2
2
  import React from 'react';
3
+ type SkillAction = {
4
+ readonly skill: string;
5
+ readonly type: 'installing' | 'removing';
6
+ };
3
7
  type SettingsContextValue = {
4
8
  readonly codingAgentInfo: GetDefaultCodingAgentInfoResponse | null;
5
9
  readonly editorInfo: GetDefaultEditorInfoResponse | null;
@@ -10,6 +14,10 @@ type SettingsContextValue = {
10
14
  readonly studioRuntimeConfig: StudioRuntimeConfig | null;
11
15
  readonly revision: number;
12
16
  readonly setPublicLicenseKey: (publicLicenseKey: string | null) => void;
17
+ readonly installSkill: (skill: string) => Promise<void>;
18
+ readonly removeSkill: (skill: string) => Promise<void>;
19
+ readonly skillAction: SkillAction | null;
20
+ readonly skillActionError: string | null;
13
21
  };
14
22
  export declare const SettingsProvider: React.FC<{
15
23
  readonly children: React.ReactNode;
@@ -6,6 +6,7 @@ const react_1 = require("react");
6
6
  const browser_studio_operations_1 = require("../helpers/browser-studio-operations");
7
7
  const client_id_1 = require("../helpers/client-id");
8
8
  const call_api_1 = require("./call-api");
9
+ const NotificationCenter_1 = require("./Notifications/NotificationCenter");
9
10
  const UpdateStatusContext_1 = require("./UpdateStatusContext");
10
11
  const SettingsContext = (0, react_1.createContext)(null);
11
12
  const SettingsProvider = ({ children }) => {
@@ -21,6 +22,8 @@ const SettingsProvider = ({ children }) => {
21
22
  renderDefaults: (_c = window.remotion_renderDefaults) !== null && _c !== void 0 ? _c : null,
22
23
  studioRuntimeConfig: (_d = window.remotion_studioConfig) !== null && _d !== void 0 ? _d : null,
23
24
  revision: 0,
25
+ skillAction: null,
26
+ skillActionError: null,
24
27
  });
25
28
  (0, react_1.useEffect)(() => {
26
29
  if (previewServerState.type !== 'connected' ||
@@ -108,9 +111,61 @@ const SettingsProvider = ({ children }) => {
108
111
  };
109
112
  });
110
113
  }, []);
114
+ const installSkill = (0, react_1.useCallback)(async (skill) => {
115
+ setSettings((currentSettings) => ({
116
+ ...currentSettings,
117
+ skillAction: { skill, type: 'installing' },
118
+ skillActionError: null,
119
+ }));
120
+ try {
121
+ const remotionSkillsInfo = await (0, call_api_1.callApi)('/api/install-remotion-skill', {
122
+ skill,
123
+ });
124
+ setSettings((currentSettings) => ({
125
+ ...currentSettings,
126
+ remotionSkillsInfo,
127
+ skillAction: null,
128
+ revision: currentSettings.revision + 1,
129
+ }));
130
+ (0, NotificationCenter_1.showNotification)(`Installed ${skill}.`, 5000);
131
+ }
132
+ catch (err) {
133
+ setSettings((currentSettings) => ({
134
+ ...currentSettings,
135
+ skillAction: null,
136
+ skillActionError: err.message,
137
+ }));
138
+ }
139
+ }, []);
140
+ const removeSkill = (0, react_1.useCallback)(async (skill) => {
141
+ setSettings((currentSettings) => ({
142
+ ...currentSettings,
143
+ skillAction: { skill, type: 'removing' },
144
+ skillActionError: null,
145
+ }));
146
+ try {
147
+ const remotionSkillsInfo = await (0, call_api_1.callApi)('/api/remove-remotion-skill', {
148
+ skill,
149
+ });
150
+ setSettings((currentSettings) => ({
151
+ ...currentSettings,
152
+ remotionSkillsInfo,
153
+ skillAction: null,
154
+ revision: currentSettings.revision + 1,
155
+ }));
156
+ (0, NotificationCenter_1.showNotification)(`Removed ${skill}.`, 5000);
157
+ }
158
+ catch (err) {
159
+ setSettings((currentSettings) => ({
160
+ ...currentSettings,
161
+ skillAction: null,
162
+ skillActionError: err.message,
163
+ }));
164
+ }
165
+ }, []);
111
166
  const value = (0, react_1.useMemo)(() => {
112
- return { ...settings, setPublicLicenseKey };
113
- }, [setPublicLicenseKey, settings]);
167
+ return { ...settings, setPublicLicenseKey, installSkill, removeSkill };
168
+ }, [installSkill, removeSkill, setPublicLicenseKey, settings]);
114
169
  return (jsx_runtime_1.jsx(SettingsContext.Provider, { value: value, children: jsx_runtime_1.jsx(UpdateStatusContext_1.UpdateStatusProvider, { children: children }) }));
115
170
  };
116
171
  exports.SettingsProvider = SettingsProvider;