@remotion/studio 4.0.513 → 4.0.515

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 (204) hide show
  1. package/dist/Studio.js +2 -1
  2. package/dist/api/install-package.js +14 -1
  3. package/dist/components/AskAiModal.js +1 -1
  4. package/dist/components/AssetSelector.js +2 -0
  5. package/dist/components/AssetSelectorItem.d.ts +2 -1
  6. package/dist/components/AssetSelectorItem.js +19 -16
  7. package/dist/components/AudioWaveform.d.ts +3 -0
  8. package/dist/components/AudioWaveform.js +65 -199
  9. package/dist/components/Canvas.js +40 -5
  10. package/dist/components/CanvasOrLoading.js +5 -0
  11. package/dist/components/CompositionSelector.js +2 -0
  12. package/dist/components/ConfigureDefaultEditorModal.js +17 -11
  13. package/dist/components/Editor.js +16 -1
  14. package/dist/components/ElementInstallConfirmation.d.ts +1 -0
  15. package/dist/components/ElementInstallConfirmation.js +4 -2
  16. package/dist/components/FixComputedValueModal.d.ts +9 -0
  17. package/dist/components/FixComputedValueModal.js +217 -0
  18. package/dist/components/InitialCompositionLoader.js +19 -0
  19. package/dist/components/InlineDropdown.js +4 -4
  20. package/dist/components/InspectorInfoHeader.js +3 -3
  21. package/dist/components/InspectorOpenInEditor.js +3 -1
  22. package/dist/components/InspectorPanel/CompositionInspector.js +37 -5
  23. package/dist/components/InspectorPanel/CompositionInspectorHeader.js +2 -2
  24. package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +1 -1
  25. package/dist/components/InspectorPanel/EasingInspector.js +1 -1
  26. package/dist/components/InspectorPanel/KeyframeInspector.js +2 -2
  27. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +1 -1
  28. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +35 -6
  29. package/dist/components/InspectorPanel/common.d.ts +5 -5
  30. package/dist/components/InspectorPanel/common.js +8 -8
  31. package/dist/components/InspectorPanel/styles.d.ts +1 -1
  32. package/dist/components/InspectorPanel/styles.js +4 -2
  33. package/dist/components/InspectorSourceLocation.d.ts +1 -1
  34. package/dist/components/InspectorSourceLocation.js +2 -2
  35. package/dist/components/InstallPackage.d.ts +1 -1
  36. package/dist/components/InstallPackage.js +38 -6
  37. package/dist/components/LicenseKeyValidation.js +2 -2
  38. package/dist/components/Menu/MenuDivider.js +1 -1
  39. package/dist/components/Modals.js +11 -3
  40. package/dist/components/NewComposition/CodemodFooter.d.ts +1 -0
  41. package/dist/components/NewComposition/CodemodFooter.js +10 -8
  42. package/dist/components/NewComposition/DeleteComposition.js +1 -1
  43. package/dist/components/NewComposition/DeleteFolder.js +1 -1
  44. package/dist/components/NewComposition/DuplicateComposition.js +7 -2
  45. package/dist/components/NewComposition/NewComposition.js +1 -1
  46. package/dist/components/NewComposition/NewFolder.js +1 -1
  47. package/dist/components/NewComposition/RenameComposition.js +1 -1
  48. package/dist/components/NewComposition/RenameFolder.js +1 -1
  49. package/dist/components/NewComposition/duplicate-composition-api.d.ts +16 -0
  50. package/dist/components/NewComposition/duplicate-composition-api.js +16 -0
  51. package/dist/components/NoRegisterRoot.js +1 -1
  52. package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.js +4 -3
  53. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +1 -0
  54. package/dist/components/QuickSwitcher/fuzzy-search.js +1 -1
  55. package/dist/components/RefreshCompositionOverlay.js +1 -1
  56. package/dist/components/RenderButton.js +6 -3
  57. package/dist/components/RenderModal/GuiRenderStatus.js +3 -1
  58. package/dist/components/RenderModal/RenderModalOutputName.js +3 -3
  59. package/dist/components/RenderModal/WebRenderModal.js +10 -4
  60. package/dist/components/RenderModal/WebRenderModalAdvanced.d.ts +2 -0
  61. package/dist/components/RenderModal/WebRenderModalAdvanced.js +9 -2
  62. package/dist/components/RenderModal/render-modals.js +5 -1
  63. package/dist/components/RenderQueue/ClientRenderQueueProcessor.js +5 -1
  64. package/dist/components/RenderQueue/RenderQueueItem.js +3 -1
  65. package/dist/components/RenderQueue/RenderQueueOpenInFolder.js +3 -1
  66. package/dist/components/RenderQueue/RenderQueueRemoveItem.js +1 -1
  67. package/dist/components/RenderQueue/actions.js +12 -2
  68. package/dist/components/RenderQueue/client-side-render-types.d.ts +1 -0
  69. package/dist/components/RenderingSettings.d.ts +2 -0
  70. package/dist/components/RenderingSettings.js +355 -0
  71. package/dist/components/SelectedOutlineCanvasRotation.d.ts +1 -0
  72. package/dist/components/SelectedOutlineCanvasRotation.js +11 -4
  73. package/dist/components/SelectedOutlineElement.js +3 -3
  74. package/dist/components/SelectedOutlinePolygon.d.ts +2 -0
  75. package/dist/components/SelectedOutlinePolygon.js +54 -9
  76. package/dist/components/SettingsContext.d.ts +4 -1
  77. package/dist/components/SettingsContext.js +9 -2
  78. package/dist/components/SettingsModal.d.ts +1 -1
  79. package/dist/components/SettingsModal.js +10 -1
  80. package/dist/components/SettingsModalFooter.js +1 -1
  81. package/dist/components/StudioSettings.d.ts +2 -0
  82. package/dist/components/StudioSettings.js +185 -0
  83. package/dist/components/Timeline/LoopedIndicator.js +1 -1
  84. package/dist/components/Timeline/LoopedTimelineIndicators.d.ts +3 -0
  85. package/dist/components/Timeline/LoopedTimelineIndicators.js +22 -14
  86. package/dist/components/Timeline/Timeline.js +11 -9
  87. package/dist/components/Timeline/TimelineAssetField.d.ts +2 -2
  88. package/dist/components/Timeline/TimelineAssetField.js +1 -1
  89. package/dist/components/Timeline/TimelineClipboardKeybindings.js +6 -2
  90. package/dist/components/Timeline/TimelineDragHandler.js +62 -76
  91. package/dist/components/Timeline/TimelineEffectItem.js +23 -6
  92. package/dist/components/Timeline/TimelineEffectPropItem.d.ts +4 -2
  93. package/dist/components/Timeline/TimelineEffectPropItem.js +22 -13
  94. package/dist/components/Timeline/TimelineExpandArrowButton.js +10 -7
  95. package/dist/components/Timeline/TimelineExpandedKeyframeRow.js +4 -1
  96. package/dist/components/Timeline/TimelineExpandedRow.d.ts +1 -1
  97. package/dist/components/Timeline/TimelineExpandedRow.js +4 -4
  98. package/dist/components/Timeline/TimelineExpandedSection.js +8 -5
  99. package/dist/components/Timeline/TimelineHeightContainer.d.ts +0 -4
  100. package/dist/components/Timeline/TimelineHeightContainer.js +4 -4
  101. package/dist/components/Timeline/TimelineImageInfo.d.ts +1 -0
  102. package/dist/components/Timeline/TimelineImageInfo.js +3 -2
  103. package/dist/components/Timeline/TimelineKeyframeControls.js +6 -1
  104. package/dist/components/Timeline/TimelineList.d.ts +1 -5
  105. package/dist/components/Timeline/TimelineList.js +14 -9
  106. package/dist/components/Timeline/TimelinePinchZoom.js +5 -5
  107. package/dist/components/Timeline/TimelineRowChrome.d.ts +1 -2
  108. package/dist/components/Timeline/TimelineRowChrome.js +50 -7
  109. package/dist/components/Timeline/TimelineSchemaField.d.ts +7 -3
  110. package/dist/components/Timeline/TimelineSchemaField.js +71 -13
  111. package/dist/components/Timeline/TimelineScrollable.js +3 -1
  112. package/dist/components/Timeline/TimelineSelection.d.ts +13 -5
  113. package/dist/components/Timeline/TimelineSelection.js +95 -106
  114. package/dist/components/Timeline/TimelineSequence.js +59 -25
  115. package/dist/components/Timeline/TimelineSequenceItem.d.ts +1 -1
  116. package/dist/components/Timeline/TimelineSequenceItem.js +21 -12
  117. package/dist/components/Timeline/TimelineSequenceName.js +1 -1
  118. package/dist/components/Timeline/TimelineSequencePropItem.d.ts +2 -1
  119. package/dist/components/Timeline/TimelineSequencePropItem.js +3 -3
  120. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +33 -10
  121. package/dist/components/Timeline/TimelineSlider.js +42 -33
  122. package/dist/components/Timeline/TimelineTimeIndicators.js +90 -98
  123. package/dist/components/Timeline/TimelineTrack.js +4 -1
  124. package/dist/components/Timeline/TimelineTracks.d.ts +0 -2
  125. package/dist/components/Timeline/TimelineTracks.js +11 -4
  126. package/dist/components/Timeline/TimelineTransformOriginField.js +1 -1
  127. package/dist/components/Timeline/TimelineVideoInfo.d.ts +4 -4
  128. package/dist/components/Timeline/TimelineVideoInfo.js +155 -63
  129. package/dist/components/Timeline/TimelineViewport.d.ts +12 -0
  130. package/dist/components/Timeline/TimelineViewport.js +62 -0
  131. package/dist/components/Timeline/TimelineVirtualization.d.ts +22 -0
  132. package/dist/components/Timeline/TimelineVirtualization.js +144 -0
  133. package/dist/components/Timeline/TimelineZoomControls.js +16 -8
  134. package/dist/components/Timeline/call-add-keyframe.js +31 -3
  135. package/dist/components/Timeline/call-delete-keyframe.js +13 -3
  136. package/dist/components/Timeline/call-move-keyframe.js +11 -1
  137. package/dist/components/Timeline/call-update-keyframe-settings.js +31 -3
  138. package/dist/components/Timeline/delete-selected-timeline-item.js +8 -3
  139. package/dist/components/Timeline/duplicate-selected-timeline-item.js +4 -2
  140. package/dist/components/Timeline/get-timeline-keyframes.d.ts +1 -2
  141. package/dist/components/Timeline/get-timeline-keyframes.js +1 -8
  142. package/dist/components/Timeline/get-timeline-sequence-visible-layout.d.ts +30 -0
  143. package/dist/components/Timeline/get-timeline-sequence-visible-layout.js +61 -0
  144. package/dist/components/Timeline/save-effect-prop.js +3 -3
  145. package/dist/components/Timeline/split-selected-timeline-item.js +2 -2
  146. package/dist/components/Timeline/timeline-scroll-logic.d.ts +24 -0
  147. package/dist/components/Timeline/timeline-scroll-logic.js +127 -4
  148. package/dist/components/Timeline/use-timeline-height.d.ts +3 -5
  149. package/dist/components/Timeline/use-timeline-height.js +16 -18
  150. package/dist/components/UpdateCheck.d.ts +2 -10
  151. package/dist/components/UpdateCheck.js +8 -2
  152. package/dist/components/VisualControls/VisualControlHandle.js +8 -0
  153. package/dist/components/delete-jsx-node-api.d.ts +2 -0
  154. package/dist/components/delete-jsx-node-api.js +12 -0
  155. package/dist/components/effect-drag-and-drop.js +6 -3
  156. package/dist/components/effect-operations-api.d.ts +8 -0
  157. package/dist/components/effect-operations-api.js +52 -0
  158. package/dist/components/element-install-api.d.ts +3 -0
  159. package/dist/components/element-install-api.js +19 -0
  160. package/dist/components/import-assets.js +20 -9
  161. package/dist/components/reorder-sequence-api.d.ts +2 -0
  162. package/dist/components/reorder-sequence-api.js +12 -0
  163. package/dist/components/split-jsx-sequence-api.d.ts +2 -0
  164. package/dist/components/split-jsx-sequence-api.js +12 -0
  165. package/dist/components/split-video-from-audio-api.d.ts +2 -0
  166. package/dist/components/split-video-from-audio-api.js +12 -0
  167. package/dist/error-overlay/remotion-overlay/Overlay.js +1 -1
  168. package/dist/error-overlay/remotion-overlay/log-studio-error.js +4 -0
  169. package/dist/esm/{chunk-r46yxrjr.js → chunk-s6k99gh2.js} +1 -1
  170. package/dist/esm/{chunk-tv7r0jy3.js → chunk-v5a8vpv4.js} +11479 -7851
  171. package/dist/esm/index.mjs +7 -5
  172. package/dist/esm/internals.mjs +11479 -7851
  173. package/dist/esm/previewEntry.mjs +11311 -7683
  174. package/dist/esm/renderEntry.mjs +3 -4
  175. package/dist/helpers/browser-studio-operations.d.ts +5 -0
  176. package/dist/helpers/browser-studio-operations.js +27 -1
  177. package/dist/helpers/colors.d.ts +1 -1
  178. package/dist/helpers/colors.js +1 -1
  179. package/dist/helpers/get-timeline-max-zoom.d.ts +26 -0
  180. package/dist/helpers/get-timeline-max-zoom.js +45 -0
  181. package/dist/helpers/inject-css.js +7 -5
  182. package/dist/helpers/render-codec-label.d.ts +1 -1
  183. package/dist/helpers/retry-payload.js +1 -0
  184. package/dist/helpers/studio-runtime-config.d.ts +1 -1
  185. package/dist/helpers/studio-runtime-config.js +2 -3
  186. package/dist/helpers/timeline-layout.d.ts +3 -1
  187. package/dist/helpers/timeline-layout.js +6 -1
  188. package/dist/helpers/url-state.js +3 -2
  189. package/dist/helpers/use-max-media-duration.js +5 -3
  190. package/dist/helpers/use-media-metadata.js +37 -20
  191. package/dist/helpers/use-menu-structure.js +67 -84
  192. package/dist/helpers/use-runtime-values.d.ts +2 -1
  193. package/dist/helpers/use-runtime-values.js +7 -3
  194. package/dist/icons/cloud-download.d.ts +4 -0
  195. package/dist/icons/cloud-download.js +8 -0
  196. package/dist/icons/remotion-triangle.d.ts +2 -0
  197. package/dist/icons/remotion-triangle.js +7 -0
  198. package/dist/renderEntry.js +1 -1
  199. package/dist/state/composition-list.d.ts +13 -0
  200. package/dist/state/composition-list.js +21 -0
  201. package/dist/state/modals.d.ts +8 -2
  202. package/dist/state/timeline-zoom.d.ts +1 -2
  203. package/dist/state/timeline-zoom.js +9 -5
  204. package/package.json +14 -13
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- type SettingsTab = 'apps' | 'license';
2
+ type SettingsTab = 'apps' | 'rendering' | 'studio' | 'license';
3
3
  export declare const SettingsModal: React.FC<{
4
4
  readonly initialTab: SettingsTab;
5
5
  readonly initialPublicLicenseKey: string | null;
@@ -5,19 +5,28 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const apps_1 = require("../icons/apps");
7
7
  const certificate_1 = require("../icons/certificate");
8
+ const remotion_triangle_1 = require("../icons/remotion-triangle");
9
+ const video_1 = require("../icons/video");
8
10
  const modals_1 = require("../state/modals");
9
11
  const ConfigureDefaultEditorModal_1 = require("./ConfigureDefaultEditorModal");
10
12
  const ConfigureLicenseModal_1 = require("./ConfigureLicenseModal");
11
13
  const is_menu_item_1 = require("./Menu/is-menu-item");
12
14
  const ModalHeader_1 = require("./ModalHeader");
13
15
  const DismissableModal_1 = require("./NewComposition/DismissableModal");
16
+ const RenderingSettings_1 = require("./RenderingSettings");
14
17
  const render_modals_1 = require("./RenderModal/render-modals");
15
18
  const SettingsContext_1 = require("./SettingsContext");
16
19
  const SettingsModalFooter_1 = require("./SettingsModalFooter");
20
+ const StudioSettings_1 = require("./StudioSettings");
17
21
  const vertical_1 = require("./Tabs/vertical");
18
22
  const hiddenPanel = {
19
23
  display: 'none',
20
24
  };
25
+ const settingsOptionsPanel = {
26
+ ...render_modals_1.optionsPanel,
27
+ boxSizing: 'border-box',
28
+ paddingBottom: 16,
29
+ };
21
30
  const appsIcon = {
22
31
  ...render_modals_1.icon,
23
32
  height: 20,
@@ -50,7 +59,7 @@ const SettingsModal = ({ initialPublicLicenseKey, initialTab }) => {
50
59
  }, [initialPublicLicenseKey, setPublicLicenseKey]);
51
60
  return (jsx_runtime_1.jsx(DismissableModal_1.DismissableModal, { panelStyle: render_modals_1.outerModalStyle, children: jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
52
61
  jsx_runtime_1.jsx(ModalHeader_1.ModalHeader, { title: "Settings", onClose: dismiss }), jsx_runtime_1.jsxs("div", { style: render_modals_1.horizontalLayout, children: [
53
- jsx_runtime_1.jsxs("div", { style: render_modals_1.leftSidebar, children: [jsx_runtime_1.jsx(vertical_1.VerticalTab, { style: render_modals_1.horizontalTab, selected: tab === 'apps', onClick: () => selectTab('apps'), renderIcon: (color) => (jsx_runtime_1.jsx("div", { style: appsIconContainer, children: jsx_runtime_1.jsx(apps_1.AppsIcon, { color: color, style: appsIcon }) })), children: "Apps" }), jsx_runtime_1.jsx(vertical_1.VerticalTab, { style: render_modals_1.horizontalTab, selected: tab === 'license', onClick: () => selectTab('license'), renderIcon: (color) => (jsx_runtime_1.jsx("div", { style: render_modals_1.iconContainer, children: jsx_runtime_1.jsx(certificate_1.CertificateIcon, { color: color, style: render_modals_1.icon }) })), children: "License" })] }), openedTabs.includes('apps') ? (jsx_runtime_1.jsx("div", { style: tab === 'apps' ? render_modals_1.optionsPanel : hiddenPanel, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: jsx_runtime_1.jsx(ConfigureDefaultEditorModal_1.DefaultEditorSettings, {}) })) : null, openedTabs.includes('license') ? (jsx_runtime_1.jsx("div", { style: tab === 'license' ? render_modals_1.optionsPanel : hiddenPanel, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: jsx_runtime_1.jsx(ConfigureLicenseModal_1.LicenseSettings, {}) })) : null] }), jsx_runtime_1.jsx(SettingsModalFooter_1.SettingsModalFooter, {})
62
+ jsx_runtime_1.jsxs("div", { style: render_modals_1.leftSidebar, children: [jsx_runtime_1.jsx(vertical_1.VerticalTab, { style: render_modals_1.horizontalTab, selected: tab === 'rendering', onClick: () => selectTab('rendering'), renderIcon: (color) => (jsx_runtime_1.jsx("div", { style: render_modals_1.iconContainer, children: jsx_runtime_1.jsx(video_1.FilmIcon, { color: color, style: render_modals_1.icon }) })), children: "Defaults" }), jsx_runtime_1.jsx(vertical_1.VerticalTab, { style: render_modals_1.horizontalTab, selected: tab === 'studio', onClick: () => selectTab('studio'), renderIcon: (color) => (jsx_runtime_1.jsx("div", { style: render_modals_1.iconContainer, children: jsx_runtime_1.jsx(remotion_triangle_1.RemotionTriangleIcon, { color: color, style: render_modals_1.icon }) })), children: "Studio" }), jsx_runtime_1.jsx(vertical_1.VerticalTab, { style: render_modals_1.horizontalTab, selected: tab === 'apps', onClick: () => selectTab('apps'), renderIcon: (color) => (jsx_runtime_1.jsx("div", { style: appsIconContainer, children: jsx_runtime_1.jsx(apps_1.AppsIcon, { color: color, style: appsIcon }) })), children: "Apps" }), jsx_runtime_1.jsx(vertical_1.VerticalTab, { style: render_modals_1.horizontalTab, selected: tab === 'license', onClick: () => selectTab('license'), renderIcon: (color) => (jsx_runtime_1.jsx("div", { style: render_modals_1.iconContainer, children: jsx_runtime_1.jsx(certificate_1.CertificateIcon, { color: color, style: render_modals_1.icon }) })), children: "License" })] }), openedTabs.includes('apps') ? (jsx_runtime_1.jsx("div", { style: tab === 'apps' ? settingsOptionsPanel : hiddenPanel, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: jsx_runtime_1.jsx(ConfigureDefaultEditorModal_1.DefaultEditorSettings, {}) })) : null, openedTabs.includes('license') ? (jsx_runtime_1.jsx("div", { style: tab === 'license' ? settingsOptionsPanel : hiddenPanel, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: jsx_runtime_1.jsx(ConfigureLicenseModal_1.LicenseSettings, {}) })) : null, openedTabs.includes('rendering') ? (jsx_runtime_1.jsx("div", { style: tab === 'rendering' ? settingsOptionsPanel : hiddenPanel, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: jsx_runtime_1.jsx(RenderingSettings_1.RenderingSettings, {}) })) : null, openedTabs.includes('studio') ? (jsx_runtime_1.jsx("div", { style: tab === 'studio' ? settingsOptionsPanel : hiddenPanel, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: jsx_runtime_1.jsx(StudioSettings_1.StudioSettings, {}) })) : null] }), jsx_runtime_1.jsx(SettingsModalFooter_1.SettingsModalFooter, {})
54
63
  ] }) }));
