@remotion/studio 4.0.500 → 4.0.501

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 (108) hide show
  1. package/dist/Studio.js +1 -1
  2. package/dist/api/delete-static-file.js +8 -3
  3. package/dist/api/rename-static-file.js +8 -0
  4. package/dist/api/watch-public-folder.js +2 -1
  5. package/dist/api/watch-static-file.js +2 -1
  6. package/dist/api/write-static-file.js +8 -3
  7. package/dist/components/AssetSelector.js +3 -1
  8. package/dist/components/AssetSelectorItem.d.ts +2 -1
  9. package/dist/components/AssetSelectorItem.js +5 -2
  10. package/dist/components/Canvas.js +6 -1
  11. package/dist/components/CaptionInspector.d.ts +10 -0
  12. package/dist/components/CaptionInspector.js +24 -0
  13. package/dist/components/CaptionTextEditor.d.ts +9 -0
  14. package/dist/components/CaptionTextEditor.js +132 -0
  15. package/dist/components/CurrentAsset.js +3 -2
  16. package/dist/components/EditorContexts.d.ts +0 -1
  17. package/dist/components/EditorContexts.js +2 -2
  18. package/dist/components/FpsCounter.js +3 -3
  19. package/dist/components/FullscreenToggle.js +2 -1
  20. package/dist/components/GlobalKeybindings.js +2 -0
  21. package/dist/components/InitialCompositionLoader.d.ts +1 -1
  22. package/dist/components/InlineAction.js +1 -0
  23. package/dist/components/InlineCaptionInspector.d.ts +11 -0
  24. package/dist/components/InlineCaptionInspector.js +108 -0
  25. package/dist/components/InspectorPanel/CompositionInspector.js +5 -3
  26. package/dist/components/InspectorPanel/SelectedInspector.d.ts +1 -0
  27. package/dist/components/InspectorPanel/SelectedInspector.js +2 -2
  28. package/dist/components/InspectorPanel/SequenceSelectionInspector.d.ts +1 -0
  29. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +4 -4
  30. package/dist/components/InspectorPanel/inspector-section-collapse.d.ts +22 -0
  31. package/dist/components/InspectorPanel/inspector-section-collapse.js +165 -0
  32. package/dist/components/InspectorPanel/styles.js +7 -1
  33. package/dist/components/InspectorPanel/use-composition-actions.d.ts +3 -0
  34. package/dist/components/InspectorPanel/use-composition-actions.js +91 -6
  35. package/dist/components/InspectorPanel.js +2 -2
  36. package/dist/components/InspectorSequenceSection.d.ts +2 -1
  37. package/dist/components/InspectorSequenceSection.js +238 -8
  38. package/dist/components/MenuToolbar.js +8 -1
  39. package/dist/components/Modals.js +1 -1
  40. package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.js +1 -0
  41. package/dist/components/QuickSwitcher/QuickSwitcher.d.ts +5 -0
  42. package/dist/components/QuickSwitcher/QuickSwitcher.js +2 -2
  43. package/dist/components/QuickSwitcher/QuickSwitcherContent.d.ts +5 -0
  44. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +26 -8
  45. package/dist/components/RenderQueue/ClientRenderQueueProcessor.d.ts +0 -1
  46. package/dist/components/RenderQueue/ClientRenderQueueProcessor.js +3 -14
  47. package/dist/components/RenderQueue/RenderQueueDownloadItem.js +2 -2
  48. package/dist/components/SelectedOutlineElement.js +1 -4
  49. package/dist/components/SelectedOutlineOverlay.js +17 -8
  50. package/dist/components/ShowOutlinesProvider.js +4 -1
  51. package/dist/components/Timeline/Timeline.js +19 -5
  52. package/dist/components/Timeline/TimelineAssetField.js +1 -0
  53. package/dist/components/Timeline/TimelineExpandedKeyframeRow.js +8 -2
  54. package/dist/components/Timeline/TimelinePrimitiveFieldValue.d.ts +7 -2
  55. package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +3 -1
  56. package/dist/components/Timeline/TimelineRowChrome.d.ts +3 -0
  57. package/dist/components/Timeline/TimelineRowChrome.js +4 -3
  58. package/dist/components/Timeline/TimelineSelection.d.ts +4 -2
  59. package/dist/components/Timeline/TimelineSelection.js +9 -6
  60. package/dist/components/Timeline/TimelineSequence.js +1 -4
  61. package/dist/components/Timeline/TimelineSequenceItem.js +4 -5
  62. package/dist/components/Timeline/TimelineSequencePropItem.js +9 -10
  63. package/dist/components/Timeline/TimelineTrack.js +4 -2
  64. package/dist/components/Timeline/border-radius-representation.d.ts +16 -0
  65. package/dist/components/Timeline/border-radius-representation.js +60 -0
  66. package/dist/components/Timeline/delete-selected-timeline-item.js +1 -6
  67. package/dist/components/Timeline/get-sequence-prop-reset-changes.d.ts +10 -0
  68. package/dist/components/Timeline/get-sequence-prop-reset-changes.js +33 -0
  69. package/dist/components/Timeline/reset-selected-timeline-props.js +2 -8
  70. package/dist/components/Timeline/save-sequence-prop.d.ts +12 -1
  71. package/dist/components/Timeline/save-sequence-prop.js +25 -1
  72. package/dist/components/Timeline/timeline-field-display-utils.js +1 -0
  73. package/dist/components/Timeline/use-timeline-asset-drop.js +4 -0
  74. package/dist/components/UndoRedoButtons.js +15 -6
  75. package/dist/components/handle-drop.d.ts +3 -2
  76. package/dist/components/handle-drop.js +2 -1
  77. package/dist/components/import-assets.d.ts +4 -2
  78. package/dist/components/import-assets.js +20 -7
  79. package/dist/components/use-element-overwrite-confirmation.d.ts +2 -0
  80. package/dist/components/use-element-overwrite-confirmation.js +73 -0
  81. package/dist/components/use-static-files.js +7 -2
  82. package/dist/error-overlay/react-overlay/effects/resolve-file-source.js +13 -2
  83. package/dist/esm/{chunk-dr1y1vm3.js → chunk-n1kj09yv.js} +7634 -6308
  84. package/dist/esm/index.mjs +24 -8
  85. package/dist/esm/internals.mjs +7634 -6308
  86. package/dist/esm/previewEntry.mjs +7646 -6320
  87. package/dist/esm/renderEntry.mjs +1 -1
  88. package/dist/helpers/browser-studio-operations.d.ts +3 -0
  89. package/dist/helpers/browser-studio-operations.js +14 -0
  90. package/dist/helpers/client-id.d.ts +0 -1
  91. package/dist/helpers/client-id.js +15 -10
  92. package/dist/helpers/download-blob.d.ts +1 -0
  93. package/dist/helpers/download-blob.js +15 -0
  94. package/dist/helpers/inject-css.js +5 -3
  95. package/dist/helpers/open-in-editor.js +26 -5
  96. package/dist/helpers/preview-server-events.js +46 -9
  97. package/dist/helpers/use-create-composition.js +8 -6
  98. package/dist/helpers/use-menu-structure.js +29 -0
  99. package/dist/hot-middleware-client/client.js +3 -3
  100. package/dist/icons/border-radius.d.ts +4 -0
  101. package/dist/icons/border-radius.js +8 -0
  102. package/dist/icons/fullscreen.d.ts +4 -0
  103. package/dist/icons/fullscreen.js +6 -0
  104. package/dist/previewEntry.js +1 -1
  105. package/dist/state/modals.d.ts +4 -0
  106. package/dist/state/timeline-sequence-hover.d.ts +17 -0
  107. package/dist/state/timeline-sequence-hover.js +33 -0
  108. package/package.json +13 -12
