@remotion/studio 4.0.479 → 4.0.482

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 (75) hide show
  1. package/dist/components/AudioWaveform.js +19 -11
  2. package/dist/components/Button.d.ts +1 -0
  3. package/dist/components/Button.js +2 -2
  4. package/dist/components/CurrentCompositionSideEffects.d.ts +0 -3
  5. package/dist/components/CurrentCompositionSideEffects.js +1 -37
  6. package/dist/components/Editor.js +2 -5
  7. package/dist/components/EditorContent.js +2 -1
  8. package/dist/components/ExpandedTracksProvider.d.ts +1 -0
  9. package/dist/components/ExpandedTracksProvider.js +81 -7
  10. package/dist/components/GlobalKeybindings.d.ts +3 -1
  11. package/dist/components/GlobalKeybindings.js +104 -10
  12. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +7 -5
  13. package/dist/components/InspectorPanel/inspector-selection.d.ts +3 -3
  14. package/dist/components/InspectorPanel/inspector-selection.js +7 -6
  15. package/dist/components/InspectorPanel/styles.d.ts +1 -0
  16. package/dist/components/InspectorPanel/styles.js +19 -1
  17. package/dist/components/InspectorPanel.js +3 -3
  18. package/dist/components/InspectorSequenceSection.d.ts +3 -0
  19. package/dist/components/InspectorSequenceSection.js +12 -2
  20. package/dist/components/KeyboardShortcutsExplainer.js +10 -2
  21. package/dist/components/MediaVolumeProvider.js +4 -4
  22. package/dist/components/Modals.js +2 -1
  23. package/dist/components/NewComposition/CodemodFooter.d.ts +1 -0
  24. package/dist/components/NewComposition/CodemodFooter.js +25 -3
  25. package/dist/components/NewComposition/InputDragger.d.ts +4 -0
  26. package/dist/components/NewComposition/InputDragger.js +18 -2
  27. package/dist/components/NewComposition/NewComposition.d.ts +2 -0
  28. package/dist/components/NewComposition/NewComposition.js +178 -0
  29. package/dist/components/PreviewToolbar.js +3 -3
  30. package/dist/components/ResetZoomButton.d.ts +2 -1
  31. package/dist/components/ResetZoomButton.js +5 -1
  32. package/dist/components/SelectedOutlineElement.js +39 -0
  33. package/dist/components/SelectedOutlineOverlay.d.ts +6 -0
  34. package/dist/components/SelectedOutlineOverlay.js +21 -3
  35. package/dist/components/Timeline/Timeline.js +9 -9
  36. package/dist/components/Timeline/TimelineEffectItem.js +1 -1
  37. package/dist/components/Timeline/TimelineEffectPropItem.js +1 -1
  38. package/dist/components/Timeline/TimelineExpandArrowButton.js +42 -2
  39. package/dist/components/Timeline/TimelineExpandedRow.js +2 -2
  40. package/dist/components/Timeline/TimelineExpandedSection.js +8 -9
  41. package/dist/components/Timeline/TimelineRowChrome.d.ts +2 -0
  42. package/dist/components/Timeline/TimelineRowChrome.js +5 -3
  43. package/dist/components/Timeline/TimelineSelection.d.ts +26 -3
  44. package/dist/components/Timeline/TimelineSelection.js +322 -91
  45. package/dist/components/Timeline/TimelineSequenceItem.js +62 -5
  46. package/dist/components/Timeline/TimelineSequencePropItem.js +1 -1
  47. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +6 -4
  48. package/dist/components/Timeline/find-track-for-node-path-info.js +2 -2
  49. package/dist/components/Timeline/get-node-keyframes.d.ts +7 -0
  50. package/dist/components/Timeline/get-node-keyframes.js +26 -1
  51. package/dist/components/Timeline/reset-selected-timeline-props.js +15 -2
  52. package/dist/components/Timeline/timeline-expanded-filter.d.ts +12 -0
  53. package/dist/components/Timeline/timeline-expanded-filter.js +38 -0
  54. package/dist/components/Timeline/timeline-field-display-utils.js +3 -0
  55. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +50 -18
  56. package/dist/components/Timeline/use-timeline-expanded-tree.d.ts +1 -0
  57. package/dist/components/Timeline/use-timeline-expanded-tree.js +27 -0
  58. package/dist/components/Timeline/use-timeline-height.js +51 -7
  59. package/dist/components/Timeline/use-timeline-keyframe-drag.js +12 -6
  60. package/dist/components/TopPanel.js +1 -1
  61. package/dist/components/composition-menu-items.js +17 -0
  62. package/dist/components/selected-outline-measurement.js +48 -14
  63. package/dist/error-overlay/remotion-overlay/ErrorLoader.js +8 -1
  64. package/dist/esm/{chunk-fge2mq5p.js → chunk-nkqfa5bw.js} +17611 -16502
  65. package/dist/esm/internals.mjs +17611 -16502
  66. package/dist/esm/previewEntry.mjs +5179 -4068
  67. package/dist/esm/renderEntry.mjs +1 -1
  68. package/dist/helpers/calculate-timeline.js +6 -2
  69. package/dist/helpers/get-sequence-visible-range.d.ts +1 -0
  70. package/dist/helpers/get-sequence-visible-range.js +15 -1
  71. package/dist/helpers/migrate-expanded-tracks-for-subscription-key.js +3 -3
  72. package/dist/state/modals.d.ts +2 -0
  73. package/package.json +11 -11
  74. package/dist/components/Timeline/TimelineItemStack.d.ts +0 -5
  75. package/dist/components/Timeline/TimelineItemStack.js +0 -29
