@remotion/studio 4.0.518 → 4.0.520

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 (196) hide show
  1. package/dist/api/visual-control.js +2 -2
  2. package/dist/components/AppLaunchButton.d.ts +16 -0
  3. package/dist/components/AppLaunchButton.js +90 -0
  4. package/dist/components/AssetSelector.js +7 -6
  5. package/dist/components/AssetSelectorItem.d.ts +12 -0
  6. package/dist/components/AssetSelectorItem.js +180 -62
  7. package/dist/components/AudioWaveform.js +6 -1
  8. package/dist/components/Button.js +20 -7
  9. package/dist/components/Canvas.js +117 -92
  10. package/dist/components/CanvasOrLoading.js +7 -7
  11. package/dist/components/CodingAgentButton.d.ts +7 -0
  12. package/dist/components/CodingAgentButton.js +59 -0
  13. package/dist/components/CompositionContextButton.d.ts +1 -0
  14. package/dist/components/CompositionContextButton.js +6 -3
  15. package/dist/components/CompositionSelector.js +21 -20
  16. package/dist/components/CompositionSelectorItem.js +23 -35
  17. package/dist/components/ConfigureLicenseModal.js +4 -48
  18. package/dist/components/CurrentAsset.js +1 -1
  19. package/dist/components/CurrentCompositionSideEffects.js +5 -0
  20. package/dist/components/ElementInstallConfirmation.d.ts +2 -10
  21. package/dist/components/ElementInstallConfirmation.js +339 -32
  22. package/dist/components/FixComputedValueModal.js +5 -131
  23. package/dist/components/FpsCounter.js +1 -1
  24. package/dist/components/FramePersistor.js +1 -1
  25. package/dist/components/InitialCompositionLoader.js +3 -2
  26. package/dist/components/InspectorOpenInEditor.js +48 -33
  27. package/dist/components/InspectorPanel/CompositionInspector.js +35 -3
  28. package/dist/components/InspectorPanel/CompositionInspectorHeader.js +22 -14
  29. package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +3 -1
  30. package/dist/components/InspectorPanel/SequenceInspectorHeader.d.ts +1 -1
  31. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +10 -5
  32. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +5 -4
  33. package/dist/components/InspectorPanel/common.js +1 -0
  34. package/dist/components/InspectorPanel/styles.js +1 -0
  35. package/dist/components/InspectorPanel/use-composition-actions.js +5 -8
  36. package/dist/components/InspectorSequenceSection.js +8 -3
  37. package/dist/components/InspectorSourceLocation.js +5 -1
  38. package/dist/components/KnownBugs.d.ts +1 -1
  39. package/dist/components/KnownBugs.js +1 -1
  40. package/dist/components/LicenseExplanation.d.ts +2 -0
  41. package/dist/components/LicenseExplanation.js +63 -0
  42. package/dist/components/MenuToolbar.js +7 -1
  43. package/dist/components/Modals.js +1 -2
  44. package/dist/components/NewComposition/InputDragger.js +29 -2
  45. package/dist/components/NewComposition/NewCompDuration.js +1 -1
  46. package/dist/components/NewComposition/NewComposition.d.ts +23 -0
  47. package/dist/components/NewComposition/NewComposition.js +217 -80
  48. package/dist/components/{UpdateModal/OpenIssueButton.js → OpenIssueButton.js} +1 -1
  49. package/dist/components/PlayPause.js +2 -13
  50. package/dist/components/PreviewToolbar.js +1 -1
  51. package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.js +2 -1
  52. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +50 -28
  53. package/dist/components/QuickSwitcher/QuickSwitcherResult.d.ts +14 -1
  54. package/dist/components/QuickSwitcher/QuickSwitcherResult.js +64 -9
  55. package/dist/components/QuickSwitcher/composition-search.d.ts +16 -0
  56. package/dist/components/QuickSwitcher/composition-search.js +136 -0
  57. package/dist/components/RenderQueue/actions.d.ts +1 -0
  58. package/dist/components/RenderQueue/actions.js +5 -1
  59. package/dist/components/ResetZoomButton.js +17 -2
  60. package/dist/components/SelectedOutlineCanvasRotation.js +27 -1
  61. package/dist/components/SelectedOutlineElement.js +12 -31
  62. package/dist/components/SelectedOutlineKeyboardControls.d.ts +2 -2
  63. package/dist/components/SelectedOutlineOverlay.d.ts +3 -1
  64. package/dist/components/SelectedOutlineOverlay.js +21 -26
  65. package/dist/components/SelectedOutlinePolygon.d.ts +1 -0
  66. package/dist/components/SelectedOutlinePolygon.js +12 -4
  67. package/dist/components/SelectedOutlineRenderer.js +88 -21
  68. package/dist/components/SettingsContext.js +2 -1
  69. package/dist/components/SettingsModal.d.ts +1 -1
  70. package/dist/components/SettingsModal.js +19 -3
  71. package/dist/components/SidebarRenderButton.d.ts +1 -0
  72. package/dist/components/SidebarRenderButton.js +14 -5
  73. package/dist/components/Timeline/SequencePropsObserver.js +29 -14
  74. package/dist/components/Timeline/Timeline.js +2 -1
  75. package/dist/components/Timeline/TimelineAssetField.js +1 -0
  76. package/dist/components/Timeline/TimelineDeleteKeybindings.js +5 -90
  77. package/dist/components/Timeline/TimelineDragHandler.js +18 -8
  78. package/dist/components/Timeline/TimelineInOutDragHandler.js +2 -3
  79. package/dist/components/Timeline/TimelineKeyframeControls.js +3 -1
  80. package/dist/components/Timeline/TimelinePinchZoom.js +14 -4
  81. package/dist/components/Timeline/TimelinePlayCursorSyncer.js +8 -4
  82. package/dist/components/Timeline/TimelineRowChrome.js +4 -2
  83. package/dist/components/Timeline/TimelineSequence.js +52 -45
  84. package/dist/components/Timeline/TimelineSequenceItem.js +44 -32
  85. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +3 -3
  86. package/dist/components/Timeline/TimelineSlider.js +2 -2
  87. package/dist/components/Timeline/TimelineStack/get-stack.d.ts +1 -0
  88. package/dist/components/Timeline/TimelineStack/get-stack.js +35 -3
  89. package/dist/components/Timeline/TimelineWidthProvider.js +15 -8
  90. package/dist/components/Timeline/TimelineZoomControls.js +25 -8
  91. package/dist/components/Timeline/delete-selected-timeline-item.js +2 -2
  92. package/dist/components/Timeline/duplicate-selected-timeline-item.js +23 -25
  93. package/dist/components/Timeline/get-sequence-context-menu-items.d.ts +6 -0
  94. package/dist/components/Timeline/get-sequence-context-menu-items.js +34 -1
  95. package/dist/components/Timeline/sequence-props-subscription-store.d.ts +2 -0
  96. package/dist/components/Timeline/sequence-props-subscription-store.js +22 -1
  97. package/dist/components/Timeline/timeline-scroll-logic.d.ts +1 -0
  98. package/dist/components/Timeline/timeline-scroll-logic.js +21 -17
  99. package/dist/components/Timeline/use-delete-timeline-items.d.ts +1 -0
  100. package/dist/components/Timeline/use-delete-timeline-items.js +118 -0
  101. package/dist/components/Timeline/use-sequence-props-subscription.js +7 -0
  102. package/dist/components/Timeline/use-timeline-asset-drop.js +8 -14
  103. package/dist/components/TimelineCombobox.js +1 -0
  104. package/dist/components/UpdateCheck.d.ts +0 -8
  105. package/dist/components/UpdateCheck.js +7 -54
  106. package/dist/components/UpdateStatusContext.d.ts +18 -0
  107. package/dist/components/UpdateStatusContext.js +74 -0
  108. package/dist/components/UpdatesSettings.d.ts +2 -0
  109. package/dist/components/UpdatesSettings.js +251 -0
  110. package/dist/components/WebMcp.js +64 -11
  111. package/dist/components/ZoomPersistor.js +2 -2
  112. package/dist/components/composition-drag-data.d.ts +36 -0
  113. package/dist/components/composition-drag-data.js +232 -0
  114. package/dist/components/drop-handler-data.d.ts +2 -1
  115. package/dist/components/drop-handler-data.js +6 -4
  116. package/dist/components/effect-drag-and-drop.d.ts +2 -5
  117. package/dist/components/get-open-in-menu-items.d.ts +4 -0
  118. package/dist/components/get-open-in-menu-items.js +28 -24
  119. package/dist/components/handle-drop.js +6 -2
  120. package/dist/components/import-assets.d.ts +5 -13
  121. package/dist/components/root-composition-menu-items.d.ts +4 -1
  122. package/dist/components/root-composition-menu-items.js +38 -1
  123. package/dist/components/selected-outline-geometry.d.ts +21 -2
  124. package/dist/components/selected-outline-geometry.js +16 -5
  125. package/dist/components/selected-outline-measurement.d.ts +40 -1
  126. package/dist/components/selected-outline-measurement.js +239 -1
  127. package/dist/components/selected-outline-order.d.ts +12 -0
  128. package/dist/components/selected-outline-order.js +251 -0
  129. package/dist/components/selected-outline-types.d.ts +15 -2
  130. package/dist/components/selected-outline-uv.js +106 -3
  131. package/dist/components/use-configure-default-apps.d.ts +1 -0
  132. package/dist/components/use-configure-default-apps.js +24 -0
  133. package/dist/error-overlay/current-error.d.ts +13 -0
  134. package/dist/error-overlay/current-error.js +21 -0
  135. package/dist/error-overlay/remotion-overlay/CodeFrame.js +5 -6
  136. package/dist/error-overlay/remotion-overlay/CopyStackTrace.js +1 -1
  137. package/dist/error-overlay/remotion-overlay/ErrorDisplay.js +47 -18
  138. package/dist/error-overlay/remotion-overlay/ErrorLoader.js +6 -2
  139. package/dist/error-overlay/remotion-overlay/ErrorTitle.js +5 -4
  140. package/dist/error-overlay/remotion-overlay/OpenInEditor.js +48 -76
  141. package/dist/error-overlay/remotion-overlay/SearchGitHubIssues.js +1 -1
  142. package/dist/error-overlay/remotion-overlay/ShortcutHint.js +2 -2
  143. package/dist/error-overlay/remotion-overlay/StackFrame.js +13 -8
  144. package/dist/error-overlay/remotion-overlay/Symbolicating.js +1 -1
  145. package/dist/esm/chunk-6jf1natv.js +25 -0
  146. package/dist/esm/{chunk-4bxz1d3g.js → chunk-je0h1bgt.js} +1 -28
  147. package/dist/esm/chunk-m0jqdbkr.js +14571 -0
  148. package/dist/esm/{chunk-7prjt5n5.js → chunk-np6q13k5.js} +18637 -12189
  149. package/dist/esm/index.mjs +4 -3
  150. package/dist/esm/internals.mjs +35826 -14822
  151. package/dist/esm/previewEntry.mjs +40028 -18935
  152. package/dist/esm/renderEntry.mjs +6 -3
  153. package/dist/helpers/can-show-updates.d.ts +5 -0
  154. package/dist/helpers/can-show-updates.js +7 -0
  155. package/dist/helpers/colors.d.ts +0 -3
  156. package/dist/helpers/colors.js +2 -5
  157. package/dist/helpers/create-folder-tree.d.ts +5 -0
  158. package/dist/helpers/create-folder-tree.js +26 -6
  159. package/dist/helpers/document-title.d.ts +2 -0
  160. package/dist/helpers/document-title.js +14 -3
  161. package/dist/helpers/get-asset-metadata.js +1 -1
  162. package/dist/helpers/get-box-quads-polyfill-internals.d.ts +82 -0
  163. package/dist/helpers/get-box-quads-polyfill-internals.js +2403 -0
  164. package/dist/helpers/get-box-quads-ponyfill.d.ts +10 -0
  165. package/dist/helpers/get-box-quads-ponyfill.js +23 -0
  166. package/dist/helpers/get-git-menu-item.d.ts +5 -0
  167. package/dist/helpers/get-git-menu-item.js +15 -1
  168. package/dist/helpers/get-timeline-max-zoom.d.ts +34 -28
  169. package/dist/helpers/get-timeline-max-zoom.js +46 -29
  170. package/dist/helpers/hoverable.js +10 -5
  171. package/dist/helpers/install-fiber-sequence-order-observer.d.ts +37 -0
  172. package/dist/helpers/install-fiber-sequence-order-observer.js +109 -0
  173. package/dist/helpers/open-in-editor.js +53 -2
  174. package/dist/helpers/preview-server-events.js +3 -0
  175. package/dist/helpers/timeline-layout.d.ts +0 -1
  176. package/dist/helpers/timeline-layout.js +1 -5
  177. package/dist/helpers/url-state.d.ts +1 -0
  178. package/dist/helpers/url-state.js +12 -5
  179. package/dist/helpers/use-runtime-values.d.ts +1 -1
  180. package/dist/helpers/use-runtime-values.js +5 -4
  181. package/dist/helpers/use-sync-external-store.d.ts +3 -0
  182. package/dist/helpers/use-sync-external-store.js +5 -0
  183. package/dist/previewEntry.js +2 -0
  184. package/dist/renderEntry.js +2 -0
  185. package/dist/state/folders.d.ts +3 -0
  186. package/dist/state/folders.js +40 -1
  187. package/dist/state/modals.d.ts +19 -8
  188. package/dist/state/timeline-sequence-hover.js +3 -2
  189. package/dist/state/timeline-zoom.d.ts +0 -1
  190. package/dist/state/timeline-zoom.js +13 -6
  191. package/package.json +18 -15
  192. package/dist/components/UpdateModal/UpdateModal.d.ts +0 -6
  193. package/dist/components/UpdateModal/UpdateModal.js +0 -104
  194. package/dist/helpers/sort-by-nonce-history.d.ts +0 -1
  195. package/dist/helpers/sort-by-nonce-history.js +0 -6
  196. /package/dist/components/{UpdateModal/OpenIssueButton.d.ts → OpenIssueButton.d.ts} +0 -0