@@ -3,18 +3,25 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.InspectorSequenceSection = exports.hasSequenceControls = exports.getInspectorSelectableItems = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
+ const remotion_1 = require("remotion");
6
7
  const client_id_1 = require("../helpers/client-id");
7
8
  const colors_1 = require("../helpers/colors");
8
9
  const get_preview_file_type_1 = require("../helpers/get-preview-file-type");
9
10
  const interactivity_enabled_1 = require("../helpers/interactivity-enabled");
10
11
  const timeline_layout_1 = require("../helpers/timeline-layout");
12
+ const border_radius_1 = require("../icons/border-radius");
13
+ const fullscreen_1 = require("../icons/fullscreen");
11
14
  const plus_1 = require("../icons/plus");
12
15
  const modals_1 = require("../state/modals");
13
16
  const AssetFileIcon_1 = require("./AssetFileIcon");
14
17
  const InlineAction_1 = require("./InlineAction");
18
+ const InlineCaptionInspector_1 = require("./InlineCaptionInspector");
15
19
  const common_1 = require("./InspectorPanel/common");
20
+ const inspector_section_collapse_1 = require("./InspectorPanel/inspector-section-collapse");
16
21
  const styles_1 = require("./InspectorPanel/styles");
17
22
  const asset_search_1 = require("./QuickSwitcher/asset-search");
23
+ const border_radius_representation_1 = require("./Timeline/border-radius-representation");
24
+ const save_sequence_prop_1 = require("./Timeline/save-sequence-prop");
18
25
  const timeline_asset_link_1 = require("./Timeline/timeline-asset-link");
19
26
  const TimelineAssetField_1 = require("./Timeline/TimelineAssetField");
20
27
  const TimelineExpandedRow_1 = require("./Timeline/TimelineExpandedRow");
@@ -44,6 +51,43 @@ const plusIcon = {
44
51
  width: 15,
45
52
  height: 15,
46
53
  };
54
+ const borderRadiusToggleIcon = {
55
+ flexShrink: 0,
56
+ height: 15,
57
+ width: 15,
58
+ };
59
+ const collapsibleSectionHeaderButton = {
60
+ appearance: 'none',
61
+ backgroundColor: 'transparent',
62
+ border: 'none',
63
+ borderRadius: 3,
64
+ cursor: 'default',
65
+ display: 'block',
66
+ flex: 1,
67
+ fontFamily: 'Arial, Helvetica, sans-serif',
68
+ fontSize: 12,
69
+ fontWeight: 'bold',
70
+ lineHeight: '16px',
71
+ margin: 0,
72
+ minWidth: 0,
73
+ overflow: 'hidden',
74
+ padding: '4px 0',
75
+ textAlign: 'left',
76
+ textOverflow: 'ellipsis',
77
+ userSelect: 'none',
78
+ whiteSpace: 'nowrap',
79
+ };
80
+ const CollapsibleInspectorSectionHeader = ({ action, expanded, label, onToggle }) => {
81
+ const [hovered, setHovered] = (0, react_1.useState)(false);
82
+ const style = (0, react_1.useMemo)(() => {
83
+ return {
84
+ ...collapsibleSectionHeaderButton,
85
+ color: hovered ? colors_1.WHITE : colors_1.LIGHT_TEXT,
86
+ };
87
+ }, [hovered]);
88
+ return (jsx_runtime_1.jsxs("div", { style: styles_1.sectionHeaderRow, children: [
89
+ jsx_runtime_1.jsx("button", { type: "button", "aria-expanded": expanded, "aria-label": `${expanded ? 'Collapse' : 'Expand'} ${label}`, className: "__remotion-inspector-section-title", onClick: onToggle, onPointerEnter: () => setHovered(true), onPointerLeave: () => setHovered(false), style: style, children: label }), action] }));
90
+ };
47
91
  const assetSelectorIcon = {
48
92
  flexShrink: 0,
49
93
  height: 18,
@@ -88,6 +132,7 @@ const isEffectsRoot = (node) => {
88
132
  return auxiliaryKeys[auxiliaryKeys.length - 1] === 'effects';
89
133
  };
90
134
  const INSPECTOR_COLLAPSED_ROWS_SESSION_STORAGE_KEY = 'remotion.editor.inspectorCollapsedRows';
135
+ const INSPECTOR_SECTION_EXPANSION_OVERRIDES_SESSION_STORAGE_KEY = 'remotion.editor.inspectorSectionExpansionOverrides';
91
136
  const getInspectorExpansionKey = (nodePathInfo) => {
92
137
  return JSON.stringify(nodePathInfo);
93
138
  };
@@ -121,6 +166,48 @@ const persistInspectorCollapsedKeys = (keys) => {
121
166
  // Ignore quota errors or disabled storage.
122
167
  }
123
168
  };
