@remotion/studio 4.0.477 → 4.0.479

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 (191) hide show
  1. package/dist/components/AssetSelector.js +8 -14
  2. package/dist/components/Button.d.ts +1 -0
  3. package/dist/components/Button.js +8 -5
  4. package/dist/components/CanvasIfSizeIsAvailable.js +2 -6
  5. package/dist/components/CompactExplanation.d.ts +12 -0
  6. package/dist/components/CompactExplanation.js +52 -0
  7. package/dist/components/CompositionSelector.js +2 -4
  8. package/dist/components/CurrentAsset.d.ts +3 -1
  9. package/dist/components/CurrentAsset.js +42 -34
  10. package/dist/components/CurrentComposition.d.ts +1 -1
  11. package/dist/components/CurrentComposition.js +38 -31
  12. package/dist/components/DefaultPropsEditor.d.ts +12 -2
  13. package/dist/components/DefaultPropsEditor.js +2 -2
  14. package/dist/components/EditorGuides/Guide.js +37 -9
  15. package/dist/components/EditorRuler/Ruler.js +4 -14
  16. package/dist/components/EditorRuler/index.js +9 -4
  17. package/dist/components/EffectPickerModal.d.ts +5 -0
  18. package/dist/components/EffectPickerModal.js +179 -0
  19. package/dist/components/InlineAction.js +1 -0
  20. package/dist/components/InspectorInfoHeader.d.ts +11 -0
  21. package/dist/components/InspectorInfoHeader.js +55 -0
  22. package/dist/components/InspectorPanel/DefaultInspector.d.ts +8 -0
  23. package/dist/components/InspectorPanel/DefaultInspector.js +93 -0
  24. package/dist/components/InspectorPanel/EasingInspector.d.ts +5 -0
  25. package/dist/components/InspectorPanel/EasingInspector.js +41 -0
  26. package/dist/components/InspectorPanel/GuideInspector.d.ts +7 -0
  27. package/dist/components/InspectorPanel/GuideInspector.js +55 -0
  28. package/dist/components/InspectorPanel/KeyframeInspector.d.ts +7 -0
  29. package/dist/components/InspectorPanel/KeyframeInspector.js +109 -0
  30. package/dist/components/InspectorPanel/SelectedInspector.d.ts +5 -0
  31. package/dist/components/InspectorPanel/SelectedInspector.js +26 -0
  32. package/dist/components/InspectorPanel/SequenceSelectionInspector.d.ts +5 -0
  33. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +116 -0
  34. package/dist/components/InspectorPanel/common.d.ts +15 -0
  35. package/dist/components/InspectorPanel/common.js +18 -0
  36. package/dist/components/InspectorPanel/inspector-selection.d.ts +10 -0
  37. package/dist/components/InspectorPanel/inspector-selection.js +34 -0
  38. package/dist/components/InspectorPanel/styles.d.ts +27 -0
  39. package/dist/components/InspectorPanel/styles.js +178 -0
  40. package/dist/components/InspectorPanel/use-track-for-selection.d.ts +2 -0
  41. package/dist/components/InspectorPanel/use-track-for-selection.js +22 -0
  42. package/dist/components/InspectorPanel.d.ts +8 -0
  43. package/dist/components/InspectorPanel.js +26 -0
  44. package/dist/components/InspectorPanelLayout.d.ts +1 -0
  45. package/dist/components/InspectorPanelLayout.js +4 -0
  46. package/dist/components/InspectorSequenceSection.d.ts +16 -0
  47. package/dist/components/InspectorSequenceSection.js +147 -0
  48. package/dist/components/InspectorSourceLocation.d.ts +7 -0
  49. package/dist/components/InspectorSourceLocation.js +71 -0
  50. package/dist/components/MenuToolbar.d.ts +1 -0
  51. package/dist/components/MenuToolbar.js +4 -1
  52. package/dist/components/Modals.js +3 -3
  53. package/dist/components/NewComposition/InputDragger.js +1 -1
  54. package/dist/components/NewComposition/RemInput.d.ts +1 -0
  55. package/dist/components/NewComposition/RemInput.js +8 -2
  56. package/dist/components/NewComposition/RemTextarea.d.ts +1 -0
  57. package/dist/components/NewComposition/RemTextarea.js +8 -2
  58. package/dist/components/NewComposition/ValidationMessage.d.ts +3 -0
  59. package/dist/components/NewComposition/ValidationMessage.js +16 -5
  60. package/dist/components/OptionsPanel.d.ts +1 -1
  61. package/dist/components/OptionsPanel.js +8 -17
  62. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +2 -7
  63. package/dist/components/QuickSwitcher/QuickSwitcherResult.js +3 -10
  64. package/dist/components/QuickSwitcher/shared.d.ts +4 -0
  65. package/dist/components/QuickSwitcher/shared.js +24 -0
  66. package/dist/components/RenderModal/DataEditor.d.ts +29 -2
  67. package/dist/components/RenderModal/DataEditor.js +107 -56
  68. package/dist/components/RenderModal/RenderModalJSONPropsEditor.d.ts +1 -0
  69. package/dist/components/RenderModal/RenderModalJSONPropsEditor.js +25 -7
  70. package/dist/components/RenderModal/SchemaEditor/Fieldset.d.ts +2 -1
  71. package/dist/components/RenderModal/SchemaEditor/Fieldset.js +10 -5
  72. package/dist/components/RenderModal/SchemaEditor/SchemaEditor.d.ts +4 -0
  73. package/dist/components/RenderModal/SchemaEditor/SchemaEditor.js +27 -4
  74. package/dist/components/RenderModal/SchemaEditor/SchemaErrorMessages.d.ts +12 -4
  75. package/dist/components/RenderModal/SchemaEditor/SchemaErrorMessages.js +23 -9
  76. package/dist/components/RenderModal/SchemaEditor/SchemaLabel.js +3 -3
  77. package/dist/components/RenderModal/SchemaEditor/SchemaSeparationLine.js +8 -1
  78. package/dist/components/RenderModal/SchemaEditor/ZodColorEditor.js +1 -1
  79. package/dist/components/RenderModal/SchemaEditor/ZodDateEditor.js +1 -1
  80. package/dist/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.js +1 -1
  81. package/dist/components/RenderModal/SchemaEditor/ZodEnumEditor.js +1 -1
  82. package/dist/components/RenderModal/SchemaEditor/ZodErrorMessages.d.ts +1 -0
  83. package/dist/components/RenderModal/SchemaEditor/ZodErrorMessages.js +23 -6
  84. package/dist/components/RenderModal/SchemaEditor/ZodFieldValidation.js +2 -2
  85. package/dist/components/RenderModal/SchemaEditor/ZodNonEditableValue.js +2 -1
  86. package/dist/components/RenderModal/SchemaEditor/ZodNumberEditor.js +1 -1
  87. package/dist/components/RenderModal/SchemaEditor/ZodObjectEditor.js +9 -11
  88. package/dist/components/RenderModal/SchemaEditor/ZodOrNullishEditor.js +1 -1
  89. package/dist/components/RenderModal/SchemaEditor/ZodStaticFileEditor.js +1 -1
  90. package/dist/components/RenderModal/SchemaEditor/ZodStringEditor.js +1 -1
  91. package/dist/components/RenderModal/SchemaEditor/ZodTextareaEditor.js +1 -1
  92. package/dist/components/RenderModal/WarningIndicatorButton.d.ts +1 -0
  93. package/dist/components/RenderModal/WarningIndicatorButton.js +17 -4
  94. package/dist/components/RenderModal/get-render-modal-warnings.d.ts +2 -1
  95. package/dist/components/RenderModal/get-render-modal-warnings.js +6 -3
  96. package/dist/components/RendersTab.js +1 -1
  97. package/dist/components/SegmentedControl.d.ts +3 -0
  98. package/dist/components/SegmentedControl.js +11 -5
  99. package/dist/components/SelectedOutlineElement.js +135 -31
  100. package/dist/components/SelectedOutlineOverlay.d.ts +1 -1
  101. package/dist/components/SelectedOutlineOverlay.js +45 -29
  102. package/dist/components/SelectedOutlineUvControls.d.ts +9 -0
  103. package/dist/components/SelectedOutlineUvControls.js +64 -10
  104. package/dist/components/Tabs/index.js +4 -4
  105. package/dist/components/Timeline/EasingEditorModal.d.ts +5 -4
  106. package/dist/components/Timeline/EasingEditorModal.js +597 -124
  107. package/dist/components/Timeline/KeyframeSettingsModal.d.ts +2 -2
  108. package/dist/components/Timeline/SubscribeToNodePaths.d.ts +2 -2
  109. package/dist/components/Timeline/TimelineClipboardKeybindings.d.ts +15 -3
  110. package/dist/components/Timeline/TimelineClipboardKeybindings.js +85 -1
  111. package/dist/components/Timeline/TimelineDeleteKeybindings.js +10 -3
  112. package/dist/components/Timeline/TimelineEffectItem.d.ts +2 -2
  113. package/dist/components/Timeline/TimelineEffectPropItem.d.ts +8 -0
  114. package/dist/components/Timeline/TimelineEffectPropItem.js +24 -20
  115. package/dist/components/Timeline/TimelineExpandedRow.d.ts +5 -2
  116. package/dist/components/Timeline/TimelineExpandedRow.js +4 -4
  117. package/dist/components/Timeline/TimelineExpandedSection.d.ts +1 -1
  118. package/dist/components/Timeline/TimelineExpandedSection.js +5 -19
  119. package/dist/components/Timeline/TimelineKeyframeControls.d.ts +8 -2
  120. package/dist/components/Timeline/TimelineKeyframeControls.js +24 -3
  121. package/dist/components/Timeline/TimelineKeyframeEasingLine.js +2 -47
  122. package/dist/components/Timeline/TimelineKeyframedValue.d.ts +1 -1
  123. package/dist/components/Timeline/TimelineKeyframedValue.js +8 -10
  124. package/dist/components/Timeline/TimelineNumberField.js +5 -11
  125. package/dist/components/Timeline/TimelineRotationField.js +5 -6
  126. package/dist/components/Timeline/TimelineScaleField.js +4 -8
  127. package/dist/components/Timeline/TimelineSelection.d.ts +6 -0
  128. package/dist/components/Timeline/TimelineSelection.js +109 -14
  129. package/dist/components/Timeline/TimelineSequence.js +22 -14
  130. package/dist/components/Timeline/TimelineSequenceItem.js +12 -67
  131. package/dist/components/Timeline/TimelineSequencePropItem.d.ts +12 -2
  132. package/dist/components/Timeline/TimelineSequencePropItem.js +56 -52
  133. package/dist/components/Timeline/TimelineTransformOriginField.js +4 -5
  134. package/dist/components/Timeline/TimelineTranslateField.js +4 -5
  135. package/dist/components/Timeline/TimelineUvCoordinateField.js +4 -4
  136. package/dist/components/Timeline/TimelineVideoInfo.d.ts +1 -0
  137. package/dist/components/Timeline/TimelineVideoInfo.js +93 -8
  138. package/dist/components/Timeline/call-add-keyframe.d.ts +4 -4
  139. package/dist/components/Timeline/call-delete-keyframe.d.ts +4 -4
  140. package/dist/components/Timeline/call-move-keyframe.d.ts +2 -2
  141. package/dist/components/Timeline/call-update-keyframe-settings.d.ts +3 -3
  142. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +2 -1
  143. package/dist/components/Timeline/delete-selected-timeline-item.js +27 -1
  144. package/dist/components/Timeline/duplicate-selected-timeline-item.d.ts +7 -0
  145. package/dist/components/Timeline/duplicate-selected-timeline-item.js +32 -3
  146. package/dist/components/Timeline/parse-keyframe-field-from-node-path.js +2 -2
  147. package/dist/components/Timeline/reset-selected-timeline-props.d.ts +3 -3
  148. package/dist/components/Timeline/reset-selected-timeline-props.js +19 -5
  149. package/dist/components/Timeline/save-effect-prop.d.ts +2 -2
  150. package/dist/components/Timeline/save-sequence-prop.d.ts +2 -2
  151. package/dist/components/Timeline/sequence-props-subscription-store.d.ts +3 -3
  152. package/dist/components/Timeline/timeline-field-display-utils.d.ts +5 -0
  153. package/dist/components/Timeline/timeline-field-display-utils.js +244 -0
  154. package/dist/components/Timeline/timeline-video-filmstrip-times.d.ts +17 -0
  155. package/dist/components/Timeline/timeline-video-filmstrip-times.js +22 -0
  156. package/dist/components/Timeline/update-selected-easing.d.ts +47 -4
  157. package/dist/components/Timeline/update-selected-easing.js +40 -9
  158. package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.d.ts +13 -0
  159. package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.js +73 -0
  160. package/dist/components/Timeline/use-sequence-props-subscription.d.ts +3 -3
  161. package/dist/components/Timeline/use-timeline-expanded-tree.d.ts +11 -0
  162. package/dist/components/Timeline/use-timeline-expanded-tree.js +33 -0
  163. package/dist/components/VisualControls/VisualControlsContent.d.ts +1 -1
  164. package/dist/components/VisualControls/VisualControlsContent.js +4 -5
  165. package/dist/components/effect-drag-and-drop.d.ts +10 -0
  166. package/dist/components/effect-drag-and-drop.js +17 -8
  167. package/dist/components/effect-picker-search.d.ts +5 -0
  168. package/dist/components/effect-picker-search.js +77 -0
  169. package/dist/components/import-assets.d.ts +11 -2
  170. package/dist/components/import-assets.js +61 -6
  171. package/dist/components/selected-outline-drag.d.ts +44 -2
  172. package/dist/components/selected-outline-drag.js +74 -1
  173. package/dist/components/selected-outline-types.d.ts +7 -7
  174. package/dist/components/selected-outline-uv.d.ts +4 -3
  175. package/dist/components/selected-outline-uv.js +6 -2
  176. package/dist/error-overlay/remotion-overlay/Overlay.js +3 -0
  177. package/dist/esm/{chunk-t8fjnw2d.js → chunk-fge2mq5p.js} +17004 -13432
  178. package/dist/esm/internals.mjs +17004 -13432
  179. package/dist/esm/previewEntry.mjs +26617 -23041
  180. package/dist/esm/renderEntry.mjs +1 -1
  181. package/dist/helpers/editor-guide-selection.js +1 -1
  182. package/dist/helpers/get-preview-file-type.js +1 -1
  183. package/dist/helpers/render-codec-label.d.ts +2 -0
  184. package/dist/helpers/render-codec-label.js +49 -0
  185. package/dist/helpers/ruler-canvas-size.d.ts +5 -0
  186. package/dist/helpers/ruler-canvas-size.js +17 -0
  187. package/dist/helpers/timeline-layout.d.ts +4 -4
  188. package/dist/helpers/use-media-metadata.d.ts +8 -2
  189. package/dist/helpers/use-media-metadata.js +17 -4
  190. package/dist/state/modals.d.ts +9 -4
  191. package/package.json +12 -12