@@ -45,7 +45,6 @@ const open_in_editor_1 = require("../helpers/open-in-editor");
45
45
  const modals_1 = require("../state/modals");
46
46
  const transform_3d_mode_1 = require("../state/transform-3d-mode");
47
47
  const ConfirmationDialog_1 = require("./ConfirmationDialog");
48
- const delete_jsx_node_api_1 = require("./delete-jsx-node-api");
49
48
  const InitialCompositionLoader_1 = require("./InitialCompositionLoader");
50
49
  const NotificationCenter_1 = require("./Notifications/NotificationCenter");
51
50
  const selected_outline_types_1 = require("./selected-outline-types");
@@ -57,6 +56,7 @@ const get_sequence_context_menu_items_1 = require("./Timeline/get-sequence-conte
57
56
  const timeline_asset_link_1 = require("./Timeline/timeline-asset-link");
58
57
  const TimelineSelection_1 = require("./Timeline/TimelineSelection");
59
58
  const get_stack_1 = require("./Timeline/TimelineStack/get-stack");
59
+ const use_delete_timeline_items_1 = require("./Timeline/use-delete-timeline-items");
60
60
  const use_default_editor_info_1 = require("./use-default-editor-info");
61
61
  const use_select_asset_1 = require("./use-select-asset");
62
62
  const use_selected_outline_control_target_1 = require("./use-selected-outline-control-target");
@@ -68,6 +68,7 @@ const SelectedOutlineElementUnmemoized = ({ compositionHeight, compositionWidth,
68
68
  const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
69
69
  const updateResolvedStackTrace = (0, react_1.useContext)(remotion_1.Internals.SequenceStackTracesUpdateContext);
70
70
  const confirm = (0, ConfirmationDialog_1.useConfirmationDialog)();
71
+ const deleteTimelineItems = (0, use_delete_timeline_items_1.useDeleteTimelineItems)();
71
72
  const selectAsset = (0, use_select_asset_1.useSelectAsset)();
72
73
  const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
73
74
  const { compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
@@ -180,38 +181,16 @@ const SelectedOutlineElementUnmemoized = ({ compositionHeight, compositionWidth,
180
181
  });
181
182
  }
182
183
  : null,
183
- onDeleteSequenceFromSource: async () => {
184
+ onDeleteSequenceFromSource: () => {
184
185
  if (sourceEditDisabled || previewServerState.type !== 'connected') {
185
186
  return;
186
187
  }
187
- if (contextMenuTarget.nodePathInfo.numberOfSequencesWithThisNodePath > 1) {
188
- const shouldDelete = await confirm({
189
- title: 'Delete sequence?',
190
- message: 'This sequence is programmatically duplicated ' +
191
- contextMenuTarget.nodePathInfo.numberOfSequencesWithThisNodePath +
192
- ' times in the code. Deleting removes all instances. Continue?',
193
- confirmLabel: 'Delete',
194
- });
195
- if (!shouldDelete) {
196
- return;
197
- }
198
- }
199
- try {
200
- const result = await (0, delete_jsx_node_api_1.deleteJsxNode)({
201
- nodes: [
202
- {
203
- fileName: nodePath.absolutePath,
204
- nodePath: nodePath.nodePath,
205
- },
206
- ],
207
- });
208
- if (!result.success) {
209
- (0, NotificationCenter_1.showNotification)(result.reason, 4000);
210
- }
211
- }
212
- catch (err) {
213
- (0, NotificationCenter_1.showNotification)(err.message, 4000);
214
- }
188
+ deleteTimelineItems([
189
+ {
190
+ type: 'sequence',
191
+ nodePathInfo: contextMenuTarget.nodePathInfo,
192
+ },
193
+ ]);
215
194
  },
216
195
  onDisableSequenceInteractivity: () => {
217
196
  if (disableInteractivityDisabled ||
@@ -343,6 +322,7 @@ const SelectedOutlineElementUnmemoized = ({ compositionHeight, compositionWidth,
343
322
  canConfigureApps,
344
323
  codingAgentInfo,
345
324
  confirm,
325
+ deleteTimelineItems,
346
326
  editorInfo,
347
327
  getTarget,
348
328
  onSelect,
@@ -362,6 +342,7 @@ const SelectedOutlineElementUnmemoized = ({ compositionHeight, compositionWidth,
362
342
  };
363
343
  }, [onContextMenuOpen, outline.key, registerContextMenuOpen]);
364
344
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
365
- jsx_runtime_1.jsx(SelectedOutlinePolygon_1.SelectedOutlinePolygon, { compositionHeight: compositionHeight, compositionWidth: compositionWidth, containsSelection: (layoutTarget === null || layoutTarget === void 0 ? void 0 : layoutTarget.containsSelection) === true, directlySelected: (layoutTarget === null || layoutTarget === void 0 ? void 0 : layoutTarget.selected) === true, dragging: dragging, getAllDragOutlines: getAllDragOutlines, getAllDragTargets: getAllDragTargets, getLayoutTarget: getLayoutTarget, getTarget: getTarget, hasTarget: layoutTarget !== undefined, hovered: hovered, outline: outline, onDraggingChange: onDraggingChange, onHoverChange: onHoverChange, onSnapPointsChange: onSnapPointsChange, onSelect: onSelect, onDoubleClickTarget: onDoubleClickTarget, scale: scale, showSelectedOutline: (_a = layoutTarget === null || layoutTarget === void 0 ? void 0 : layoutTarget.showSelectedOutline) !== null && _a !== void 0 ? _a : false }), (layoutTarget === null || layoutTarget === void 0 ? void 0 : layoutTarget.selectedForRotation) && (controlTarget === null || controlTarget === void 0 ? void 0 : controlTarget.rotationDrag) ? (jsx_runtime_1.jsx(SelectedOutlineCanvasRotation_1.SelectedOutlineCanvasRotation, { getLatestTargetByKey: getLatestTargetByKey, layoutTarget: layoutTarget, onDraggingChange: onDraggingChange, outline: outline, transform3DMode: controlTarget.rotationDrag.transform3DMode })) : null] }));
345
+ jsx_runtime_1.jsx(SelectedOutlinePolygon_1.SelectedOutlinePolygon, { compositionHeight: compositionHeight, compositionWidth: compositionWidth, containsSelection: (layoutTarget === null || layoutTarget === void 0 ? void 0 : layoutTarget.containsSelection) === true, directlySelected: (layoutTarget === null || layoutTarget === void 0 ? void 0 : layoutTarget.selected) === true, dragging: dragging, getAllDragOutlines: getAllDragOutlines, getAllDragTargets: getAllDragTargets, getLayoutTarget: getLayoutTarget, getTarget: getTarget, hasTarget: layoutTarget !== undefined, hovered: hovered, outline: outline, onDraggingChange: onDraggingChange, onHoverChange: onHoverChange, onSnapPointsChange: onSnapPointsChange, onSelect: onSelect, onDoubleClickTarget: onDoubleClickTarget, scale: scale, showSelectedOutline: (_a = layoutTarget === null || layoutTarget === void 0 ? void 0 : layoutTarget.showSelectedOutline) !== null && _a !== void 0 ? _a : false, translateWithCommandKey: (layoutTarget === null || layoutTarget === void 0 ? void 0 : layoutTarget.selectedForRotation) === true &&
346
+ Boolean(controlTarget === null || controlTarget === void 0 ? void 0 : controlTarget.rotationDrag) }), (layoutTarget === null || layoutTarget === void 0 ? void 0 : layoutTarget.selectedForRotation) && (controlTarget === null || controlTarget === void 0 ? void 0 : controlTarget.rotationDrag) ? (jsx_runtime_1.jsx(SelectedOutlineCanvasRotation_1.SelectedOutlineCanvasRotation, { getLatestTargetByKey: getLatestTargetByKey, layoutTarget: layoutTarget, onDraggingChange: onDraggingChange, outline: outline, transform3DMode: controlTarget.rotationDrag.transform3DMode })) : null] }));
366
347
  };