169
+ const loadInspectorSectionExpansionOverrides = () => {
170
+ if (typeof window === 'undefined') {
171
+ return {};
172
+ }
173
+ try {
174
+ const raw = window.sessionStorage.getItem(INSPECTOR_SECTION_EXPANSION_OVERRIDES_SESSION_STORAGE_KEY);
175
+ if (raw === null) {
176
+ return {};
177
+ }
178
+ const parsed = JSON.parse(raw);
179
+ if (parsed === null ||
180
+ typeof parsed !== 'object' ||
181
+ Array.isArray(parsed)) {
182
+ return {};
183
+ }
184
+ return Object.fromEntries(Object.entries(parsed).filter((entry) => {
185
+ return typeof entry[1] === 'boolean';
186
+ }));
187
+ }
188
+ catch (_a) {
189
+ return {};
190
+ }
191
+ };
192
+ const persistInspectorSectionExpansionOverrides = (overrides) => {
193
+ if (typeof window === 'undefined') {
194
+ return;
195
+ }
196
+ try {
197
+ window.sessionStorage.setItem(INSPECTOR_SECTION_EXPANSION_OVERRIDES_SESSION_STORAGE_KEY, JSON.stringify(overrides));
198
+ }
199
+ catch (_a) {
200
+ // Ignore quota errors or disabled storage.
201
+ }
202
+ };
203
+ const getInspectorSectionExpansionKey = ({ nodePathInfo, groupId, }) => {
204
+ return JSON.stringify([
205
+ nodePathInfo.sequenceSubscriptionKey.absolutePath,
206
+ nodePathInfo.sequenceSubscriptionKey.nodePath,
207
+ nodePathInfo.index,
208
+ groupId,
209
+ ]);
210
+ };
124
211
  const getInspectorControlGroups = (rows) => {
125
212
  return timeline_layout_1.SCHEMA_FIELD_GROUPS.map((group) => ({
126
213
  ...group,
@@ -141,15 +228,20 @@ const hasSequenceControls = (sequence) => {
141
228
  return sequence.controls !== null;
142
229
  };
143
230
  exports.hasSequenceControls = hasSequenceControls;
144
- const InspectorSequenceSection = ({ sequence, validatedLocation, nodePathInfo, keyframeDisplayOffset, renderTransformControls, }) => {
145
- const { tree } = (0, use_timeline_expanded_tree_1.useTimelineExpandedTree)({
231
+ const InspectorSequenceSection = ({ sequence, readOnlyStudio, validatedLocation, nodePathInfo, keyframeDisplayOffset, renderTransformControls, }) => {
232
+ var _a;
233
+ const { tree, propStatuses } = (0, use_timeline_expanded_tree_1.useTimelineExpandedTree)({
146
234
  sequence,
147
235
  nodePathInfo,
148
236
  includeTextContent: true,
149
237
  includeSourceControls: true,
150
238
  });
151
239
  const [collapsedKeys, setCollapsedKeys] = (0, react_1.useState)(loadInspectorCollapsedKeys);
240
+ const [sectionExpansionOverrides, setSectionExpansionOverrides] = (0, react_1.useState)(loadInspectorSectionExpansionOverrides);
241
+ const [automaticSectionExpansion, setAutomaticSectionExpansion] = (0, react_1.useState)({});
152
242
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
243
+ const { getDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
244
+ const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
153
245
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
154
246
  const selectAsset = (0, use_select_asset_1.useSelectAsset)();
155
247
  const mediaSrc = (0, timeline_asset_link_1.getTimelineAssetSrcFromSchema)(sequence.controls);
@@ -229,15 +321,102 @@ const InspectorSequenceSection = ({ sequence, validatedLocation, nodePathInfo, k
229
321
  }),
230
322
  };
231
323
  }, [getIsExpanded, tree]);
232
- const controlSelectableItems = (0, react_1.useMemo)(() => (0, exports.getInspectorSelectableItems)(controlRows.filter(({ node }) => {
233
- var _a;
234
- return node.kind !== 'field' || ((_a = node.field) === null || _a === void 0 ? void 0 : _a.key) !== 'src';
235
- })), [controlRows]);
236
324
  const effectSelectableItems = (0, react_1.useMemo)(() => (0, exports.getInspectorSelectableItems)(effectRows), [effectRows]);
237
325
  const controlGroups = (0, react_1.useMemo)(() => getInspectorControlGroups(controlRows), [controlRows]);
238
326
  const layoutGroup = controlGroups.find((group) => group.id === 'layout');
239
327
  const controlGroupsWithoutLayout = controlGroups.filter((group) => group.id !== 'layout');
328
+ const sequencePropStatuses = remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePathInfo.sequenceSubscriptionKey);
240
329
  const { schema } = sequence.controls;
330
+ const getControlGroupActivity = (0, react_1.useCallback)((group) => {
331
+ if (!(0, inspector_section_collapse_1.isSmartCollapsibleInspectorGroup)(group.id)) {
332
+ return 'active';
333
+ }
334
+ return (0, inspector_section_collapse_1.getInspectorSectionActivity)({
335
+ group: group.id,
336
+ propStatuses: sequencePropStatuses,
337
+ schema,
338
+ });
339
+ }, [schema, sequencePropStatuses]);
340
+ (0, react_1.useEffect)(() => {
341
+ setAutomaticSectionExpansion((previous) => {
342
+ let changed = false;
343
+ const next = { ...previous };
344
+ for (const group of controlGroups) {
345
+ if (!(0, inspector_section_collapse_1.isSmartCollapsibleInspectorGroup)(group.id)) {
346
+ continue;
347
+ }
348
+ const expansionKey = getInspectorSectionExpansionKey({
349
+ nodePathInfo,
350
+ groupId: group.id,
351
+ });
352
+ const activity = getControlGroupActivity(group);
353
+ if (activity === 'active' && next[expansionKey] !== true) {
354
+ next[expansionKey] = true;
355
+ changed = true;
356
+ }
357
+ else if (activity === 'inactive' &&
358
+ next[expansionKey] === undefined) {
359
+ next[expansionKey] = false;
360
+ changed = true;
361
+ }
362
+ }
363
+ return changed ? next : previous;
364
+ });
365
+ }, [controlGroups, getControlGroupActivity, nodePathInfo]);
366
+ const isControlGroupExpanded = (0, react_1.useCallback)((group) => {
367
+ if (!(0, inspector_section_collapse_1.isSmartCollapsibleInspectorGroup)(group.id)) {
368
+ return true;
369
+ }
370
+ const expansionKey = getInspectorSectionExpansionKey({
371
+ nodePathInfo,
372
+ groupId: group.id,
373
+ });
374
+ const override = sectionExpansionOverrides[expansionKey];
375
+ if (override !== undefined) {
376
+ return override;
377
+ }
378
+ const automaticExpansion = automaticSectionExpansion[expansionKey];
379
+ if (automaticExpansion !== undefined) {
380
+ return automaticExpansion;
381
+ }
382
+ return getControlGroupActivity(group) !== 'inactive';
383
+ }, [
384
+ automaticSectionExpansion,
385
+ getControlGroupActivity,
386
+ nodePathInfo,
387
+ sectionExpansionOverrides,
388
+ ]);
389
+ const toggleControlGroup = (0, react_1.useCallback)((group) => {
390
+ const expansionKey = getInspectorSectionExpansionKey({
391
+ nodePathInfo,
392
+ groupId: group.id,
393
+ });
394
+ const nextExpanded = !isControlGroupExpanded(group);
395
+ setSectionExpansionOverrides((previous) => {
396
+ const next = { ...previous, [expansionKey]: nextExpanded };
397
+ persistInspectorSectionExpansionOverrides(next);
398
+ return next;
399
+ });
400
+ }, [isControlGroupExpanded, nodePathInfo]);
401
+ const visibleControlRows = controlGroups.flatMap((group) => {
402
+ return isControlGroupExpanded(group) ? group.rows : [];
403
+ });
404
+ const controlSelectableItems = (0, react_1.useMemo)(() => (0, exports.getInspectorSelectableItems)(visibleControlRows.filter(({ node }) => {
405
+ var _a;
406
+ return node.kind !== 'field' || ((_a = node.field) === null || _a === void 0 ? void 0 : _a.key) !== 'src';
407
+ })), [visibleControlRows]);
408
+ const borderRadiusGroup = controlGroups.find((group) => group.id === 'border-radius');
409
+ const borderRadiusUsesShorthand = borderRadiusGroup === null || borderRadiusGroup === void 0 ? void 0 : borderRadiusGroup.rows.some(({ node }) => {
410
+ var _a;
411
+ return node.kind === 'field' && ((_a = node.field) === null || _a === void 0 ? void 0 : _a.key) === border_radius_representation_1.BORDER_RADIUS_SHORTHAND_KEY;
412
+ });
413
+ const borderRadiusConversion = (0, border_radius_representation_1.getBorderRadiusConversion)(sequencePropStatuses, getDragOverrides(nodePathInfo.sequenceSubscriptionKey));
414
+ const inlineCaptionValue = ((_a = schema.captions) === null || _a === void 0 ? void 0 : _a.type) === 'remotion-captions'
415
+ ? sequence.controls.currentRuntimeValueDotNotation.captions
416
+ : null;
417
+ const inlineCaptions = Array.isArray(inlineCaptionValue)
418
+ ? inlineCaptionValue
419
+ : null;
241
420
  const showEffectsSection = nodePathInfo.supportsEffects || effectRows.length > 0;
242
421
  const canAddEffect = nodePathInfo.supportsEffects &&
243
422
  previewServerState.type === 'connected' &&
@@ -260,14 +439,65 @@ const InspectorSequenceSection = ({ sequence, validatedLocation, nodePathInfo, k
260
439
  setSelectedModal,
261
440
  validatedLocation.source,
262
441
  ]);
442
+ const onConvertBorderRadius = (0, react_1.useCallback)(() => {
443
+ if (borderRadiusConversion === null ||
444
+ previewServerState.type !== 'connected') {
445
+ return;
446
+ }
447
+ const common = {
448
+ fileName: validatedLocation.source,
449
+ nodePath: nodePathInfo.sequenceSubscriptionKey,
450
+ defaultValue: null,
451
+ schema,
452
+ };
453
+ const changes = (0, border_radius_representation_1.getBorderRadiusConversionChanges)(borderRadiusConversion).map((change) => ({ ...common, ...change }));
454
+ (0, save_sequence_prop_1.saveSequenceProps)({
455
+ changes,
456
+ addedKeyframes: null,
457
+ movedKeyframes: null,
458
+ setPropStatuses,
459
+ clientId: previewServerState.clientId,
460
+ undoLabel: 'Change border radius representation',
461
+ redoLabel: 'Change border radius representation again',
462
+ });
463
+ }, [
464
+ borderRadiusConversion,
465
+ nodePathInfo.sequenceSubscriptionKey,
466
+ previewServerState,
467
+ schema,
468
+ setPropStatuses,
469
+ validatedLocation.source,
470
+ ]);
471
+ const borderRadiusAction = borderRadiusGroup ? (jsx_runtime_1.jsx(InlineAction_1.InlineAction, { disabled: borderRadiusConversion === null ||
472
+ previewServerState.type !== 'connected', onClick: onConvertBorderRadius, title: borderRadiusConversion === null
473
+ ? borderRadiusUsesShorthand
474
+ ? 'A static border radius is required to use individual corners'
475
+ : 'All four corners must have the same static value'
476
+ : borderRadiusUsesShorthand
477
+ ? 'Use individual corner radii'
478
+ : 'Use one border radius value', renderAction: (color) => borderRadiusUsesShorthand ? (jsx_runtime_1.jsx(fullscreen_1.FullscreenIcon, { color: color, style: borderRadiusToggleIcon })) : (jsx_runtime_1.jsx(border_radius_1.BorderRadiusIcon, { color: color, style: borderRadiusToggleIcon })) })) : null;
263
479
  const effectsHeader = (jsx_runtime_1.jsxs("div", { style: styles_1.sectionHeaderRow, children: [
264
480
  jsx_runtime_1.jsx("div", { style: effectsHeaderTitle, children: "Effects" }), jsx_runtime_1.jsx(InlineAction_1.InlineAction, { disabled: !canAddEffect, onClick: onAddEffect, title: canAddEffect ? 'Add effect' : undefined, renderAction: (color) => jsx_runtime_1.jsx(plus_1.Plus, { color: color, style: plusIcon }) })] }));
265
481
  const renderRow = ({ node, depth }) => {
266
482
  return (jsx_runtime_1.jsx(TimelineRowLayoutContext_1.TimelineRowLayoutContext.Provider, { value: TimelineRowLayoutContext_1.INSPECTOR_TIMELINE_ROW_LAYOUT, children: jsx_runtime_1.jsx(TimelineExpandedRow_1.TimelineExpandedRow, { node: node, depth: depth, nestedDepth: 0, rowDepthBase: 0, getIsExpanded: getIsExpanded, toggleTrack: toggleTrack, validatedLocation: validatedLocation, nodePath: nodePathInfo.sequenceSubscriptionKey, schema: schema, keyframeDisplayOffset: keyframeDisplayOffset, keyframeControlsMode: "inspector" }) }, JSON.stringify(node.nodePathInfo)));
267
483
  };
268
- if (controlRows.length === 0 && !showEffectsSection) {
484
+ const renderControlGroupHeader = (group) => {
485
+ const collapsible = (0, inspector_section_collapse_1.isSmartCollapsibleInspectorGroup)(group.id);
486
+ const expanded = isControlGroupExpanded(group);
487
+ if (collapsible) {
488
+ return (jsx_runtime_1.jsx(CollapsibleInspectorSectionHeader, { action: group.id === 'border-radius' && expanded ? borderRadiusAction : null, expanded: expanded, label: group.label, onToggle: () => toggleControlGroup(group) }));
489
+ }
490
+ return (jsx_runtime_1.jsx("div", { style: styles_1.sectionHeaderRow, children: jsx_runtime_1.jsx("div", { style: effectsHeaderTitle, children: group.label }) }));
491
+ };
492
+ if (controlRows.length === 0 &&
493
+ !showEffectsSection &&
494
+ inlineCaptions === null) {
269
495
  return (jsx_runtime_1.jsx("div", { style: container, children: jsx_runtime_1.jsx(common_1.InspectorSection, { header: "Controls", children: jsx_runtime_1.jsx("div", { style: emptyState, children: "No schema" }) }) }));
270
496
  }
271
- return (jsx_runtime_1.jsx(TimelineAssetField_1.AssetSelectionContext.Provider, { value: assetSelectionContextValue, children: jsx_runtime_1.jsxs("div", { style: container, children: [controlRows.length > 0 ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionOrderProvider, { items: controlSelectableItems, children: controlGroupsWithoutLayout.map((group) => (jsx_runtime_1.jsxs(common_1.InspectorSection, { header: group.label, children: [group.id === 'transforms' ? renderTransformControls() : null, group.rows.map(renderRow)] }, group.id))) })) : null, showEffectsSection ? (jsx_runtime_1.jsx(common_1.InspectorSection, { header: effectsHeader, children: effectRows.length > 0 ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionOrderProvider, { items: effectSelectableItems, children: effectRows.map(renderRow) })) : null })) : null, layoutGroup ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionOrderProvider, { items: controlSelectableItems, children: jsx_runtime_1.jsx(common_1.InspectorSection, { header: layoutGroup.label, children: layoutGroup.rows.map(renderRow) }) })) : null] }) }));
497
+ return (jsx_runtime_1.jsx(TimelineAssetField_1.AssetSelectionContext.Provider, { value: assetSelectionContextValue, children: jsx_runtime_1.jsxs("div", { style: container, children: [controlRows.length > 0 ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionOrderProvider, { items: controlSelectableItems, children: controlGroupsWithoutLayout.map((group) => (jsx_runtime_1.jsx(common_1.InspectorSection, { header: renderControlGroupHeader(group), children: isControlGroupExpanded(group) ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [group.id === 'transforms'
498
+ ? renderTransformControls()
499
+ : null, group.rows.map(renderRow)] })) : null }, group.id))) })) : null, inlineCaptions ? (jsx_runtime_1.jsx(InlineCaptionInspector_1.InlineCaptionInspector, { captions: inlineCaptions, controls: sequence.controls, nodePath: nodePathInfo.sequenceSubscriptionKey, readOnlyStudio: readOnlyStudio, validatedLocation: validatedLocation })) : null, showEffectsSection ? (jsx_runtime_1.jsx(common_1.InspectorSection, { header: effectsHeader, children: effectRows.length > 0 ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionOrderProvider, { items: effectSelectableItems, children: effectRows.map(renderRow) })) : null })) : null, layoutGroup ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionOrderProvider, { items: controlSelectableItems, children: jsx_runtime_1.jsx(common_1.InspectorSection, { header: renderControlGroupHeader(layoutGroup), children: isControlGroupExpanded(layoutGroup)
500
+ ? layoutGroup.rows.map(renderRow)
501
+ : null }) })) : null] }) }));
272
502
  };
