@remotion/studio 4.0.523 → 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 (182) hide show
  1. package/dist/components/ActionTooltip.d.ts +11 -0
  2. package/dist/components/ActionTooltip.js +153 -0
  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 +18 -3
  7. package/dist/components/CheckboardToggle.js +8 -10
  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 +35 -62
  15. package/dist/components/FullscreenToggle.js +5 -8
  16. package/dist/components/GlobalKeybindings.js +71 -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 +23 -14
  25. package/dist/components/LazySyntaxHighlightedSource.d.ts +4 -0
  26. package/dist/components/LazySyntaxHighlightedSource.js +43 -0
  27. package/dist/components/LoopToggle.js +9 -2
  28. package/dist/components/Menu/MenuItem.js +1 -2
  29. package/dist/components/MenuBuildIndicator.js +1 -1
  30. package/dist/components/MenuToolbar.js +6 -4
  31. package/dist/components/Modals.js +2 -1
  32. package/dist/components/MuteToggle.d.ts +1 -0
  33. package/dist/components/MuteToggle.js +17 -6
  34. package/dist/components/NewComposition/CodemodFooter.js +1 -0
  35. package/dist/components/NewComposition/DeleteComposition.js +42 -6
  36. package/dist/components/NewComposition/DeleteFolder.js +1 -0
  37. package/dist/components/NewComposition/DuplicateComposition.js +5 -0
  38. package/dist/components/NewComposition/InputDragger.js +2 -2
  39. package/dist/components/NewComposition/NewComposition.d.ts +1 -0
  40. package/dist/components/NewComposition/NewComposition.js +5 -4
  41. package/dist/components/NewComposition/NewFolder.js +31 -6
  42. package/dist/components/NewComposition/RenameComposition.js +3 -2
  43. package/dist/components/NewComposition/RenameFolder.js +3 -4
  44. package/dist/components/NewComposition/SlugPreview.d.ts +7 -0
  45. package/dist/components/NewComposition/SlugPreview.js +18 -0
  46. package/dist/components/NewComposition/duplicate-composition-api.d.ts +3 -2
  47. package/dist/components/NewComposition/duplicate-composition-api.js +9 -2
  48. package/dist/components/Notifications/NotificationCenter.d.ts +1 -0
  49. package/dist/components/Notifications/NotificationCenter.js +22 -1
  50. package/dist/components/OutlineToggle.js +17 -10
  51. package/dist/components/PlayPause.js +7 -1
  52. package/dist/components/PlaybackKeyboardShortcutsManager.d.ts +2 -0
  53. package/dist/components/PlaybackKeyboardShortcutsManager.js +36 -1
  54. package/dist/components/PlaybackRateSelector.js +2 -2
  55. package/dist/components/Preview.js +0 -3
  56. package/dist/components/PreviewToolbar.js +4 -7
  57. package/dist/components/PreviewToolbarOverflowButton.js +10 -3
  58. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +1 -1
  59. package/dist/components/RenderButton.js +40 -4
  60. package/dist/components/RenderModal/WebRenderModalBasic.js +1 -1
  61. package/dist/components/RenderModal/render-modals.js +3 -0
  62. package/dist/components/RenderQueue/CaptionQueueItem.js +2 -1
  63. package/dist/components/RenderQueue/RenderQueueCopyToClipboard.js +2 -1
  64. package/dist/components/RenderQueue/RenderQueueDownloadItem.js +2 -1
  65. package/dist/components/RenderQueue/RenderQueueItemCancelButton.js +2 -1
  66. package/dist/components/RenderQueue/RenderQueueOpenInFolder.js +2 -1
  67. package/dist/components/RenderQueue/RenderQueueRemoveItem.js +2 -1
  68. package/dist/components/RenderQueue/RenderQueueRepeat.js +2 -1
  69. package/dist/components/RenderQueue/VideoMattingQueueItem.js +2 -1
  70. package/dist/components/RenderQueue/actions.d.ts +2 -1
  71. package/dist/components/RenderQueue/actions.js +2 -1
  72. package/dist/components/RulersAndGuidesToggle.js +8 -1
  73. package/dist/components/SegmentedButton.d.ts +1 -0
  74. package/dist/components/SegmentedButton.js +9 -3
  75. package/dist/components/SelectedOutlineElement.js +16 -6
  76. package/dist/components/SelectedOutlinePolygon.js +4 -2
  77. package/dist/components/SettingsButton.js +8 -6
  78. package/dist/components/SettingsContext.d.ts +8 -0
  79. package/dist/components/SettingsContext.js +57 -2
  80. package/dist/components/SettingsModal.js +4 -1
  81. package/dist/components/SettingsModalFooter.js +1 -1
  82. package/dist/components/SidebarCollapserControls.js +13 -16
  83. package/dist/components/SizeSelector.js +2 -2
  84. package/dist/components/SkillsSettings.js +35 -4
  85. package/dist/components/SnappingToggle.js +7 -8
  86. package/dist/components/Splitter/SplitterHandle.js +1 -2
  87. package/dist/components/StudioSettings.js +32 -18
  88. package/dist/components/SyntaxHighlightedSource.d.ts +5 -0
  89. package/dist/components/{HighlightedElementSource.js → SyntaxHighlightedSource.js} +2 -2
  90. package/dist/components/Tabs/vertical.d.ts +1 -1
  91. package/dist/components/Tabs/vertical.js +16 -2
  92. package/dist/components/Timeline/EasingEditorModal.js +2 -2
  93. package/dist/components/Timeline/Timeline.js +47 -39
  94. package/dist/components/Timeline/TimelineAssetField.js +148 -9
  95. package/dist/components/Timeline/TimelineDragHandler.js +1 -2
  96. package/dist/components/Timeline/TimelineEffectItem.d.ts +1 -0
  97. package/dist/components/Timeline/TimelineEffectItem.js +2 -2
  98. package/dist/components/Timeline/TimelineEffectPropItem.d.ts +1 -0
  99. package/dist/components/Timeline/TimelineEffectPropItem.js +2 -2
  100. package/dist/components/Timeline/TimelineExpandedRow.js +2 -2
  101. package/dist/components/Timeline/TimelineInOutDragHandler.js +1 -2
  102. package/dist/components/Timeline/TimelineLayerChildren.js +12 -9
  103. package/dist/components/Timeline/TimelineSchemaField.js +8 -1
  104. package/dist/components/Timeline/TimelineSelection.d.ts +3 -1
  105. package/dist/components/Timeline/TimelineSelection.js +32 -5
  106. package/dist/components/Timeline/TimelineSequence.js +6 -6
  107. package/dist/components/Timeline/TimelineSequenceItem.js +12 -10
  108. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +3 -12
  109. package/dist/components/Timeline/TimelineTranslateField.js +25 -12
  110. package/dist/components/Timeline/TimelineZoomControls.js +2 -1
  111. package/dist/components/Timeline/get-sequence-context-menu-items.js +22 -6
  112. package/dist/components/Timeline/timeline-field-display-utils.js +12 -7
  113. package/dist/components/Timeline/timeline-translate-utils.d.ts +17 -0
  114. package/dist/components/Timeline/timeline-translate-utils.js +53 -12
  115. package/dist/components/Timeline/use-open-sequence-in-apps.d.ts +2 -0
  116. package/dist/components/Timeline/use-open-sequence-in-apps.js +17 -0
  117. package/dist/components/Timeline/use-timeline-asset-drop.js +17 -3
  118. package/dist/components/Timeline/use-timeline-keyframe-drag.js +4 -4
  119. package/dist/components/TimelineCombobox.d.ts +1 -0
  120. package/dist/components/TimelineCombobox.js +9 -4
  121. package/dist/components/TimelineInOutToggle.js +8 -15
  122. package/dist/components/UndoRedoButtons.js +11 -0
  123. package/dist/components/composition-menu-items.js +56 -2
  124. package/dist/components/folder-menu-items.js +44 -0
  125. package/dist/components/get-open-in-menu-items.js +1 -1
  126. package/dist/components/handle-drop.js +3 -2
  127. package/dist/components/import-assets.d.ts +24 -1
  128. package/dist/components/import-assets.js +3 -1
  129. package/dist/components/keyboard-shortcuts.d.ts +4 -4
  130. package/dist/components/keyboard-shortcuts.js +28 -9
  131. package/dist/error-overlay/remotion-overlay/CodeFrame.js +29 -18
  132. package/dist/esm/LazyModels-gfmpcy4h.mjs +11 -0
  133. package/dist/esm/LazyModels-m1rf06wh.mjs +11 -0
  134. package/dist/esm/{HighlightedElementSource-jfc66k4p.mjs → SyntaxHighlightedSource-3xks91rz.mjs} +4 -4
  135. package/dist/esm/{TranscriptionModal-916jqhry.mjs → TranscriptionModal-8pvrehg4.mjs} +7 -7
  136. package/dist/esm/{VideoMattingModal-2tm79s9b.mjs → VideoMattingModal-fefbzgka.mjs} +7 -7
  137. package/dist/esm/{index-xhe2m2qr.mjs → index-0x13f28h.mjs} +35 -13
  138. package/dist/esm/{index-sgtmgc4h.mjs → index-1089795y.mjs} +3 -3
  139. package/dist/esm/{index-hy4xcgty.mjs → index-41kqns5c.mjs} +5 -3
  140. package/dist/esm/{index-6cvm9a65.mjs → index-ggqpre9v.mjs} +2868 -2099
  141. package/dist/esm/{index-czwvnn9g.mjs → index-hbezgbbq.mjs} +1 -1
  142. package/dist/esm/{index-1x7bsdh6.mjs → index-jrw61pkj.mjs} +2 -2
  143. package/dist/esm/{index-jg13hf2g.mjs → index-k426ye99.mjs} +2 -1
  144. package/dist/esm/{index-te66vvrp.mjs → index-mww32xc8.mjs} +4 -4
  145. package/dist/esm/{index-x7t2y7ws.mjs → index-s848rffx.mjs} +6985 -5956
  146. package/dist/esm/{index-3hgr6gjx.mjs → index-tzxb8808.mjs} +1 -1
  147. package/dist/esm/{index-5qddp5h7.mjs → index-vsxrxfpj.mjs} +1 -1
  148. package/dist/esm/index.mjs +3 -3
  149. package/dist/esm/internals.mjs +8 -8
  150. package/dist/esm/previewEntry.mjs +8 -8
  151. package/dist/esm/renderEntry.mjs +3 -3
  152. package/dist/helpers/colors.d.ts +1 -0
  153. package/dist/helpers/colors.js +4 -3
  154. package/dist/helpers/get-git-menu-item.d.ts +4 -0
  155. package/dist/helpers/get-git-menu-item.js +8 -1
  156. package/dist/helpers/get-sequence-double-click-action.d.ts +3 -3
  157. package/dist/helpers/get-sequence-double-click-action.js +2 -2
  158. package/dist/helpers/inject-css.js +2 -2
  159. package/dist/helpers/pointer-session.d.ts +1 -0
  160. package/dist/helpers/pointer-session.js +10 -1
  161. package/dist/helpers/prism-vsc-dark-plus.d.ts +1 -0
  162. package/dist/helpers/prism-vsc-dark-plus.js +305 -0
  163. package/dist/helpers/studio-runtime-config.d.ts +1 -1
  164. package/dist/helpers/use-create-composition.d.ts +1 -0
  165. package/dist/helpers/use-create-composition.js +17 -7
  166. package/dist/helpers/use-keybinding.d.ts +1 -1
  167. package/dist/helpers/use-keyboard-shortcut-label.d.ts +2 -2
  168. package/dist/helpers/use-media-metadata.js +5 -1
  169. package/dist/helpers/use-menu-structure.js +6 -2
  170. package/dist/helpers/use-rename-composition.d.ts +1 -0
  171. package/dist/helpers/use-rename-composition.js +16 -5
  172. package/dist/icons/skills.js +1 -1
  173. package/dist/renderEntry.js +2 -2
  174. package/dist/state/modals.d.ts +13 -1
  175. package/dist/state/z-index.js +1 -3
  176. package/package.json +20 -20
  177. package/dist/components/HighlightedElementSource.d.ts +0 -5
  178. package/dist/esm/LazyModels-2trdm224.mjs +0 -11
  179. package/dist/esm/LazyModels-fjb5ckaq.mjs +0 -11
  180. package/dist/helpers/prism-tomorrow.d.ts +0 -1
  181. package/dist/helpers/prism-tomorrow.js +0 -151
  182. /package/dist/esm/{resolve-composition-component-location-14148845.mjs → resolve-composition-component-location-bt2d6qxq.mjs} +0 -0