367
348
  exports.SelectedOutlineElement = react_1.default.memo(SelectedOutlineElementUnmemoized);
@@ -1,7 +1,7 @@
1
- import type { CanvasSelectableOutline } from '@remotion/canvas';
2
1
  import type React from 'react';
2
+ import type { getSequencesWithSelectableOutlines } from './selected-outline-measurement';
3
3
  import { type SelectedOutlineTarget } from './selected-outline-types';
4
4
  export declare const SelectedOutlineKeyboardControls: React.FC<{
5
5
  readonly getLatestOutlineTargetByKey: (key: string) => SelectedOutlineTarget | undefined;
6
- readonly getSelectableOutlines: () => readonly CanvasSelectableOutline[];
6
+ readonly getSelectableOutlines: () => ReturnType<typeof getSequencesWithSelectableOutlines>;
7
7
  }>;
@@ -1,6 +1,8 @@
1
1
  import React from 'react';
2
+ import { orderOutlinesForRendering } from './selected-outline-order';
3
+ export { orderOutlinesForRendering };
2
4
  export { applySelectedOutlineDragAxisLock, applySelectedOutlineTransformOriginAxisLock, compensateTranslateForTransformOrigin, getSelectedOutline3DRotationDragValues, getSelectedOutlineActiveSchema, getSelectedOutlineCropDragChanges, getSelectedOutlineCropDragValues, getSelectedOutlineCropFollowingTransformOrigin, getSelectedOutlineDragChanges, getSelectedOutlineDragValues, getSelectedOutlineKeyboardNudgeDelta, getSelectedOutlineKeyboardNudgeDeltas, getSelectedOutlineRotationDragChanges, getSelectedOutlineRotationDragStates, getSelectedOutlineRotationDragValues, getSelectedOutlineScaleDragChanges, getSelectedOutlineScaleDragStates, getSelectedOutlineScaleDragValues, getSelectedOutlineScaleEdgeInfo, getSelectedOutlineTransformOriginDragChanges, getSelectedOutlineTransformOriginLockedAxis, isSelectedOutlineDragPastThreshold, selectedOutlineTransformOriginSnapThresholdPx, selectedOutlineUvSnapThresholdPx, snapSelectedOutlineRotationDeltaDegrees, snapSelectedOutlineTransformOriginUv, snapSelectedOutlineUv, } from './selected-outline-drag';
3
- export { getOutlineSelectionInteraction, getSelectedCropInfo, getSelectedEffectFieldsBySequenceKey, getSelectedOutlineRotationCornerInfo, getSelectedOutlineRotationDeltaDegrees, getSelectedOutlineRotationPivot, getSelectedSequenceKeys, } from './selected-outline-measurement';
5
+ export { getOutlineSelectionInteraction, getSelectedCropInfo, getSelectedEffectFieldsBySequenceKey, getSelectedOutlineRotationCornerInfo, getSelectedOutlineRotationDeltaDegrees, getSelectedOutlineRotationPivot, getSelectedSequenceKeys, getSequencesWithSelectableOutlines, getTransformedSvgViewportPoints, } from './selected-outline-measurement';
4
6
  export { selectedOutlineDragThresholdPx } from './selected-outline-types';