273
503
  exports.InspectorSequenceSection = InspectorSequenceSection;
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MenuToolbar = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
+ const browser_studio_operations_1 = require("../helpers/browser-studio-operations");
7
+ const client_id_1 = require("../helpers/client-id");
6
8
  const colors_1 = require("../helpers/colors");
7
9
  const mobile_layout_1 = require("../helpers/mobile-layout");
8
10
  const use_menu_structure_1 = require("../helpers/use-menu-structure");
@@ -31,6 +33,11 @@ const flex = {
31
33
  };
32
34
  const MenuToolbar = ({ readOnlyStudio }) => {
33
35
  const [selected, setSelected] = (0, react_1.useState)(null);
36
+ const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
37
+ const browserStudioOperations = (0, browser_studio_operations_1.getBrowserStudioOperations)();
38
+ const canUndoAndRedo = !readOnlyStudio ||
39
+ (previewServerState.type === 'connected' &&
40
+ browserStudioOperations !== null);
34
41
  const mobileLayout = (0, mobile_layout_1.useMobileLayout)();
35
42
  const fixedWidthRight = (0, react_1.useMemo)(() => {
36
43
  return {
@@ -101,7 +108,7 @@ const MenuToolbar = ({ readOnlyStudio }) => {
101
108
  jsx_runtime_1.jsxs("div", { style: fixedWidthLeft, children: [
102
109
  jsx_runtime_1.jsx(SidebarCollapserControls_1.SidebarCollapserControl, { side: "left" }), structure.map((s) => {
103
110
  return (jsx_runtime_1.jsx(MenuItem_1.MenuItem, { selected: selected === s.id, onItemSelected: itemClicked, onItemHovered: itemHovered, id: s.id, label: s.label, onItemQuit: onItemQuit, menu: s, onPreviousMenu: onPreviousMenu, onNextMenu: onNextMenu, leaveLeftPadding: s.leaveLeftPadding }, s.id));
104
- }), readOnlyStudio ? null : jsx_runtime_1.jsx(UpdateCheck_1.UpdateCheck, {})] }), jsx_runtime_1.jsx("div", { style: flex }), jsx_runtime_1.jsx(MenuBuildIndicator_1.MenuBuildIndicator, {}), jsx_runtime_1.jsx("div", { style: flex }), jsx_runtime_1.jsxs("div", { style: fixedWidthRight, children: [readOnlyStudio ? null : jsx_runtime_1.jsx(UndoRedoButtons_1.UndoRedoButtons, {}), jsx_runtime_1.jsx(SidebarCollapserControls_1.SidebarCollapserControl, { side: "right" })
111
+ }), readOnlyStudio ? null : jsx_runtime_1.jsx(UpdateCheck_1.UpdateCheck, {})] }), jsx_runtime_1.jsx("div", { style: flex }), jsx_runtime_1.jsx(MenuBuildIndicator_1.MenuBuildIndicator, {}), jsx_runtime_1.jsx("div", { style: flex }), jsx_runtime_1.jsxs("div", { style: fixedWidthRight, children: [canUndoAndRedo ? jsx_runtime_1.jsx(UndoRedoButtons_1.UndoRedoButtons, {}) : null, jsx_runtime_1.jsx(SidebarCollapserControls_1.SidebarCollapserControl, { side: "right" })
105
112
  ] })
106
113
  ] }));
