@remotion/studio 4.0.491 → 4.0.493

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 (97) hide show
  1. package/dist/ResolveCompositionConfigInStudio.js +16 -6
  2. package/dist/components/AssetSelectorItem.js +7 -4
  3. package/dist/components/Canvas.js +1 -0
  4. package/dist/components/CompositionOrStillIcon.d.ts +7 -0
  5. package/dist/components/CompositionOrStillIcon.js +11 -0
  6. package/dist/components/CompositionSelector.js +14 -2
  7. package/dist/components/CompositionSelectorItem.js +34 -6
  8. package/dist/components/CurrentAsset.d.ts +6 -0
  9. package/dist/components/CurrentAsset.js +14 -8
  10. package/dist/components/CurrentComposition.d.ts +1 -1
  11. package/dist/components/CurrentComposition.js +3 -4
  12. package/dist/components/InlineEditableTitle.d.ts +1 -0
  13. package/dist/components/InlineEditableTitle.js +12 -7
  14. package/dist/components/InspectorInfoHeader.d.ts +2 -0
  15. package/dist/components/InspectorInfoHeader.js +12 -4
  16. package/dist/components/InspectorPanel/CompositionDimensions.d.ts +6 -0
  17. package/dist/components/InspectorPanel/CompositionDimensions.js +173 -0
  18. package/dist/components/InspectorPanel/ConnectedCompositionsSection.d.ts +9 -0
  19. package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +32 -0
  20. package/dist/components/InspectorPanel/DefaultInspector.js +6 -3
  21. package/dist/components/InspectorPanel/EasingInspector.js +3 -3
  22. package/dist/components/InspectorPanel/KeyframeInspector.js +6 -4
  23. package/dist/components/InspectorPanel/KeyframeSettings.js +1 -1
  24. package/dist/components/InspectorPanel/SequenceInspectorHeader.d.ts +1 -1
  25. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +9 -5
  26. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +5 -1
  27. package/dist/components/InspectorPanel/common.d.ts +2 -1
  28. package/dist/components/InspectorPanel/common.js +11 -7
  29. package/dist/components/InspectorPanel/optimistic-composition-metadata.d.ts +22 -0
  30. package/dist/components/InspectorPanel/optimistic-composition-metadata.js +41 -0
  31. package/dist/components/InspectorPanel/styles.d.ts +2 -0
  32. package/dist/components/InspectorPanel/styles.js +7 -2
  33. package/dist/components/InspectorSequenceSection.js +58 -7
  34. package/dist/components/NewComposition/NewComposition.js +11 -4
  35. package/dist/components/NewComposition/get-new-composition-defaults.d.ts +4 -0
  36. package/dist/components/NewComposition/get-new-composition-defaults.js +13 -0
  37. package/dist/components/SelectedOutlineElement.js +21 -2
  38. package/dist/components/SelectedOutlineOverlay.d.ts +1 -1
  39. package/dist/components/SelectedOutlineOverlay.js +4 -3
  40. package/dist/components/Timeline/Timeline.js +8 -1
  41. package/dist/components/Timeline/TimelineAssetField.d.ts +14 -0
  42. package/dist/components/Timeline/TimelineAssetField.js +125 -0
  43. package/dist/components/Timeline/TimelineClipboardKeybindings.js +133 -1
  44. package/dist/components/Timeline/TimelineExpandedSection.js +1 -0
  45. package/dist/components/Timeline/TimelineFieldLabel.js +4 -2
  46. package/dist/components/Timeline/TimelineKeyframeControls.js +1 -0
  47. package/dist/components/Timeline/TimelineList.js +2 -1
  48. package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +5 -3
  49. package/dist/components/Timeline/TimelineRowChrome.js +8 -6
  50. package/dist/components/Timeline/TimelineRowLayoutContext.d.ts +7 -0
  51. package/dist/components/Timeline/TimelineRowLayoutContext.js +13 -0
  52. package/dist/components/Timeline/TimelineSelection.js +20 -5
  53. package/dist/components/Timeline/TimelineSequenceItem.d.ts +2 -1
  54. package/dist/components/Timeline/TimelineSequenceItem.js +32 -8
  55. package/dist/components/Timeline/TimelineSequenceName.js +4 -0
  56. package/dist/components/Timeline/get-sequence-context-menu-items.js +3 -3
  57. package/dist/components/Timeline/keyframe-clipboard.d.ts +34 -0
  58. package/dist/components/Timeline/keyframe-clipboard.js +278 -0
  59. package/dist/components/Timeline/sequence-props-subscription-store.js +5 -1
  60. package/dist/components/Timeline/timeline-asset-link.d.ts +6 -0
  61. package/dist/components/Timeline/timeline-asset-link.js +27 -1
  62. package/dist/components/Timeline/timeline-field-display-utils.js +3 -1
  63. package/dist/components/Timeline/timeline-field-row-layout.d.ts +1 -1
  64. package/dist/components/Timeline/timeline-field-row-layout.js +2 -2
  65. package/dist/components/Timeline/timeline-row-layout.d.ts +3 -2
  66. package/dist/components/Timeline/timeline-row-layout.js +6 -5
  67. package/dist/components/Timeline/update-selected-easing.d.ts +1 -1
  68. package/dist/components/Timeline/update-selected-easing.js +4 -5
  69. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +4 -4
  70. package/dist/components/Timeline/use-timeline-expanded-tree.d.ts +2 -1
  71. package/dist/components/Timeline/use-timeline-expanded-tree.js +3 -1
  72. package/dist/components/Timeline/use-timeline-height.js +1 -0
  73. package/dist/components/import-assets.d.ts +10 -2
  74. package/dist/components/import-assets.js +20 -6
  75. package/dist/components/root-composition-menu-items.d.ts +8 -0
  76. package/dist/components/root-composition-menu-items.js +45 -0
  77. package/dist/components/selected-outline-measurement.d.ts +2 -5
  78. package/dist/components/selected-outline-measurement.js +3 -4
  79. package/dist/esm/{chunk-9wh9k3jj.js → chunk-mndqr3zx.js} +7439 -6121
  80. package/dist/esm/internals.mjs +7439 -6121
  81. package/dist/esm/previewEntry.mjs +7371 -6057
  82. package/dist/esm/renderEntry.mjs +1 -1
  83. package/dist/helpers/calculate-timeline.d.ts +2 -1
  84. package/dist/helpers/calculate-timeline.js +36 -5
  85. package/dist/helpers/get-connected-compositions.d.ts +6 -0
  86. package/dist/helpers/get-connected-compositions.js +11 -0
  87. package/dist/helpers/get-file-manager-name.d.ts +1 -0
  88. package/dist/helpers/get-file-manager-name.js +13 -0
  89. package/dist/helpers/get-sequence-double-click-action.d.ts +6 -0
  90. package/dist/helpers/get-sequence-double-click-action.js +13 -0
  91. package/dist/helpers/get-timeline-sequence-sort-key.d.ts +2 -1
  92. package/dist/helpers/timeline-layout.d.ts +2 -1
  93. package/dist/helpers/timeline-layout.js +5 -1
  94. package/dist/helpers/url-state.d.ts +1 -0
  95. package/dist/helpers/url-state.js +8 -6
  96. package/dist/helpers/use-menu-structure.js +4 -2
  97. package/package.json +11 -11