5
7
  export type { SelectedOutlineDragState, SelectedOutlineRotationDragState, SelectedOutlineScaleDragState, } from './selected-outline-types';
6
8
  type SelectedOutlineOverlayProps = {
@@ -33,9 +33,8 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.SelectedOutlineOverlay = exports.selectedOutlineDragThresholdPx = exports.getSelectedSequenceKeys = exports.getSelectedOutlineRotationPivot = exports.getSelectedOutlineRotationDeltaDegrees = exports.getSelectedOutlineRotationCornerInfo = exports.getSelectedEffectFieldsBySequenceKey = exports.getSelectedCropInfo = exports.getOutlineSelectionInteraction = exports.snapSelectedOutlineUv = exports.snapSelectedOutlineTransformOriginUv = exports.snapSelectedOutlineRotationDeltaDegrees = exports.selectedOutlineUvSnapThresholdPx = exports.selectedOutlineTransformOriginSnapThresholdPx = exports.isSelectedOutlineDragPastThreshold = exports.getSelectedOutlineTransformOriginLockedAxis = exports.getSelectedOutlineTransformOriginDragChanges = exports.getSelectedOutlineScaleEdgeInfo = exports.getSelectedOutlineScaleDragValues = exports.getSelectedOutlineScaleDragStates = exports.getSelectedOutlineScaleDragChanges = exports.getSelectedOutlineRotationDragValues = exports.getSelectedOutlineRotationDragStates = exports.getSelectedOutlineRotationDragChanges = exports.getSelectedOutlineKeyboardNudgeDeltas = exports.getSelectedOutlineKeyboardNudgeDelta = exports.getSelectedOutlineDragValues = exports.getSelectedOutlineDragChanges = exports.getSelectedOutlineCropFollowingTransformOrigin = exports.getSelectedOutlineCropDragValues = exports.getSelectedOutlineCropDragChanges = exports.getSelectedOutlineActiveSchema = exports.getSelectedOutline3DRotationDragValues = exports.compensateTranslateForTransformOrigin = exports.applySelectedOutlineTransformOriginAxisLock = exports.applySelectedOutlineDragAxisLock = void 0;
36
+ exports.SelectedOutlineOverlay = exports.selectedOutlineDragThresholdPx = exports.getTransformedSvgViewportPoints = exports.getSequencesWithSelectableOutlines = exports.getSelectedSequenceKeys = exports.getSelectedOutlineRotationPivot = exports.getSelectedOutlineRotationDeltaDegrees = exports.getSelectedOutlineRotationCornerInfo = exports.getSelectedEffectFieldsBySequenceKey = exports.getSelectedCropInfo = exports.getOutlineSelectionInteraction = exports.snapSelectedOutlineUv = exports.snapSelectedOutlineTransformOriginUv = exports.snapSelectedOutlineRotationDeltaDegrees = exports.selectedOutlineUvSnapThresholdPx = exports.selectedOutlineTransformOriginSnapThresholdPx = exports.isSelectedOutlineDragPastThreshold = exports.getSelectedOutlineTransformOriginLockedAxis = exports.getSelectedOutlineTransformOriginDragChanges = exports.getSelectedOutlineScaleEdgeInfo = exports.getSelectedOutlineScaleDragValues = exports.getSelectedOutlineScaleDragStates = exports.getSelectedOutlineScaleDragChanges = exports.getSelectedOutlineRotationDragValues = exports.getSelectedOutlineRotationDragStates = exports.getSelectedOutlineRotationDragChanges = exports.getSelectedOutlineKeyboardNudgeDeltas = exports.getSelectedOutlineKeyboardNudgeDelta = exports.getSelectedOutlineDragValues = exports.getSelectedOutlineDragChanges = exports.getSelectedOutlineCropFollowingTransformOrigin = exports.getSelectedOutlineCropDragValues = exports.getSelectedOutlineCropDragChanges = exports.getSelectedOutlineActiveSchema = exports.getSelectedOutline3DRotationDragValues = exports.compensateTranslateForTransformOrigin = exports.applySelectedOutlineTransformOriginAxisLock = exports.applySelectedOutlineDragAxisLock = exports.orderOutlinesForRendering = void 0;
37
37
  const jsx_runtime_1 = require("react/jsx-runtime");
38
- const canvas_1 = require("@remotion/canvas");
39
38
  const player_1 = require("@remotion/player");
40
39
  const react_1 = __importStar(require("react"));
41
40
  const remotion_1 = require("remotion");
@@ -51,6 +50,8 @@ const timeline_sequence_hover_1 = require("../state/timeline-sequence-hover");
51
50
  const transform_3d_mode_1 = require("../state/transform-3d-mode");
52
51
  const selected_outline_drag_1 = require("./selected-outline-drag");
53
52
  const selected_outline_measurement_1 = require("./selected-outline-measurement");
53
+ const selected_outline_order_1 = require("./selected-outline-order");
54
+ Object.defineProperty(exports, "orderOutlinesForRendering", { enumerable: true, get: function () { return selected_outline_order_1.orderOutlinesForRendering; } });
54
55
  const selected_outline_types_1 = require("./selected-outline-types");
55
56
  const SelectedOutlineKeyboardControls_1 = require("./SelectedOutlineKeyboardControls");
56
57
  const SelectedOutlineRenderer_1 = require("./SelectedOutlineRenderer");
@@ -93,6 +94,8 @@ Object.defineProperty(exports, "getSelectedOutlineRotationCornerInfo", { enumera
93
94
  Object.defineProperty(exports, "getSelectedOutlineRotationDeltaDegrees", { enumerable: true, get: function () { return selected_outline_measurement_2.getSelectedOutlineRotationDeltaDegrees; } });
94
95
  Object.defineProperty(exports, "getSelectedOutlineRotationPivot", { enumerable: true, get: function () { return selected_outline_measurement_2.getSelectedOutlineRotationPivot; } });
95
96
  Object.defineProperty(exports, "getSelectedSequenceKeys", { enumerable: true, get: function () { return selected_outline_measurement_2.getSelectedSequenceKeys; } });
97
+ Object.defineProperty(exports, "getSequencesWithSelectableOutlines", { enumerable: true, get: function () { return selected_outline_measurement_2.getSequencesWithSelectableOutlines; } });
98
+ Object.defineProperty(exports, "getTransformedSvgViewportPoints", { enumerable: true, get: function () { return selected_outline_measurement_2.getTransformedSvgViewportPoints; } });
96
99
  const selected_outline_types_2 = require("./selected-outline-types");
97
100
  Object.defineProperty(exports, "selectedOutlineDragThresholdPx", { enumerable: true, get: function () { return selected_outline_types_2.selectedOutlineDragThresholdPx; } });
98
101
  const getEffectiveCropValue = ({ activeSchema, dragOverrides, fieldKey, frame, propStatuses, runtimeValues, }) => {
@@ -260,7 +263,6 @@ const calculateOutlineTargets = ({ connectedClientId, editorShowOutlines, getDra
260
263
  key,
261
264
  containsSelection,
262
265
  crop,
263
- includeOutsideContainer: showSelectedOutline,
264
266
  keyframeDisplayOffset: nodeKeyframeDisplayOffset,
265
267
  nodePathInfo,
266
268
  ref: sequence.refForOutline,
@@ -531,30 +533,21 @@ const ActiveSelectedOutlineOverlayUnmemoized = ({ calculateOutlineTargetsForCurr
531
533
  controls.runtimeValues,
532
534
  outlineRuntimeSnapshots[index],
533
535
  ])), [outlineRuntimeControls, outlineRuntimeSnapshots]);
534
- const outlineTargets = (0, react_1.useMemo)(() => {
535
- const targets = calculateOutlineTargetsForCurrentState({
536
- mode: 'layout',
537
- runtimeValuesByStore: outlineRuntimeValuesByStore,
538
- selectableOutlines: selectableOutlinesForLayout,
539
- targetKey: null,
540
- targetTimelinePosition: timelinePosition,
541
- });
542
- return targets.map((target) => {
543
- const hovered = (0, timeline_node_path_key_1.timelineSequenceNodePathToKey)(target.nodePathInfo.sequenceSubscriptionKey) === hoveredTimelineNodePathKey;
544
- return hovered && !target.includeOutsideContainer
545
- ? { ...target, includeOutsideContainer: true }
546
- : target;
547
- });
548
- }, [
536
+ const outlineTargets = (0, react_1.useMemo)(() => calculateOutlineTargetsForCurrentState({
537
+ mode: 'layout',
538
+ runtimeValuesByStore: outlineRuntimeValuesByStore,
539
+ selectableOutlines: selectableOutlinesForLayout,
540
+ targetKey: null,
541
+ targetTimelinePosition: timelinePosition,
542
+ }), [
549
543
  calculateOutlineTargetsForCurrentState,
550
- hoveredTimelineNodePathKey,
551
544
  outlineRuntimeValuesByStore,
552
545
  selectableOutlinesForLayout,
553
546
  timelinePosition,
554
547
  ]);
555
548
  (0, react_1.useLayoutEffect)(() => {
556
549
  updateOutlinesRef.current();
557
- }, [outlineTargets, scale, translationX, translationY]);
550
+ }, [scale, translationX, translationY]);
558
551
  return (jsx_runtime_1.jsx(SelectedOutlineRenderer_1.SelectedOutlineRenderer, { compositionHeight: compositionHeight, compositionWidth: compositionWidth, dragging: draggingOutline, getLatestOutlineTargetByKey: getLatestOutlineTargetByKey, outlineTargets: outlineTargets, onDraggingChange: onDraggingChange, onContextMenuOpenChange: onContextMenuOpenChange, onSelect: onSelect, scale: scale, sequences: sequences, updateOutlinesRef: updateOutlinesRef }));
559
552
  };
560
553
  const ActiveSelectedOutlineOverlay = react_1.default.memo(ActiveSelectedOutlineOverlayUnmemoized);
@@ -589,7 +582,7 @@ const SelectedOutlineOverlayUnmemoized = ({ canvasHovered, compositionHeight, co
589
582
  !editorShowOutlines) {
590
583
  return [];
591
584
  }
592
- return (0, canvas_1.getCanvasSelectableOutlines)({
585
+ return (0, selected_outline_measurement_1.getSequencesWithSelectableOutlines)({
593
586
  sequences,
594
587
  overrideIdsToNodePaths: overrideIdToNodePathMappings,
595
588
  compositions,
@@ -638,13 +631,11 @@ const SelectedOutlineOverlayUnmemoized = ({ canvasHovered, compositionHeight, co
638
631
  selectedTransformOriginInfo,
639
632
  sequenceKeysContainingSelection,
640
633
  ]);
641
- const calculateOutlineTargetsRef = (0, react_1.useRef)(calculateOutlineTargetsForCurrentState);
642
634
  const getSelectableOutlinesRef = (0, react_1.useRef)(getSelectableOutlines);
643
635
  const selectableOutlinesCacheRef = (0, react_1.useRef)(null);
644
636
  (0, react_1.useLayoutEffect)(() => {
645
- calculateOutlineTargetsRef.current = calculateOutlineTargetsForCurrentState;
646
637
  getSelectableOutlinesRef.current = getSelectableOutlines;
647
- }, [calculateOutlineTargetsForCurrentState, getSelectableOutlines]);
638
+ }, [getSelectableOutlines]);
648
639
  const getSelectableOutlinesAtFrame = (0, react_1.useCallback)((timelinePosition) => {
649
640
  const currentGetSelectableOutlines = getSelectableOutlinesRef.current;
650
641
  const cached = selectableOutlinesCacheRef.current;
@@ -662,7 +653,7 @@ const SelectedOutlineOverlayUnmemoized = ({ canvasHovered, compositionHeight, co
662
653
  }, []);
663
654
  const getLatestOutlineTargetByKey = (0, react_1.useCallback)((key) => {
664
655
  const timelinePosition = getCurrentFrame();
665
- const target = calculateOutlineTargetsRef.current({
656
+ const target = calculateOutlineTargetsForCurrentState({
666
657
  mode: 'controls',
667
658
  runtimeValuesByStore: new Map(),
668
659
  selectableOutlines: getSelectableOutlinesAtFrame(timelinePosition),
@@ -670,7 +661,11 @@ const SelectedOutlineOverlayUnmemoized = ({ canvasHovered, compositionHeight, co
670
661
  targetTimelinePosition: timelinePosition,
671
662
  })[0];
672
663
  return target;
673
- }, [getCurrentFrame, getSelectableOutlinesAtFrame]);
664
+ }, [
665
+ calculateOutlineTargetsForCurrentState,
666
+ getCurrentFrame,
667
+ getSelectableOutlinesAtFrame,
668
+ ]);
674
669
  const getCurrentSelectableOutlines = (0, react_1.useCallback)(() => getSelectableOutlinesAtFrame(getCurrentFrame()), [getCurrentFrame, getSelectableOutlinesAtFrame]);
675
670
  const onDraggingChange = (0, react_1.useCallback)((dragging) => {
676
671
  setDraggingOutline(dragging);
@@ -23,4 +23,5 @@ export declare const SelectedOutlinePolygon: React.NamedExoticComponent<{
23
23
  readonly onDoubleClickTarget: (target: SelectedOutlineTarget, button: number, sequenceWasDragged: boolean) => boolean;
24
24
  readonly scale: number;
25
25
  readonly showSelectedOutline: boolean;
26
+ readonly translateWithCommandKey: boolean;
26
27
  }>;
@@ -41,6 +41,7 @@ const client_id_1 = require("../helpers/client-id");
41
41
  const colors_1 = require("../helpers/colors");
42
42
  const drag_aware_double_click_1 = require("../helpers/drag-aware-double-click");
43
43
  const interactivity_enabled_1 = require("../helpers/interactivity-enabled");
44
+ const is_mac_1 = require("../helpers/is-mac");
44
45
  const pointer_session_1 = require("../helpers/pointer-session");
45
46
  const editor_guides_1 = require("../state/editor-guides");
46
47
  const editor_snapping_1 = require("../state/editor-snapping");
@@ -57,7 +58,7 @@ const imperative_state_1 = require("./Timeline/imperative-state");
57
58
  const save_sequence_prop_1 = require("./Timeline/save-sequence-prop");
58
59
  const should_clear_selection_on_pointer_down_1 = require("./Timeline/should-clear-selection-on-pointer-down");
59
60
  exports.SELECTED_OUTLINE_KEY_ATTR = 'data-remotion-studio-selected-outline-key';
60
- const SelectedOutlinePolygonUnmemoized = ({ compositionHeight, compositionWidth, containsSelection, directlySelected, dragging, getAllDragOutlines, getAllDragTargets, getLayoutTarget, getTarget, hasTarget, hovered, outline, onDraggingChange, onHoverChange, onSnapPointsChange, onSelect, onDoubleClickTarget, scale, showSelectedOutline, }) => {
61
+ const SelectedOutlinePolygonUnmemoized = ({ compositionHeight, compositionWidth, containsSelection, directlySelected, dragging, getAllDragOutlines, getAllDragTargets, getLayoutTarget, getTarget, hasTarget, hovered, outline, onDraggingChange, onHoverChange, onSnapPointsChange, onSelect, onDoubleClickTarget, scale, showSelectedOutline, translateWithCommandKey, }) => {
61
62
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
62
63
  const dragAwareDoubleClick = (0, react_1.useMemo)(() => (0, drag_aware_double_click_1.createDragAwareDoubleClickTracker)(), []);
63
64
  const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
@@ -95,7 +96,12 @@ const SelectedOutlinePolygonUnmemoized = ({ compositionHeight, compositionWidth,
95
96
  const { drag, selected } = target;
96
97
  event.preventDefault();
97
98
  event.stopPropagation();
98
- const interaction = (0, selected_outline_measurement_1.getOutlineSelectionInteraction)(event);
99
+ const temporaryTranslate = translateWithCommandKey &&
100
+ (selected || containsSelection) &&
101
+ (is_mac_1.isMac ? event.metaKey : event.ctrlKey);
102
+ const interaction = temporaryTranslate
103
+ ? { shiftKey: false, toggleKey: false }
104
+ : (0, selected_outline_measurement_1.getOutlineSelectionInteraction)(event);
99
105
  const shouldUpdateSelection = !selected || interaction.shiftKey || interaction.toggleKey;
100
106
  const ownerSvg = (_a = polygonRef.current) === null || _a === void 0 ? void 0 : _a.ownerSVGElement;
101
107
  let pointerInsideSelectedOutline = false;
@@ -159,7 +165,7 @@ const SelectedOutlinePolygonUnmemoized = ({ compositionHeight, compositionWidth,
159
165
  let currentPointerY = startPointerY;
160
166
  let axisLocked = false;
161
167
  let dragStarted = false;
162
- let snappingDisabled = event.metaKey || event.ctrlKey;
168
+ let snappingDisabled = !temporaryTranslate && (event.metaKey || event.ctrlKey);
163
169
  let snapTargets = null;
164
170
  const updateDragOverrides = () => {
165
171
  const screenDeltaX = currentPointerX - startPointerX;
@@ -241,7 +247,8 @@ const SelectedOutlinePolygonUnmemoized = ({ compositionHeight, compositionWidth,
241
247
  currentPointerX = moveEvent.clientX;
242
248
  currentPointerY = moveEvent.clientY;
243
249
  axisLocked = moveEvent.shiftKey;
244
- snappingDisabled = moveEvent.metaKey || moveEvent.ctrlKey;
250
+ snappingDisabled =
251
+ !temporaryTranslate && (moveEvent.metaKey || moveEvent.ctrlKey);
245
252
  updateDragOverrides();
246
253
  };
247
254
  const onKeyChange = (keyEvent) => {
@@ -336,6 +343,7 @@ const SelectedOutlinePolygonUnmemoized = ({ compositionHeight, compositionWidth,
336
343
  scale,
337
344
  setPropStatuses,
338
345
  setDragOverrides,
346
+ translateWithCommandKey,
339
347
  ]);
340
348
  const onDoubleClick = react_1.default.useCallback((event) => {
341
349
  const target = getTarget();
@@ -35,11 +35,12 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.SelectedOutlineRenderer = void 0;
37
37
  const jsx_runtime_1 = require("react/jsx-runtime");
38
- const canvas_1 = require("@remotion/canvas");
39
38
  const react_1 = __importStar(require("react"));
40
39
  const timeline_node_path_key_1 = require("../helpers/timeline-node-path-key");
41
40
  const timeline_sequence_hover_1 = require("../state/timeline-sequence-hover");
42
41
  const ContextMenu_1 = require("./ContextMenu");
42
+ const selected_outline_measurement_1 = require("./selected-outline-measurement");
43
+ const selected_outline_order_1 = require("./selected-outline-order");
43
44
  const SelectedOutlineEditingHandles_1 = require("./SelectedOutlineEditingHandles");
44
45
  const SelectedOutlineElement_1 = require("./SelectedOutlineElement");
45
46
  const SelectedOutlinePolygon_1 = require("./SelectedOutlinePolygon");
@@ -54,9 +55,14 @@ const outlineContainer = {
54
55
  };
55
56
  const SelectedOutlineRendererUnmemoized = ({ compositionHeight, compositionWidth, dragging, getLatestOutlineTargetByKey, outlineTargets, onDraggingChange, onContextMenuOpenChange, onSelect, scale, sequences, updateOutlinesRef, }) => {
56
57
  var _a;
57
- const outlinesController = (0, canvas_1.useCanvasOutlinesController)();
58
- const renderState = (0, canvas_1.useCanvasOutlines)(outlinesController);
58
+ // Targets are derived props and can receive a new identity on every render.
59
+ // Keep only measured geometry in state to avoid layout-effect update loops.
60
+ const [outlines, setOutlines] = (0, react_1.useState)([]);
61
+ const outlinesRef = (0, react_1.useRef)(outlines);
59
62
  const overlayRef = (0, react_1.useRef)(null);
63
+ const resizeObserverRef = (0, react_1.useRef)(null);
64
+ const resizeObserverAnimationFrameRef = (0, react_1.useRef)(null);
65
+ const observedOutlineElementsRef = (0, react_1.useRef)(new Set());
60
66
  const contextMenuOpenHandlersRef = (0, react_1.useRef)(new Map());
61
67
  const registerContextMenuOpen = (0, react_1.useCallback)((key, handler) => {
62
68
  if (handler === null) {
@@ -83,9 +89,23 @@ const SelectedOutlineRendererUnmemoized = ({ compositionHeight, compositionWidth
83
89
  const hoveredSequence = (0, timeline_sequence_hover_1.useTimelineSequenceHoverState)();
84
90
  const setHoveredSequence = (0, timeline_sequence_hover_1.useSetTimelineSequenceHover)();
85
91
  const hoveredNodePathKey = (_a = hoveredSequence === null || hoveredSequence === void 0 ? void 0 : hoveredSequence.nodePathKey) !== null && _a !== void 0 ? _a : null;
92
+ const hoveredTimelineNodePathKey = (hoveredSequence === null || hoveredSequence === void 0 ? void 0 : hoveredSequence.source) === 'timeline' ? hoveredNodePathKey : null;
86
93
  const updateOutlines = (0, react_1.useCallback)(() => {
87
- outlinesController.update(overlayRef.current, outlineTargets);
88
- }, [outlineTargets, outlinesController]);
94
+ if (overlayRef.current === null || outlineTargets.length === 0) {
95
+ if (outlinesRef.current.length === 0) {
96
+ return;
97
+ }
98
+ outlinesRef.current = [];
99
+ setOutlines(outlinesRef.current);
100
+ return;
101
+ }
102
+ const nextOutlines = (0, selected_outline_measurement_1.measureOutlines)(overlayRef.current, outlineTargets, hoveredTimelineNodePathKey);
103
+ if ((0, selected_outline_measurement_1.outlinesAreEqual)(outlinesRef.current, nextOutlines)) {
104
+ return;
105
+ }
106
+ outlinesRef.current = nextOutlines;
107
+ setOutlines(nextOutlines);
108
+ }, [hoveredTimelineNodePathKey, outlineTargets]);
89
109
  (0, react_1.useLayoutEffect)(() => {
90
110
  updateOutlinesRef.current = updateOutlines;
91
111
  updateOutlines();
@@ -96,32 +116,79 @@ const SelectedOutlineRendererUnmemoized = ({ compositionHeight, compositionWidth
96
116
  };
97
117
  }, [updateOutlines, updateOutlinesRef]);
98
118
  (0, react_1.useLayoutEffect)(() => {
99
- return () => outlinesController.disconnect();
100
- }, [outlinesController]);
119
+ if (typeof ResizeObserver === 'undefined') {
120
+ return;
121
+ }
122
+ const resizeObserver = new ResizeObserver(() => {
123
+ if (resizeObserverAnimationFrameRef.current !== null) {
124
+ return;
125
+ }
126
+ resizeObserverAnimationFrameRef.current = requestAnimationFrame(() => {
127
+ resizeObserverAnimationFrameRef.current = null;
128
+ updateOutlinesRef.current();
129
+ });
130
+ });
131
+ resizeObserverRef.current = resizeObserver;
132
+ return () => {
133
+ if (resizeObserverAnimationFrameRef.current !== null) {
134
+ cancelAnimationFrame(resizeObserverAnimationFrameRef.current);
135
+ resizeObserverAnimationFrameRef.current = null;
136
+ }
137
+ resizeObserver.disconnect();
138
+ resizeObserverRef.current = null;
139
+ observedOutlineElementsRef.current = new Set();
140
+ };
141
+ }, [updateOutlinesRef]);
142
+ (0, react_1.useLayoutEffect)(() => {
143
+ const resizeObserver = resizeObserverRef.current;
144
+ if (resizeObserver === null) {
145
+ return;
146
+ }
147
+ const nextObservedElements = new Set();
148
+ if (overlayRef.current !== null) {
149
+ nextObservedElements.add(overlayRef.current);
150
+ }
151
+ for (const target of outlineTargets) {
152
+ if (target.ref.current !== null) {
153
+ nextObservedElements.add(target.ref.current);
154
+ }
155
+ }
156
+ for (const element of observedOutlineElementsRef.current) {
157
+ if (!nextObservedElements.has(element)) {
158
+ resizeObserver.unobserve(element);
159
+ }
160
+ }
161
+ for (const element of nextObservedElements) {
162
+ if (!observedOutlineElementsRef.current.has(element)) {
163
+ resizeObserver.observe(element);
164
+ }
165
+ }
166
+ observedOutlineElementsRef.current = nextObservedElements;
167
+ }, [outlineTargets]);
101
168
  const targetsByKey = (0, react_1.useMemo)(() => {
102
- return new Map(renderState.targets.map((target) => [target.key, target]));
103
- }, [renderState.targets]);
169
+ return new Map(outlineTargets.map((target) => [target.key, target]));
170
+ }, [outlineTargets]);
104
171
  (0, react_1.useEffect)(() => {
105
172
  if ((hoveredSequence === null || hoveredSequence === void 0 ? void 0 : hoveredSequence.source) === 'canvas' &&
106
- !renderState.targets.some((target) => target.key === hoveredSequence.key)) {
173
+ !outlineTargets.some((target) => target.key === hoveredSequence.key)) {
107
174
  setHoveredSequence((currentHover) => (currentHover === null || currentHover === void 0 ? void 0 : currentHover.source) === 'canvas' ? null : currentHover);
108
175
  }
109
- }, [hoveredSequence, renderState.targets, setHoveredSequence]);
176
+ }, [hoveredSequence, outlineTargets, setHoveredSequence]);
110
177
  // Reordering a captured SVG target can cancel the active pointer session.
111
178
  const outlineRenderingOrderRef = (0, react_1.useRef)([]);
112
179
  const outlinesForRendering = (0, react_1.useMemo)(() => {
113
180
  if (!dragging || outlineRenderingOrderRef.current.length === 0) {
114
- const orderedOutlines = (0, canvas_1.orderCanvasOutlinesForRendering)({
115
- outlines: renderState.outlines,
181
+ const orderedOutlines = (0, selected_outline_order_1.orderOutlinesForRendering)({
182
+ outlines,
116
183
  sequences,
117
184
  targetsByKey,
118
185
  });
119
186
  outlineRenderingOrderRef.current = orderedOutlines.map((outline) => outline.key);
120
187
  return orderedOutlines;
121
188
  }
122
- const currentOutlinesByKey = new Map(renderState.outlines.map((outline) => [outline.key, outline]));
189
+ const currentOutlinesByKey = new Map(outlines.map((outline) => [outline.key, outline]));
123
190
  const frozenKeys = new Set(outlineRenderingOrderRef.current);
124
- const newOutlines = renderState.outlines.filter((outline) => !frozenKeys.has(outline.key));
191
+ const newOutlines = outlines.filter((outline) => !frozenKeys.has(outline.key));
125
192
  outlineRenderingOrderRef.current = [
126
193
  ...outlineRenderingOrderRef.current,
127
194
  ...newOutlines.map((outline) => outline.key),
@@ -130,10 +197,10 @@ const SelectedOutlineRendererUnmemoized = ({ compositionHeight, compositionWidth
130
197
  const outline = currentOutlinesByKey.get(key);
131
198
  return outline === undefined ? [] : [outline];
132
199
  });
133
- }, [dragging, renderState.outlines, sequences, targetsByKey]);
200
+ }, [dragging, outlines, sequences, targetsByKey]);
134
201
  const outlinesByKey = (0, react_1.useMemo)(() => {
135
- return new Map(renderState.outlines.map((outline) => [outline.key, outline]));
136
- }, [renderState.outlines]);
202
+ return new Map(outlines.map((outline) => [outline.key, outline]));
203
+ }, [outlines]);
137
204
  const { outlinesForEditingHandles, outlinesForTransformOrigin, outlinesForUvHandles, } = (0, react_1.useMemo)(() => {
138
205
  const editingHandles = [];
139
206
  const transformOrigin = [];
@@ -159,12 +226,12 @@ const SelectedOutlineRendererUnmemoized = ({ compositionHeight, compositionWidth
159
226
  outlinesForUvHandles: uvHandles,
160
227
  };
161
228
  }, [hoveredNodePathKey, outlinesForRendering, targetsByKey]);
162
- const targetsRef = (0, react_1.useRef)(renderState.targets);
229
+ const targetsRef = (0, react_1.useRef)(outlineTargets);
163
230
  const outlinesByKeyRef = (0, react_1.useRef)(outlinesByKey);
164
231
  (0, react_1.useLayoutEffect)(() => {
165
- targetsRef.current = renderState.targets;
232
+ targetsRef.current = outlineTargets;
166
233
  outlinesByKeyRef.current = outlinesByKey;
167
- }, [outlinesByKey, renderState.targets]);
234
+ }, [outlineTargets, outlinesByKey]);
168
235
  const getAllDragTargets = (0, react_1.useCallback)(() => targetsRef.current.flatMap((target) => {
169
236
  var _a;
170
237
  var _b;
@@ -6,6 +6,7 @@ const react_1 = require("react");
6
6
  const browser_studio_operations_1 = require("../helpers/browser-studio-operations");
7
7
  const client_id_1 = require("../helpers/client-id");
8
8
  const call_api_1 = require("./call-api");
9
+ const UpdateStatusContext_1 = require("./UpdateStatusContext");
9
10
  const SettingsContext = (0, react_1.createContext)(null);
10
11
  const SettingsProvider = ({ children }) => {
11
12
  var _a;
@@ -110,7 +111,7 @@ const SettingsProvider = ({ children }) => {
110
111
  const value = (0, react_1.useMemo)(() => {
111
112
  return { ...settings, setPublicLicenseKey };
112
113
  }, [setPublicLicenseKey, settings]);
113
- return (jsx_runtime_1.jsx(SettingsContext.Provider, { value: value, children: children }));
114
+ return (jsx_runtime_1.jsx(SettingsContext.Provider, { value: value, children: jsx_runtime_1.jsx(UpdateStatusContext_1.UpdateStatusProvider, { children: children }) }));
114
115
  };
115
116
  exports.SettingsProvider = SettingsProvider;
116
117
  const useSettings = () => {
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- type SettingsTab = 'apps' | 'rendering' | 'studio' | 'packages' | 'shortcuts' | 'skills' | 'license';
2
+ type SettingsTab = 'apps' | 'rendering' | 'studio' | 'packages' | 'shortcuts' | 'skills' | 'license' | 'updates';
3
3
  export declare const SettingsModal: React.FC<{
4
4
  readonly initialTab: SettingsTab;
5
5
  readonly initialPublicLicenseKey: string | null;
@@ -4,7 +4,10 @@ exports.SettingsModal = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const browser_studio_operations_1 = require("../helpers/browser-studio-operations");
7
+ const can_show_updates_1 = require("../helpers/can-show-updates");
8
+ const client_id_1 = require("../helpers/client-id");
7
9
  const apps_1 = require("../icons/apps");
10
+ const cloud_download_1 = require("../icons/cloud-download");
8
11
  const keyboard_1 = require("../icons/keyboard");
9
12
  const license_1 = require("../icons/license");
10
13
  const package_1 = require("../icons/package");
@@ -26,6 +29,7 @@ const SettingsModalFooter_1 = require("./SettingsModalFooter");
26
29
  const SkillsSettings_1 = require("./SkillsSettings");
27
30
  const StudioSettings_1 = require("./StudioSettings");
28
31
  const vertical_1 = require("./Tabs/vertical");
32
+ const UpdatesSettings_1 = require("./UpdatesSettings");
29
33
  const hiddenPanel = {
30
34
  display: 'none',
31
35
  };
@@ -58,13 +62,20 @@ const keyboardIcon = {
58
62
  const SettingsModal = ({ initialPublicLicenseKey, initialTab }) => {
59
63
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.SetSelectedModalContext);
60
64
  const { setPublicLicenseKey } = (0, SettingsContext_1.useSettings)();
65
+ const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
61
66
  const isBrowserStudio = (0, browser_studio_operations_1.getBrowserStudioOperations)() !== null;
67
+ const showUpdates = (0, can_show_updates_1.canShowUpdates)({
68
+ connectionStatus: previewServerState.type,
69
+ isBrowserStudio,
70
+ readOnlyStudio: window.remotion_isReadOnlyStudio,
71
+ });
62
72
  const packageManager = window.remotion_packageManager === 'unknown'
63
73
  ? null
64
74
  : window.remotion_packageManager;
65
75
  const showPackages = (0, browser_studio_operations_1.canInstallPackages)() && (isBrowserStudio || packageManager !== null);
66
- const [tab, setTab] = (0, react_1.useState)(initialTab);
67
- const [openedTabs, setOpenedTabs] = (0, react_1.useState)([initialTab]);
76
+ const safeInitialTab = initialTab === 'updates' && !showUpdates ? 'shortcuts' : initialTab;
77
+ const [tab, setTab] = (0, react_1.useState)(safeInitialTab);
78
+ const [openedTabs, setOpenedTabs] = (0, react_1.useState)([safeInitialTab]);
68
79
  const [packagesFooterContainer, setPackagesFooterContainer] = (0, react_1.useState)(null);
69
80
  const dismiss = (0, react_1.useCallback)(() => {
70
81
  setSelectedModal(null);
@@ -78,11 +89,16 @@ const SettingsModal = ({ initialPublicLicenseKey, initialTab }) => {
78
89
  return [...currentOpenedTabs, newTab];
79
90
  });
80
91
  }, []);
92
+ (0, react_1.useLayoutEffect)(() => {
93
+ if (!showUpdates && tab === 'updates') {
94
+ selectTab('shortcuts');
95
+ }
96
+ }, [selectTab, showUpdates, tab]);
81
97
  (0, react_1.useEffect)(() => {
82
98
  setPublicLicenseKey(initialPublicLicenseKey);
83
99
  }, [initialPublicLicenseKey, setPublicLicenseKey]);
84
100
  return (jsx_runtime_1.jsx(DismissableModal_1.DismissableModal, { panelStyle: render_modals_1.outerModalStyle, children: jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
85
101
  jsx_runtime_1.jsx(ModalHeader_1.ModalHeader, { title: "Settings", onClose: dismiss }), jsx_runtime_1.jsxs("div", { style: render_modals_1.horizontalLayout, children: [
86
- jsx_runtime_1.jsxs("div", { style: settingsLeftSidebar, children: [isBrowserStudio ? null : (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" })), isBrowserStudio ? null : (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 === 'shortcuts', onClick: () => selectTab('shortcuts'), renderIcon: (color) => (jsx_runtime_1.jsx("div", { style: render_modals_1.iconContainer, children: jsx_runtime_1.jsx(keyboard_1.KeyboardIcon, { color: color, style: keyboardIcon }) })), children: "Shortcuts" }), showPackages ? (jsx_runtime_1.jsx(vertical_1.VerticalTab, { style: render_modals_1.horizontalTab, selected: tab === 'packages', onClick: () => selectTab('packages'), renderIcon: (color) => (jsx_runtime_1.jsx("div", { style: render_modals_1.iconContainer, children: jsx_runtime_1.jsx(package_1.PackageIcon, { color: color, style: render_modals_1.icon }) })), children: "Packages" })) : null, isBrowserStudio ? null : (jsx_runtime_1.jsx(vertical_1.VerticalTab, { style: render_modals_1.horizontalTab, selected: tab === 'skills', onClick: () => selectTab('skills'), renderIcon: (color) => (jsx_runtime_1.jsx("div", { style: render_modals_1.iconContainer, children: jsx_runtime_1.jsx(skills_1.SkillsIcon, { color: color, style: skillsIcon }) })), children: "Skills" })), isBrowserStudio ? null : (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: render_modals_1.iconContainer, children: jsx_runtime_1.jsx(apps_1.AppsIcon, { color: color, style: appsIcon }) })), children: "Apps" })), isBrowserStudio ? null : (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(license_1.LicenseIcon, { color: color, style: render_modals_1.icon }) })), children: "License" }))] }), openedTabs.includes('packages') ? (jsx_runtime_1.jsx("div", { style: tab === 'packages' ? render_modals_1.optionsPanel : hiddenPanel, children: jsx_runtime_1.jsx(InstallPackage_1.InstallPackageSettings, { footerContainer: packagesFooterContainer, packageManager: packageManager }) })) : null, 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('skills') ? (jsx_runtime_1.jsx("div", { style: tab === 'skills' ? settingsOptionsPanel : hiddenPanel, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: jsx_runtime_1.jsx(SkillsSettings_1.SkillsSettings, {}) })) : null, openedTabs.includes('shortcuts') ? (jsx_runtime_1.jsx("div", { style: tab === 'shortcuts' ? settingsOptionsPanel : hiddenPanel, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: jsx_runtime_1.jsx(KeyboardShortcutsSettings_1.KeyboardShortcutsSettings, {}) })) : 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] }), tab === 'packages' ? (jsx_runtime_1.jsx("div", { ref: setPackagesFooterContainer })) : isBrowserStudio ? null : (jsx_runtime_1.jsx(SettingsModalFooter_1.SettingsModalFooter, { showLicenseFaq: tab === 'license' }))] }) }));
102
+ jsx_runtime_1.jsxs("div", { style: settingsLeftSidebar, children: [isBrowserStudio ? null : (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" })), isBrowserStudio ? null : (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 === 'shortcuts', onClick: () => selectTab('shortcuts'), renderIcon: (color) => (jsx_runtime_1.jsx("div", { style: render_modals_1.iconContainer, children: jsx_runtime_1.jsx(keyboard_1.KeyboardIcon, { color: color, style: keyboardIcon }) })), children: "Shortcuts" }), showPackages ? (jsx_runtime_1.jsx(vertical_1.VerticalTab, { style: render_modals_1.horizontalTab, selected: tab === 'packages', onClick: () => selectTab('packages'), renderIcon: (color) => (jsx_runtime_1.jsx("div", { style: render_modals_1.iconContainer, children: jsx_runtime_1.jsx(package_1.PackageIcon, { color: color, style: render_modals_1.icon }) })), children: "Packages" })) : null, isBrowserStudio ? null : (jsx_runtime_1.jsx(vertical_1.VerticalTab, { style: render_modals_1.horizontalTab, selected: tab === 'skills', onClick: () => selectTab('skills'), renderIcon: (color) => (jsx_runtime_1.jsx("div", { style: render_modals_1.iconContainer, children: jsx_runtime_1.jsx(skills_1.SkillsIcon, { color: color, style: skillsIcon }) })), children: "Skills" })), isBrowserStudio ? null : (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: render_modals_1.iconContainer, children: jsx_runtime_1.jsx(apps_1.AppsIcon, { color: color, style: appsIcon }) })), children: "Apps" })), isBrowserStudio ? null : (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(license_1.LicenseIcon, { color: color, style: render_modals_1.icon }) })), children: "License" })), showUpdates ? (jsx_runtime_1.jsx(vertical_1.VerticalTab, { style: render_modals_1.horizontalTab, selected: tab === 'updates', onClick: () => selectTab('updates'), renderIcon: (color) => (jsx_runtime_1.jsx("div", { style: render_modals_1.iconContainer, children: jsx_runtime_1.jsx(cloud_download_1.CloudDownloadIcon, { color: color, style: render_modals_1.icon }) })), children: "Updates" })) : null] }), openedTabs.includes('packages') ? (jsx_runtime_1.jsx("div", { style: tab === 'packages' ? render_modals_1.optionsPanel : hiddenPanel, children: jsx_runtime_1.jsx(InstallPackage_1.InstallPackageSettings, { footerContainer: packagesFooterContainer, packageManager: packageManager }) })) : null, 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('skills') ? (jsx_runtime_1.jsx("div", { style: tab === 'skills' ? settingsOptionsPanel : hiddenPanel, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: jsx_runtime_1.jsx(SkillsSettings_1.SkillsSettings, {}) })) : null, openedTabs.includes('shortcuts') ? (jsx_runtime_1.jsx("div", { style: tab === 'shortcuts' ? settingsOptionsPanel : hiddenPanel, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: jsx_runtime_1.jsx(KeyboardShortcutsSettings_1.KeyboardShortcutsSettings, {}) })) : 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, showUpdates && openedTabs.includes('updates') ? (jsx_runtime_1.jsx("div", { style: tab === 'updates' ? settingsOptionsPanel : hiddenPanel, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: jsx_runtime_1.jsx(UpdatesSettings_1.UpdatesSettings, {}) })) : null] }), tab === 'packages' ? (jsx_runtime_1.jsx("div", { ref: setPackagesFooterContainer })) : isBrowserStudio || tab === 'updates' ? null : (jsx_runtime_1.jsx(SettingsModalFooter_1.SettingsModalFooter, { showLicenseFaq: tab === 'license' }))] }) }));
87
103
  };
88
104
  exports.SettingsModal = SettingsModal;
@@ -3,4 +3,5 @@ import type { _InternalTypes } from 'remotion';
3
3
  export declare const SidebarRenderButton: React.FC<{
4
4
  readonly composition: _InternalTypes['AnyCompMetadata'];
5
5
  readonly visible: boolean;
6
+ readonly readOnlyStudio: boolean;
6
7
  }>;