107
114
  };
@@ -36,6 +36,6 @@ const Modals = ({ readOnlyStudio }) => {
36
36
  'connected';
37
37
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [modalContextType && modalContextType.type === 'new-comp' && (jsx_runtime_1.jsx(NewComposition_1.NewComposition, { folderName: modalContextType.folderName, parentName: modalContextType.parentName, stack: modalContextType.stack })), modalContextType && modalContextType.type === 'new-folder' && (jsx_runtime_1.jsx(NewFolder_1.NewFolder, { parentName: modalContextType.parentName, stack: modalContextType.stack })), modalContextType && modalContextType.type === 'duplicate-comp' && (jsx_runtime_1.jsx(DuplicateComposition_1.DuplicateComposition, { compositionType: modalContextType.compositionType, compositionId: modalContextType.compositionId })), modalContextType && modalContextType.type === 'delete-comp' && (jsx_runtime_1.jsx(DeleteComposition_1.DeleteComposition, { compositionId: modalContextType.compositionId })), modalContextType && modalContextType.type === 'rename-comp' && (jsx_runtime_1.jsx(RenameComposition_1.RenameComposition, { compositionId: modalContextType.compositionId })), modalContextType && modalContextType.type === 'delete-folder' && (jsx_runtime_1.jsx(DeleteFolder_1.DeleteFolder, { folderName: modalContextType.folderName, parentName: modalContextType.parentName, stack: modalContextType.stack })), modalContextType && modalContextType.type === 'rename-folder' && (jsx_runtime_1.jsx(RenameFolder_1.RenameFolder, { folderName: modalContextType.folderName, parentName: modalContextType.parentName, stack: modalContextType.stack })), modalContextType && modalContextType.type === 'rename-static-file' && (jsx_runtime_1.jsx(RenameStaticFile_1.RenameStaticFileModal, { relativePath: modalContextType.relativePath })), modalContextType && modalContextType.type === 'input-props-override' && (jsx_runtime_1.jsx(OverrideInputProps_1.OverrideInputPropsModal, {})), modalContextType && modalContextType.type === 'configure-license' && (jsx_runtime_1.jsx(ConfigureLicenseModal_1.ConfigureLicenseModal, { initialPublicLicenseKey: modalContextType.initialPublicLicenseKey })), modalContextType && modalContextType.type === 'web-render' && (jsx_runtime_1.jsx(WebRenderModal_1.WebRenderModalWithLoader, { ...modalContextType })), modalContextType &&
38
38
  modalContextType.type === 'server-render' &&
39
- (canRender || modalContextType.readOnlyStudio) ? (jsx_runtime_1.jsx(ServerRenderModal_1.RenderModalWithLoader, { readOnlyStudio: (_a = modalContextType.readOnlyStudio) !== null && _a !== void 0 ? _a : false, initialFrame: modalContextType.initialFrame, initialDarkMode: modalContextType.initialDarkMode, compositionId: modalContextType.compositionId, initialVideoImageFormat: modalContextType.initialVideoImageFormat, initialJpegQuality: modalContextType.initialJpegQuality, initialScale: modalContextType.initialScale, initialLogLevel: modalContextType.initialLogLevel, initialOffthreadVideoCacheSizeInBytes: modalContextType.initialOffthreadVideoCacheSizeInBytes, initialOffthreadVideoThreads: modalContextType.initialOffthreadVideoThreads, initialMediaCacheSizeInBytes: modalContextType.initialMediaCacheSizeInBytes, initialConcurrency: modalContextType.initialConcurrency, maxConcurrency: modalContextType.maxConcurrency, minConcurrency: modalContextType.minConcurrency, initialStillImageFormat: modalContextType.initialStillImageFormat, initialMuted: modalContextType.initialMuted, initialEnforceAudioTrack: modalContextType.initialEnforceAudioTrack, initialProResProfile: modalContextType.initialProResProfile, initialx264Preset: modalContextType.initialx264Preset, initialGopSize: modalContextType.initialGopSize, initialPixelFormat: modalContextType.initialPixelFormat, initialAudioBitrate: modalContextType.initialAudioBitrate, initialVideoBitrate: modalContextType.initialVideoBitrate, initialEveryNthFrame: modalContextType.initialEveryNthFrame, initialNumberOfGifLoops: modalContextType.initialNumberOfGifLoops, initialDelayRenderTimeout: modalContextType.initialDelayRenderTimeout, initialEnvVariables: modalContextType.initialEnvVariables, initialDisableWebSecurity: modalContextType.initialDisableWebSecurity, initialGl: modalContextType.initialOpenGlRenderer, initialHeadless: modalContextType.initialHeadless, initialIgnoreCertificateErrors: modalContextType.initialIgnoreCertificateErrors, initialEncodingBufferSize: modalContextType.initialEncodingBufferSize, initialEncodingMaxRate: modalContextType.initialEncodingMaxRate, initialUserAgent: modalContextType.initialUserAgent, initialColorSpace: modalContextType.initialColorSpace, initialMultiProcessOnLinux: modalContextType.initialMultiProcessOnLinux, initialRepro: modalContextType.initialRepro, initialBeep: modalContextType.initialBeep, initialForSeamlessAacConcatenation: modalContextType.initialForSeamlessAacConcatenation, defaultProps: modalContextType.defaultProps, inFrameMark: modalContextType.inFrameMark, outFrameMark: modalContextType.outFrameMark, defaultConfigurationAudioCodec: modalContextType.defaultConfigurationAudioCodec, defaultConfigurationVideoCodec: modalContextType.defaultConfigurationVideoCodec, renderTypeOfLastRender: modalContextType.renderTypeOfLastRender, defaultMetadata: modalContextType.defaulMetadata, initialHardwareAcceleration: modalContextType.initialHardwareAcceleration, initialSampleRate: modalContextType.initialSampleRate, initialChromeMode: modalContextType.initialChromeMode, renderDefaults: modalContextType.renderDefaults })) : null, modalContextType && modalContextType.type === 'render-progress' && (jsx_runtime_1.jsx(RenderStatusModal_1.RenderStatusModal, { jobId: modalContextType.jobId })), modalContextType && modalContextType.type === 'update' && (jsx_runtime_1.jsx(UpdateModal_1.UpdateModal, { info: modalContextType.info, knownBugs: modalContextType.knownBugs })), modalContextType && modalContextType.type === 'install-packages' && (jsx_runtime_1.jsx(InstallPackage_1.InstallPackageModal, { packageManager: modalContextType.packageManager })), modalContextType && modalContextType.type === 'quick-switcher' && (jsx_runtime_1.jsx(QuickSwitcher_1.default, { readOnlyStudio: readOnlyStudio, invocationTimestamp: modalContextType.invocationTimestamp, initialMode: modalContextType.mode, assetSelection: modalContextType.assetSelection })), modalContextType && modalContextType.type === 'add-effect' && (jsx_runtime_1.jsx(EffectPickerModal_1.EffectPickerModal, { state: modalContextType })), modalContextType && modalContextType.type === 'confirmation-dialog' && (jsx_runtime_1.jsx(ConfirmationDialog_1.ConfirmationDialog, { state: modalContextType })), modalContextType && modalContextType.type === 'svg-import-dialog' && (jsx_runtime_1.jsx(SvgImportDialog_1.SvgImportDialog, { state: modalContextType })), (0, studio_runtime_config_1.getStudioAskAIEnabled)() && jsx_runtime_1.jsx(AskAiModal_1.AskAiModal, {})] }));
39
+ (canRender || modalContextType.readOnlyStudio) ? (jsx_runtime_1.jsx(ServerRenderModal_1.RenderModalWithLoader, { readOnlyStudio: (_a = modalContextType.readOnlyStudio) !== null && _a !== void 0 ? _a : false, initialFrame: modalContextType.initialFrame, initialDarkMode: modalContextType.initialDarkMode, compositionId: modalContextType.compositionId, initialVideoImageFormat: modalContextType.initialVideoImageFormat, initialJpegQuality: modalContextType.initialJpegQuality, initialScale: modalContextType.initialScale, initialLogLevel: modalContextType.initialLogLevel, initialOffthreadVideoCacheSizeInBytes: modalContextType.initialOffthreadVideoCacheSizeInBytes, initialOffthreadVideoThreads: modalContextType.initialOffthreadVideoThreads, initialMediaCacheSizeInBytes: modalContextType.initialMediaCacheSizeInBytes, initialConcurrency: modalContextType.initialConcurrency, maxConcurrency: modalContextType.maxConcurrency, minConcurrency: modalContextType.minConcurrency, initialStillImageFormat: modalContextType.initialStillImageFormat, initialMuted: modalContextType.initialMuted, initialEnforceAudioTrack: modalContextType.initialEnforceAudioTrack, initialProResProfile: modalContextType.initialProResProfile, initialx264Preset: modalContextType.initialx264Preset, initialGopSize: modalContextType.initialGopSize, initialPixelFormat: modalContextType.initialPixelFormat, initialAudioBitrate: modalContextType.initialAudioBitrate, initialVideoBitrate: modalContextType.initialVideoBitrate, initialEveryNthFrame: modalContextType.initialEveryNthFrame, initialNumberOfGifLoops: modalContextType.initialNumberOfGifLoops, initialDelayRenderTimeout: modalContextType.initialDelayRenderTimeout, initialEnvVariables: modalContextType.initialEnvVariables, initialDisableWebSecurity: modalContextType.initialDisableWebSecurity, initialGl: modalContextType.initialOpenGlRenderer, initialHeadless: modalContextType.initialHeadless, initialIgnoreCertificateErrors: modalContextType.initialIgnoreCertificateErrors, initialEncodingBufferSize: modalContextType.initialEncodingBufferSize, initialEncodingMaxRate: modalContextType.initialEncodingMaxRate, initialUserAgent: modalContextType.initialUserAgent, initialColorSpace: modalContextType.initialColorSpace, initialMultiProcessOnLinux: modalContextType.initialMultiProcessOnLinux, initialRepro: modalContextType.initialRepro, initialBeep: modalContextType.initialBeep, initialForSeamlessAacConcatenation: modalContextType.initialForSeamlessAacConcatenation, defaultProps: modalContextType.defaultProps, inFrameMark: modalContextType.inFrameMark, outFrameMark: modalContextType.outFrameMark, defaultConfigurationAudioCodec: modalContextType.defaultConfigurationAudioCodec, defaultConfigurationVideoCodec: modalContextType.defaultConfigurationVideoCodec, renderTypeOfLastRender: modalContextType.renderTypeOfLastRender, defaultMetadata: modalContextType.defaulMetadata, initialHardwareAcceleration: modalContextType.initialHardwareAcceleration, initialSampleRate: modalContextType.initialSampleRate, initialChromeMode: modalContextType.initialChromeMode, renderDefaults: modalContextType.renderDefaults })) : null, modalContextType && modalContextType.type === 'render-progress' && (jsx_runtime_1.jsx(RenderStatusModal_1.RenderStatusModal, { jobId: modalContextType.jobId })), modalContextType && modalContextType.type === 'update' && (jsx_runtime_1.jsx(UpdateModal_1.UpdateModal, { info: modalContextType.info, knownBugs: modalContextType.knownBugs })), modalContextType && modalContextType.type === 'install-packages' && (jsx_runtime_1.jsx(InstallPackage_1.InstallPackageModal, { packageManager: modalContextType.packageManager })), modalContextType && modalContextType.type === 'quick-switcher' && (jsx_runtime_1.jsx(QuickSwitcher_1.default, { readOnlyStudio: readOnlyStudio, invocationTimestamp: modalContextType.invocationTimestamp, initialMode: modalContextType.mode, assetSelection: modalContextType.assetSelection, compositionSelection: modalContextType.compositionSelection })), modalContextType && modalContextType.type === 'add-effect' && (jsx_runtime_1.jsx(EffectPickerModal_1.EffectPickerModal, { state: modalContextType })), modalContextType && modalContextType.type === 'confirmation-dialog' && (jsx_runtime_1.jsx(ConfirmationDialog_1.ConfirmationDialog, { state: modalContextType })), modalContextType && modalContextType.type === 'svg-import-dialog' && (jsx_runtime_1.jsx(SvgImportDialog_1.SvgImportDialog, { state: modalContextType })), (0, studio_runtime_config_1.getStudioAskAIEnabled)() && jsx_runtime_1.jsx(AskAiModal_1.AskAiModal, {})] }));
40
40
  };