55
64
  };
56
65
  exports.SettingsModal = SettingsModal;
@@ -37,7 +37,7 @@ const SettingsModalFooter = () => {
37
37
  column: 1,
38
38
  };
39
39
  }, []);
40
- return (jsx_runtime_1.jsx(ModalFooter_1.ModalFooterContainer, { style: footer, noBorder: true, children: jsx_runtime_1.jsx("div", { style: footerRow, children: jsx_runtime_1.jsxs("div", { style: configFileHint, children: ["Changes save to",
40
+ return (jsx_runtime_1.jsx(ModalFooter_1.ModalFooterContainer, { style: footer, children: jsx_runtime_1.jsx("div", { style: footerRow, children: jsx_runtime_1.jsxs("div", { style: configFileHint, children: ["Changes save to",
41
41
  jsx_runtime_1.jsx(InspectorOpenInEditor_1.InspectorOpenInEditor, { locationType: null, location: configFileLocation, label: jsx_runtime_1.jsx("strong", { style: configFileName, children: "remotion.config.ts" }) })
42
42
  ] }) }) }));
43
43
  };
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare const StudioSettings: React.FC;
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StudioSettings = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const client_1 = require("@remotion/renderer/client");
6
+ const studio_shared_1 = require("@remotion/studio-shared");
7
+ const react_1 = require("react");
8
+ const colors_1 = require("../helpers/colors");
9
+ const Checkmark_1 = require("../icons/Checkmark");
10
+ const undo_1 = require("../icons/undo");
11
+ const Button_1 = require("./Button");
12
+ const styles_1 = require("./InspectorPanel/styles");
13
+ const layout_1 = require("./layout");
14
+ const ComboBox_1 = require("./NewComposition/ComboBox");
15
+ const InputDragger_1 = require("./NewComposition/InputDragger");
16
+ const ValidationMessage_1 = require("./NewComposition/ValidationMessage");
17
+ const layout_2 = require("./RenderModal/layout");
18
+ const RenderModalHr_1 = require("./RenderModal/RenderModalHr");
19
+ const SettingsContext_1 = require("./SettingsContext");
20
+ const use_auto_save_config_1 = require("./use-auto-save-config");
21
+ const container = {
22
+ display: 'flex',
23
+ flex: 1,
24
+ flexDirection: 'column',
25
+ minWidth: 0,
26
+ };
27
+ const dividerLabel = {
28
+ ...styles_1.sectionHeader,
29
+ margin: 0,
30
+ padding: '4px 16px',
31
+ };
32
+ const controlWidth = {
33
+ boxSizing: 'border-box',
34
+ width: 180,
35
+ };
36
+ const resetIcon = {
37
+ height: 12,
38
+ width: 12,
39
+ };
40
+ const DEFAULT_VALUE = 'studio-default';
41
+ const initialSettings = {
42
+ askAIEnabled: null,
43
+ audioLatencyHint: null,
44
+ beepOnFinish: null,
45
+ enableCrossSiteIsolation: null,
46
+ interactivityEnabled: null,
47
+ keyboardShortcutsEnabled: null,
48
+ logLevel: null,
49
+ maxTimelineTracks: null,
50
+ numberOfSharedAudioTags: null,
51
+ rspack: null,
52
+ };
53
+ const ConfigSelect = ({ defaultLabel, name, onChange, options, value, }) => {
54
+ const values = [
55
+ {
56
+ id: DEFAULT_VALUE,
57
+ keyHint: null,
58
+ label: `Default (${defaultLabel})`,
59
+ leftItem: value === null ? jsx_runtime_1.jsx(Checkmark_1.Checkmark, {}) : null,
60
+ onClick: () => onChange(null),
61
+ quickSwitcherLabel: null,
62
+ subMenu: null,
63
+ type: 'item',
64
+ value: DEFAULT_VALUE,
65
+ },
66
+ { id: `${DEFAULT_VALUE}-divider`, type: 'divider' },
67
+ ...options.map((option) => {
68
+ const id = `${name}-${String(option.value)}`;
69
+ return {
70
+ id,
71
+ keyHint: null,
72
+ label: option.label,
73
+ leftItem: value === option.value ? jsx_runtime_1.jsx(Checkmark_1.Checkmark, {}) : null,
74
+ onClick: () => onChange(option.value),
75
+ quickSwitcherLabel: null,
76
+ subMenu: null,
77
+ type: 'item',
78
+ value: id,
79
+ };
80
+ }),
81
+ ];
82
+ return (jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [
83
+ jsx_runtime_1.jsx("div", { style: layout_2.label, children: name }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsx(ComboBox_1.Combobox, { values: values, selectedId: value === null ? DEFAULT_VALUE : `${name}-${String(value)}`, style: controlWidth, title: name }) })
84
+ ] }));
85
+ };
86
+ const ConfigNumber = ({ defaultLabel, defaultValue, name, onChange, onChangeEnd, value, }) => {
87
+ const resolvedDefaultLabel = defaultLabel !== null && defaultLabel !== void 0 ? defaultLabel : String(defaultValue);
88
+ return (jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [
89
+ jsx_runtime_1.jsx("div", { style: layout_2.label, children: name }), jsx_runtime_1.jsxs("div", { style: { ...layout_2.rightRow, gap: 6 }, children: [
90
+ jsx_runtime_1.jsx(InputDragger_1.InputDragger, { "aria-label": name, buttonStyle: { textAlign: 'right', width: 140 }, formatter: () => value === null ? `Default (${resolvedDefaultLabel})` : String(value), min: 0, onTextChange: () => undefined, onValueChange: onChange, onValueChangeEnd: onChangeEnd, placeholder: `Default (${resolvedDefaultLabel})`, rightAlign: true, status: "ok", step: 1, value: value !== null && value !== void 0 ? value : defaultValue }), jsx_runtime_1.jsx(Button_1.Button, { disabled: value === null, onClick: () => onChangeEnd(null), size: "compact", style: { color: colors_1.LIGHT_TEXT }, title: `Use default (${resolvedDefaultLabel})`, children: jsx_runtime_1.jsx(undo_1.UndoIcon, { style: resetIcon }) })
91
+ ] })
92
+ ] }));
93
+ };
94
+ const booleanOptions = [
95
+ { label: 'Enabled', value: true },
96
+ { label: 'Disabled', value: false },
97
+ ];
98
+ const StudioSettings = () => {
99
+ var _a;
100
+ const { error: settingsError, revision, studioRuntimeConfig } = (0, SettingsContext_1.useSettings)();
101
+ const [settings, setSettings] = (0, react_1.useState)(initialSettings);
102
+ const [committedNumberSettings, setCommittedNumberSettings] = (0, react_1.useState)({ maxTimelineTracks: null, numberOfSharedAudioTags: null });
103
+ const [editedSetters, setEditedSetters] = (0, react_1.useState)(() => new Set());
104
+ const [syncedRevision, setSyncedRevision] = (0, react_1.useState)(-1);
105
+ const [error, setError] = (0, react_1.useState)(null);
106
+ (0, react_1.useEffect)(() => {
107
+ var _a, _b;
108
+ var _c, _d, _e;
109
+ if (studioRuntimeConfig === null) {
110
+ return;
111
+ }
112
+ setSettings((_c = studioRuntimeConfig.configFileStudioSettings) !== null && _c !== void 0 ? _c : initialSettings);
113
+ setCommittedNumberSettings({
114
+ maxTimelineTracks: (_d = (_a = studioRuntimeConfig.configFileStudioSettings) === null || _a === void 0 ? void 0 : _a.maxTimelineTracks) !== null && _d !== void 0 ? _d : null,
115
+ numberOfSharedAudioTags: (_e = (_b = studioRuntimeConfig.configFileStudioSettings) === null || _b === void 0 ? void 0 : _b.numberOfSharedAudioTags) !== null && _e !== void 0 ? _e : null,
116
+ });
117
+ setEditedSetters(new Set());
118
+ setSyncedRevision(revision);
119
+ setError(null);
120
+ }, [revision, studioRuntimeConfig]);
121
+ const changeSetting = (0, react_1.useCallback)((key, setter, value) => {
122
+ setSettings((current) => ({ ...current, [key]: value }));
123
+ setEditedSetters((current) => new Set(current).add(setter));
124
+ }, []);
125
+ const previewNumberSetting = (0, react_1.useCallback)((key, value) => {
126
+ setSettings((current) => ({ ...current, [key]: value }));
127
+ }, []);
128
+ const commitNumberSetting = (0, react_1.useCallback)((key, setter, value) => {
129
+ setSettings((current) => ({ ...current, [key]: value }));
130
+ setCommittedNumberSettings((current) => ({ ...current, [key]: value }));
131
+ setEditedSetters((current) => new Set(current).add(setter));
132
+ }, []);
133
+ const updates = (0, react_1.useMemo)(() => {
134
+ const update = (setter, value) => value === null ? { setter, type: 'delete' } : { setter, type: 'set', value };
135
+ const updatesForEditedSetters = [
136
+ update('setAskAIEnabled', settings.askAIEnabled),
137
+ update('setEnableCrossSiteIsolation', settings.enableCrossSiteIsolation),
138
+ update('setBeepOnFinish', settings.beepOnFinish),
139
+ update('setMaxTimelineTracks', committedNumberSettings.maxTimelineTracks),
140
+ update('setAudioLatencyHint', settings.audioLatencyHint),
141
+ update('setNumberOfSharedAudioTags', committedNumberSettings.numberOfSharedAudioTags),
142
+ update('setRspack', settings.rspack),
143
+ update('setKeyboardShortcutsEnabled', settings.keyboardShortcutsEnabled),
144
+ update('setInteractivityEnabled', settings.interactivityEnabled),
145
+ update('setLogLevel', settings.logLevel),
146
+ ].filter((item) => editedSetters.has(item.setter));
147
+ if (editedSetters.has('setRspack')) {
148
+ updatesForEditedSetters.push({
149
+ setter: 'setExperimentalRspackEnabled',
150
+ type: 'delete',
151
+ });
152
+ }
153
+ if (editedSetters.has('setLogLevel')) {
154
+ updatesForEditedSetters.push({ setter: 'setLevel', type: 'delete' });
155
+ }
156
+ return updatesForEditedSetters;
157
+ }, [committedNumberSettings, editedSetters, settings]);
158
+ const ready = studioRuntimeConfig !== null && syncedRevision === revision;
159
+ (0, use_auto_save_config_1.useAutoSaveConfig)({
160
+ enabled: ready,
161
+ onError: setError,
162
+ ready,
163
+ syncRevision: syncedRevision,
164
+ updates,
165
+ });
166
+ if (studioRuntimeConfig === null) {
167
+ return null;
168
+ }
169
+ return (jsx_runtime_1.jsxs("div", { style: container, children: [
170
+ jsx_runtime_1.jsx("p", { style: dividerLabel, children: "Interface" }), jsx_runtime_1.jsx(ConfigSelect, { defaultLabel: "Enabled", name: "Ask AI enabled", onChange: (value) => changeSetting('askAIEnabled', 'setAskAIEnabled', value), options: booleanOptions, value: settings.askAIEnabled }), jsx_runtime_1.jsx(ConfigSelect, { defaultLabel: "Enabled", name: "Keyboard shortcuts enabled", onChange: (value) => changeSetting('keyboardShortcutsEnabled', 'setKeyboardShortcutsEnabled', value), options: booleanOptions, value: settings.keyboardShortcutsEnabled }), jsx_runtime_1.jsx(ConfigSelect, { defaultLabel: "Enabled", name: "Interactivity enabled", onChange: (value) => changeSetting('interactivityEnabled', 'setInteractivityEnabled', value), options: booleanOptions, value: settings.interactivityEnabled }), jsx_runtime_1.jsx(ConfigNumber, { defaultLabel: "Unlimited", defaultValue: studio_shared_1.DEFAULT_TIMELINE_TRACKS, name: "Max timeline tracks", onChange: (value) => previewNumberSetting('maxTimelineTracks', value), onChangeEnd: (value) => commitNumberSetting('maxTimelineTracks', 'setMaxTimelineTracks', value), value: settings.maxTimelineTracks }), jsx_runtime_1.jsx(RenderModalHr_1.RenderModalHr, {}), jsx_runtime_1.jsx("p", { style: dividerLabel, children: "Audio" }), jsx_runtime_1.jsx(ConfigSelect, { defaultLabel: "Playback", name: "Audio latency hint", onChange: (value) => changeSetting('audioLatencyHint', 'setAudioLatencyHint', value), options: [
171
+ { label: 'Interactive', value: 'interactive' },
172
+ { label: 'Balanced', value: 'balanced' },
173
+ { label: 'Playback', value: 'playback' },
174
+ ], value: settings.audioLatencyHint }), jsx_runtime_1.jsx(ConfigNumber, { defaultValue: 0, name: "Number of shared audio tags", onChange: (value) => previewNumberSetting('numberOfSharedAudioTags', value), onChangeEnd: (value) => commitNumberSetting('numberOfSharedAudioTags', 'setNumberOfSharedAudioTags', value), value: settings.numberOfSharedAudioTags }), jsx_runtime_1.jsx(ConfigSelect, { defaultLabel: "Disabled", name: "Beep on finish", onChange: (value) => changeSetting('beepOnFinish', 'setBeepOnFinish', value), options: booleanOptions, value: settings.beepOnFinish }), jsx_runtime_1.jsx(RenderModalHr_1.RenderModalHr, {}), jsx_runtime_1.jsx("p", { style: dividerLabel, children: "Development" }), jsx_runtime_1.jsx(ConfigSelect, { defaultLabel: "Webpack", name: "Bundler", onChange: (value) => changeSetting('rspack', 'setRspack', value), options: [
175
+ { label: 'Rspack', value: true },
176
+ { label: 'Webpack', value: false },
177
+ ], value: settings.rspack }), jsx_runtime_1.jsx(ConfigSelect, { defaultLabel: "Disabled", name: "Cross-site isolation", onChange: (value) => changeSetting('enableCrossSiteIsolation', 'setEnableCrossSiteIsolation', value), options: booleanOptions, value: settings.enableCrossSiteIsolation }), jsx_runtime_1.jsx(ConfigSelect, { defaultLabel: "Info", name: "Log level", onChange: (value) => changeSetting('logLevel', 'setLogLevel', value), options: client_1.BrowserSafeApis.logLevels.map((value) => ({
178
+ label: value[0].toUpperCase() + value.slice(1),
179
+ value,
180
+ })), value: settings.logLevel }), (error !== null && error !== void 0 ? error : settingsError) ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
181
+ jsx_runtime_1.jsx(layout_1.Spacing, { y: 1, block: true }), jsx_runtime_1.jsx("div", { style: { paddingLeft: 16, paddingRight: 16 }, children: jsx_runtime_1.jsx(ValidationMessage_1.ValidationMessage, { align: "flex-start", message: (_a = error !== null && error !== void 0 ? error : settingsError) !== null && _a !== void 0 ? _a : '', type: "error" }) })
182
+ ] })) : null, jsx_runtime_1.jsx(layout_1.Spacing, { y: 2, block: true })
183
+ ] }));
184
+ };
185
+ exports.StudioSettings = StudioSettings;
@@ -26,7 +26,7 @@ const centerContainer = {
26
26
  };