@@ -41,6 +41,7 @@ const client_id_1 = require("../../helpers/client-id");
41
41
  const format_file_location_1 = require("../../helpers/format-file-location");
42
42
  const timeline_layout_1 = require("../../helpers/timeline-layout");
43
43
  const use_keybinding_1 = require("../../helpers/use-keybinding");
44
+ const modals_1 = require("../../state/modals");
44
45
  const call_api_1 = require("../call-api");
45
46
  const ConfirmationDialog_1 = require("../ConfirmationDialog");
46
47
  const ContextMenu_1 = require("../ContextMenu");
@@ -56,7 +57,6 @@ const save_sequence_prop_1 = require("./save-sequence-prop");
56
57
  const timeline_asset_link_1 = require("./timeline-asset-link");
57
58
  const TimelineExpandArrowButton_1 = require("./TimelineExpandArrowButton");
58
59
  const TimelineExpandedSection_1 = require("./TimelineExpandedSection");
59
- const TimelineItemStack_1 = require("./TimelineItemStack");
60
60
  const TimelineLayerEye_1 = require("./TimelineLayerEye");
61
61
  const TimelineMediaInfo_1 = require("./TimelineMediaInfo");
62
62
  const TimelineRowChrome_1 = require("./TimelineRowChrome");
@@ -64,6 +64,7 @@ const TimelineSelection_1 = require("./TimelineSelection");
64
64
  const TimelineSequenceName_1 = require("./TimelineSequenceName");
65
65
  const use_open_sequence_in_editor_1 = require("./use-open-sequence-in-editor");
66
66
  const use_sequence_freeze_frame_menu_item_1 = require("./use-sequence-freeze-frame-menu-item");
67
+ const use_timeline_expanded_tree_1 = require("./use-timeline-expanded-tree");
67
68
  const labelContainerStyle = {
68
69
  alignItems: 'center',
69
70
  alignSelf: 'stretch',
@@ -78,6 +79,16 @@ const effectDropHighlight = {
78
79
  };
79
80
  const SEQUENCE_REORDER_MIME_TYPE = 'application/remotion-sequence-reorder';
80
81
  let currentSequenceDrag = null;
82
+ const TimelineSequenceExpandArrow = ({ disabled, isExpanded, nodePathInfo, onToggleExpand, sequence }) => {
83
+ const { filteredTree } = (0, use_timeline_expanded_tree_1.useTimelineExpandedTree)({
84
+ sequence,
85
+ nodePathInfo,
86
+ });
87
+ if (filteredTree.length === 0) {
88
+ return jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {});
89
+ }
90
+ return (jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowButton, { isExpanded: isExpanded, onClick: onToggleExpand, label: "track properties", disabled: disabled }));
91
+ };
81
92
  const sequenceReorderWrapper = {
82
93
  position: 'relative',
83
94
  };
@@ -148,9 +159,10 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
148
159
  const { toggleTrack } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksSetterContext);
149
160
  const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
150
161
  const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
162
+ const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
151
163
  const { isHighestContext } = (0, use_keybinding_1.useKeybinding)();
152
164
  const selectAsset = (0, use_select_asset_1.useSelectAsset)();
153
- const { onSelect, selectable, selected } = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
165
+ const { onSelect, selectable, selected, selectionItem } = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
154
166
  const { selectedItems } = (0, TimelineSelection_1.useTimelineSelection)();
155
167
  const containsSelection = (0, TimelineSelection_1.useTimelineRowContainsSelection)(nodePathInfo);
156
168
  const [effectDropHovered, setEffectDropHovered] = (0, react_1.useState)(false);
@@ -629,6 +641,29 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
629
641
  timelinePosition,
630
642
  validatedSource: (_f = validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source) !== null && _f !== void 0 ? _f : null,
631
643
  });
644
+ const canAddEffect = (nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.supportsEffects) === true &&
645
+ previewServerState.type === 'connected' &&
646
+ Boolean(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source);
647
+ const onAddEffect = (0, react_1.useCallback)(() => {
648
+ if (!canAddEffect ||
649
+ previewServerState.type !== 'connected' ||
650
+ !nodePath ||
651
+ !(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source)) {
652
+ return;
653
+ }
654
+ setSelectedModal({
655
+ type: 'add-effect',
656
+ clientId: previewServerState.clientId,
657
+ fileName: validatedLocation.source,
658
+ nodePath,
659
+ });
660
+ }, [
661
+ canAddEffect,
662
+ nodePath,
663
+ previewServerState,
664
+ setSelectedModal,
665
+ validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source,
666
+ ]);
632
667
  const contextMenuValues = (0, react_1.useMemo)(() => {
633
668
  if (!previewConnected) {
634
669
  return [];
@@ -649,6 +684,26 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
649
684
  selectAsset,
650
685
  sequence,
651
686
  sourceActions: [
687
+ ...((nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.supportsEffects)
688
+ ? [
689
+ {
690
+ type: 'item',
691
+ id: 'add-effect',
692
+ keyHint: null,
693
+ label: 'Add effect...',
694
+ leftItem: null,
695
+ disabled: !canAddEffect,
696
+ onClick: onAddEffect,
697
+ quickSwitcherLabel: null,
698
+ subMenu: null,
699
+ value: 'add-effect',
700
+ },
701
+ {
702
+ type: 'divider',
703
+ id: 'add-effect-divider',
704
+ },
705
+ ]
706
+ : []),
652
707
  {
653
708
  type: 'item',
654
709
  id: 'rename-sequence',
@@ -668,6 +723,7 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
668
723
  });
669
724
  }, [
670
725
  assetLinkInfo,
726
+ canAddEffect,
671
727
  canOpenInEditor,
672
728
  canRenameThisSequence,
673
729
  deleteDisabled,
@@ -675,6 +731,8 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
675
731
  duplicateDisabled,
676
732
  fileLocation,
677
733
  freezeFrameMenuItem,
734
+ nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.supportsEffects,
735
+ onAddEffect,
678
736
  onDeleteSequenceFromSource,
679
737
  onDisableSequenceInteractivity,
680
738
  onDuplicateSequenceFromSource,
@@ -743,13 +801,12 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
743
801
  clientId: previewServerState.clientId,
744
802
  });
745
803
  }, [canDropEffect, nodePath, previewServerState, validatedLocation]);