41
41
  exports.Modals = Modals;
@@ -37,6 +37,7 @@ const ExplorerQuickSwitcherTrigger = ({ mode, showShortcut, tabIndex }) => {
37
37
  mode,
38
38
  invocationTimestamp: Date.now(),
39
39
  assetSelection: null,
40
+ compositionSelection: null,
40
41
  });
41
42
  }, [mode, setSelectedModal]);
42
43
  return (jsx_runtime_1.jsx("div", { style: quickSwitcherArea, children: jsx_runtime_1.jsxs("button", { type: "button", style: quickSwitcherTrigger, onClick: openQuickSwitcher, tabIndex: tabIndex, children: ["Search...", showShortcut && !(0, use_keybinding_1.areKeyboardShortcutsDisabled)() ? (jsx_runtime_1.jsxs("span", { style: shortcutLabel, children: [ShortcutHint_1.cmdOrCtrlCharacter, "+K"] })) : null] }) }));
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import type { _InternalTypes } from 'remotion';
2
3
  import type { StaticFile } from '../../api/get-static-files';
3
4
  import type { QuickSwitcherMode } from './NoResults';
4
5
  declare const QuickSwitcher: React.FC<{
@@ -9,5 +10,9 @@ declare const QuickSwitcher: React.FC<{
9
10
  readonly initialQuery: string;
10
11
  readonly onSelected: (asset: StaticFile) => void;
11
12
  } | null;
13
+ readonly compositionSelection: {
14
+ readonly excludeCompositionId: string;
15
+ readonly onSelected: (composition: _InternalTypes['AnyComposition']) => void;
16
+ } | null;
12
17
  }>;