27
27
  const LoopedIndicator = () => {
28
28
  return (jsx_runtime_1.jsxs("div", { style: width, children: [
29
- jsx_runtime_1.jsx(remotion_1.AbsoluteFill, { style: centerContainer, children: jsx_runtime_1.jsx("div", { style: verticalLine }) }), jsx_runtime_1.jsx(remotion_1.AbsoluteFill, { style: centerContainer, children: jsx_runtime_1.jsx(Icon, {}) })
29
+ jsx_runtime_1.jsx(remotion_1.Internals.AbsoluteFillElement, { style: centerContainer, children: jsx_runtime_1.jsx("div", { style: verticalLine }) }), jsx_runtime_1.jsx(remotion_1.Internals.AbsoluteFillElement, { style: centerContainer, children: jsx_runtime_1.jsx(Icon, {}) })
30
30
  ] }));
31
31
  };
32
32
  exports.LoopedIndicator = LoopedIndicator;
@@ -1,4 +1,7 @@
1
1
  import React from 'react';
2
2
  export declare const LoopedTimelineIndicator: React.FC<{
3
3
  readonly loops: number;
4
+ readonly fullWidth: number;
5
+ readonly visibleOffset: number;
6
+ readonly visibleWidth: number;
4
7
  }>;
@@ -1,24 +1,32 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.LoopedTimelineIndicator = void 0;
7
4
  const jsx_runtime_1 = require("react/jsx-runtime");