746
- 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 ? (jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowButton, { isExpanded: isExpanded, onClick: onToggleExpand, label: "track properties", disabled: !previewConnected || nodePathInfo === null })) : (jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {})), style: rowStyle, selected: selected, selectable: selectable, 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: [
804
+ 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: !previewConnected, 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: [
747
805
  jsx_runtime_1.jsx(TimelineSequenceName_1.TimelineSequenceName, { displayName: displayName, selected: selected, containsSelection: containsSelection, editing: isRenaming, onCancelEditing: onCancelRenaming, onSaveName: onSaveName }), mediaSrc ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
748
806
  jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }),
749
807
  " ",
750
808
  jsx_runtime_1.jsx(TimelineMediaInfo_1.TimelineMediaInfo, { src: mediaSrc })
751
- ] })) : null, jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(TimelineItemStack_1.TimelineItemStack, { originalLocation: originalLocation })
752
- ] }) }));
809
+ ] })) : null] }) }));
753
810
  const draggableTrackRow = canHandleSequenceDrag ? (jsx_runtime_1.jsxs("div", { draggable: canReorderSequence, onDragStart: onSequenceDragStart, onDragEnd: onSequenceDragEnd, onDragOver: onSequenceDragOver, onDragLeave: onSequenceDragLeave, onDrop: onSequenceDrop, style: sequenceReorderWrapper, children: [sequenceReorderLineStyle ? (jsx_runtime_1.jsx("div", { style: sequenceReorderLineStyle })) : null, sequenceDropRejection ? (jsx_runtime_1.jsx("div", { style: sequenceReorderRejectionStyle, children: sequenceDropRejection })) : null, trackRow] })) : (trackRow);
754
811
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [previewConnected ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, onOpen: selectable ? onSelect : null, children: draggableTrackRow })) : (draggableTrackRow), previewConnected &&
755
812
  isExpanded &&
@@ -306,7 +306,7 @@ const TimelineSequencePropItem = ({ field, validatedLocation, rowDepth, nodePath
306
306
  if (propStatus === null) {
307
307
  return null;
308
308
  }
309
- const row = (jsx_runtime_1.jsxs(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {}), keyframeControls: keyframeControls, arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {}), style: style, selected: selection.selected, selectable: selection.selectable, onSelect: selection.onSelect, showSelectedBackground: true, containsSelection: false, outerHeight: null, children: [
309
+ const row = (jsx_runtime_1.jsxs(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {}), keyframeControls: keyframeControls, arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {}), style: style, selected: selection.selected, selectable: selection.selectable, selectionItem: selection.selectionItem, onSelect: selection.onSelect, showSelectedBackground: true, containsSelection: false, outerHeight: null, children: [
310
310
  jsx_runtime_1.jsx(TimelineFieldLabel_1.TimelineFieldLabel, { rowDepth: rowDepth, selected: selection.selected, label: (_b = field.description) !== null && _b !== void 0 ? _b : field.key }), isKeyframedStatus(propStatus) ? (jsx_runtime_1.jsx("div", { style: timeline_field_row_layout_1.timelineFieldValueColumnStyle, children: jsx_runtime_1.jsx(exports.TimelineSequenceKeyframedValue, { field: field, fileName: validatedLocation.source, nodePath: nodePath, schema: schema, propStatus: propStatus, sourceFrame: sourceFrame }) })) : propStatus.status === 'static' ? (jsx_runtime_1.jsx("div", { style: timeline_field_row_layout_1.timelineFieldValueColumnStyle, children: jsx_runtime_1.jsx(Value, { field: field, nodePath: nodePath, validatedLocation: validatedLocation, schema: schema, propStatus: propStatus }) })) : (jsx_runtime_1.jsx("div", { style: timeline_field_row_layout_1.timelineFieldValueColumnStyle, children: jsx_runtime_1.jsx(TimelineSchemaField_1.TimelineNonEditableStatus, { propStatus: propStatus }) }))] }));
311
311
  return (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, onOpen: selection.selectable ? selection.onSelect : null, children: row }));
312
312
  };
@@ -92,12 +92,12 @@ const getTimelineSequenceFromDragChanges = ({ targets, deltaFrames, }) => {
92
92
  };