13
18
  export default QuickSwitcher;
@@ -7,7 +7,7 @@ const panelStyle = {
7
7
  borderRadius: 6,
8
8
  overflow: 'hidden',
9
9
  };
10
- const QuickSwitcher = ({ initialMode, invocationTimestamp, readOnlyStudio, assetSelection }) => {
11
- return (jsx_runtime_1.jsx(DismissableModal_1.DismissableModal, { panelStyle: panelStyle, children: jsx_runtime_1.jsx(QuickSwitcherContent_1.QuickSwitcherContent, { readOnlyStudio: readOnlyStudio, invocationTimestamp: invocationTimestamp, initialMode: initialMode, assetSelection: assetSelection }) }));
10
+ const QuickSwitcher = ({ initialMode, invocationTimestamp, readOnlyStudio, assetSelection, compositionSelection, }) => {
11
+ return (jsx_runtime_1.jsx(DismissableModal_1.DismissableModal, { panelStyle: panelStyle, children: jsx_runtime_1.jsx(QuickSwitcherContent_1.QuickSwitcherContent, { readOnlyStudio: readOnlyStudio, invocationTimestamp: invocationTimestamp, initialMode: initialMode, assetSelection: assetSelection, compositionSelection: compositionSelection }) }));
12
12
  };
13
13
  exports.default = QuickSwitcher;
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import type { _InternalTypes } from 'remotion';
2
3
  import type { StaticFile } from '../../api/get-static-files';
3
4
  import type { QuickSwitcherMode } from './NoResults';
4
5
  export declare const QuickSwitcherContent: React.FC<{
@@ -9,4 +10,8 @@ export declare const QuickSwitcherContent: React.FC<{
9
10
  readonly initialQuery: string;
10
11
  readonly onSelected: (asset: StaticFile) => void;
11
12
  } | null;
13
+ readonly compositionSelection: {
14
+ readonly excludeCompositionId: string;
15
+ readonly onSelected: (composition: _InternalTypes['AnyComposition']) => void;
16
+ } | null;
12
17
  }>;
@@ -97,13 +97,15 @@ const mapModeToQuery = (mode) => {
97
97
  }
98
98
  throw new Error('no mode' + mode);
99
99
  };
100
- const QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio, assetSelection }) => {
100
+ const QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio, assetSelection, compositionSelection, }) => {
101
101
  const { compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
102
102
  const staticFiles = (0, use_static_files_1.useStaticFiles)();
103
103
  const [state, setState] = (0, react_1.useState)(() => {
104
104
  return {
105
105
  query: assetSelection === null
106
- ? mapModeToQuery(initialMode)
106
+ ? compositionSelection === null
107
+ ? mapModeToQuery(initialMode)
108
+ : ''
107
109
  : assetSelection.initialQuery,
108
110
  selectedIndex: 0,
109
111
  };
@@ -111,11 +113,13 @@ const QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio
111
113
  (0, react_1.useEffect)(() => {
112
114
  setState({
113
115
  query: assetSelection === null
114
- ? mapModeToQuery(initialMode)
116
+ ? compositionSelection === null
117
+ ? mapModeToQuery(initialMode)
118
+ : ''
115
119
  : assetSelection.initialQuery,
116
120
  selectedIndex: 0,
117
121
  });
118
- }, [assetSelection, initialMode, invocationTimestamp]);
122
+ }, [assetSelection, compositionSelection, initialMode, invocationTimestamp]);
119
123
  const inputRef = (0, react_1.useRef)(null);
120
124
  const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
121
125
  const selectAsset = (0, use_select_asset_1.useSelectAsset)();
@@ -124,7 +128,11 @@ const QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio
124
128
  const [docResults, setDocResults] = (0, react_1.useState)({ type: 'initial' });
125
129
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
126
130
  const keybindings = (0, use_keybinding_1.useKeybinding)();
127
- const mode = assetSelection !== null ? 'assets' : mapQueryToMode(state.query);
131
+ const mode = assetSelection !== null
132
+ ? 'assets'
133
+ : compositionSelection !== null
134
+ ? 'compositions'
135
+ : mapQueryToMode(state.query);
128
136
  const actualQuery = (0, react_1.useMemo)(() => {
129
137
  return stripQuery(state.query);
130
138
  }, [state.query]);
@@ -167,13 +175,20 @@ const QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio
167
175
  };
168
176
  }));