8
- const react_1 = __importDefault(require("react"));
9
5
  const remotion_1 = require("remotion");
10
- const layout_1 = require("../layout");
11
6
  const LoopedIndicator_1 = require("./LoopedIndicator");
12
7
  const row = {
13
- flexDirection: 'row',
8
+ overflow: 'hidden',
14
9
  };
15
- const LoopedTimelineIndicator = ({ loops }) => {
16
- const leftOver = loops % 1;
17
- return (jsx_runtime_1.jsxs(remotion_1.AbsoluteFill, { style: row, children: [new Array(Math.floor(loops)).fill(true).map((_l, i) => {
18
- return (jsx_runtime_1.jsxs(react_1.default.Fragment
19
- // eslint-disable-next-line
20
- , { children: [
21
- jsx_runtime_1.jsx(layout_1.Flex, {}), i === loops - 1 ? null : jsx_runtime_1.jsx(LoopedIndicator_1.LoopedIndicator, {})] }, i));
22
- }), leftOver > 0 ? jsx_runtime_1.jsx("div", { style: { flex: leftOver } }) : null] }));
10
+ const LoopedTimelineIndicator = ({ loops, fullWidth, visibleOffset, visibleWidth }) => {
11
+ if (loops <= 1 || fullWidth <= 0 || visibleWidth <= 0) {
12
+ return null;
13
+ }
14
+ const loopWidth = fullWidth / loops;
15
+ const lastBoundaryIndex = Math.ceil(loops) - 1;
16
+ const firstVisibleBoundaryIndex = Math.max(1, Math.floor(visibleOffset / loopWidth));
17
+ const lastVisibleBoundaryIndex = Math.min(lastBoundaryIndex, Math.ceil((visibleOffset + visibleWidth) / loopWidth));
18
+ const visibleBoundaryCount = Math.max(0, lastVisibleBoundaryIndex - firstVisibleBoundaryIndex + 1);
19
+ const boundaries = new Array(visibleBoundaryCount)
20
+ .fill(true)
21
+ .map((_, index) => (firstVisibleBoundaryIndex + index) * loopWidth);
22
+ return (jsx_runtime_1.jsx(remotion_1.Internals.AbsoluteFillElement, { style: row, children: boundaries.map((boundary) => {
23
+ return (jsx_runtime_1.jsx("div", { style: {
24
+ position: 'absolute',
25
+ display: 'flex',
26
+ left: boundary - visibleOffset,
27
+ top: 0,
28
+ bottom: 0,
29
+ }, children: jsx_runtime_1.jsx(LoopedIndicator_1.LoopedIndicator, {}) }, boundary));
30
+ }) }));
23
31
  };
24
32
  exports.LoopedTimelineIndicator = LoopedTimelineIndicator;
@@ -75,6 +75,7 @@ const TimelineSelection_1 = require("./TimelineSelection");
75
75
  const TimelineSlider_1 = require("./TimelineSlider");
76
76
  const TimelineTimeIndicators_1 = require("./TimelineTimeIndicators");
77
77
  const TimelineTracks_1 = require("./TimelineTracks");
78
+ const TimelineVirtualization_1 = require("./TimelineVirtualization");
78
79
  const TimelineWidthProvider_1 = require("./TimelineWidthProvider");
79
80
  const use_resolved_stack_1 = require("./use-resolved-stack");
80
81
  const use_timeline_asset_drop_1 = require("./use-timeline-asset-drop");
@@ -329,7 +330,7 @@ const TimelineInner = () => {
329
330
  }, [filtered]);