@@ -42,7 +42,6 @@ const client_id_1 = require("../../helpers/client-id");
42
42
  const colors_1 = require("../../helpers/colors");
43
43
  const get_left_of_timeline_slider_1 = require("../../helpers/get-left-of-timeline-slider");
44
44
  const timeline_layout_1 = require("../../helpers/timeline-layout");
45
- const modals_1 = require("../../state/modals");
46
45
  const ContextMenu_1 = require("../ContextMenu");
47
46
  const TimelineSelection_1 = require("./TimelineSelection");
48
47
  const TimelineWidthProvider_1 = require("./TimelineWidthProvider");
@@ -85,7 +84,6 @@ const TimelineKeyframeEasingLineUnmemoized = ({ fromFrame, toFrame, rowHeight, n
85
84
  const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
86
85
  const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
87
86
  const currentSelection = (0, TimelineSelection_1.useCurrentTimelineSelectionStateAsRef)();
88
- const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
89
87
  const getTargetSelections = (0, react_1.useCallback)(() => {
90
88
  const selectedEasings = (0, update_selected_easing_1.getEasingSelections)(currentSelection.current.selectedItems);
91
89
  return selected ? selectedEasings : [selectionItem];
@@ -112,33 +110,6 @@ const TimelineKeyframeEasingLineUnmemoized = ({ fromFrame, toFrame, rowHeight, n
112
110
  sequencesRef,
113
111
  setPropStatuses,
114
112
  ]);
115
- const onOpenEasingEditor = (0, react_1.useCallback)(() => {
116
- if (previewServerState.type !== 'connected') {
117
- return;
118
- }
119
- const initialEasing = (0, update_selected_easing_1.getTimelineEasingValueForSelection)({
120
- selection: selectionItem,
121
- sequences: sequencesRef.current,
122
- overrideIdsToNodePaths: overrideIdToNodePathMappings,
123
- propStatuses: propStatusesRef.current,
124
- });
125
- if (initialEasing === null) {
126
- return;
127
- }
128
- setSelectedModal({
129
- type: 'easing-editor',
130
- initialEasing,
131
- selections: getTargetSelections(),
132
- });
133
- }, [
134
- getTargetSelections,
135
- overrideIdToNodePathMappings,
136
- previewServerState,
137
- propStatusesRef,
138
- selectionItem,
139
- sequencesRef,
140
- setSelectedModal,
141
- ]);
142
113
  const contextMenuValues = (0, react_1.useMemo)(() => {
143
114
  return [
144
115
  {
@@ -148,7 +119,7 @@ const TimelineKeyframeEasingLineUnmemoized = ({ fromFrame, toFrame, rowHeight, n
148
119
  label: 'Linear',
149
120
  leftItem: null,
150
121
  disabled: previewServerState.type !== 'connected',
151
- onClick: () => updateEasing('linear'),
122
+ onClick: () => updateEasing(studio_shared_1.LINEAR_KEYFRAME_EASING),
152
123
  quickSwitcherLabel: null,
153
124
  subMenu: null,
154
125
  value: 'linear',
@@ -165,24 +136,8 @@ const TimelineKeyframeEasingLineUnmemoized = ({ fromFrame, toFrame, rowHeight, n
165
136
  subMenu: null,
166
137
  value: preset.id,
167
138
  })),
168
- {
169
- type: 'divider',
170
- id: 'edit-easing-divider',
171
- },
172
- {
173
- type: 'item',
174
- id: 'edit-easing',
175
- keyHint: null,
176
- label: 'Edit...',
177
- leftItem: null,
178
- disabled: previewServerState.type !== 'connected',
179
- onClick: onOpenEasingEditor,
180
- quickSwitcherLabel: null,
181
- subMenu: null,
182
- value: 'edit-easing',
183
- },
184
139
  ];
185
- }, [onOpenEasingEditor, previewServerState.type, updateEasing]);
140
+ }, [previewServerState.type, updateEasing]);
186
141
  const onOpenContextMenu = (0, react_1.useCallback)((event) => {
187
142
  if (!selectable) {
188
143
  return false;
@@ -4,7 +4,7 @@ import type { SchemaFieldInfo, TimelineFieldOnDragValueChange } from '../../help
4
4
  export declare const TimelineKeyframedValue: React.FC<{
5
5
  readonly field: SchemaFieldInfo;
6
6
  readonly propStatus: CanUpdateSequencePropStatusKeyframed;
7
- readonly keyframeDisplayOffset: number;
7
+ readonly sourceFrame: number;
8
8
  readonly dragOverrideValue: DragOverrideValue | undefined;
9
9
  readonly onSave: (value: unknown, sourceFrame: number) => Promise<void>;
10
10
  readonly onDragValueChange: TimelineFieldOnDragValueChange;
@@ -8,19 +8,17 @@ const TimelineSchemaField_1 = require("./TimelineSchemaField");
8
8
  const valuesEqual = (left, right) => {
9
9
  return JSON.stringify(left) === JSON.stringify(right);
10
10
  };
11
- const TimelineKeyframedValue = ({ field, propStatus, keyframeDisplayOffset, dragOverrideValue, onSave, onDragValueChange, onDragEnd, scaleLockNodePath, }) => {
12
- const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
13
- const jsxFrame = timelinePosition - keyframeDisplayOffset;
11
+ const TimelineKeyframedValue = ({ field, propStatus, sourceFrame, dragOverrideValue, onSave, onDragValueChange, onDragEnd, scaleLockNodePath, }) => {
14
12
  const computedValue = (0, react_1.useMemo)(() => {
15
13
  const raw = remotion_1.Internals.interpolateKeyframedStatus({
16
- frame: jsxFrame,
14
+ frame: sourceFrame,
17
15
  status: propStatus,
18
16
  });
19
17
  if (typeof raw === 'number') {
20
18
  return Math.round(raw * 100) / 100;
21
19
  }
22
20
  return raw;
23
- }, [jsxFrame, propStatus]);
21
+ }, [propStatus, sourceFrame]);
24
22
  const fakeStatus = (0, react_1.useMemo)(() => ({
25
23
  status: 'static',
26
24
  codeValue: computedValue,
@@ -29,19 +27,19 @@ const TimelineKeyframedValue = ({ field, propStatus, keyframeDisplayOffset, drag
29
27
  return remotion_1.Internals.getEffectiveVisualModeValue({
30
28
  propStatus: fakeStatus,
31
29
  dragOverrideValue,
32
- frame: jsxFrame,
30
+ frame: sourceFrame,
33
31
  defaultValue: field.fieldSchema.default,
34
32
  shouldResortToDefaultValueIfUndefined: true,
35
33
  });
36
- }, [dragOverrideValue, fakeStatus, field.fieldSchema.default, jsxFrame]);
34
+ }, [dragOverrideValue, fakeStatus, field.fieldSchema.default, sourceFrame]);
37
35
  const onSaveIfChanged = (0, react_1.useCallback)((value) => {
38
- const existingKeyframe = propStatus.keyframes.find((keyframe) => keyframe.frame === jsxFrame);
36
+ const existingKeyframe = propStatus.keyframes.find((keyframe) => keyframe.frame === sourceFrame);
39
37
  if (valuesEqual(value, computedValue) ||
40
38
  (existingKeyframe && valuesEqual(value, existingKeyframe.value))) {
41
39
  return Promise.resolve();
42
40
  }
43
- return onSave(value, jsxFrame);
44
- }, [computedValue, jsxFrame, onSave, propStatus.keyframes]);
41
+ return onSave(value, sourceFrame);
42
+ }, [computedValue, onSave, propStatus.keyframes, sourceFrame]);
45
43
  if (computedValue === null) {
46
44
  return null;
47
45
  }
@@ -4,6 +4,7 @@ exports.TimelineNumberField = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const InputDragger_1 = require("../NewComposition/InputDragger");
7
+ const timeline_field_display_utils_1 = require("./timeline-field-display-utils");
7
8
  const timeline_field_utils_1 = require("./timeline-field-utils");
8
9
  const TimelineNumberField = ({ field, effectiveValue, onSave, onDragValueChange, onDragEnd, propStatus, }) => {
9
10
  var _a, _b;
@@ -35,19 +36,12 @@ const TimelineNumberField = ({ field, effectiveValue, onSave, onDragValueChange,
35
36
  }, [onSave, propStatus]);
36
37
  const configuredStep = field.fieldSchema.type === 'number' ? field.fieldSchema.step : undefined;
37
38
  const step = configuredStep !== null && configuredStep !== void 0 ? configuredStep : 1;
38
- const stepDecimals = (0, react_1.useMemo)(() => configuredStep === undefined ? null : (0, timeline_field_utils_1.getDecimalPlaces)(configuredStep), [configuredStep]);
39
39
  const formatter = (0, react_1.useCallback)((v) => {
40
- const num = Number(v);
41
- if (stepDecimals === null) {
42
- const digits = (0, timeline_field_utils_1.getDecimalPlaces)(num);
43
- return digits === 0 ? String(num) : num.toFixed(digits);
44
- }
45
- return (0, timeline_field_utils_1.formatTimelineNumber)({
46
- decimalPlaces: stepDecimals,
47
- fixed: true,
48
- value: num,
40
+ return (0, timeline_field_display_utils_1.formatTimelineFieldValueForDisplay)({
41
+ fieldSchema: field.fieldSchema,
42
+ value: v,
49
43
  });
50
- }, [stepDecimals]);
44
+ }, [field.fieldSchema]);
51
45
  return (jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragValue !== null && dragValue !== void 0 ? dragValue : effectiveValue, style: timeline_field_utils_1.draggerStyle, status: "ok", small: true, onValueChange: onValueChange, onValueChangeEnd: onValueChangeEnd, onTextChange: onTextChange, min: field.fieldSchema.type === 'number'
52
46
  ? ((_a = field.fieldSchema.min) !== null && _a !== void 0 ? _a : -Infinity)
53
47
  : -Infinity, max: field.fieldSchema.type === 'number'
@@ -4,6 +4,7 @@ exports.TimelineRotationField = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const InputDragger_1 = require("../NewComposition/InputDragger");
7
+ const timeline_field_display_utils_1 = require("./timeline-field-display-utils");
7
8
  const timeline_field_utils_1 = require("./timeline-field-utils");
8
9
  const timeline_rotation_utils_1 = require("./timeline-rotation-utils");
9
10
  const TimelineRotationField = ({ field, effectiveValue, propStatus, onSave, onDragValueChange, onDragEnd, }) => {
@@ -66,13 +67,11 @@ const TimelineRotationField = ({ field, effectiveValue, propStatus, onSave, onDr
66
67
  }
67
68
  }, [propStatus, onSave, serializeValue]);
68
69
  const formatter = (0, react_1.useCallback)((v) => {
69
- const formatted = (0, timeline_field_utils_1.formatTimelineNumber)({
70
- decimalPlaces,
71
- fixed: false,
72
- value: (0, timeline_field_utils_1.normalizeTimelineNumber)(Number(v)),
70
+ return (0, timeline_field_display_utils_1.formatTimelineFieldValueForDisplay)({
71
+ fieldSchema: field.fieldSchema,
72
+ value: v,
73
73
  });
74
- return `${formatted}\u00B0`;
75
- }, [decimalPlaces]);
74
+ }, [field.fieldSchema]);
76
75
  return (jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragValue !== null && dragValue !== void 0 ? dragValue : degrees, style: timeline_field_utils_1.draggerStyle, status: "ok", small: true, onValueChange: onValueChange, onValueChangeEnd: onValueChangeEnd, onTextChange: onTextChange, min: min, max: max, step: step, formatter: formatter, rightAlign: false }));
77
76
  };
78
77
  exports.TimelineRotationField = TimelineRotationField;
@@ -7,6 +7,7 @@ const no_react_1 = require("remotion/no-react");
7
7
  const colors_1 = require("../../helpers/colors");
8
8
  const scale_lock_1 = require("../../state/scale-lock");
9
9
  const InputDragger_1 = require("../NewComposition/InputDragger");
10
+ const timeline_field_display_utils_1 = require("./timeline-field-display-utils");
10
11
  const timeline_field_utils_1 = require("./timeline-field-utils");
11
12
  const TimelineLayerEye_1 = require("./TimelineLayerEye");
12
13
  const leftDraggerStyle = {
@@ -98,17 +99,12 @@ const TimelineScaleField = ({ field, propStatus, effectiveValue, onSave, onDragV
98
99
  const max = field.fieldSchema.type === 'scale'
99
100
  ? ((_b = field.fieldSchema.max) !== null && _b !== void 0 ? _b : Infinity)
100
101
  : Infinity;
101
- const decimalPlaces = (0, react_1.useMemo)(() => (0, timeline_field_utils_1.getTimelineDisplayDecimalPlaces)({
102
- defaultDecimalPlaces: 3,
103
- step: configuredStep,
104
- }), [configuredStep]);
105
102
  const formatter = (0, react_1.useCallback)((v) => {
106
- return (0, timeline_field_utils_1.formatTimelineNumber)({
107
- decimalPlaces,
108
- fixed: true,
103
+ return (0, timeline_field_display_utils_1.formatTimelineFieldValueForDisplay)({
104
+ fieldSchema: field.fieldSchema,
109
105
  value: v,
110
106
  });
111
- }, [decimalPlaces]);
107
+ }, [field.fieldSchema]);
112
108
  const getDragStart = (0, react_1.useCallback)(() => {
113
109
  if (dragStartRef.current === null) {
114
110
  dragStartRef.current = [dragX !== null && dragX !== void 0 ? dragX : codeX, dragY !== null && dragY !== void 0 ? dragY : codeY];
@@ -64,6 +64,7 @@ export type TimelineSelectionState = {
64
64
  readonly selectedItems: readonly TimelineSelection[];
65
65
  readonly anchor: TimelineSelection | null;
66
66
  };
67
+ export declare const EMPTY_TIMELINE_SELECTION_STATE: TimelineSelectionState;
67
68
  export type TimelineMarqueeRect = {
68
69
  readonly left: number;
69
70
  readonly top: number;
@@ -81,6 +82,11 @@ export declare const getTimelineSelectionAfterInteraction: ({ currentState, clic
81
82
  readonly interaction: TimelineSelectionInteraction;
82
83
  readonly allSelectableItems: readonly TimelineSelection[];
83
84
  }) => TimelineSelectionState;
85
+ export declare const getAvailableTimelineSelectionState: ({ availableKeys, availableItemsByKey, state, }: {
86
+ readonly availableKeys: ReadonlySet<string>;
87
+ readonly availableItemsByKey?: ReadonlyMap<string, TimelineSelection> | undefined;
88
+ readonly state: TimelineSelectionState;
89
+ }) => TimelineSelectionState;
84
90
  export declare const getNormalizedTimelineMarqueeRect: ({ startX, startY, currentX, currentY, }: {
85
91
  readonly startX: number;
86
92
  readonly startY: number;
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useTimelineRowContainsSelection = exports.useTimelineGuideSelection = exports.useTimelineEasingSelection = exports.useTimelineKeyframeSelection = exports.useTimelineRowSelection = exports.useTimelineMarqueeSelectableItem = exports.useTimelineMarqueeSelection = exports.useCurrentTimelineSelectionStateAsRef = exports.TIMELINE_SCRUBBER_ATTR = exports.TIMELINE_MARQUEE_ITEM_ATTR = exports.useTimelineSelection = exports.TimelineSelectionProvider = exports.TimelineSelectAllKeybindings = exports.getTimelineSequenceSelectionKey = exports.getSelectableTimelineSequenceSelections = exports.getTimelineSelectionKey = exports.getTimelineSelectionFromNodePathInfo = exports.getTimelineMarqueeSelection = exports.timelineMarqueeRectsIntersect = exports.getClampedTimelineMarqueePoint = exports.getNormalizedTimelineMarqueeRect = exports.getTimelineSelectionAfterInteraction = exports.shouldSelectTimelineRowOnPointerDown = exports.isTimelineSelectionModifierEvent = exports.TIMELINE_TICKS_BACKGROUND = exports.TIMELINE_BACKGROUND = exports.getTimelineSelectedTrackHighlightStyle = exports.getTimelineColor = exports.getTimelineSelectedLabelStyle = exports.TIMELINE_SELECTED_LABEL_HORIZONTAL_PADDING = exports.TIMELINE_SELECTED_LABEL_TEXT = exports.TIMELINE_SELECTED_LABEL_BACKGROUND = exports.TIMELINE_SELECTED_BACKGROUND = void 0;
3
+ exports.useTimelineRowContainsSelection = exports.useTimelineGuideSelection = exports.useTimelineEasingSelection = exports.useTimelineKeyframeSelection = exports.useTimelineRowSelection = exports.useTimelineMarqueeSelectableItem = exports.useTimelineMarqueeSelection = exports.useCurrentTimelineSelectionStateAsRef = exports.TIMELINE_SCRUBBER_ATTR = exports.TIMELINE_MARQUEE_ITEM_ATTR = exports.useTimelineSelection = exports.TimelineSelectionProvider = exports.TimelineSelectAllKeybindings = exports.getTimelineSequenceSelectionKey = exports.getSelectableTimelineSequenceSelections = exports.getTimelineSelectionKey = exports.getTimelineSelectionFromNodePathInfo = exports.getTimelineMarqueeSelection = exports.timelineMarqueeRectsIntersect = exports.getClampedTimelineMarqueePoint = exports.getNormalizedTimelineMarqueeRect = exports.getAvailableTimelineSelectionState = exports.getTimelineSelectionAfterInteraction = exports.EMPTY_TIMELINE_SELECTION_STATE = exports.shouldSelectTimelineRowOnPointerDown = exports.isTimelineSelectionModifierEvent = exports.TIMELINE_TICKS_BACKGROUND = exports.TIMELINE_BACKGROUND = exports.getTimelineSelectedTrackHighlightStyle = exports.getTimelineColor = exports.getTimelineSelectedLabelStyle = exports.TIMELINE_SELECTED_LABEL_HORIZONTAL_PADDING = exports.TIMELINE_SELECTED_LABEL_TEXT = exports.TIMELINE_SELECTED_LABEL_BACKGROUND = exports.TIMELINE_SELECTED_BACKGROUND = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const studio_shared_1 = require("@remotion/studio-shared");
6
6
  const react_1 = require("react");
7
+ const remotion_1 = require("remotion");
7
8
  const client_id_1 = require("../../helpers/client-id");
8
9
  const colors_1 = require("../../helpers/colors");
9
10
  const timeline_layout_1 = require("../../helpers/timeline-layout");
@@ -56,6 +57,10 @@ const shouldSelectTimelineRowOnPointerDown = ({ selected, shiftKey, metaKey, ctr
56
57
  return (!selected || (0, exports.isTimelineSelectionModifierEvent)({ shiftKey, metaKey, ctrlKey }));
57
58
  };
58
59
  exports.shouldSelectTimelineRowOnPointerDown = shouldSelectTimelineRowOnPointerDown;
60
+ exports.EMPTY_TIMELINE_SELECTION_STATE = {
61
+ selectedItems: [],
62
+ anchor: null,
63
+ };
59
64
  const getTimelineSelectionType = (item) => item.type;
60
65
  const areTimelineSelectionTypesCompatible = (firstType, secondType) => {
61
66
  if (firstType === secondType) {
@@ -144,6 +149,32 @@ const getTimelineSelectionAfterInteraction = ({ currentState, clickedItem, inter
144
149
  };
145
150
  };
146
151
  exports.getTimelineSelectionAfterInteraction = getTimelineSelectionAfterInteraction;
152
+ const getAvailableTimelineSelectionState = ({ availableKeys, availableItemsByKey, state, }) => {
153
+ if (state.selectedItems.length === 0 && state.anchor === null) {
154
+ return state;
155
+ }
156
+ const getCurrentSelectionItem = (item) => {
157
+ var _a;
158
+ const key = (0, exports.getTimelineSelectionKey)(item);
159
+ if (!availableKeys.has(key)) {
160
+ return null;
161
+ }
162
+ return (_a = availableItemsByKey === null || availableItemsByKey === void 0 ? void 0 : availableItemsByKey.get(key)) !== null && _a !== void 0 ? _a : item;
163
+ };
164
+ const selectedItems = state.selectedItems
165
+ .map(getCurrentSelectionItem)
166
+ .filter((item) => item !== null);
167
+ const anchor = state.anchor ? getCurrentSelectionItem(state.anchor) : null;
168
+ if (selectedItems.length === state.selectedItems.length &&
169
+ anchor === state.anchor) {
170
+ return state;
171
+ }
172
+ return {
173
+ selectedItems,
174
+ anchor,
175
+ };
176
+ };
177
+ exports.getAvailableTimelineSelectionState = getAvailableTimelineSelectionState;
147
178
  const getNormalizedTimelineMarqueeRect = ({ startX, startY, currentX, currentY, }) => ({
148
179
  left: Math.min(startX, currentX),
149
180
  top: Math.min(startY, currentY),
@@ -347,22 +378,68 @@ const TimelineSelectAllKeybindings = ({ timeline }) => {
347
378
  exports.TimelineSelectAllKeybindings = TimelineSelectAllKeybindings;
348
379
  const TimelineSelectionProvider = ({ children }) => {
349
380
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
381
+ const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
382
+ const timelineSelectionScope = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition' ? canvasContent.compositionId : null;
350
383
  const canSelect = previewServerState.type === 'connected' &&
351
384
  !window.remotion_isReadOnlyStudio;
352
385
  const [selectedItems, setSelectedItems] = (0, react_1.useState)([]);
353
386
  const selectionAnchor = (0, react_1.useRef)(null);
387
+ const selectionScope = (0, react_1.useRef)(null);
354
388
  const selectableItemsOrder = (0, react_1.useRef)(new Map());
355
389
  const selectableItems = (0, react_1.useRef)(new Map());
390
+ const selectableItemRegistrationCounts = (0, react_1.useRef)(new Map());
356
391
  const marqueeSelectableItems = (0, react_1.useRef)(new Map());
357
392
  const registrationCounter = (0, react_1.useRef)(0);
358
393
  const marqueeRegistrationCounter = (0, react_1.useRef)(0);
394
+ const [selectableItemsVersion, setSelectableItemsVersion] = (0, react_1.useState)(0);
395
+ const bumpSelectableItemsVersion = (0, react_1.useCallback)(() => {
396
+ setSelectableItemsVersion((version) => version + 1);
397
+ }, []);
359
398
  (0, react_1.useEffect)(() => {
360
399
  if (!canSelect) {
400
+ selectionScope.current = null;
401
+ selectionAnchor.current = null;
361
402
  setSelectedItems([]);
362
403
  }
363
404
  }, [canSelect]);
364
405
  const canSelectItem = (0, react_1.useCallback)((_item) => canSelect, [canSelect]);
365
- const selectedKeys = (0, react_1.useMemo)(() => new Set(selectedItems.map(exports.getTimelineSelectionKey)), [selectedItems]);
406
+ const getCurrentAvailableSelectionState = (0, react_1.useCallback)((currentSelectedItems) => {
407
+ if (selectionScope.current !== timelineSelectionScope) {
408
+ return exports.EMPTY_TIMELINE_SELECTION_STATE;
409
+ }
410
+ return (0, exports.getAvailableTimelineSelectionState)({
411
+ availableKeys: new Set(selectableItems.current.keys()),
412
+ availableItemsByKey: selectableItems.current,
413
+ state: {
414
+ selectedItems: currentSelectedItems,
415
+ anchor: selectionAnchor.current,
416
+ },
417
+ });
418
+ }, [timelineSelectionScope]);
419
+ const availableSelectionState = getCurrentAvailableSelectionState(selectedItems);
420
+ const availableSelectedItems = availableSelectionState.selectedItems;
421
+ (0, react_1.useEffect)(() => {
422
+ setSelectedItems((currentSelectedItems) => {
423
+ const nextState = selectionScope.current === timelineSelectionScope
424
+ ? (0, exports.getAvailableTimelineSelectionState)({
425
+ availableKeys: new Set(selectableItems.current.keys()),
426
+ availableItemsByKey: selectableItems.current,
427
+ state: {
428
+ selectedItems: currentSelectedItems,
429
+ anchor: selectionAnchor.current,
430
+ },
431
+ })
432
+ : exports.EMPTY_TIMELINE_SELECTION_STATE;
433
+ selectionScope.current = timelineSelectionScope;
434
+ selectionAnchor.current = nextState.anchor;
435
+ if (nextState.selectedItems.length === currentSelectedItems.length &&
436
+ nextState.selectedItems.every((item, index) => item === currentSelectedItems[index])) {
437
+ return currentSelectedItems;
438
+ }
439
+ return nextState.selectedItems;
440
+ });
441
+ }, [selectableItemsVersion, timelineSelectionScope]);
442
+ const selectedKeys = (0, react_1.useMemo)(() => new Set(availableSelectedItems.map(exports.getTimelineSelectionKey)), [availableSelectedItems]);
366
443
  const isSelected = (0, react_1.useCallback)((item) => {
367
444
  return selectedKeys.has((0, exports.getTimelineSelectionKey)(item));
368
445
  }, [selectedKeys]);
@@ -374,6 +451,7 @@ const TimelineSelectionProvider = ({ children }) => {
374
451
  return;
375
452
  }
376
453
  setSelectedItems((currentSelectedItems) => {
454
+ const currentSelectionState = getCurrentAvailableSelectionState(currentSelectedItems);
377
455
  const orderedSelectableItems = [
378
456
  ...selectableItems.current.values(),
379
457
  ].sort((a, b) => {
@@ -383,36 +461,52 @@ const TimelineSelectionProvider = ({ children }) => {
383
461
  });
384
462
  const nextState = (0, exports.getTimelineSelectionAfterInteraction)({
385
463
  currentState: {
386
- selectedItems: currentSelectedItems,
387
- anchor: selectionAnchor.current,
464
+ selectedItems: currentSelectionState.selectedItems,
465
+ anchor: currentSelectionState.anchor,
388
466
  },
389
467
  clickedItem: item,
390
468
  interaction,
391
469
  allSelectableItems: orderedSelectableItems,
392
470
  });
471
+ selectionScope.current = timelineSelectionScope;
393
472
  selectionAnchor.current = nextState.anchor;
394
473
  return nextState.selectedItems;
395
474
  });
396
- }, [canSelectItem]);
475
+ }, [canSelectItem, getCurrentAvailableSelectionState, timelineSelectionScope]);
397
476
  const selectItems = (0, react_1.useCallback)((items) => {
398
477
  if (!items.every(canSelectItem)) {
399
478
  return;
400
479
  }
480
+ selectionScope.current = timelineSelectionScope;
401
481
  selectionAnchor.current =
402
482
  items.length === 0 ? null : items[items.length - 1];
403
483
  setSelectedItems(items);
404
- }, [canSelectItem]);
484
+ }, [canSelectItem, timelineSelectionScope]);
405
485
  const registerSelectableItem = (0, react_1.useCallback)((item) => {
486
+ var _a;
406
487
  const key = (0, exports.getTimelineSelectionKey)(item);
407
- const registrationOrder = registrationCounter.current;
408
- registrationCounter.current += 1;
488
+ const currentRegistrationCount = (_a = selectableItemRegistrationCounts.current.get(key)) !== null && _a !== void 0 ? _a : 0;
489
+ if (currentRegistrationCount === 0) {
490
+ const registrationOrder = registrationCounter.current;
491
+ registrationCounter.current += 1;
492
+ selectableItemsOrder.current.set(key, registrationOrder);
493
+ }
494
+ selectableItemRegistrationCounts.current.set(key, currentRegistrationCount + 1);
409
495
  selectableItems.current.set(key, item);
410
- selectableItemsOrder.current.set(key, registrationOrder);
496
+ bumpSelectableItemsVersion();
411
497
  return () => {
498
+ var _a;
499
+ const nextRegistrationCount = ((_a = selectableItemRegistrationCounts.current.get(key)) !== null && _a !== void 0 ? _a : 1) - 1;
500
+ if (nextRegistrationCount > 0) {
501
+ selectableItemRegistrationCounts.current.set(key, nextRegistrationCount);
502
+ return;
503
+ }
504
+ selectableItemRegistrationCounts.current.delete(key);
412
505
  selectableItems.current.delete(key);
413
506
  selectableItemsOrder.current.delete(key);
507
+ bumpSelectableItemsVersion();
414
508
  };
415
- }, []);
509
+ }, [bumpSelectableItemsVersion]);
416
510
  const registerMarqueeSelectableItem = (0, react_1.useCallback)((item, getRect) => {
417
511
  const key = (0, exports.getTimelineSelectionKey)(item);
418
512
  const registrationOrder = marqueeRegistrationCounter.current;
@@ -456,16 +550,17 @@ const TimelineSelectionProvider = ({ children }) => {
456
550
  });
457
551
  }, [canSelectItem]);
458
552
  const clearSelection = (0, react_1.useCallback)(() => {
553
+ selectionScope.current = null;
459
554
  selectionAnchor.current = null;
460
555
  setSelectedItems([]);
461
556
  }, []);
462
557
  const containsSelection = (0, react_1.useCallback)((nodePathInfo) => {
463
- return selectedItems.some((selected) => selected.type !== 'guide' &&
558
+ return availableSelectedItems.some((selected) => selected.type !== 'guide' &&
464
559
  nodePathDescendsFrom(selected.nodePathInfo, nodePathInfo));
465
- }, [selectedItems]);
560
+ }, [availableSelectedItems]);
466
561
  const value = (0, react_1.useMemo)(() => ({
467
562
  canSelect,
468
- selectedItems,
563
+ selectedItems: availableSelectedItems,
469
564
  isSelected,
470
565
  selectItem,
471
566
  selectItems,
@@ -476,7 +571,7 @@ const TimelineSelectionProvider = ({ children }) => {
476
571
  clearSelection,
477
572
  }), [
478
573
  canSelect,
479
- selectedItems,
574
+ availableSelectedItems,
480
575
  isSelected,
481
576
  selectItem,
482
577
  selectItems,
@@ -62,6 +62,7 @@ const TimelineSequenceRightEdgeDragHandle_1 = require("./TimelineSequenceRightEd
62
62
  const TimelineVideoInfo_1 = require("./TimelineVideoInfo");
63
63
  const TimelineWidthProvider_1 = require("./TimelineWidthProvider");
64
64
  const use_resolved_stack_react_to_change_1 = require("./use-resolved-stack-react-to-change");
65
+ const use_sequence_freeze_frame_menu_item_1 = require("./use-sequence-freeze-frame-menu-item");
65
66
  const AUDIO_GRADIENT = 'linear-gradient(rgb(16 171 58), rgb(43 165 63) 60%)';
66
67
  const VIDEO_GRADIENT = 'linear-gradient(to top, #8e44ad, #9b59b6)';
67
68
  const IMAGE_GRADIENT = 'linear-gradient(to top, #2980b9, #3498db)';
@@ -153,10 +154,10 @@ const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffs
153
154
  // If a duration is 1, it is essentially a still and it should have width 0
154
155
  // Some compositions may not be longer than their media duration,
155
156
  // if that is the case, it needs to be asynchronously determined
156
- var _a, _b, _c;
157
- var _d, _e, _f, _g;
157
+ var _a, _b;
158
+ var _c, _d, _e, _f, _g;
158
159
  const video = remotion_1.Internals.useVideo();
159
- const maxMediaDuration = (0, use_max_media_duration_1.useMaxMediaDuration)(s, (_d = video === null || video === void 0 ? void 0 : video.fps) !== null && _d !== void 0 ? _d : 30);
160
+ const maxMediaDuration = (0, use_max_media_duration_1.useMaxMediaDuration)(s, (_c = video === null || video === void 0 ? void 0 : video.fps) !== null && _c !== void 0 ? _c : 30);
160
161
  const effectiveMaxMediaDuration = s.loopDisplay ? null : maxMediaDuration;
161
162
  const originalLocation = (0, use_resolved_stack_react_to_change_1.useResolveStackAndReactToChange)(s.getStack);
162
163
  const validatedLocation = (0, react_1.useMemo)(() => {
@@ -173,7 +174,7 @@ const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffs
173
174
  };
174
175
  }, [originalLocation]);
175
176
  const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
176
- const nodePath = (_e = nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.sequenceSubscriptionKey) !== null && _e !== void 0 ? _e : null;
177
+ const nodePath = (_d = nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.sequenceSubscriptionKey) !== null && _d !== void 0 ? _d : null;
177
178
  const propStatusesForOverride = (0, react_1.useMemo)(() => {
178
179
  return nodePath
179
180
  ? remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePath)
@@ -184,6 +185,7 @@ const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffs
184
185
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
185
186
  const previewConnected = previewServerState.type === 'connected';
186
187
  const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
188
+ const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
187
189
  const selectAsset = (0, use_select_asset_1.useSelectAsset)();
188
190
  const confirm = (0, ConfirmationDialog_1.useConfirmationDialog)();
189
191
  const { onSelect, selectable } = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
@@ -279,6 +281,18 @@ const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffs
279
281
  setPropStatuses,
280
282
  validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source,
281
283
  ]);
284
+ const freezeFrameMenuItem = (0, use_sequence_freeze_frame_menu_item_1.useSequenceFreezeFrameMenuItem)({
285
+ clientId: previewServerState.type === 'connected'
286
+ ? previewServerState.clientId
287
+ : null,
288
+ nodePath,
289
+ propStatusesForOverride,
290
+ sequence: s,
291
+ sequenceFrameOffset,
292
+ setPropStatuses,
293
+ timelinePosition,
294
+ validatedSource: (_e = validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source) !== null && _e !== void 0 ? _e : null,
295
+ });
282
296
  const contextMenuValues = (0, react_1.useMemo)(() => {
283
297
  if (!previewConnected) {
284
298
  return [];
@@ -298,6 +312,7 @@ const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffs
298
312
  originalLocation,
299
313
  selectAsset,
300
314
  sequence: s,
315
+ sourceActions: [freezeFrameMenuItem],
301
316
  });
302
317
  }, [
303
318
  assetLinkInfo,
@@ -306,6 +321,7 @@ const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffs
306
321
  disableInteractivityDisabled,
307
322
  duplicateDisabled,
308
323
  fileLocation,
324
+ freezeFrameMenuItem,
309
325
  onDeleteSequenceFromSource,
310
326
  onDisableSequenceInteractivity,
311
327
  onDuplicateSequenceFromSource,
@@ -320,15 +336,7 @@ const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffs
320
336
  onSelect({ shiftKey: false, toggleKey: false });
321
337
  }
322
338
  }, [onSelect, selectable]);
323
- const freezeStatus = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.freeze;
324
- const runtimeFreezeFrame = typeof ((_c = s.controls) === null || _c === void 0 ? void 0 : _c.currentRuntimeValueDotNotation.freeze) === 'number'
325
- ? s.controls.currentRuntimeValueDotNotation.freeze
326
- : null;
327
- const frozenFrame = (freezeStatus === null || freezeStatus === void 0 ? void 0 : freezeStatus.status) === 'static'
328
- ? typeof freezeStatus.codeValue === 'number'
329
- ? freezeStatus.codeValue
330
- : null
331
- : runtimeFreezeFrame;
339
+ const { frozenFrame } = s;
332
340
  const { onPointerDown: onMoveDragPointerDown } = (0, TimelineSequenceRightEdgeDragHandle_1.useTimelineSequenceFromDrag)({
333
341
  nodePathInfo,
334
342
  windowWidth,
@@ -386,7 +394,7 @@ const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffs
386
394
  if (maxMediaDuration === null && !s.loopDisplay) {
387
395
  return null;
388
396
  }
389
- const sequence = (jsx_runtime_1.jsxs(TimelineSequenceCurrentFrame, { s: s, displayDurationInFrames: displayDurationInFrames, premountWidth: premountWidth, postmountWidth: postmountWidth, style: style, nodePathInfo: nodePathInfo, sequenceFrameOffset: sequenceFrameOffset, fromCanUpdate: fromCanUpdate, frozenFrame: frozenFrame, onMoveDragPointerDown: onMoveDragPointerDown, children: [s.type === 'audio' ? (jsx_runtime_1.jsx(AudioWaveform_1.AudioWaveform, { src: s.src, height: timeline_layout_1.TIMELINE_LAYER_HEIGHT_AUDIO, doesVolumeChange: s.doesVolumeChange, visualizationWidth: width, startFrom: s.startMediaFrom, durationInFrames: s.duration, volume: s.volume, playbackRate: s.playbackRate, loopDisplay: s.loopDisplay })) : null, s.type === 'video' ? (jsx_runtime_1.jsx(TimelineVideoInfo_1.TimelineVideoInfo, { src: s.src, visualizationWidth: width, naturalWidth: naturalWidth, trimBefore: s.startMediaFrom, durationInFrames: s.duration, playbackRate: s.playbackRate, volume: s.volume, doesVolumeChange: s.doesVolumeChange, premountWidth: premountWidth !== null && premountWidth !== void 0 ? premountWidth : 0, postmountWidth: postmountWidth !== null && postmountWidth !== void 0 ? postmountWidth : 0, loopDisplay: s.loopDisplay })) : null, s.type === 'image' ? (jsx_runtime_1.jsx(TimelineImageInfo_1.TimelineImageInfo, { src: s.src, visualizationWidth: width })) : null, s.loopDisplay === undefined ? null : (jsx_runtime_1.jsx(LoopedTimelineIndicators_1.LoopedTimelineIndicator, { loops: s.loopDisplay.numberOfTimes })), showRightEdgeDragHandle && nodePathInfo && validatedLocation ? (jsx_runtime_1.jsx(TimelineSequenceRightEdgeDragHandle_1.TimelineSequenceRightEdgeDragHandle, { nodePathInfo: nodePathInfo, windowWidth: windowWidth, timelineDurationInFrames: (_g = video.durationInFrames) !== null && _g !== void 0 ? _g : 1 })) : null] }));
397
+ const sequence = (jsx_runtime_1.jsxs(TimelineSequenceCurrentFrame, { s: s, displayDurationInFrames: displayDurationInFrames, premountWidth: premountWidth, postmountWidth: postmountWidth, style: style, nodePathInfo: nodePathInfo, sequenceFrameOffset: sequenceFrameOffset, fromCanUpdate: fromCanUpdate, frozenFrame: frozenFrame, onMoveDragPointerDown: onMoveDragPointerDown, children: [s.type === 'audio' ? (jsx_runtime_1.jsx(AudioWaveform_1.AudioWaveform, { src: s.src, height: timeline_layout_1.TIMELINE_LAYER_HEIGHT_AUDIO, doesVolumeChange: s.doesVolumeChange, visualizationWidth: width, startFrom: s.startMediaFrom, durationInFrames: s.duration, volume: s.volume, playbackRate: s.playbackRate, loopDisplay: s.loopDisplay })) : null, s.type === 'video' ? (jsx_runtime_1.jsx(TimelineVideoInfo_1.TimelineVideoInfo, { src: s.src, visualizationWidth: width, naturalWidth: naturalWidth, trimBefore: s.startMediaFrom, durationInFrames: s.duration, playbackRate: s.playbackRate, volume: s.volume, doesVolumeChange: s.doesVolumeChange, premountWidth: premountWidth !== null && premountWidth !== void 0 ? premountWidth : 0, postmountWidth: postmountWidth !== null && postmountWidth !== void 0 ? postmountWidth : 0, loopDisplay: s.loopDisplay, frozenMediaFrame: s.frozenMediaFrame })) : null, s.type === 'image' ? (jsx_runtime_1.jsx(TimelineImageInfo_1.TimelineImageInfo, { src: s.src, visualizationWidth: width })) : null, s.loopDisplay === undefined ? null : (jsx_runtime_1.jsx(LoopedTimelineIndicators_1.LoopedTimelineIndicator, { loops: s.loopDisplay.numberOfTimes })), showRightEdgeDragHandle && nodePathInfo && validatedLocation ? (jsx_runtime_1.jsx(TimelineSequenceRightEdgeDragHandle_1.TimelineSequenceRightEdgeDragHandle, { nodePathInfo: nodePathInfo, windowWidth: windowWidth, timelineDurationInFrames: (_g = video.durationInFrames) !== null && _g !== void 0 ? _g : 1 })) : null] }));
390
398
  return previewConnected ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, onOpen: onContextMenuOpen, children: sequence })) : (sequence);
391
399
  };
392
400
  exports.TimelineSequence = react_1.default.memo(TimelineSequenceFn);