93
93
  exports.getTimelineSequenceFromDragChanges = getTimelineSequenceFromDragChanges;
94
94
  const findSequenceTrack = ({ tracks, nodePathInfo, }) => {
95
- const key = (0, studio_shared_1.stringifySequenceSubscriptionKey)(nodePathInfo.sequenceSubscriptionKey);
95
+ const key = (0, studio_shared_1.stringifySequenceExpandedRowKey)(nodePathInfo.sequenceSubscriptionKey);
96
96
  return tracks.find((candidate) => {
97
97
  if (candidate.nodePathInfo === null) {
98
98
  return false;
99
99
  }
100
- return ((0, studio_shared_1.stringifySequenceSubscriptionKey)(candidate.nodePathInfo.sequenceSubscriptionKey) === key && candidate.nodePathInfo.index === nodePathInfo.index);
100
+ return ((0, studio_shared_1.stringifySequenceExpandedRowKey)(candidate.nodePathInfo.sequenceSubscriptionKey) === key && candidate.nodePathInfo.index === nodePathInfo.index);
101
101
  });
102
102
  };
103
103
  const getTimelineSequenceDurationDragTargets = ({ draggedNodePathInfo, selectedItems, sequences, overrideIdsToNodePaths, propStatuses, }) => {
@@ -120,11 +120,12 @@ const getTimelineSequenceDurationDragTargets = ({ draggedNodePathInfo, selectedI
120
120
  ? sequences.find((sequence) => sequence.id === track.sequence.id)
121
121
  : null;
122
122
  if (!track ||
123
+ !track.nodePathInfo ||
123
124
  !originalSequence ||
124
125
  !isDurationDraggableSequence(originalSequence)) {
125
126
  return null;
126
127
  }
127
- const nodePath = nodePathInfo.sequenceSubscriptionKey;
128
+ const nodePath = track.nodePathInfo.sequenceSubscriptionKey;
128
129
  if (!canUpdateDurationInFrames({ propStatuses, nodePath })) {
129
130
  return null;
130
131
  }
@@ -160,11 +161,12 @@ const getTimelineSequenceFromDragTargets = ({ draggedNodePathInfo, selectedItems
160
161
  ? sequences.find((sequence) => sequence.id === track.sequence.id)
161
162
  : null;
162
163
  if (!track ||
164
+ !track.nodePathInfo ||
163
165
  !originalSequence ||
164
166
  !isFromDraggableSequence(originalSequence)) {
165
167
  return null;
166
168
  }
167
- const nodePath = nodePathInfo.sequenceSubscriptionKey;
169
+ const nodePath = track.nodePathInfo.sequenceSubscriptionKey;
168
170
  if (!canUpdateFrom({ propStatuses, nodePath })) {
169
171
  return null;
170
172
  }
@@ -6,8 +6,8 @@ const calculate_timeline_1 = require("../../helpers/calculate-timeline");
6
6
  const findTrackForNodePathInfo = ({ sequences, overrideIdsToNodePaths, nodePathInfo, }) => {
7
7
  const tracks = (0, calculate_timeline_1.calculateTimeline)({ sequences, overrideIdsToNodePaths });
8
8
  return tracks.find((candidate) => candidate.nodePathInfo !== null &&
9
- (0, studio_shared_1.stringifySequenceSubscriptionKey)(candidate.nodePathInfo.sequenceSubscriptionKey) ===
10
- (0, studio_shared_1.stringifySequenceSubscriptionKey)(nodePathInfo.sequenceSubscriptionKey) &&
9
+ (0, studio_shared_1.stringifySequenceExpandedRowKey)(candidate.nodePathInfo.sequenceSubscriptionKey) ===
10
+ (0, studio_shared_1.stringifySequenceExpandedRowKey)(nodePathInfo.sequenceSubscriptionKey) &&
11
11
  candidate.nodePathInfo.index === nodePathInfo.index);
12
12
  };
13
13
  exports.findTrackForNodePathInfo = findTrackForNodePathInfo;
@@ -12,3 +12,10 @@ export declare const getNodeKeyframes: ({ node, nodePath, propStatuses, keyframe
12
12
  frame: number;
13
13
  value: unknown;
14
14
  }[];
15
+ export declare const getNodeHasKeyframes: ({ node, nodePath, propStatuses, getDragOverrides, getEffectDragOverrides, }: {
16
+ node: TimelineTreeNode;
17
+ nodePath: SequencePropsSubscriptionKey;
18
+ propStatuses: PropStatuses;
19
+ getDragOverrides: GetDragOverrides;
20
+ getEffectDragOverrides: GetEffectDragOverrides;
21
+ }) => boolean;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getNodeKeyframes = void 0;
3
+ exports.getNodeHasKeyframes = exports.getNodeKeyframes = void 0;
4
4
  const remotion_1 = require("remotion");
5
5
  const get_timeline_keyframes_1 = require("./get-timeline-keyframes");
6
6
  const hasOverride = (overrides, key) => Object.prototype.hasOwnProperty.call(overrides, key);
@@ -54,3 +54,28 @@ const getNodeKeyframes = ({ node, nodePath, propStatuses, keyframeDisplayOffset,
54
54
  });
55
55
  };
56
56
  exports.getNodeKeyframes = getNodeKeyframes;
57
+ const getNodeHasKeyframes = ({ node, nodePath, propStatuses, getDragOverrides, getEffectDragOverrides, }) => {
58
+ var _a, _b, _c, _d, _e, _f;
59
+ if (node.kind !== 'field' || node.field === null) {
60
+ return false;
61
+ }
62
+ if (node.field.kind === 'sequence-field') {
63
+ const dragOverrides = getDragOverrides(nodePath);
64
+ if (((_a = dragOverrides[node.field.key]) === null || _a === void 0 ? void 0 : _a.type) === 'keyframed') {
65
+ return true;
66
+ }
67
+ return (((_c = (_b = remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePath)) === null || _b === void 0 ? void 0 : _b[node.field.key]) === null || _c === void 0 ? void 0 : _c.status) === 'keyframed');
68
+ }
69
+ const effectDragOverrides = getEffectDragOverrides(nodePath, node.field.effectIndex);
70
+ if (((_d = effectDragOverrides[node.field.key]) === null || _d === void 0 ? void 0 : _d.type) === 'keyframed') {
71
+ return true;
72
+ }
73
+ const effectStatus = remotion_1.Internals.getEffectPropStatusesCtx({
74
+ propStatuses,
75
+ nodePath,
76
+ effectIndex: node.field.effectIndex,
77
+ });
78
+ return (effectStatus.type === 'can-update-effect' &&
79
+ ((_f = (_e = effectStatus.props) === null || _e === void 0 ? void 0 : _e[node.field.key]) === null || _f === void 0 ? void 0 : _f.status) === 'keyframed');
80
+ };
81
+ exports.getNodeHasKeyframes = getNodeHasKeyframes;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resetSelectedTimelineProps = exports.getTimelinePropResetTargets = void 0;
4
+ const studio_shared_1 = require("@remotion/studio-shared");
4
5
  const remotion_1 = require("remotion");
5
6
  const find_track_for_node_path_info_1 = require("./find-track-for-node-path-info");
6
7
  const save_effect_prop_1 = require("./save-effect-prop");
@@ -23,9 +24,12 @@ const isResettablePropStatus = ({ propStatus, defaultValue, }) => {
23
24
  if (defaultValue === undefined) {
24
25
  return false;
25
26
  }
26
- if (propStatus.status === 'keyframed' || propStatus.status === 'computed') {
27
+ if (propStatus.status === 'keyframed') {
27
28
  return true;
28
29
  }
30
+ if (propStatus.status === 'computed') {
31
+ return false;
32
+ }
29
33
  return isNonDefaultCodeValue({
30
34
  propStatus: propStatus.codeValue,
31
35
  defaultValue,
@@ -96,7 +100,16 @@ const getTimelinePropResetTargets = ({ selections, sequences, overrideIdsToNodeP
96
100
  continue;
97
101
  }
98
102
  const effect = sequence.effects[selection.i];
99
- const fieldSchema = effect === null || effect === void 0 ? void 0 : effect.schema[selection.key];
103
+ const field = effect
104
+ ? (0, studio_shared_1.getEffectFieldsToShow)({
105
+ effect,
106
+ effectIndex: selection.i,
107
+ nodePath,
108
+ propStatuses,
109
+ getEffectDragOverrides: () => ({}),
110
+ }).find((candidate) => candidate.key === selection.key)
111
+ : null;
112
+ const fieldSchema = field === null || field === void 0 ? void 0 : field.fieldSchema;
100
113
  const effectStatus = remotion_1.Internals.getEffectPropStatusesCtx({
101
114
  propStatuses,
102
115
  nodePath,
@@ -0,0 +1,12 @@
1
+ import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
2
+ import type { TimelineTreeNode } from '../../helpers/timeline-layout';
3
+ import type { TimelineSelection } from './TimelineSelection';
4
+ export declare const filterTimelineExpandedTree: ({ nodes, shouldShowNode, }: {
5
+ readonly nodes: readonly TimelineTreeNode[];
6
+ readonly shouldShowNode: (node: TimelineTreeNode) => boolean;
7
+ }) => TimelineTreeNode[];
8
+ export declare const getSelectedTimelineExpandedRowKeys: (selectedItems: readonly TimelineSelection[]) => ReadonlySet<string>;
9
+ export declare const isTimelineExpandedNodeSelected: ({ nodePathInfo, selectedRowKeys, }: {
10
+ readonly nodePathInfo: SequenceNodePathInfo;
11
+ readonly selectedRowKeys: ReadonlySet<string>;
12
+ }) => boolean;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isTimelineExpandedNodeSelected = exports.getSelectedTimelineExpandedRowKeys = exports.filterTimelineExpandedTree = void 0;
4
+ const timeline_node_path_key_1 = require("../../helpers/timeline-node-path-key");
5
+ const filterTimelineExpandedTree = ({ nodes, shouldShowNode, }) => {
6
+ const out = [];
7
+ for (const node of nodes) {
8
+ if (node.kind === 'field') {
9
+ if (shouldShowNode(node)) {
10
+ out.push(node);
11
+ }
12
+ continue;
13
+ }
14
+ const children = (0, exports.filterTimelineExpandedTree)({
15
+ nodes: node.children,
16
+ shouldShowNode,
17
+ });
18
+ if (children.length > 0 || shouldShowNode(node)) {
19
+ out.push({
20
+ ...node,
21
+ children,
22
+ });
23
+ }
24
+ }
25
+ return out;
26
+ };
27
+ exports.filterTimelineExpandedTree = filterTimelineExpandedTree;
28
+ const getSelectedTimelineExpandedRowKeys = (selectedItems) => {
29
+ return new Set(selectedItems.flatMap((item) => {
30
+ if (item.type === 'guide') {
31
+ return [];
32
+ }
33
+ return [(0, timeline_node_path_key_1.timelineNodePathInfoToKey)(item.nodePathInfo)];
34
+ }));
35
+ };
36
+ exports.getSelectedTimelineExpandedRowKeys = getSelectedTimelineExpandedRowKeys;
37
+ const isTimelineExpandedNodeSelected = ({ nodePathInfo, selectedRowKeys, }) => selectedRowKeys.has((0, timeline_node_path_key_1.timelineNodePathInfoToKey)(nodePathInfo));
38
+ exports.isTimelineExpandedNodeSelected = isTimelineExpandedNodeSelected;
@@ -214,6 +214,9 @@ const formatTimelineFieldValueForDisplay = ({ fieldSchema, value, }) => {
214
214
  if (!fieldSchema) {
215
215
  return formatUnknownTimelineValueForDisplay(value);
216
216
  }
217
+ if (value === undefined) {
218
+ return 'unset';
219
+ }
217
220
  switch (fieldSchema.type) {
218
221
  case 'number':
219
222
  return ((_a = formatNumberTimelineFieldValueForDisplay({ fieldSchema, value })) !== null && _a !== void 0 ? _a : formatUnknownTimelineValueForDisplay(value));
@@ -7,6 +7,8 @@ const timeline_layout_1 = require("../../helpers/timeline-layout");
7
7
  const timeline_node_path_key_1 = require("../../helpers/timeline-node-path-key");
8
8
  const ExpandedTracksProvider_1 = require("../ExpandedTracksProvider");
9
9
  const get_node_keyframes_1 = require("./get-node-keyframes");
10
+ const timeline_expanded_filter_1 = require("./timeline-expanded-filter");
11
+ const TimelineSelection_1 = require("./TimelineSelection");
10
12
  const canEditEasingForInterpolationFunction = (interpolationFunction) => interpolationFunction === 'interpolate' ||
11
13
  interpolationFunction === 'interpolateColors';
12
14
  const getNodeCanEditEasing = ({ node, nodePath, propStatuses, }) => {
@@ -34,6 +36,7 @@ const useExpandedTrackKeyframeRows = ({ sequence, nodePathInfo, keyframeDisplayO
34
36
  const { getIsExpanded } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksGetterContext);
35
37
  const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
36
38
  const { getDragOverrides, getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
39
+ const { selectedItems } = (0, TimelineSelection_1.useTimelineSelection)();
37
40
  const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
38
41
  const tree = (0, react_1.useMemo)(() => (0, timeline_layout_1.buildTimelineTree)({
39
42
  sequence,
@@ -48,16 +51,37 @@ const useExpandedTrackKeyframeRows = ({ sequence, nodePathInfo, keyframeDisplayO
48
51
  nodePathInfo,
49
52
  sequence,
50
53
  ]);
51
- const flat = (0, react_1.useMemo)(() => (0, timeline_layout_1.flattenVisibleTreeNodes)({ nodes: tree, getIsExpanded }), [tree, getIsExpanded]);
52
- const expandedHeight = (0, react_1.useMemo)(() => (0, timeline_layout_1.getExpandedTrackHeight)({
53
- sequence,
54
- nodePathInfo,
55
- getIsExpanded,
54
+ const selectedRowKeys = (0, react_1.useMemo)(() => (0, timeline_expanded_filter_1.getSelectedTimelineExpandedRowKeys)(selectedItems), [selectedItems]);
55
+ const filteredTree = (0, react_1.useMemo)(() => (0, timeline_expanded_filter_1.filterTimelineExpandedTree)({
56
+ nodes: tree,
57
+ shouldShowNode: (node) => (0, timeline_expanded_filter_1.isTimelineExpandedNodeSelected)({
58
+ nodePathInfo: node.nodePathInfo,
59
+ selectedRowKeys,
60
+ }) ||
61
+ (0, get_node_keyframes_1.getNodeHasKeyframes)({
62
+ node,
63
+ nodePath: nodePathInfo.sequenceSubscriptionKey,
64
+ propStatuses,
65
+ getDragOverrides,
66
+ getEffectDragOverrides,
67
+ }),
68
+ }), [
69
+ getDragOverrides,
70
+ getEffectDragOverrides,
71
+ nodePathInfo.sequenceSubscriptionKey,
56
72
  propStatuses,
57
- }), [propStatuses, getIsExpanded, nodePathInfo, sequence]);
58
- const rows = (0, react_1.useMemo)(() => flat.map(({ node }) => ({
59
- height: (0, timeline_layout_1.getTreeRowHeight)(node),
60
- keyframes: (0, get_node_keyframes_1.getNodeKeyframes)({
73
+ selectedRowKeys,
74
+ tree,
75
+ ]);
76
+ const flat = (0, react_1.useMemo)(() => (0, timeline_layout_1.flattenVisibleTreeNodes)({ nodes: filteredTree, getIsExpanded }), [filteredTree, getIsExpanded]);
77
+ const expandedHeight = (0, react_1.useMemo)(() => {
78
+ const totalRowsHeight = flat.reduce((sum, { node }) => sum + (0, timeline_layout_1.getTreeRowHeight)(node), 0);
79
+ const separators = Math.max(0, flat.length - 1);
80
+ return totalRowsHeight + separators;
81
+ }, [flat]);
82
+ const nodeKeyframes = (0, react_1.useMemo)(() => new Map(flat.map(({ node }) => [
83
+ (0, timeline_node_path_key_1.timelineNodePathInfoToKey)(node.nodePathInfo),
84
+ (0, get_node_keyframes_1.getNodeKeyframes)({
61
85
  node,
62
86
  nodePath: nodePathInfo.sequenceSubscriptionKey,
63
87
  propStatuses,
@@ -66,22 +90,30 @@ const useExpandedTrackKeyframeRows = ({ sequence, nodePathInfo, keyframeDisplayO
66
90
  getEffectDragOverrides,
67
91
  timelinePosition,
68
92
  }),
69
- canEditEasing: getNodeCanEditEasing({
70
- node,
71
- nodePath: nodePathInfo.sequenceSubscriptionKey,
72
- propStatuses,
73
- }),
74
- rowKey: (0, timeline_node_path_key_1.timelineNodePathInfoToKey)(node.nodePathInfo),
75
- nodePathInfo: node.nodePathInfo,
76
- })), [
77
- propStatuses,
93
+ ])), [
78
94
  flat,
79
95
  getDragOverrides,
80
96
  getEffectDragOverrides,
81
97
  keyframeDisplayOffset,
82
98
  nodePathInfo.sequenceSubscriptionKey,
99
+ propStatuses,
83
100
  timelinePosition,
84
101
  ]);
102
+ const rows = (0, react_1.useMemo)(() => flat.map(({ node }) => {
103
+ var _a;
104
+ const rowKey = (0, timeline_node_path_key_1.timelineNodePathInfoToKey)(node.nodePathInfo);
105
+ return {
106
+ height: (0, timeline_layout_1.getTreeRowHeight)(node),
107
+ keyframes: (_a = nodeKeyframes.get(rowKey)) !== null && _a !== void 0 ? _a : [],
108
+ canEditEasing: getNodeCanEditEasing({
109
+ node,
110
+ nodePath: nodePathInfo.sequenceSubscriptionKey,
111
+ propStatuses,
112
+ }),
113
+ rowKey,
114
+ nodePathInfo: node.nodePathInfo,
115
+ };
116
+ }), [propStatuses, flat, nodePathInfo.sequenceSubscriptionKey, nodeKeyframes]);
85
117
  return { rows, expandedHeight };
86
118
  };
87
119
  exports.useExpandedTrackKeyframeRows = useExpandedTrackKeyframeRows;
@@ -4,6 +4,7 @@ export declare const useTimelineExpandedTree: ({ sequence, nodePathInfo, }: {
4
4
  readonly sequence: TSequence;
5
5
  readonly nodePathInfo: SequenceNodePathInfo;
6
6
  }) => {
7
+ filteredTree: import("../../helpers/timeline-layout").TimelineTreeNode[];
7
8
  getIsExpanded: import("../ExpandedTracksProvider").GetIsExpanded;
8
9
  propStatuses: import("remotion").PropStatuses;
9
10
  toggleTrack: (nodePathInfo: SequenceNodePathInfo) => void;
@@ -5,11 +5,15 @@ const react_1 = require("react");
5
5
  const remotion_1 = require("remotion");
6
6
  const timeline_layout_1 = require("../../helpers/timeline-layout");
7
7
  const ExpandedTracksProvider_1 = require("../ExpandedTracksProvider");
8
+ const get_node_keyframes_1 = require("./get-node-keyframes");
9
+ const timeline_expanded_filter_1 = require("./timeline-expanded-filter");
10
+ const TimelineSelection_1 = require("./TimelineSelection");
8
11
  const useTimelineExpandedTree = ({ sequence, nodePathInfo, }) => {
9
12
  const { getIsExpanded } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksGetterContext);
10
13
  const { toggleTrack } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksSetterContext);
11
14
  const { propStatuses: visualModePropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
12
15
  const { getDragOverrides, getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
16
+ const { selectedItems } = (0, TimelineSelection_1.useTimelineSelection)();
13
17
  const tree = (0, react_1.useMemo)(() => (0, timeline_layout_1.buildTimelineTree)({
14
18
  sequence,
15
19
  nodePathInfo,
@@ -23,7 +27,30 @@ const useTimelineExpandedTree = ({ sequence, nodePathInfo, }) => {
23
27
  getEffectDragOverrides,
24
28
  visualModePropStatuses,
25
29
  ]);
30
+ const selectedRowKeys = (0, react_1.useMemo)(() => (0, timeline_expanded_filter_1.getSelectedTimelineExpandedRowKeys)(selectedItems), [selectedItems]);
31
+ const filteredTree = (0, react_1.useMemo)(() => (0, timeline_expanded_filter_1.filterTimelineExpandedTree)({
32
+ nodes: tree,
33
+ shouldShowNode: (node) => (0, timeline_expanded_filter_1.isTimelineExpandedNodeSelected)({
34
+ nodePathInfo: node.nodePathInfo,
35
+ selectedRowKeys,
36
+ }) ||
37
+ (0, get_node_keyframes_1.getNodeHasKeyframes)({
38
+ node,
39
+ nodePath: nodePathInfo.sequenceSubscriptionKey,
40
+ propStatuses: visualModePropStatuses,
41
+ getDragOverrides,
42
+ getEffectDragOverrides,
43
+ }),
44
+ }), [
45
+ getDragOverrides,
46
+ getEffectDragOverrides,
47
+ nodePathInfo.sequenceSubscriptionKey,
48
+ selectedRowKeys,
49
+ tree,
50
+ visualModePropStatuses,
51
+ ]);
26
52
  return {
53
+ filteredTree,
27
54
  getIsExpanded,
28
55
  propStatuses: visualModePropStatuses,
29
56
  toggleTrack,
@@ -6,13 +6,19 @@ const remotion_1 = require("remotion");
6
6
  const client_id_1 = require("../../helpers/client-id");
7
7
  const timeline_layout_1 = require("../../helpers/timeline-layout");
8
8
  const ExpandedTracksProvider_1 = require("../ExpandedTracksProvider");
9
+ const get_node_keyframes_1 = require("./get-node-keyframes");
9
10
  const MaxTimelineTracks_1 = require("./MaxTimelineTracks");
11
+ const timeline_expanded_filter_1 = require("./timeline-expanded-filter");
12
+ const TimelineSelection_1 = require("./TimelineSelection");
10
13
  const TimelineTimeIndicators_1 = require("./TimelineTimeIndicators");
11
14
  const useTimelineHeight = ({ shown, hasBeenCut, }) => {
12
15
  const { getIsExpanded } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksGetterContext);
13
16
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
14
17
  const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
18
+ const { getDragOverrides, getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
19
+ const { selectedItems } = (0, TimelineSelection_1.useTimelineSelection)();
15
20
  const previewServerConnected = previewServerState.type === 'connected';
21
+ const selectedRowKeys = (0, react_1.useMemo)(() => (0, timeline_expanded_filter_1.getSelectedTimelineExpandedRowKeys)(selectedItems), [selectedItems]);
16
22
  return (0, react_1.useMemo)(() => {
17
23
  const tracksHeight = shown.reduce((acc, track) => {
18
24
  const isExpanded = previewServerConnected &&
@@ -20,20 +26,58 @@ const useTimelineHeight = ({ shown, hasBeenCut, }) => {
20
26
  getIsExpanded(track.nodePathInfo);
21
27
  const layerHeight = (0, timeline_layout_1.getTimelineLayerHeight)(track.sequence.type) +
22
28
  timeline_layout_1.TIMELINE_ITEM_BORDER_BOTTOM;
23
- const expandedHeight = isExpanded && track.nodePathInfo
24
- ? (0, timeline_layout_1.getExpandedTrackHeight)({
29
+ const expandedHeight = (() => {
30
+ if (!isExpanded || track.nodePathInfo === null) {
31
+ return 0;
32
+ }
33
+ const { nodePathInfo } = track;
34
+ const tree = (0, timeline_layout_1.buildTimelineTree)({
25
35
  sequence: track.sequence,
26
- nodePathInfo: track.nodePathInfo,
27
- getIsExpanded,
36
+ nodePathInfo,
37
+ getDragOverrides,
38
+ getEffectDragOverrides,
28
39
  propStatuses,
29
- }) + timeline_layout_1.TIMELINE_ITEM_BORDER_BOTTOM
30
- : 0;
40
+ });
41
+ const filteredTree = (0, timeline_expanded_filter_1.filterTimelineExpandedTree)({
42
+ nodes: tree,
43
+ shouldShowNode: (node) => (0, timeline_expanded_filter_1.isTimelineExpandedNodeSelected)({
44
+ nodePathInfo: node.nodePathInfo,
45
+ selectedRowKeys,
46
+ }) ||
47
+ (0, get_node_keyframes_1.getNodeHasKeyframes)({
48
+ node,
49
+ nodePath: nodePathInfo.sequenceSubscriptionKey,
50
+ propStatuses,
51
+ getDragOverrides,
52
+ getEffectDragOverrides,
53
+ }),
54
+ });
55
+ const flat = (0, timeline_layout_1.flattenVisibleTreeNodes)({
56
+ nodes: filteredTree,
57
+ getIsExpanded,
58
+ });
59
+ if (flat.length === 0) {
60
+ return 0;
61
+ }
62
+ const totalRowsHeight = flat.reduce((sum, { node }) => sum + (0, timeline_layout_1.getTreeRowHeight)(node), 0);
63
+ const separators = Math.max(0, flat.length - 1);
64
+ return totalRowsHeight + separators + timeline_layout_1.TIMELINE_ITEM_BORDER_BOTTOM;
65
+ })();
31
66
  return acc + layerHeight + expandedHeight;
32
67
  }, 0);
33
68
  return (tracksHeight +
34
69
  timeline_layout_1.TIMELINE_ITEM_BORDER_BOTTOM +
35
70
  (hasBeenCut ? MaxTimelineTracks_1.MAX_TIMELINE_TRACKS_NOTICE_HEIGHT : 0) +
36
71
  TimelineTimeIndicators_1.TIMELINE_TIME_INDICATOR_HEIGHT);
37
- }, [shown, hasBeenCut, previewServerConnected, getIsExpanded, propStatuses]);
72
+ }, [
73
+ shown,
74
+ hasBeenCut,
75
+ previewServerConnected,
76
+ getIsExpanded,
77
+ propStatuses,
78
+ getDragOverrides,
79
+ getEffectDragOverrides,
80
+ selectedRowKeys,
81
+ ]);
38
82
  };
39
83
  exports.useTimelineHeight = useTimelineHeight;