@@ -4,7 +4,6 @@ exports.RenameFolder = 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 colors_1 = require("../../helpers/colors");
8
7
  const get_folder_id_1 = require("../../helpers/get-folder-id");
9
8
  const slugify_name_1 = require("../../helpers/slugify-name");
10
9
  const validate_folder_rename_1 = require("../../helpers/validate-folder-rename");
@@ -17,6 +16,7 @@ const CodemodFooter_1 = require("./CodemodFooter");
17
16
  const DismissableModal_1 = require("./DismissableModal");
18
17
  const InputAndValidationContainer_1 = require("./InputAndValidationContainer");
19
18
  const RemInput_1 = require("./RemInput");
19
+ const SlugPreview_1 = require("./SlugPreview");
20
20
  const ValidationMessage_1 = require("./ValidationMessage");
21
21
  const content = {
22
22
  padding: 12,
@@ -64,9 +64,7 @@ const RenameFolder = ({ folderName, parentName, stack }) => {
64
64
  jsx_runtime_1.jsx(ModalHeader_1.ModalHeader, { title: `Rename ${folderId}` }), jsx_runtime_1.jsxs("form", { onSubmit: onSubmit, children: [
65
65
  jsx_runtime_1.jsx("div", { style: content, children: jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [
66
66
  jsx_runtime_1.jsx("div", { style: layout_2.label, children: "Name" }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsxs(InputAndValidationContainer_1.InputAndValidationContainer, { children: [
67
- jsx_runtime_1.jsx(RemInput_1.RemotionInput, { ref: inputRef, value: newName, onChange: onNameChange, type: "text", autoFocus: true, placeholder: "Folder name", status: "ok", rightAlign: true }), slug && slug !== newName ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
68
- jsx_runtime_1.jsx(layout_1.Spacing, { y: 1, block: true }), jsx_runtime_1.jsxs("div", { "aria-live": "polite", style: { fontSize: 12, color: colors_1.LIGHT_TEXT }, children: ["Will be renamed to ", slug] })
69
- ] })) : null, folderNameErrMessage ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
67
+ jsx_runtime_1.jsx(RemInput_1.RemotionInput, { ref: inputRef, value: newName, onChange: onNameChange, type: "text", autoFocus: true, placeholder: "Folder name", status: "ok", rightAlign: true }), jsx_runtime_1.jsx(SlugPreview_1.SlugPreview, { action: "rename", currentName: folderName, input: newName, slug: slug }), folderNameErrMessage ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
70
68
  jsx_runtime_1.jsx(layout_1.Spacing, { y: 1, block: true }), jsx_runtime_1.jsx(ValidationMessage_1.ValidationMessage, { align: "flex-start", message: folderNameErrMessage, type: "error" })
71
69
  ] })) : null] }) })