169
177
  }
170
- return (0, fuzzy_search_1.fuzzySearch)(actualQuery, compositions.map((c) => {
178
+ return (0, fuzzy_search_1.fuzzySearch)(actualQuery, compositions
179
+ .filter((c) => c.id !== (compositionSelection === null || compositionSelection === void 0 ? void 0 : compositionSelection.excludeCompositionId))
180
+ .map((c) => {
171
181
  return {
172
182
  id: 'composition-' + c.id,
173
183
  title: c.id,
174
184
  type: 'composition',
175
185
  onSelected: () => {
176
186
  var _a;
187
+ if (compositionSelection !== null) {
188
+ compositionSelection.onSelected(c);
189
+ setSelectedModal(null);
190
+ return;
191
+ }
177
192
  selectComposition(c, true);
178
193
  setSelectedModal(null);
179
194
  const selector = `.__remotion-composition[data-compname="${c.id}"]`;
@@ -195,6 +210,7 @@ const QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio
195
210
  docResults,
196
211
  assetSearch,
197
212
  assetSelection,
213
+ compositionSelection,
198
214
  selectAsset,
199
215
  selectComposition,
200
216
  setSelectedModal,
@@ -337,9 +353,11 @@ const QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio
337
353
  height: 300,
338
354
  };
339
355
  }, [showKeyboardShortcuts]);
340
- return (jsx_runtime_1.jsxs("div", { style: container, children: [assetSelection === null && (jsx_runtime_1.jsxs("div", { style: modeSelector, children: [
356
+ return (jsx_runtime_1.jsxs("div", { style: container, children: [assetSelection === null && compositionSelection === null && (jsx_runtime_1.jsxs("div", { style: modeSelector, children: [
341
357
  jsx_runtime_1.jsx("button", { onClick: onCompositionsSelected, style: mode === 'compositions' ? modeActive : modeInactive, type: "button", children: "Compositions" }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("button", { onClick: onAssetsSelected, style: mode === 'assets' ? modeActive : modeInactive, type: "button", children: "Assets" }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("button", { onClick: onActionsSelected, style: mode === 'commands' ? modeActive : modeInactive, type: "button", children: "Actions" }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("button", { onClick: onDocSearchSelected, style: mode === 'docs' ? modeActive : modeInactive, type: "button", children: "Documentation" })
342
- ] })), jsx_runtime_1.jsxs("div", { style: assetSelection === null ? content : contentWithoutModeSelector, children: [
358
+ ] })), jsx_runtime_1.jsxs("div", { style: assetSelection === null && compositionSelection === null
359
+ ? content
360
+ : contentWithoutModeSelector, children: [
343
361
  jsx_runtime_1.jsx(RemInput_1.RemotionInput, { ref: inputRef, type: "text", style: input, autoFocus: true, status: "ok", value: state.query, onChange: onTextChange, placeholder: placeholder, rightAlign: false }), showKeyboardShortcuts ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
344
362
  jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }),
345
363
  " ",
@@ -1,2 +1 @@
1
- export declare const downloadBlob: (blob: Blob, filename: string) => void;
2
1
  export declare const ClientRenderQueueProcessor: React.FC;
@@ -1,22 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ClientRenderQueueProcessor = exports.downloadBlob = void 0;
3
+ exports.ClientRenderQueueProcessor = void 0;
4
4
  const web_renderer_1 = require("@remotion/web-renderer");
5
5
  const react_1 = require("react");
6
6
  const save_render_output_1 = require("../../api/save-render-output");
7
+ const download_blob_1 = require("../../helpers/download-blob");
7
8
  const context_1 = require("./context");
8
- const downloadBlob = (blob, filename) => {
9
- const url = URL.createObjectURL(blob);
10
- const a = document.createElement('a');
11
- a.href = url;
12
- const cleanFilename = filename.includes('/')
13
- ? filename.substring(filename.lastIndexOf('/') + 1)
14
- : filename;
15
- a.download = cleanFilename;
16
- a.click();
17
- URL.revokeObjectURL(url);
18
- };
19
- exports.downloadBlob = downloadBlob;
20
9
  const ClientRenderQueueProcessor = () => {
21
10
  const { getAbortController, getCompositionForJob, updateClientJobProgress, markClientJobSaving, markClientJobDone, markClientJobFailed, markClientJobCancelled, setProcessJobCallback, } = (0, react_1.useContext)(context_1.RenderQueueContext);
22
11
  const processStillJob = (0, react_1.useCallback)(async (job, signal) => {
@@ -126,7 +115,7 @@ const ClientRenderQueueProcessor = () => {
126
115
  markClientJobSaving(job.id);
127
116
  const getBlob = () => Promise.resolve(blob);
128
117
  const downloadAndFinish = () => {
129
- (0, exports.downloadBlob)(blob, job.outName);
118
+ (0, download_blob_1.downloadBlob)(blob, job.outName);
130
119
  markClientJobDone(job.id, metadata, getBlob);
131
120
  };
132
121
  if (window.remotion_isReadOnlyStudio) {
@@ -4,9 +4,9 @@ exports.RenderQueueDownloadItem = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const colors_1 = require("../../helpers/colors");
7
+ const download_blob_1 = require("../../helpers/download-blob");
7
8
  const InlineAction_1 = require("../InlineAction");
8
9
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
9
- const ClientRenderQueueProcessor_1 = require("./ClientRenderQueueProcessor");
10
10
  const RenderQueueDownloadItem = ({ job }) => {
11
11
  const onClick = (0, react_1.useCallback)((e) => {
12
12
  e.stopPropagation();
@@ -16,7 +16,7 @@ const RenderQueueDownloadItem = ({ job }) => {
16
16
  job
17
17
  .getBlob()
18
18
  .then((blob) => {
19
- (0, ClientRenderQueueProcessor_1.downloadBlob)(blob, job.outName);
19
+ (0, download_blob_1.downloadBlob)(blob, job.outName);
20
20
  })
21
21
  .catch((err) => {
22
22
  (0, NotificationCenter_1.showNotification)(`Could not download file: ${err.message}`, 2000);
@@ -1077,10 +1077,7 @@ const SelectedOutlineElement = ({ allDragTargets, allDragOutlines, allRotationDr
1077
1077
  },
1078
1078
  ],
1079
1079
  });
1080
- if (result.success) {
1081
- (0, NotificationCenter_1.showNotification)('Removed sequence from source file', 2000);
1082
- }
1083
- else {
1080
+ if (!result.success) {
1084
1081
  (0, NotificationCenter_1.showNotification)(result.reason, 4000);
1085
1082
  }
1086
1083
  }