330
331
  const maxTimelineTracks = (0, studio_runtime_config_1.getStudioMaxTimelineTracks)();
331
332
  const shown = (0, react_1.useMemo)(() => {
332
- return collapsed.length > maxTimelineTracks
333
+ return maxTimelineTracks !== null && collapsed.length > maxTimelineTracks
333
334
  ? collapsed.slice(0, maxTimelineTracks)
334
335
  : collapsed;
335
336
  }, [collapsed, maxTimelineTracks]);
@@ -339,14 +340,15 @@ const TimelineInner = () => {
339
340
  return null;
340
341
  }
341
342
  return (jsx_runtime_1.jsx(SubscribeToNodePaths_1.SubscribeToNodePaths, { overrideId: sequence.controls.overrideId, componentIdentity: sequence.controls.componentIdentity, schema: sequence.controls.schema, getStack: sequence.getStack, effects: sequence.effects }, sequence.id));
342
- }), (0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? jsx_runtime_1.jsx(SequencePropsObserver_1.SequencePropsObserver, {}) : null, jsx_runtime_1.jsx(TimelineKeyframeTracksContext_1.TimelineKeyframeTracksProvider, { tracks: filtered, children: jsx_runtime_1.jsxs(TimelineSelection_1.TimelineSelectableItemsProvider, { timeline: shown, children: [(0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectAllKeybindings, { timeline: shown })) : null, jsx_runtime_1.jsx(TimelineHeightContainer_1.TimelineHeightContainer, { shown: shown, hasBeenCut: hasBeenCut, isStill: isStill, children: isStill ? (jsx_runtime_1.jsx(TimelineList_1.TimelineList, { timeline: shown, showTimePadding: false })) : (jsx_runtime_1.jsxs(TimelineWidthProvider_1.TimelineWidthProvider, { children: [
343
- jsx_runtime_1.jsx(TimelinePinchZoom_1.TimelinePinchZoom, {}), jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { orientation: "vertical", defaultFlex: 0.2, id: "names-to-timeline", maxFlex: 0.5, minFlex: 0.15, maxFlexerSize: null, minFlexerSize: MIN_TIMELINE_LABELS_WIDTH, maxAntiFlexerSize: null, minAntiFlexerSize: null, children: [
344
- jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "flexer", sticky: jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePlaceholders, {}), children: jsx_runtime_1.jsx(TimelineList_1.TimelineList, { timeline: shown, showTimePadding: true }) }), jsx_runtime_1.jsx(SplitterHandle_1.SplitterHandle, { onCollapse: noop, allowToCollapse: "none" }), jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "anti-flexer", sticky: null, children: jsx_runtime_1.jsxs(TimelineScrollable_1.TimelineScrollable, { children: [
345
- jsx_runtime_1.jsx(TimelineTracks_1.TimelineTracks, { timeline: shown, hasBeenCut: hasBeenCut }), jsx_runtime_1.jsx(TimelinePlayCursorSyncer_1.TimelinePlayCursorSyncer, {}), jsx_runtime_1.jsx(TimelineInOutPointer_1.TimelineInOutPointer, {}), jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimeIndicators, {}), jsx_runtime_1.jsx(TimelineDragHandler_1.TimelineDragHandler, {}), (0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? (jsx_runtime_1.jsx(TimelineInOutDragHandler_1.TimelineInOutDragHandler, {})) : null, jsx_runtime_1.jsx(TimelineSlider_1.TimelineSlider, {})
346
- ] }) })
347
- ] })
348
- ] })) })
349
- ] }) })
343
+ }), (0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? jsx_runtime_1.jsx(SequencePropsObserver_1.SequencePropsObserver, {}) : null, jsx_runtime_1.jsx(TimelineKeyframeTracksContext_1.TimelineKeyframeTracksProvider, { tracks: filtered, children: jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectableItemsProvider, { timeline: shown, children: jsx_runtime_1.jsxs(TimelineVirtualization_1.TimelineVirtualizationProvider, { hasBeenCut: hasBeenCut, isStill: isStill, timeline: shown, children: [(0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectAllKeybindings, { timeline: shown })) : null, jsx_runtime_1.jsx(TimelineHeightContainer_1.TimelineHeightContainer, { children: isStill ? (jsx_runtime_1.jsx(TimelineList_1.TimelineList, {})) : (jsx_runtime_1.jsxs(TimelineWidthProvider_1.TimelineWidthProvider, { children: [
344
+ jsx_runtime_1.jsx(TimelinePinchZoom_1.TimelinePinchZoom, {}), jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { orientation: "vertical", defaultFlex: 0.2, id: "names-to-timeline", maxFlex: 0.5, minFlex: 0.15, maxFlexerSize: null, minFlexerSize: MIN_TIMELINE_LABELS_WIDTH, maxAntiFlexerSize: null, minAntiFlexerSize: null, children: [
345
+ jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "flexer", sticky: jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePlaceholders, {}), children: jsx_runtime_1.jsx(TimelineList_1.TimelineList, {}) }), jsx_runtime_1.jsx(SplitterHandle_1.SplitterHandle, { onCollapse: noop, allowToCollapse: "none" }), jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "anti-flexer", sticky: jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
346
+ jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimeIndicators, {}), jsx_runtime_1.jsx(TimelineSlider_1.TimelineSlider, {})
347
+ ] }), children: jsx_runtime_1.jsxs(TimelineScrollable_1.TimelineScrollable, { children: [
348
+ jsx_runtime_1.jsx(TimelineTracks_1.TimelineTracks, { hasBeenCut: hasBeenCut }), jsx_runtime_1.jsx(TimelinePlayCursorSyncer_1.TimelinePlayCursorSyncer, {}), jsx_runtime_1.jsx(TimelineInOutPointer_1.TimelineInOutPointer, {}), jsx_runtime_1.jsx(TimelineDragHandler_1.TimelineDragHandler, {}), (0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? (jsx_runtime_1.jsx(TimelineInOutDragHandler_1.TimelineInOutDragHandler, {})) : null] }) })
349
+ ] })
350
+ ] })) })
351
+ ] }) }) })
350
352
  ] }));