72
70
  ] }) }), jsx_runtime_1.jsx(ModalFooter_1.ModalFooterContainer, { children: jsx_runtime_1.jsx(CodemodFooter_1.CodemodFooter, { loadingNotification: 'Renaming folder...', errorNotification: 'Could not rename folder', genericSubmitLabel: 'Rename', submitLabel: ({ relativeRootPath }) => `Modify ${relativeRootPath}`, codemod: codemod, stack: stack, valid: valid, onSuccess: null, applyCodemod: ({ signal, symbolicatedStack }) => (0, actions_1.applyCodemod)({
@@ -74,6 +72,7 @@ const RenameFolder = ({ folderName, parentName, stack }) => {
74
72
  dryRun: false,
75
73
  signal,
76
74
  symbolicatedStack,
75
+ undoRedoNavigation: null,
77
76
  }), applyCodemodForPreview: null }) })
78
77
  ] })
79
78
  ] }));
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ export declare const SlugPreview: React.FC<{
3
+ readonly action: 'create' | 'rename';
4
+ readonly currentName: string | null;
5
+ readonly input: string;
6
+ readonly slug: string;
7
+ }>;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SlugPreview = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const colors_1 = require("../../helpers/colors");
6
+ const layout_1 = require("../layout");
7
+ const SlugPreview = ({ action, currentName, input, slug }) => {
8
+ if (!slug ||
9
+ slug === input ||
10
+ slug === input.trim() ||
11
+ slug === currentName) {
12
+ return null;
13
+ }
14
+ return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
15
+ jsx_runtime_1.jsx(layout_1.Spacing, { y: 1, block: true }), jsx_runtime_1.jsxs("div", { "aria-live": "polite", style: { fontSize: 12, color: colors_1.LIGHT_TEXT }, children: ["Will be ", action === 'create' ? 'created as' : 'renamed to', " ", slug] })
16
+ ] }));
17
+ };
18
+ exports.SlugPreview = SlugPreview;
@@ -1,5 +1,5 @@
1
- import type { DuplicateCompositionResponse, SymbolicatedStackFrame } from '@remotion/studio-shared';
2
- export declare const duplicateComposition: ({ codemod, dryRun, signal, symbolicatedStack, }: {
1
+ import type { DuplicateCompositionResponse, SymbolicatedStackFrame, UndoRedoNavigation } from '@remotion/studio-shared';
2
+ export declare const duplicateComposition: ({ codemod, dryRun, signal, symbolicatedStack, undoRedoNavigation, }: {
3
3
  codemod: {
4
4
  type: "duplicate-composition";
5
5
  idToDuplicate: string;
@@ -13,4 +13,5 @@ export declare const duplicateComposition: ({ codemod, dryRun, signal, symbolica
13
13
  dryRun: boolean;
14
14
  signal: AbortSignal;
15
15
  symbolicatedStack: SymbolicatedStackFrame | null;
16
+ undoRedoNavigation: UndoRedoNavigation | null;
16
17
  }) => Promise<DuplicateCompositionResponse>;
@@ -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)();
@@ -4,25 +4,32 @@ exports.OutlineToggle = 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 use_keybinding_1 = require("../helpers/use-keybinding");
8
+ const use_keyboard_shortcut_label_1 = require("../helpers/use-keyboard-shortcut-label");
7
9
  const editor_outlines_1 = require("../state/editor-outlines");
10
+ const ActionTooltip_1 = require("./ActionTooltip");
8
11
  const ControlButton_1 = require("./ControlButton");
12
+ const buttonStyle = { width: 26 };
9
13
  const OutlineToggle = () => {
10
14
  const { editorShowOutlines, setEditorShowOutlines } = (0, react_1.useContext)(editor_outlines_1.EditorShowOutlinesContext);
11
15
  const onClick = (0, react_1.useCallback)(() => {
12
16
  setEditorShowOutlines((current) => !current);
13
17
  }, [setEditorShowOutlines]);
18
+ const shortcut = (0, use_keyboard_shortcut_label_1.useKeyboardShortcutLabel)('toggleOutlines');
19
+ const ariaShortcut = (0, use_keyboard_shortcut_label_1.useKeyboardShortcutAriaKeyShortcuts)('toggleOutlines');
20
+ const shortcutsDisabled = (0, use_keybinding_1.areKeyboardShortcutsDisabled)();
14
21
  const accessibilityLabel = editorShowOutlines
15
22
  ? 'Hide outlines'
16
23
  : 'Show outlines';
17
- return (jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: accessibilityLabel, "aria-label": accessibilityLabel, onClick: onClick, children: (color) => {
18
- const iconColor = editorShowOutlines ? colors_1.BLUE : color;
19
- return (jsx_runtime_1.jsxs("svg", { style: { width: 17, height: 17 }, viewBox: "0 0 512 512", fill: "none", "aria-hidden": "true", focusable: "false", children: [
20
- jsx_runtime_1.jsx("path", { d: "M64 64H448V448H64V64Z", stroke: iconColor, strokeWidth: "36" }), [
21
- [16, 16],
22
- [400, 16],
23
- [16, 400],
24
- [400, 400],
25
- ].map(([x, y]) => (jsx_runtime_1.jsx("rect", { x: x, y: y, width: "96", height: "96", rx: "24", fill: colors_1.BACKGROUND_HEX, stroke: iconColor, strokeWidth: "32" }, `${x}-${y}`)))] }));
26
- } }));
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) => {
25
+ const iconColor = editorShowOutlines ? colors_1.BLUE : color;
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: [
27
+ jsx_runtime_1.jsx("path", { d: "M64 64H448V448H64V64Z", stroke: iconColor, strokeWidth: "36" }), [
28
+ [16, 16],
29
+ [400, 16],
30
+ [16, 400],
31
+ [400, 400],
32
+ ].map(([x, y]) => (jsx_runtime_1.jsx("rect", { x: x, y: y, width: "96", height: "96", rx: "24", fill: colors_1.BACKGROUND_HEX, stroke: iconColor, strokeWidth: "32" }, `${x}-${y}`)))] }));
33
+ } }) }));
27
34
  };