@@ -6,6 +6,7 @@ const react_1 = require("react");
6
6
  const colors_1 = require("../../helpers/colors");
7
7
  const timeline_layout_1 = require("../../helpers/timeline-layout");
8
8
  const timeline_field_row_layout_1 = require("./timeline-field-row-layout");
9
+ const TimelineRowLayoutContext_1 = require("./TimelineRowLayoutContext");
9
10
  const TimelineSelection_1 = require("./TimelineSelection");
10
11
  const fieldNameBase = {
11
12
  fontSize: 12,
@@ -18,12 +19,13 @@ const fieldNameBase = {
18
19
  minWidth: 0,
19
20
  };
20
21
  const TimelineFieldLabel = ({ rowDepth, selected, label, stacked = false }) => {
22
+ const { basePadding } = (0, react_1.useContext)(TimelineRowLayoutContext_1.TimelineRowLayoutContext);
21
23
  const labelRowStyle = (0, react_1.useMemo)(() => ({
22
- ...(0, timeline_field_row_layout_1.getTimelineFieldLabelRowStyle)(rowDepth),
24
+ ...(0, timeline_field_row_layout_1.getTimelineFieldLabelRowStyle)(rowDepth, basePadding),
23
25
  ...(0, TimelineSelection_1.getTimelineSelectedLabelStyle)(selected, true),
24
26
  ...(stacked ? { flex: `0 0 ${timeline_layout_1.SCHEMA_FIELD_ROW_HEIGHT}px` } : null),
25
27
  alignSelf: 'stretch',
26
- }), [rowDepth, selected, stacked]);
28
+ }), [basePadding, rowDepth, selected, stacked]);
27
29
  const fieldNameStyle = (0, react_1.useMemo)(() => ({
28
30
  ...fieldNameBase,
29
31
  color: (0, TimelineSelection_1.getTimelineColor)(selected, true),
@@ -114,6 +114,7 @@ const resolveKeyframeControlTarget = ({ nodePathInfo, tracks, propStatuses, getD
114
114
  getEffectDragOverrides,
115
115
  propStatuses,
116
116
  includeTextContent: false,
117
+ includeSourceControls: false,
117
118
  });
118
119
  const fieldNode = findFieldNode(tree, (0, timeline_node_path_key_1.timelineNodePathInfoToKey)(nodePathInfo));
119
120
  if (fieldNode === null || fieldNode.field === null) {
@@ -12,7 +12,8 @@ const container = {
12
12
  const TimelineList = ({ timeline }) => {
13
13
  return (jsx_runtime_1.jsxs("div", { style: container, children: [
14
14
  jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePadding, {}), timeline.map((track, trackIndex) => {
15
- return (jsx_runtime_1.jsx("div", { children: jsx_runtime_1.jsx(TimelineSequenceItem_1.TimelineSequenceItem, { trackIndex: trackIndex, nestedDepth: track.depth, sequence: track.sequence, nodePathInfo: track.nodePathInfo, keyframeDisplayOffset: track.keyframeDisplayOffset, sequenceFrameOffset: track.sequenceFrameOffset }, track.sequence.id) }, track.sequence.id));
15
+ var _a;
16
+ return (jsx_runtime_1.jsx("div", { children: jsx_runtime_1.jsx(TimelineSequenceItem_1.TimelineSequenceItem, { trackIndex: trackIndex, connectedCompositions: (_a = track.connectedCompositions) !== null && _a !== void 0 ? _a : [], nestedDepth: track.depth, sequence: track.sequence, nodePathInfo: track.nodePathInfo, keyframeDisplayOffset: track.keyframeDisplayOffset, sequenceFrameOffset: track.sequenceFrameOffset }, track.sequence.id) }, track.sequence.id));
16
17
  })] }));
17
18
  };
18
19
  exports.TimelineList = TimelineList;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TimelinePrimitiveFieldValue = exports.isTimelinePrimitiveFieldInfo = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const TimelineAssetField_1 = require("./TimelineAssetField");
5
6
  const TimelineBooleanField_1 = require("./TimelineBooleanField");
6
7
  const TimelineColorField_1 = require("./TimelineColorField");
7
8
  const TimelineEnumField_1 = require("./TimelineEnumField");
@@ -17,9 +18,7 @@ const inlineWrapper = {
17
18
  fontSize: 12,
18
19
  };
19
20
  const isTimelinePrimitiveFieldInfo = (field) => {
20
- return (field.typeName !== 'array' &&
21
- field.typeName !== 'hidden' &&
22
- field.fieldSchema.type !== 'array');
21
+ return field.typeName !== 'array' && field.fieldSchema.type !== 'array';
23
22
  };
24
23
  exports.isTimelinePrimitiveFieldInfo = isTimelinePrimitiveFieldInfo;
25
24
  const TimelinePrimitiveFieldValue = ({ field, onSave, onDragValueChange, onDragEnd, propStatus, effectiveValue, scaleLockNodePath, }) => {
@@ -60,6 +59,9 @@ const TimelinePrimitiveFieldValue = ({ field, onSave, onDragValueChange, onDragE
60
59
  if (field.typeName === 'font-family') {
61
60
  return (jsx_runtime_1.jsx("span", { style: inlineWrapper, children: jsx_runtime_1.jsx(TimelineFontFamilyField_1.TimelineFontFamilyField, { effectiveValue: effectiveValue, field: field, onDragEnd: onDragEnd, onDragValueChange: onDragValueChange, onSave: onSave, propStatus: propStatus }) }));
62
61
  }
62
+ if (field.typeName === 'asset') {
63
+ return (jsx_runtime_1.jsx("span", { style: inlineWrapper, children: jsx_runtime_1.jsx(TimelineAssetField_1.TimelineAssetField, { effectiveValue: effectiveValue, field: field, onDragEnd: onDragEnd, onDragValueChange: onDragValueChange, onSave: onSave, propStatus: propStatus }) }));
64
+ }
63
65
  throw new Error(`Unsupported field type: ${field.typeName}`);
64
66
  };
65
67
  exports.TimelinePrimitiveFieldValue = TimelinePrimitiveFieldValue;
@@ -6,6 +6,7 @@ const react_1 = require("react");
6
6
  const colors_1 = require("../../helpers/colors");
7
7
  const Padder_1 = require("./Padder");
8
8
  const timeline_row_layout_1 = require("./timeline-row-layout");
9
+ const TimelineRowLayoutContext_1 = require("./TimelineRowLayoutContext");
9
10
  const TimelineSelection_1 = require("./TimelineSelection");
10
11
  const rowBase = {
11
12
  alignItems: 'stretch',
@@ -19,27 +20,28 @@ const leftChromeStyle = {
19
20
  };
20
21
  const keyframeControlsColumnBaseStyle = {
21
22
  alignItems: 'center',
22
- boxSizing: 'border-box',
23
23
  display: 'flex',
24
24
  flexShrink: 0,
25
25
  justifyContent: 'flex-start',
26
- paddingLeft: timeline_row_layout_1.TIMELINE_ROW_BASE_PADDING,
27
26
  };
28
27
  const TimelineRowChrome = ({ depth, eye, keyframeControls, arrow, children, style, selected, selectable, selectionItem, onSelect, showSelectedBackground, containsSelection, outerHeight, onDragLeave, onDragOver, onDrop, onDoubleClick, }) => {
29
28
  const ref = (0, react_1.useRef)(null);
29
+ const { basePadding, keyframeControlsPadding } = (0, react_1.useContext)(TimelineRowLayoutContext_1.TimelineRowLayoutContext);
30
30
  const indentWidth = (0, timeline_row_layout_1.getTimelineRowIndentWidth)(depth);
31
31
  (0, TimelineSelection_1.useTimelineFocusableItem)(selectionItem, ref);
32
32
  const keyframeControlsColumnStyle = (0, react_1.useMemo)(() => ({
33
33
  ...keyframeControlsColumnBaseStyle,
34
- width: (0, timeline_row_layout_1.getTimelineRowLeftChromeWidth)(depth),
35
- }), [depth]);
34
+ boxSizing: keyframeControlsPadding === 0 ? undefined : 'border-box',
35
+ paddingLeft: keyframeControlsPadding,
36
+ width: (0, timeline_row_layout_1.getTimelineRowLeftChromeWidth)(depth, basePadding),
37
+ }), [basePadding, depth, keyframeControlsPadding]);
36
38
  const chromeColumnStyle = (0, react_1.useMemo)(() => ({
37
39
  alignItems: 'center',
38
40
  alignSelf: 'stretch',
39
41
  display: 'flex',
40
42
  flexShrink: 0,
41
- paddingLeft: timeline_row_layout_1.TIMELINE_ROW_BASE_PADDING,
42
- }), []);
43
+ paddingLeft: basePadding,
44
+ }), [basePadding]);
43
45
  const onPointerDown = (0, react_1.useCallback)((e) => {
44
46
  if (e.button === 0) {
45
47
  e.stopPropagation();
@@ -0,0 +1,7 @@
1
+ type TimelineRowLayout = {
2
+ readonly basePadding: number;
3
+ readonly keyframeControlsPadding: number;
4
+ };
5
+ export declare const INSPECTOR_TIMELINE_ROW_LAYOUT: TimelineRowLayout;
6
+ export declare const TimelineRowLayoutContext: import("react").Context<TimelineRowLayout>;
7
+ export {};
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TimelineRowLayoutContext = exports.INSPECTOR_TIMELINE_ROW_LAYOUT = void 0;
4
+ const react_1 = require("react");
5
+ const timeline_row_layout_1 = require("./timeline-row-layout");
6
+ exports.INSPECTOR_TIMELINE_ROW_LAYOUT = {
7
+ basePadding: timeline_row_layout_1.INSPECTOR_ROW_BASE_PADDING,
8
+ keyframeControlsPadding: 0,
9
+ };
10
+ exports.TimelineRowLayoutContext = (0, react_1.createContext)({
11
+ basePadding: timeline_row_layout_1.TIMELINE_ROW_BASE_PADDING,
12
+ keyframeControlsPadding: timeline_row_layout_1.TIMELINE_ROW_BASE_PADDING,
13
+ });
@@ -221,10 +221,26 @@ const isTimelineSelectionCompatibleWithMarqueeKind = (item, kind) => {
221
221
  return item.type === 'keyframe' || item.type === 'easing';
222
222
  };
223
223
  const getTimelineMarqueeSelection = ({ candidates, lockedSelectionKind, marqueeRect, }) => {
224
- const intersectingCandidates = candidates.filter((candidate) => {
224
+ const geometricallyIntersectingCandidates = candidates.filter((candidate) => {
225
225
  return (getTimelineMarqueeSelectionKind(candidate.item) !== null &&
226
226
  (0, exports.timelineMarqueeRectsIntersect)(candidate.rect, marqueeRect));
227
227
  });
228
+ const intersectingKeyframes = new Set(geometricallyIntersectingCandidates.flatMap((candidate) => {
229
+ if (candidate.item.type !== 'keyframe') {
230
+ return [];
231
+ }
232
+ return [
233
+ `${(0, timeline_node_path_key_1.timelineNodePathInfoToKey)(candidate.item.nodePathInfo)}.${candidate.item.frame}`,
234
+ ];
235
+ }));
236
+ const intersectingCandidates = geometricallyIntersectingCandidates.filter((candidate) => {
237
+ if (candidate.item.type !== 'easing') {
238
+ return true;
239
+ }
240
+ const fieldKey = (0, timeline_node_path_key_1.timelineNodePathInfoToKey)(candidate.item.nodePathInfo);
241
+ return (intersectingKeyframes.has(`${fieldKey}.${candidate.item.fromFrame}`) &&
242
+ intersectingKeyframes.has(`${fieldKey}.${candidate.item.toFrame}`));
243
+ });
228
244
  const getFirstIntersectingSelectionKind = () => intersectingCandidates.length === 0
229
245
  ? null
230
246
  : getTimelineMarqueeSelectionKind(intersectingCandidates[0].item);
@@ -363,8 +379,6 @@ const getSelectableTimelineSequenceSelections = (tracks) => {
363
379
  });
364
380
  };
365
381
  exports.getSelectableTimelineSequenceSelections = getSelectableTimelineSequenceSelections;
366
- const canEditEasingForInterpolationFunction = (interpolationFunction) => interpolationFunction === 'interpolate' ||
367
- interpolationFunction === 'interpolateColors';
368
382
  const getTimelineTreeNodeCanEditEasing = ({ node, nodePathInfo, propStatuses, }) => {
369
383
  var _a;
370
384
  if (node.kind !== 'field' || node.field === null) {
@@ -373,7 +387,7 @@ const getTimelineTreeNodeCanEditEasing = ({ node, nodePathInfo, propStatuses, })
373
387
  if (node.field.kind === 'sequence-field') {
374
388
  const sequencePropStatus = (_a = remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePathInfo.sequenceSubscriptionKey)) === null || _a === void 0 ? void 0 : _a[node.field.key];
375
389
  return ((sequencePropStatus === null || sequencePropStatus === void 0 ? void 0 : sequencePropStatus.status) === 'keyframed' &&
376
- canEditEasingForInterpolationFunction(sequencePropStatus.interpolationFunction));
390
+ (0, studio_shared_1.canEditEasingForInterpolationFunction)(sequencePropStatus.interpolationFunction));
377
391
  }
378
392
  const effectStatus = remotion_1.Internals.getEffectPropStatusesCtx({
379
393
  propStatuses,
@@ -384,7 +398,7 @@ const getTimelineTreeNodeCanEditEasing = ({ node, nodePathInfo, propStatuses, })
384
398
  ? effectStatus.props[node.field.key]
385
399
  : null;
386
400
  return ((effectPropStatus === null || effectPropStatus === void 0 ? void 0 : effectPropStatus.status) === 'keyframed' &&
387
- canEditEasingForInterpolationFunction(effectPropStatus.interpolationFunction));
401
+ (0, studio_shared_1.canEditEasingForInterpolationFunction)(effectPropStatus.interpolationFunction));
388
402
  };
389
403
  const getSelectableTimelineItems = ({ getDragOverrides, getEffectDragOverrides, getIsExpanded, propStatuses, selectedItems, timeline, timelinePosition, }) => {
390
404
  const selectedRowKeys = (0, timeline_expanded_filter_1.getSelectedTimelineExpandedRowKeys)(selectedItems);
@@ -407,6 +421,7 @@ const getSelectableTimelineItems = ({ getDragOverrides, getEffectDragOverrides,
407
421
  getEffectDragOverrides,
408
422
  propStatuses,
409
423
  includeTextContent: false,
424
+ includeSourceControls: false,
410
425
  });
411
426
  const filteredTree = (0, timeline_expanded_filter_1.filterTimelineExpandedTree)({
412
427
  nodes: tree,
@@ -1,8 +1,9 @@
1
1
  import React from 'react';
2
- import type { TSequence } from 'remotion';
2
+ import type { _InternalTypes, TSequence } from 'remotion';
3
3
  import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
4
4
  export declare const TimelineSequenceItem: React.FC<{
5
5
  readonly sequence: TSequence;
6
+ readonly connectedCompositions: readonly _InternalTypes['AnyComposition'][];
6
7
  readonly nestedDepth: number;
7
8
  readonly nodePathInfo: SequenceNodePathInfo | null;
8
9
  readonly keyframeDisplayOffset: number;
@@ -40,16 +40,19 @@ const remotion_1 = require("remotion");
40
40
  const client_id_1 = require("../../helpers/client-id");
41
41
  const colors_1 = require("../../helpers/colors");
42
42
  const format_file_location_1 = require("../../helpers/format-file-location");
43
+ const get_sequence_double_click_action_1 = require("../../helpers/get-sequence-double-click-action");
43
44
  const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
44
45
  const studio_runtime_config_1 = require("../../helpers/studio-runtime-config");
45
46
  const timeline_layout_1 = require("../../helpers/timeline-layout");
46
47
  const use_keybinding_1 = require("../../helpers/use-keybinding");
47
48
  const modals_1 = require("../../state/modals");
48
49
  const call_api_1 = require("../call-api");
50
+ const CompositionOrStillIcon_1 = require("../CompositionOrStillIcon");
49
51
  const ConfirmationDialog_1 = require("../ConfirmationDialog");
50
52
  const ContextMenu_1 = require("../ContextMenu");
51
53
  const effect_drag_and_drop_1 = require("../effect-drag-and-drop");
52
54
  const ExpandedTracksProvider_1 = require("../ExpandedTracksProvider");
55
+ const InitialCompositionLoader_1 = require("../InitialCompositionLoader");
53
56
  const layout_1 = require("../layout");
54
57
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
55
58
  const use_select_asset_1 = require("../use-select-asset");
@@ -76,6 +79,11 @@ const labelContainerStyle = {
76
79
  flexDirection: 'row',
77
80
  minWidth: 0,
78
81
  };
82
+ const connectedCompositionIconStyle = {
83
+ flexShrink: 0,
84
+ height: 12,
85
+ width: 12,
86
+ };
79
87
  const effectDropHighlight = {
80
88
  backgroundColor: colors_1.TIMELINE_DROP_BLUE_ALPHA_16,
81
89
  outline: colors_1.BORDER_TIMELINE_DROP_BLUE,
@@ -88,6 +96,7 @@ const TimelineSequenceExpandArrow = ({ disabled, isExpanded, nodePathInfo, onTog
88
96
  sequence,
89
97
  nodePathInfo,
90
98
  includeTextContent: false,
99
+ includeSourceControls: false,
91
100
  });
92
101
  if (filteredTree.length === 0) {
93
102
  return jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {});
@@ -154,7 +163,7 @@ const getSequenceReorderDragData = (dataTransfer) => {
154
163
  const getDestinationIndex = ({ fromIndex, insertionIndex, }) => {
155
164
  return insertionIndex > fromIndex ? insertionIndex - 1 : insertionIndex;
156
165
  };
157
- const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDisplayOffset, sequenceFrameOffset, trackIndex, }) => {
166
+ const TimelineSequenceItem = ({ connectedCompositions, nestedDepth, sequence, nodePathInfo, keyframeDisplayOffset, sequenceFrameOffset, trackIndex, }) => {
158
167
  var _a, _b, _c;
159
168
  var _d, _e, _f;
160
169
  const nodePath = (_d = nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.sequenceSubscriptionKey) !== null && _d !== void 0 ? _d : null;
@@ -167,6 +176,7 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
167
176
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
168
177
  const { isHighestContext } = (0, use_keybinding_1.useKeybinding)();
169
178
  const selectAsset = (0, use_select_asset_1.useSelectAsset)();
179
+ const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
170
180
  const { onSelect, selectable, selected, selectionItem } = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
171
181
  const { selectedItems } = (0, TimelineSelection_1.useTimelineSelection)();
172
182
  const containsSelection = (0, TimelineSelection_1.useTimelineRowContainsSelection)(nodePathInfo);
@@ -201,6 +211,9 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
201
211
  sequence,
202
212
  validatedLocation,
203
213
  });
214
+ const timelineDisplayName = sequence.displayName === '' && connectedCompositions.length === 1
215
+ ? connectedCompositions[0].id
216
+ : displayName;
204
217
  const canDeleteFromSource = Boolean(nodePath && (validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source));
205
218
  const nodePathKey = (0, react_1.useMemo)(() => nodePath ? remotion_1.Internals.makeSequencePropsSubscriptionKey(nodePath) : null, [nodePath]);
206
219
  const parentId = (_e = sequence.parent) !== null && _e !== void 0 ? _e : null;
@@ -535,17 +548,27 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
535
548
  codeHiddenStatus !== undefined &&
536
549
  codeHiddenStatus !== null &&
537
550
  codeHiddenStatus.status === 'static';
538
- const onShowInEditorDoubleClick = (0, react_1.useCallback)((e) => {
539
- if (!canOpenInEditor) {
540
- return;
541
- }
551
+ const onSequenceDoubleClick = (0, react_1.useCallback)((e) => {
542
552
  if ((0, TimelineSelection_1.isTimelineSelectionModifierEvent)(e)) {
543
553
  e.stopPropagation();
544
554
  return;
545
555
  }
556
+ const action = (0, get_sequence_double_click_action_1.getSequenceDoubleClickAction)({
557
+ button: e.button,
558
+ canOpenInEditor,
559
+ numberOfConnectedCompositions: connectedCompositions.length,
560
+ });
561
+ if (action === null) {
562
+ return;
563
+ }
546
564
  e.stopPropagation();
565
+ if (action === 'open-connected-composition') {
566
+ selectComposition(connectedCompositions[0], true);
567
+ return;
568
+ }
547
569
  openInEditor();
548
- }, [canOpenInEditor, openInEditor]);
570
+ }, [canOpenInEditor, connectedCompositions, openInEditor, selectComposition]);
571
+ const canHandleSequenceDoubleClick = connectedCompositions.length === 1 || canOpenInEditor;
549
572
  const canRenameSelectedSequence = canRenameThisSequence &&
550
573
  selected &&
551
574
  selectedItems.length === 1 &&
@@ -765,8 +788,9 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
765
788
  clientId: previewServerState.clientId,
766
789
  });
767
790
  }, [canDropEffect, nodePath, previewServerState, validatedLocation]);
768
- const trackRow = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: nestedDepth, eye: canToggleVisibility ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: sequence.type === 'audio' ? 'speaker' : 'eye', hidden: isItemHidden, onInvoked: onToggleVisibility })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: hasExpandableContent && nodePathInfo !== null ? (jsx_runtime_1.jsx(TimelineSequenceExpandArrow, { disabled: !previewInteractive, isExpanded: isExpanded, nodePathInfo: nodePathInfo, onToggleExpand: onToggleExpand, sequence: sequence })) : (jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {})), style: rowStyle, selected: selected, selectable: selectable, selectionItem: selectionItem, onSelect: onSelect, showSelectedBackground: true, containsSelection: containsSelection, outerHeight: outerHeight, onDragLeave: canDropEffect ? onEffectDragLeave : undefined, onDragOver: canDropEffect ? onEffectDragOver : undefined, onDrop: canDropEffect ? onEffectDrop : undefined, onDoubleClick: canOpenInEditor ? onShowInEditorDoubleClick : undefined, children: jsx_runtime_1.jsxs("div", { style: labelContainerStyle, children: [
769
- jsx_runtime_1.jsx(TimelineSequenceName_1.TimelineSequenceName, { displayName: displayName, fallbackDisplayName: fallbackDisplayName, selected: selected, containsSelection: containsSelection, editing: isRenaming, onCancelEditing: onCancelRenaming, onSaveName: onSaveName }), mediaSrc ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
791
+ const trackRow = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: nestedDepth, eye: canToggleVisibility ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: sequence.type === 'audio' ? 'speaker' : 'eye', hidden: isItemHidden, onInvoked: onToggleVisibility })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: hasExpandableContent && nodePathInfo !== null ? (jsx_runtime_1.jsx(TimelineSequenceExpandArrow, { disabled: !previewInteractive, isExpanded: isExpanded, nodePathInfo: nodePathInfo, onToggleExpand: onToggleExpand, sequence: sequence })) : (jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {})), style: rowStyle, selected: selected, selectable: selectable, selectionItem: selectionItem, onSelect: onSelect, showSelectedBackground: true, containsSelection: containsSelection, outerHeight: outerHeight, onDragLeave: canDropEffect ? onEffectDragLeave : undefined, onDragOver: canDropEffect ? onEffectDragOver : undefined, onDrop: canDropEffect ? onEffectDrop : undefined, onDoubleClick: canHandleSequenceDoubleClick ? onSequenceDoubleClick : undefined, children: jsx_runtime_1.jsxs("div", { style: labelContainerStyle, children: [connectedCompositions.length > 0 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
792
+ jsx_runtime_1.jsx(CompositionOrStillIcon_1.CompositionOrStillIcon, { color: (0, TimelineSelection_1.getTimelineColor)(false, false), composition: connectedCompositions[0], style: connectedCompositionIconStyle }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 })
793
+ ] })) : null, jsx_runtime_1.jsx(TimelineSequenceName_1.TimelineSequenceName, { displayName: timelineDisplayName, fallbackDisplayName: fallbackDisplayName, selected: selected, containsSelection: containsSelection, editing: isRenaming, onCancelEditing: onCancelRenaming, onSaveName: onSaveName }), mediaSrc ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
770
794
  jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }),