351
353
  };
352
354
  exports.Timeline = react_1.default.memo(TimelineInner);
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
2
  import { type CanUpdateSequencePropStatusStatic } from 'remotion';
3
3
  import type { SchemaFieldInfo, TimelineFieldOnDragValueChange, TimelineFieldOnSave } from '../../helpers/timeline-layout';
4
- import { type InspectorInlineActionProps } from '../InspectorPanel/common';
5
- export type InspectorSourceAction = Omit<InspectorInlineActionProps, 'variant'>;
4
+ import { type InspectorQuickActionProps } from '../InspectorPanel/common';
5
+ export type InspectorSourceAction = Omit<InspectorQuickActionProps, 'variant'>;
6
6
  type AssetSelectionContextValue = {
7
7
  readonly initialQuery: string;
8
8
  readonly getSourceAction: (src: string) => InspectorSourceAction | null;
@@ -100,7 +100,7 @@ const TimelineAssetField = ({ field, effectiveValue, propStatus, onSave, onDragV
100
100
  if (inlineSourceAction === null) {
101
101
  return action;
102
102
  }
103
- return (jsx_runtime_1.jsx(common_1.InspectorInlineAction, { ...inlineSourceAction, size: "compact", variant: {
103
+ return (jsx_runtime_1.jsx(common_1.InspectorQuickAction, { ...inlineSourceAction, size: "compact", variant: {
104
104
  type: 'segmented',
105
105
  trailing: {
106
106
  disabled: window.remotion_isReadOnlyStudio,
@@ -4,13 +4,14 @@ exports.TimelineClipboardKeybindings = exports.getPasteEffectPropTarget = export
4
4
  const studio_shared_1 = require("@remotion/studio-shared");
5
5
  const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
+ const browser_studio_operations_1 = require("../../helpers/browser-studio-operations");
7
8
  const client_id_1 = require("../../helpers/client-id");
8
9
  const clipboard_figma_1 = require("../../helpers/clipboard-figma");
9
10
  const clipboard_images_1 = require("../../helpers/clipboard-images");
10
11
  const clipboard_svg_1 = require("../../helpers/clipboard-svg");
11
12
  const use_keybinding_1 = require("../../helpers/use-keybinding");
12
- const call_api_1 = require("../call-api");
13
13
  const ConfirmationDialog_1 = require("../ConfirmationDialog");
14
+ const effect_operations_api_1 = require("../effect-operations-api");
14
15
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
15
16
  const call_add_keyframe_1 = require("./call-add-keyframe");
16
17
  const call_delete_keyframe_1 = require("./call-delete-keyframe");
@@ -869,6 +870,9 @@ const TimelineClipboardKeybindings = () => {
869
870
  if (result.status === 'invalid') {
870
871
  return;
871
872
  }
873
+ if (!(0, browser_studio_operations_1.canUseEffectOperations)()) {
874
+ return;
875
+ }
872
876
  e.preventDefault();
873
877
  if (result.status === 'unsupported-version') {
874
878
  (0, NotificationCenter_1.showNotification)('Cannot paste effects copied from a different Remotion Studio version', 4000);
@@ -892,7 +896,7 @@ const TimelineClipboardKeybindings = () => {
892
896
  const insertAtIndices = (envelope === null || envelope === void 0 ? void 0 : envelope.sourceIdentity) === makeTargetKey(targetSequenceNodePath)
893
897
  ? envelope.originalEffectIndices
894
898
  : null;
895
- return (0, call_api_1.callApi)('/api/paste-effects', {
899
+ return (0, effect_operations_api_1.pasteEffects)({
896
900
  targetFileName: targetSequenceNodePath.absolutePath,
897
901
  targetSequenceNodePath,
898
902
  type: payload.type,
@@ -40,10 +40,10 @@ const react_1 = __importStar(require("react"));
40
40
  const remotion_1 = require("remotion");
41
41
  const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
42
42
  const pointer_session_1 = require("../../helpers/pointer-session");
43
- const timeline_layout_1 = require("../../helpers/timeline-layout");
44
43
  const timeline_zoom_1 = require("../../state/timeline-zoom");
45
44
  const z_index_1 = require("../../state/z-index");
46
45
  const is_menu_item_1 = require("../Menu/is-menu-item");
46
+ const imperative_state_1 = require("./imperative-state");
47
47
  const timeline_refs_1 = require("./timeline-refs");
48
48
  const timeline_scroll_logic_1 = require("./timeline-scroll-logic");
49
49
  const TimelineSelection_1 = require("./TimelineSelection");
@@ -109,13 +109,7 @@ const TimelineDragHandlerInner = () => {
109
109
  dragging: false,
110
110
  });
111
111
  const { isPlaying, play, pause, seek } = player_1.PlayerInternals.usePlayerMethods();
112
- const scroller = (0, react_1.useRef)(null);
113
- const stopInterval = () => {
114
- if (scroller.current) {
115
- clearInterval(scroller.current);
116
- scroller.current = null;
117
- }
118
- };
112
+ const autoScroller = (0, react_1.useRef)(null);
119
113
  const onPointerDown = (0, react_1.useCallback)((e) => {
120
114
  var _a, _b;
121
115
  if (e.button !== 0) {
@@ -124,7 +118,6 @@ const TimelineDragHandlerInner = () => {
124
118
  if (!isHighestContext) {
125
119
  return;
126
120
  }
127
- stopInterval();
128
121
  if (!videoConfig) {
129
122
  return;
130
123
  }
@@ -148,87 +141,66 @@ const TimelineDragHandlerInner = () => {
148
141
  (_b = (_a = e.currentTarget).setPointerCapture) === null || _b === void 0 ? void 0 : _b.call(_a, e.pointerId);
149
142
  pause();
150
143
  }, [isHighestContext, videoConfig, left, width, seek, isPlaying, pause]);
144
+ const onEdgeScrollTick = (0, react_1.useCallback)((directions) => {
145
+ var _a;
146
+ if (!videoConfig || directions.x === null) {
147
+ return;
148
+ }
149
+ const nextFrame = directions.x === 'left'
150
+ ? (0, timeline_scroll_logic_1.getFrameWhileScrollingLeft)({
151
+ durationInFrames: videoConfig.durationInFrames,
152
+ width,
153
+ })
154
+ : (0, timeline_scroll_logic_1.getFrameWhileScrollingRight)({
155
+ durationInFrames: videoConfig.durationInFrames,
156
+ width,
157
+ });
158
+ const scrollPos = directions.x === 'left'
159
+ ? (0, timeline_scroll_logic_1.getScrollPositionForCursorOnLeftEdge)({
160
+ nextFrame,
161
+ durationInFrames: videoConfig.durationInFrames,
162
+ })
163
+ : (0, timeline_scroll_logic_1.getScrollPositionForCursorOnRightEdge)({
164
+ nextFrame,
165
+ durationInFrames: videoConfig.durationInFrames,
166
+ });
167
+ // Update the imperative frame and apply the scroll before drawing, so
168
+ // every redraw (including the scroll event listener in TimelineSlider)
169
+ // sees a consistent (frame, scrollLeft) pair. Otherwise the playhead
170
+ // flickers between stale combinations while React commits the seek.
171
+ (0, imperative_state_1.setCurrentFrame)(nextFrame);
172
+ (0, timeline_scroll_logic_1.scrollToTimelineXOffset)(scrollPos);
173
+ (_a = TimelineSlider_1.redrawTimelineSliderFast.current) === null || _a === void 0 ? void 0 : _a.draw(nextFrame);
174
+ seek(nextFrame);
175
+ }, [videoConfig, width, seek]);
151
176
  const onPointerMoveScrubbing = (0, react_1.useCallback)((e) => {
152
177
  var _a;
178
+ var _b;
153
179
  if (!videoConfig) {
154
180
  return;
155
181
  }
156
182
  if (!dragging.dragging) {
157
183
  return;
158
184
  }
159
- const isRightOfArea = e.clientX >=
160
- ((_a = timeline_refs_1.scrollableRef.current) === null || _a === void 0 ? void 0 : _a.clientWidth) +
161
- left -
162
- timeline_layout_1.TIMELINE_PADDING;
163
- const isLeftOfArea = e.clientX <= left;
185
+ const directions = (_b = (_a = autoScroller.current) === null || _a === void 0 ? void 0 : _a.update(e)) !== null && _b !== void 0 ? _b : {
186
+ x: null,
187
+ y: null,
188
+ };
189
+ // While edge auto-scrolling is active, the tick owns seeking
190
+ if (directions.x !== null) {
191
+ return;
192
+ }
164
193
  const frame = (0, timeline_scroll_logic_1.getFrameFromX)({
165
194
  clientX: getClientXWithScroll(e.clientX) - left,
166
195
  durationInFrames: videoConfig.durationInFrames,
167
196
  width,
168
197
  extrapolate: 'clamp',
169
198
  });
170
- if (isLeftOfArea && (0, timeline_scroll_logic_1.canScrollTimelineIntoDirection)().canScrollLeft) {
171
- if (scroller.current) {
172
- return;
173
- }
174
- const scrollEvery = () => {
175
- var _a;
176
- if (!(0, timeline_scroll_logic_1.canScrollTimelineIntoDirection)().canScrollLeft) {
177
- stopInterval();
178
- return;
179
- }
180
- const nextFrame = (0, timeline_scroll_logic_1.getFrameWhileScrollingLeft)({
181
- durationInFrames: videoConfig.durationInFrames,
182
- width,
183
- });
184
- const scrollPos = (0, timeline_scroll_logic_1.getScrollPositionForCursorOnLeftEdge)({
185
- nextFrame,
186
- durationInFrames: videoConfig.durationInFrames,
187
- });
188
- (_a = TimelineSlider_1.redrawTimelineSliderFast.current) === null || _a === void 0 ? void 0 : _a.draw(nextFrame);
189
- seek(nextFrame);
190
- (0, timeline_scroll_logic_1.scrollToTimelineXOffset)(scrollPos);
191
- };
192
- scrollEvery();
193
- scroller.current = setInterval(() => {
194
- scrollEvery();
195
- }, 100);
196
- }
197
- else if (isRightOfArea &&
198
- (0, timeline_scroll_logic_1.canScrollTimelineIntoDirection)().canScrollRight) {
199
- if (scroller.current) {
200
- return;
201
- }
202
- const scrollEvery = () => {
203
- var _a;
204
- if (!(0, timeline_scroll_logic_1.canScrollTimelineIntoDirection)().canScrollRight) {
205
- stopInterval();
206
- return;
207
- }
208
- const nextFrame = (0, timeline_scroll_logic_1.getFrameWhileScrollingRight)({
209
- durationInFrames: videoConfig.durationInFrames,
210
- width,
211
- });
212
- const scrollPos = (0, timeline_scroll_logic_1.getScrollPositionForCursorOnRightEdge)({
213
- nextFrame,
214
- durationInFrames: videoConfig.durationInFrames,
215
- });
216
- (_a = TimelineSlider_1.redrawTimelineSliderFast.current) === null || _a === void 0 ? void 0 : _a.draw(nextFrame);
217
- seek(nextFrame);
218
- (0, timeline_scroll_logic_1.scrollToTimelineXOffset)(scrollPos);
219
- };
220
- scrollEvery();
221
- scroller.current = setInterval(() => {
222
- scrollEvery();
223
- }, 100);
224
- }
225
- else {
226
- stopInterval();
227
- seek(frame);
228
- }
199
+ seek(frame);
229
200
  }, [videoConfig, dragging.dragging, left, width, seek]);
230
201
  const onPointerUpScrubbing = (0, react_1.useCallback)((e) => {
231
- stopInterval();
202
+ var _a;
203
+ (_a = autoScroller.current) === null || _a === void 0 ? void 0 : _a.stop();
232
204
  document.body.style.userSelect = '';
233
205
  document.body.style.webkitUserSelect = '';
234
206
  if (!videoConfig) {
@@ -259,7 +231,8 @@ const TimelineDragHandlerInner = () => {
259
231
  }
260
232
  }, [dragging, left, play, videoConfig, setFrame, width]);
261
233
  const onPointerCancelScrubbing = (0, react_1.useCallback)(() => {
262
- stopInterval();
234
+ var _a;
235
+ (_a = autoScroller.current) === null || _a === void 0 ? void 0 : _a.stop();
263
236
  document.body.style.userSelect = '';
264
237
  document.body.style.webkitUserSelect = '';
265
238
  if (!dragging.dragging) {
@@ -274,7 +247,12 @@ const TimelineDragHandlerInner = () => {
274
247
  if (!dragging.dragging) {
275
248
  return;
276
249
  }
277
- return (0, pointer_session_1.startCapturedPointerSession)({
250
+ const scroller = (0, timeline_scroll_logic_1.startTimelineEdgeAutoScroll)({
251
+ includeVertical: false,
252
+ onTick: onEdgeScrollTick,
253
+ });
254
+ autoScroller.current = scroller;
255
+ const endSession = (0, pointer_session_1.startCapturedPointerSession)({
278
256
  event: dragging,
279
257
  captureTarget: dragging.target,
280
258
  onMove: onPointerMoveScrubbing,
@@ -288,8 +266,16 @@ const TimelineDragHandlerInner = () => {
288
266
  }
289
267
  },
290
268
  });
269
+ return () => {
270
+ scroller.stop();
271
+ if (autoScroller.current === scroller) {
272
+ autoScroller.current = null;
273
+ }
274
+ endSession();
275
+ };
291
276
  }, [
292
277
  dragging,
278
+ onEdgeScrollTick,
293
279
  onPointerCancelScrubbing,
294
280
  onPointerMoveScrubbing,
295
281
  onPointerUpScrubbing,