28
35
  exports.OutlineToggle = OutlineToggle;
@@ -40,12 +40,14 @@ const react_1 = __importStar(require("react"));
40
40
  const remotion_1 = require("remotion");
41
41
  const is_current_selected_still_1 = require("../helpers/is-current-selected-still");
42
42
  const use_keybinding_1 = require("../helpers/use-keybinding");
43
+ const use_keyboard_shortcut_label_1 = require("../helpers/use-keyboard-shortcut-label");
43
44
  const jump_to_start_1 = require("../icons/jump-to-start");
44
45
  const pause_1 = require("../icons/pause");
45
46
  const play_1 = require("../icons/play");
46
47
  const step_back_1 = require("../icons/step-back");
47
48
  const step_forward_1 = require("../icons/step-forward");
48
49
  const in_out_1 = require("../state/in-out");
50
+ const ActionTooltip_1 = require("./ActionTooltip");
49
51
  const ControlButton_1 = require("./ControlButton");
50
52
  const imperative_state_1 = require("./Timeline/imperative-state");
51
53
  const timeline_scroll_logic_1 = require("./Timeline/timeline-scroll-logic");
@@ -82,6 +84,10 @@ const PlayPauseInner = ({ playbackRate, loop, bufferStateDelayInMilliseconds, mu
82
84
  const { play, pause, pauseAndReturnToPlayStart, frameBack, seek, frameForward, emitter, getCurrentFrame, } = player_1.PlayerInternals.usePlayerMethods();
83
85
  const playing = remotion_1.Internals.usePlaying();
84
86
  const isStill = (0, is_current_selected_still_1.useIsStill)();
87
+ const jumpToBeginningShortcut = (0, use_keyboard_shortcut_label_1.useKeyboardShortcutLabel)('jumpToBeginning');
88
+ const jumpToBeginningAriaShortcut = (0, use_keyboard_shortcut_label_1.useKeyboardShortcutAriaKeyShortcuts)('jumpToBeginning');
89
+ const playPauseShortcut = (0, use_keyboard_shortcut_label_1.useKeyboardShortcutLabel)('playPause');
90
+ const playPauseAriaShortcut = (0, use_keyboard_shortcut_label_1.useKeyboardShortcutAriaKeyShortcuts)('playPause');
85
91
  (0, react_1.useEffect)(() => {
86
92
  if (isStill) {
87
93
  pause();
@@ -229,6 +235,6 @@ const PlayPauseInner = ({ playbackRate, loop, bufferStateDelayInMilliseconds, mu
229
235
  };
230
236
  }, [bufferStateDelayInMilliseconds, emitter]);
231
237
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
232
- jsx_runtime_1.jsx(PlaybackManager, { loop: loop, playbackRate: playbackRate, muted: muted, inFrame: inFrame, outFrame: outFrame, getCurrentFrame: getCurrentFrame }), hideNavigationControls ? null : (jsx_runtime_1.jsx(ControlButton_1.ControlButton, { "aria-label": "Jump to beginning", title: "Jump to beginning", 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(ControlButton_1.ControlButton, { "aria-label": "Step back one frame", title: "Step back one frame", disabled: !videoConfig, onClick: oneFrameBack, children: (color) => jsx_runtime_1.jsx(step_back_1.StepBack, { style: forwardBackStyle, color: color }) })), jsx_runtime_1.jsx(ControlButton_1.ControlButton, { "aria-label": playing ? 'Pause' : 'Play', title: playing ? 'Pause' : 'Play', 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(ControlButton_1.ControlButton, { "aria-label": "Step forward one frame", title: "Step forward one frame", 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 }) }) }))] }));
233
239
  };