771
795
  " ",
772
796
  jsx_runtime_1.jsx(TimelineMediaInfo_1.TimelineMediaInfo, { src: mediaSrc })
@@ -24,7 +24,11 @@ const TimelineSequenceName = ({ displayName, fallbackDisplayName, selected, cont
24
24
  alignSelf: 'stretch',
25
25
  ...(0, TimelineSelection_1.getTimelineSelectedLabelStyle)(selected, false),
26
26
  display: 'inline-flex',
27
+ fontFamily: 'inherit',
27
28
  fontSize: 12,
29
+ lineHeight: 'normal',
30
+ minWidth: 0,
31
+ overflow: 'hidden',
28
32
  whiteSpace: 'nowrap',
29
33
  textOverflow: 'ellipsis',
30
34
  color: (0, TimelineSelection_1.getTimelineColor)(selected, false),
@@ -31,15 +31,15 @@ const getSequenceContextMenuItems = ({ assetLinkInfo, canOpenInEditor, deleteDis
31
31
  editorName
32
32
  ? {
33
33
  type: 'item',
34
- id: 'show-in-editor',
34
+ id: 'open-in-editor',
35
35
  keyHint: null,
36
- label: `Show in ${editorName}`,
36
+ label: `Open in ${editorName}`,
37
37
  leftItem: null,
38
38
  disabled: !canOpenInEditor || !originalLocation,
39
39
  onClick: openInEditor,
40
40
  quickSwitcherLabel: null,
41
41
  subMenu: null,
42
- value: 'show-in-editor',
42
+ value: 'open-in-editor',
43
43
  }
44
44
  : null,
45
45
  {
@@ -0,0 +1,34 @@
1
+ import type { KeyframeClipboardData } from '@remotion/studio-shared';
2
+ import { type InteractivitySchema, type OverrideIdToNodePaths, type PropStatuses, type SequencePropsSubscriptionKey, type TSequence } from 'remotion';
3
+ import type { TimelineSelection } from './TimelineSelection';
4
+ export declare const getKeyframeClipboardDataFromSelections: ({ selections, sequences, overrideIdsToNodePaths, propStatuses, }: {
5
+ readonly selections: readonly TimelineSelection[];
6
+ readonly sequences: TSequence[];
7
+ readonly overrideIdsToNodePaths: OverrideIdToNodePaths;
8
+ readonly propStatuses: PropStatuses;
9
+ }) => KeyframeClipboardData | null;
10
+ export type PasteKeyframeTarget = {
11
+ readonly type: 'valid';
12
+ readonly fileName: string;
13
+ readonly nodePath: SequencePropsSubscriptionKey;
14
+ readonly fieldKey: string;
15
+ readonly effectIndex: number | null;
16
+ readonly keyframes: readonly {
17
+ readonly sourceFrame: number;
18
+ readonly value: unknown;
19
+ }[];
20
+ readonly keyframesToDelete: readonly number[];
21
+ readonly easing: KeyframeClipboardData['easing'];
22
+ readonly firstEasingSegmentIndex: number;
23
+ readonly schema: InteractivitySchema;
24
+ } | {
25
+ readonly type: 'none' | 'multiple' | 'uncopyable' | 'incompatible';
26
+ };
27
+ export declare const getPasteKeyframeTarget: ({ selectedItems, payload, timelinePosition, sequences, overrideIdsToNodePaths, propStatuses, }: {
28
+ readonly selectedItems: readonly TimelineSelection[];
29
+ readonly payload: KeyframeClipboardData;
30
+ readonly timelinePosition: number;
31
+ readonly sequences: TSequence[];
32
+ readonly overrideIdsToNodePaths: OverrideIdToNodePaths;
33
+ readonly propStatuses: PropStatuses;
34
+ }) => PasteKeyframeTarget;