234
240
  exports.PlayPause = react_1.default.memo(PlayPauseInner);
@@ -1,4 +1,6 @@
1
1
  import type React from 'react';
2
2
  export declare const PlaybackKeyboardShortcutsManager: React.FC<{
3
3
  readonly setPlaybackRate: React.Dispatch<React.SetStateAction<number>>;
4
+ readonly setMuted: React.Dispatch<React.SetStateAction<boolean>>;
5
+ readonly setLoop: React.Dispatch<React.SetStateAction<boolean>>;
4
6
  }>;
@@ -3,9 +3,44 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PlaybackKeyboardShortcutsManager = void 0;
4
4
  const player_1 = require("@remotion/player");
5
5
  const react_1 = require("react");
6
+ const is_current_selected_still_1 = require("../helpers/is-current-selected-still");
6
7
  const use_keybinding_1 = require("../helpers/use-keybinding");
7
- const PlaybackKeyboardShortcutsManager = ({ setPlaybackRate }) => {
8
+ const LoopToggle_1 = require("./LoopToggle");
9
+ const MuteToggle_1 = require("./MuteToggle");
10
+ const PlaybackKeyboardShortcutsManager = ({ setPlaybackRate, setMuted, setLoop }) => {
8
11
  const keybindings = (0, use_keybinding_1.useKeybinding)();
12
+ const isVideoComposition = (0, is_current_selected_still_1.useIsVideoComposition)();
13
+ (0, react_1.useEffect)(() => {
14
+ if (!isVideoComposition) {
15
+ return;
16
+ }
17
+ const mute = keybindings.registerKeybinding({
18
+ event: 'keydown',
19
+ action: 'toggleMute',
20
+ callback: (event) => {
21
+ if (!event.repeat)
22
+ (0, MuteToggle_1.toggleMute)(setMuted);
23
+ },
24
+ preventDefault: true,
25
+ triggerIfInputFieldFocused: false,
26
+ keepRegisteredWhenNotHighestContext: false,
27
+ });
28
+ const loop = keybindings.registerKeybinding({
29
+ event: 'keydown',
30
+ action: 'toggleLoop',
31
+ callback: (event) => {
32
+ if (!event.repeat)
33
+ (0, LoopToggle_1.toggleLoop)(setLoop);
34
+ },
35
+ preventDefault: true,
36
+ triggerIfInputFieldFocused: false,
37
+ keepRegisteredWhenNotHighestContext: false,
38
+ });
39
+ return () => {
40
+ mute.unregister();
41
+ loop.unregister();
42
+ };
43
+ }, [isVideoComposition, keybindings, setLoop, setMuted]);
9
44
  const { play, pause, isPlaying } = player_1.PlayerInternals.usePlayerMethods();
10
45
  const onJKey = (0, react_1.useCallback)(() => {
11
46
  const wasPlaying = isPlaying();
@@ -13,7 +13,7 @@ const TimelineCombobox_1 = require("./TimelineCombobox");
13
13
  const getPlaybackRateLabel = (playbackRate) => {
14
14
  return `${playbackRate}x`;
15
15
  };
16
- const accessibilityLabel = 'Change the playback rate';
16
+ const accessibilityLabel = 'Playback rate';
17
17
  const usePlaybackRateMenuItems = ({ playbackRate, setPlaybackRate, }) => {
18
18
  const items = (0, react_1.useMemo)(() => {
19
19
  const divider = {
@@ -57,6 +57,6 @@ const PlaybackRateSelector = ({ playbackRate, setPlaybackRate, }) => {
57
57
  if (isStill || canvasContent === null) {
58
58
  return null;
59
59
  }
60
- return (jsx_runtime_1.jsx(TimelineCombobox_1.TimelineCombobox, { title: accessibilityLabel, labelWidth: 30, selectedId: selectedId, values: items, renderLeftItem: (color) => (jsx_runtime_1.jsx(playback_rate_1.PlaybackRateIcon, { color: color, playbackRate: playbackRate })), unhoveredIconColor: colors_1.WHITE_ALPHA_80 }));
60
+ return (jsx_runtime_1.jsx(TimelineCombobox_1.TimelineCombobox, { title: accessibilityLabel, tooltipDelay: 800, labelWidth: 30, selectedId: selectedId, values: items, renderLeftItem: (color) => (jsx_runtime_1.jsx(playback_rate_1.PlaybackRateIcon, { color: color, playbackRate: playbackRate })), unhoveredIconColor: colors_1.WHITE_ALPHA_80 }));
61
61
  };
62
62
  exports.PlaybackRateSelector = PlaybackRateSelector;
@@ -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,15 +91,12 @@ 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
- ] }), jsx_runtime_1.jsx(PlaybackKeyboardShortcutsManager_1.PlaybackKeyboardShortcutsManager, { setPlaybackRate: setPlaybackRate }), jsx_runtime_1.jsx(PlaybackRatePersistor_1.PlaybackRatePersistor, {})
99
+ ] }), jsx_runtime_1.jsx(PlaybackKeyboardShortcutsManager_1.PlaybackKeyboardShortcutsManager, { setPlaybackRate: setPlaybackRate, setMuted: setPlayerMuted, setLoop: setLoop }), jsx_runtime_1.jsx(PlaybackRatePersistor_1.PlaybackRatePersistor, {})
103
100
  ] }));
104
101
  };
105
102
  exports.PreviewToolbar = PreviewToolbar;
@@ -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");
@@ -23,6 +24,8 @@ const clickButton = (id) => {
23
24
  const PreviewToolbarOverflowButton = ({ showFullscreen, showPlaybackRate, showLoop, showCanvasViewControls, showCompositionControls, playbackRate, setPlaybackRate, loop, setLoop, }) => {
24
25
  const keyboardShortcutsDisabled = (0, use_keybinding_1.areKeyboardShortcutsDisabled)();
25
26
  const fullscreenShortcut = (0, use_keyboard_shortcut_label_1.useKeyboardShortcutLabel)('enterFullscreen');
27
+ const loopShortcut = (0, use_keyboard_shortcut_label_1.useKeyboardShortcutLabel)('toggleLoop');
28
+ const outlinesShortcut = (0, use_keyboard_shortcut_label_1.useKeyboardShortcutLabel)('toggleOutlines');
26
29
  const checkerboardShortcut = (0, use_keyboard_shortcut_label_1.useKeyboardShortcutLabel)('toggleCheckerboard');
27
30
  const { checkerboard, setCheckerboard } = (0, react_1.useContext)(checkerboard_1.CheckerboardContext);
28
31
  const { editorShowOutlines, setEditorShowOutlines } = (0, react_1.useContext)(editor_outlines_1.EditorShowOutlinesContext);
@@ -83,7 +86,9 @@ const PreviewToolbarOverflowButton = ({ showFullscreen, showPlaybackRate, showLo
83
86
  label: 'Loop',
84
87
  value: 'loop',
85
88
  onClick: () => (0, LoopToggle_1.toggleLoop)(setLoop),
86
- keyHint: null,
89
+ keyHint: keyboardShortcutsDisabled || loopShortcut === ''
90
+ ? null
91
+ : loopShortcut,
87
92
  leftItem: loop ? jsx_runtime_1.jsx(Checkmark_1.Checkmark, {}) : null,
88
93
  subMenu: null,
89
94
  quickSwitcherLabel: null,
@@ -111,7 +116,7 @@ const PreviewToolbarOverflowButton = ({ showFullscreen, showPlaybackRate, showLo
111
116
  label: 'Outlines',
112
117
  value: 'outlines',
113
118
  onClick: () => setEditorShowOutlines((current) => !current),
114
- keyHint: null,
119
+ keyHint: keyboardShortcutsDisabled ? null : outlinesShortcut || null,
115
120
  leftItem: editorShowOutlines ? jsx_runtime_1.jsx(Checkmark_1.Checkmark, {}) : null,
116
121
  subMenu: null,
117
122
  quickSwitcherLabel: null,
@@ -162,6 +167,7 @@ const PreviewToolbarOverflowButton = ({ showFullscreen, showPlaybackRate, showLo
162
167
  }, [
163
168
  checkerboardShortcut,
164
169
  fullscreenShortcut,
170
+ loopShortcut,
165
171
  previewSizeItems,
166
172
  playbackRateItems,
167
173
  selectedPlaybackRate,
@@ -175,6 +181,7 @@ const PreviewToolbarOverflowButton = ({ showFullscreen, showPlaybackRate, showLo
175
181
  checkerboard,
176
182
  editorShowGuides,
177
183
  editorShowOutlines,
184
+ outlinesShortcut,
178
185
  editorShowRulers,
179
186
  setCheckerboard,
180
187
  setEditorShowGuides,
@@ -187,6 +194,6 @@ const PreviewToolbarOverflowButton = ({ showFullscreen, showPlaybackRate, showLo
187
194
  if (values.length === 0) {
188
195
  return null;
189
196
  }
190
- 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 }) }));
191
198
  };
192
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',
@@ -5,6 +5,7 @@ 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 url_state_1 = require("../../helpers/url-state");
8
+ const ActionTooltip_1 = require("../ActionTooltip");
8
9
  const InlineAction_1 = require("../InlineAction");
9
10
  const layout_1 = require("../layout");
10
11
  const use_select_asset_1 = require("../use-select-asset");
@@ -124,6 +125,6 @@ const CaptionQueueItem = ({ job, selected }) => {
124
125
  return (jsx_runtime_1.jsxs(layout_1.Row, { "data-render-queue-item": job.id, style: containerStyle, align: "center", onClick: onClick, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, className: selected ? item_style_1.RENDER_QUEUE_ITEM_SELECTED_CLASSNAME : undefined, children: [
125
126
  jsx_runtime_1.jsx(CaptionJobStatus, { job: job }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsxs("div", { style: right, children: [
126
127
  jsx_runtime_1.jsx("div", { style: title, children: job.displayName }), jsx_runtime_1.jsx("div", { style: subtitleContainer, children: jsx_runtime_1.jsx("span", { style: subtitle, title: message, children: message }) })
127
- ] }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), job.status === 'running' ? null : (jsx_runtime_1.jsx(InlineAction_1.InlineAction, { renderAction: renderRemoveAction, onClick: onRemove, title: "Remove", variant: null }))] }));
128
+ ] }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), job.status === 'running' ? null : (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "Clear", shortcut: null, delay: 800, dismissOnClick: true, children: jsx_runtime_1.jsx(InlineAction_1.InlineAction, { renderAction: renderRemoveAction, onClick: onRemove, "aria-label": "Clear", variant: null }) }))] }));
128
129
  };
129
130
  exports.CaptionQueueItem = CaptionQueueItem;
@@ -7,6 +7,7 @@ const colors_1 = require("../../helpers/colors");
7
7
  const get_asset_metadata_1 = require("../../helpers/get-asset-metadata");
8
8
  const use_copy_feedback_1 = require("../../helpers/use-copy-feedback");
9
9
  const copy_1 = require("../../icons/copy");
10
+ const ActionTooltip_1 = require("../ActionTooltip");
10
11
  const InlineAction_1 = require("../InlineAction");
11
12
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
12
13
  const revealIconStyle = {
@@ -56,6 +57,6 @@ const RenderQueueCopyToClipboard = ({ job }) => {
56
57
  (0, NotificationCenter_1.showNotification)(`Could not copy to clipboard: ${err.message}`, 2000);
57
58
  }
58
59
  }, [job.outName, markCopied]);
59
- return (jsx_runtime_1.jsx(InlineAction_1.InlineAction, { variant: null, title: "Copy to clipboard", 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 }) }));
60
61
  };
61
62
  exports.RenderQueueCopyToClipboard = RenderQueueCopyToClipboard;
@@ -5,6 +5,7 @@ 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 download_blob_1 = require("../../helpers/download-blob");
8
+ const ActionTooltip_1 = require("../ActionTooltip");
8
9
  const InlineAction_1 = require("../InlineAction");
9
10
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
10
11
  const RenderQueueDownloadItem = ({ job }) => {
@@ -31,6 +32,6 @@ const RenderQueueDownloadItem = ({ job }) => {
31
32
  const renderAction = (0, react_1.useCallback)((color) => {
32
33
  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: "M288 32c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 242.7-73.4-73.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l128 128c12.5 12.5 32.8 12.5 45.3 0l128-128c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L288 274.7 288 32zM64 352c-35.3 0-64 28.7-64 64l0 32c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-32c0-35.3-28.7-64-64-64l-101.5 0-45.3 45.3c-25 25-65.5 25-90.5 0L165.5 352 64 352zm368 56a24 24 0 1 1 0 48 24 24 0 1 1 0-48z" }) }));
33
34
  }, [icon]);
34
- return (jsx_runtime_1.jsx(InlineAction_1.InlineAction, { variant: null, renderAction: renderAction, onClick: onClick, title: "Download" }));
35
+ return (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "Download", shortcut: null, delay: 800, dismissOnClick: true, children: jsx_runtime_1.jsx(InlineAction_1.InlineAction, { "aria-label": "Download", variant: null, renderAction: renderAction, onClick: onClick }) }));
35
36
  };
36
37
  exports.RenderQueueDownloadItem = RenderQueueDownloadItem;
@@ -4,6 +4,7 @@ exports.RenderQueueCancelButton = 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 ActionTooltip_1 = require("../ActionTooltip");
7
8
  const InlineAction_1 = require("../InlineAction");
8
9
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
9
10
  const actions_1 = require("./actions");
@@ -30,6 +31,6 @@ const RenderQueueCancelButton = ({ job }) => {
30
31
  const renderAction = (0, react_1.useCallback)((color) => {
31
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" }) }));
32
33
  }, [icon]);
33
- return (jsx_runtime_1.jsx(InlineAction_1.InlineAction, { 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 }) }));
34
35
  };
35
36
  exports.RenderQueueCancelButton = RenderQueueCancelButton;