@remotion/studio 4.0.512 → 4.0.513

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 (55) hide show
  1. package/dist/components/CompositionSelectorItem.js +14 -1
  2. package/dist/components/InspectorOpenInEditor.js +24 -24
  3. package/dist/components/InspectorPanel/AlignmentControls.js +13 -2
  4. package/dist/components/InspectorPanel/CompositionInspectorHeader.js +12 -8
  5. package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +12 -1
  6. package/dist/components/InspectorPanel/EasingInspector.js +11 -2
  7. package/dist/components/InspectorPanel/KeyframeInspector.js +19 -5
  8. package/dist/components/InspectorPanel/easing-inspector-selection.js +7 -2
  9. package/dist/components/InspectorPanel/inspector-section-collapse.d.ts +1 -0
  10. package/dist/components/SelectedOutlineElement.js +12 -10
  11. package/dist/components/SelectedOutlineOverlay.js +30 -8
  12. package/dist/components/Timeline/TimelineArrayField.js +1 -0
  13. package/dist/components/Timeline/TimelineEffectPropItem.js +10 -4
  14. package/dist/components/Timeline/TimelineKeyframeControls.js +25 -7
  15. package/dist/components/Timeline/TimelineKeyframedValue.js +1 -0
  16. package/dist/components/Timeline/TimelineSequencePropItem.js +11 -4
  17. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +3 -0
  18. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +96 -18
  19. package/dist/components/Timeline/call-move-keyframe.d.ts +2 -1
  20. package/dist/components/Timeline/call-move-keyframe.js +70 -17
  21. package/dist/components/Timeline/delete-selected-keyframe.d.ts +0 -8
  22. package/dist/components/Timeline/delete-selected-keyframe.js +23 -44
  23. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +0 -8
  24. package/dist/components/Timeline/delete-selected-timeline-item.js +16 -43
  25. package/dist/components/Timeline/get-easing-selection-after-keyframe-delete.js +8 -3
  26. package/dist/components/Timeline/get-sequence-context-menu-items.js +10 -8
  27. package/dist/components/Timeline/get-timeline-keyframes.d.ts +4 -0
  28. package/dist/components/Timeline/get-timeline-keyframes.js +16 -3
  29. package/dist/components/Timeline/keyframe-clipboard.js +9 -2
  30. package/dist/components/Timeline/use-open-sequence-in-apps.js +8 -8
  31. package/dist/components/Timeline/use-timeline-keyframe-drag.js +14 -4
  32. package/dist/components/VisualControls/ClickableFileName.js +13 -6
  33. package/dist/components/composition-menu-items.d.ts +6 -1
  34. package/dist/components/composition-menu-items.js +9 -6
  35. package/dist/components/folder-menu-items.d.ts +4 -1
  36. package/dist/components/folder-menu-items.js +4 -5
  37. package/dist/components/get-open-in-menu-items.d.ts +1 -1
  38. package/dist/components/get-open-in-menu-items.js +15 -13
  39. package/dist/components/sequence-props-api.js +44 -3
  40. package/dist/components/use-default-editor-info.d.ts +8 -0
  41. package/dist/components/use-default-editor-info.js +25 -9
  42. package/dist/error-overlay/remotion-overlay/ErrorDisplay.js +10 -3
  43. package/dist/error-overlay/remotion-overlay/OpenInEditor.d.ts +3 -1
  44. package/dist/error-overlay/remotion-overlay/OpenInEditor.js +6 -6
  45. package/dist/error-overlay/remotion-overlay/Overlay.js +14 -12
  46. package/dist/error-overlay/remotion-overlay/StackFrame.d.ts +2 -1
  47. package/dist/error-overlay/remotion-overlay/StackFrame.js +7 -4
  48. package/dist/esm/{chunk-s8gwjng0.js → chunk-tv7r0jy3.js} +1692 -1322
  49. package/dist/esm/internals.mjs +1692 -1322
  50. package/dist/esm/previewEntry.mjs +3167 -2793
  51. package/dist/esm/renderEntry.mjs +1 -1
  52. package/dist/helpers/open-in-editor.d.ts +6 -4
  53. package/dist/helpers/open-in-editor.js +4 -4
  54. package/dist/helpers/use-menu-structure.js +11 -6
  55. package/package.json +12 -12
@@ -22,6 +22,7 @@ const NotificationCenter_1 = require("./Notifications/NotificationCenter");
22
22
  const actions_1 = require("./RenderQueue/actions");
23
23
  const SidebarRenderButton_1 = require("./SidebarRenderButton");
24
24
  const use_resolved_stack_1 = require("./Timeline/use-resolved-stack");
25
+ const use_default_editor_info_1 = require("./use-default-editor-info");
25
26
  const itemStyle = {
26
27
  paddingRight: 2,
27
28
  paddingTop: 5,
@@ -119,6 +120,7 @@ const CompositionSelectorItem = ({ item, level, currentComposition, tabIndex, se
119
120
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.SetSelectedModalContext);
120
121
  const connectionStatus = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx)
121
122
  .previewServerState.type;
123
+ const { defaultEditorId, defaultEditorName } = (0, use_default_editor_info_1.useEditorOpening)(connectionStatus === 'connected');
122
124
  const resolvedLocation = (0, use_resolved_stack_1.useResolvedStack)(item.type === 'composition' ? item.composition.stack : item.folder.stack);
123
125
  const getContextMenuItems = (0, react_1.useCallback)(() => {
124
126
  if (item.type === 'composition') {
@@ -126,6 +128,8 @@ const CompositionSelectorItem = ({ item, level, currentComposition, tabIndex, se
126
128
  closeMenu: noop_1.noop,
127
129
  composition: item.composition,
128
130
  connectionStatus,
131
+ editorId: defaultEditorId,
132
+ editorName: defaultEditorName,
129
133
  includeCompositionManagementItems: true,
130
134
  resolvedLocation,
131
135
  setSelectedModal,
@@ -135,12 +139,21 @@ const CompositionSelectorItem = ({ item, level, currentComposition, tabIndex, se
135
139
  return (0, folder_menu_items_1.getFolderMenuItems)({
136
140
  closeMenu: noop_1.noop,
137
141
  connectionStatus,
142
+ editorId: defaultEditorId,
143
+ editorName: defaultEditorName,
138
144
  folder: item.folder,
139
145
  resolvedLocation,
140
146
  setSelectedModal,
141
147
  readOnlyStudio: window.remotion_isReadOnlyStudio,
142
148
  });
143
- }, [connectionStatus, item, resolvedLocation, setSelectedModal]);
149
+ }, [
150
+ connectionStatus,
151
+ defaultEditorId,
152
+ defaultEditorName,
153
+ item,
154
+ resolvedLocation,
155
+ setSelectedModal,
156
+ ]);
144
157
  const onCompositionDragStart = (0, react_1.useCallback)((event) => {
145
158
  var _a, _b, _c, _d;
146
159
  if (item.type !== 'composition' || window.remotion_isReadOnlyStudio) {
@@ -42,16 +42,14 @@ const mainButtonBase = {
42
42
  };
43
43
  const editorButtonIconSize = 18;
44
44
  const InspectorOpenInEditor = ({ contextForAgents = null, label, location, locationType }) => {
45
- var _a, _b;
46
45
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
47
46
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.SetSelectedModalContext);
48
47
  const { tabIndex } = (0, z_index_1.useZIndex)();
49
48
  const [hovered, setHovered] = (0, react_1.useState)(false);
50
49
  const [dropdownOpened, setDropdownOpened] = (0, react_1.useState)(false);
51
50
  const ignorePointerEnter = (0, react_1.useRef)(false);
52
- const editorPickerAvailable = (0, use_default_editor_info_1.canUseEditorPicker)(previewServerState.type === 'connected');
53
- const editorInfo = (0, use_default_editor_info_1.useDefaultEditorInfo)(editorPickerAvailable);
54
- const codingAgentInfo = (0, use_default_editor_info_1.useDefaultCodingAgentInfo)(editorPickerAvailable);
51
+ const { canConfigureApps, canOpenInEditor, defaultEditorId, defaultEditorName, editorInfo, } = (0, use_default_editor_info_1.useEditorOpening)(previewServerState.type === 'connected');
52
+ const codingAgentInfo = (0, use_default_editor_info_1.useDefaultCodingAgentInfo)(canConfigureApps);
55
53
  const openWithEditor = (0, react_1.useCallback)(async (editorId) => {
56
54
  if (!location) {
57
55
  return;
@@ -63,8 +61,6 @@ const InspectorOpenInEditor = ({ contextForAgents = null, label, location, locat
63
61
  (0, NotificationCenter_1.showNotification)(err.message, 2000);
64
62
  }
65
63
  }, [location]);
66
- const preferredEditorId = (0, use_default_editor_info_1.getPreferredEditorId)(editorInfo);
67
- const preferredEditor = editorInfo === null || editorInfo === void 0 ? void 0 : editorInfo.installedEditors.find((editor) => editor.id === preferredEditorId);
68
64
  const openWithCodingAgent = (0, react_1.useCallback)(async (codingAgentId, codingAgentName) => {
69
65
  try {
70
66
  const response = await (0, open_in_editor_1.openInCodingAgent)(codingAgentId, codingAgentId === 'copilot' ? null : contextForAgents);
@@ -76,13 +72,14 @@ const InspectorOpenInEditor = ({ contextForAgents = null, label, location, locat
76
72
  (0, NotificationCenter_1.showNotification)(err.message, 2000);
77
73
  }
78
74
  }, [contextForAgents]);
79
- const editorName = (_b = (_a = window.remotion_editorName) !== null && _a !== void 0 ? _a : preferredEditor === null || preferredEditor === void 0 ? void 0 : preferredEditor.nameWithType) !== null && _b !== void 0 ? _b : 'default editor';
80
- const canOpenDefault = location !== null &&
81
- (window.remotion_editorName !== null || preferredEditorId !== null);
75
+ const editorName = defaultEditorName !== null && defaultEditorName !== void 0 ? defaultEditorName : 'default editor';
76
+ const canOpenDefault = location !== null && canOpenInEditor;
82
77
  const onOpenDefault = (0, react_1.useCallback)((event) => {
83
78
  event.stopPropagation();
84
- openWithEditor(window.remotion_editorName === null ? preferredEditorId : null).catch(() => undefined);
85
- }, [openWithEditor, preferredEditorId]);
79
+ if (defaultEditorId) {
80
+ openWithEditor(defaultEditorId).catch(() => undefined);
81
+ }
82
+ }, [defaultEditorId, openWithEditor]);
86
83
  const onDropdownOpenChange = (0, react_1.useCallback)((open) => {
87
84
  setDropdownOpened(open);
88
85
  if (!open) {
@@ -123,19 +120,21 @@ const InspectorOpenInEditor = ({ contextForAgents = null, label, location, locat
123
120
  editorDisabled: location === null,
124
121
  editorInfo,
125
122
  excludeCodingAgentId: null,
126
- excludeEditorId: preferredEditorId,
123
+ excludeEditorId: defaultEditorId,
127
124
  fileManagerDisabled: !(location === null || location === void 0 ? void 0 : location.source),
128
125
  folder: locationType === 'folder',
129
126
  location,
130
- onConfigureApps: () => {
131
- var _a;
132
- var _b;
133
- setSelectedModal({
134
- type: 'settings',
135
- initialTab: 'apps',
136
- initialPublicLicenseKey: (_b = (_a = window.remotion_renderDefaults) === null || _a === void 0 ? void 0 : _a.publicLicenseKey) !== null && _b !== void 0 ? _b : null,
137
- });
138
- },
127
+ onConfigureApps: canConfigureApps
128
+ ? () => {
129
+ var _a;
130
+ var _b;
131
+ setSelectedModal({
132
+ type: 'settings',
133
+ initialTab: 'apps',
134
+ initialPublicLicenseKey: (_b = (_a = window.remotion_renderDefaults) === null || _a === void 0 ? void 0 : _a.publicLicenseKey) !== null && _b !== void 0 ? _b : null,
135
+ });
136
+ }
137
+ : null,
139
138
  onOpenInCodingAgent: (codingAgentId, codingAgentName) => {
140
139
  openWithCodingAgent(codingAgentId, codingAgentName).catch(() => undefined);
141
140
  },
@@ -178,15 +177,16 @@ const InspectorOpenInEditor = ({ contextForAgents = null, label, location, locat
178
177
  });
179
178
  }, [
180
179
  codingAgentInfo,
180
+ canConfigureApps,
181
+ defaultEditorId,
181
182
  editorInfo,
182
183
  location,
183
184
  locationType,
184
185
  openWithCodingAgent,
185
186
  openWithEditor,
186
- preferredEditorId,
187
187
  setSelectedModal,
188
188
  ]);
189
- if (!editorPickerAvailable) {
189
+ if (previewServerState.type !== 'connected') {
190
190
  return null;
191
191
  }
192
192
  return (jsx_runtime_1.jsxs("div", { style: splitButton, onPointerEnter: () => {
@@ -197,7 +197,7 @@ const InspectorOpenInEditor = ({ contextForAgents = null, label, location, locat
197
197
  ignorePointerEnter.current = false;
198
198
  setHovered(false);
199
199
  }, children: [
200
- jsx_runtime_1.jsxs("button", { "aria-label": `Open in ${editorName}`, disabled: !canOpenDefault, onClick: onOpenDefault, style: mainButtonStyle, tabIndex: tabIndex, title: `Open in ${editorName}`, type: "button", children: [label, jsx_runtime_1.jsx(editor_1.EditorIcon, { editorId: preferredEditorId, size: editorButtonIconSize })
200
+ jsx_runtime_1.jsxs("button", { "aria-label": `Open in ${editorName}`, disabled: !canOpenDefault, onClick: onOpenDefault, style: mainButtonStyle, tabIndex: tabIndex, title: `Open in ${editorName}`, type: "button", children: [label, jsx_runtime_1.jsx(editor_1.EditorIcon, { editorId: defaultEditorId, size: editorButtonIconSize })
201
201
  ] }), jsx_runtime_1.jsx(InlineDropdown_1.InlineDropdown, { onOpenChange: onDropdownOpenChange, renderAction: renderDropdownAction, style: dropdownStyle, title: "Open in another app", unhoveredColor: dropdownForegroundColor, values: menuItems, variant: "compact" })
202
202
  ] }));
203
203
  };
@@ -18,6 +18,7 @@ const InspectorPanelLayout_1 = require("../InspectorPanelLayout");
18
18
  const selected_outline_drag_1 = require("../selected-outline-drag");
19
19
  const selected_outline_types_1 = require("../selected-outline-types");
20
20
  const call_add_keyframe_1 = require("../Timeline/call-add-keyframe");
21
+ const get_timeline_keyframes_1 = require("../Timeline/get-timeline-keyframes");
21
22
  const save_sequence_prop_1 = require("../Timeline/save-sequence-prop");
22
23
  const timeline_translate_utils_1 = require("../Timeline/timeline-translate-utils");
23
24
  const alignment_controls_1 = require("./alignment-controls");
@@ -77,7 +78,12 @@ const AlignmentControls = ({ track }) => {
77
78
  }
78
79
  const nodePath = track.nodePathInfo.sequenceSubscriptionKey;
79
80
  const nodePropStatuses = remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePath);
80
- const sourceFrame = timelinePosition - track.keyframeDisplayOffset;
81
+ const firstKeyframedStatus = Object.values(nodePropStatuses !== null && nodePropStatuses !== void 0 ? nodePropStatuses : {}).find((status) => status.status === 'keyframed');
82
+ const sourceFrame = timelinePosition -
83
+ (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
84
+ propStatus: firstKeyframedStatus,
85
+ keyframeDisplayOffset: track.keyframeDisplayOffset,
86
+ });
81
87
  const dragOverrides = (_b = getDragOverrides(nodePath)) !== null && _b !== void 0 ? _b : {};
82
88
  const activeSchema = (0, selected_outline_drag_1.getSelectedOutlineActiveSchema)({
83
89
  schema: track.sequence.controls.schema,
@@ -191,7 +197,12 @@ const AlignmentControls = ({ track }) => {
191
197
  }
192
198
  const renderNodePath = track.nodePathInfo.sequenceSubscriptionKey;
193
199
  const renderNodePropStatuses = remotion_1.Internals.getPropStatusesCtx(propStatuses, renderNodePath);
194
- const renderSourceFrame = timelinePosition - track.keyframeDisplayOffset;
200
+ const firstRenderKeyframedStatus = Object.values(renderNodePropStatuses !== null && renderNodePropStatuses !== void 0 ? renderNodePropStatuses : {}).find((status) => status.status === 'keyframed');
201
+ const renderSourceFrame = timelinePosition -
202
+ (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
203
+ propStatus: firstRenderKeyframedStatus,
204
+ keyframeDisplayOffset: track.keyframeDisplayOffset,
205
+ });
195
206
  const renderDragOverrides = (_a = getDragOverrides(renderNodePath)) !== null && _a !== void 0 ? _a : {};
196
207
  const renderActiveSchema = (0, selected_outline_drag_1.getSelectedOutlineActiveSchema)({
197
208
  schema: track.sequence.controls.schema,
@@ -4,6 +4,7 @@ exports.CompositionInspectorHeader = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
+ const client_id_1 = require("../../helpers/client-id");
7
8
  const is_composition_still_1 = require("../../helpers/is-composition-still");
8
9
  const open_in_editor_1 = require("../../helpers/open-in-editor");
9
10
  const react_2 = require("../../icons/react");
@@ -16,6 +17,7 @@ const InspectorSourceLocation_1 = require("../InspectorSourceLocation");
16
17
  const layout_1 = require("../layout");
17
18
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
18
19
  const use_resolved_stack_1 = require("../Timeline/use-resolved-stack");
20
+ const use_default_editor_info_1 = require("../use-default-editor-info");
19
21
  const COMPOSITION_INSPECTOR_HEADER_HEIGHT = 66;
20
22
  const sourceLocationIconStyle = {
21
23
  flexShrink: 0,
@@ -33,6 +35,8 @@ const CompositionInspectorHeader = () => {
33
35
  var _a, _b, _c, _d, _e;
34
36
  const video = remotion_1.Internals.useVideo();
35
37
  const { compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
38
+ const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
39
+ const { canOpenInEditor, defaultEditorId } = (0, use_default_editor_info_1.useEditorOpening)(previewServerState.type === 'connected');
36
40
  const currentComposition = (0, react_1.useMemo)(() => {
37
41
  var _a;
38
42
  if (!video) {
@@ -69,21 +73,21 @@ const CompositionInspectorHeader = () => {
69
73
  });
70
74
  }, [compositionFile, compositionId]);
71
75
  const openFileLocation = (0, react_1.useCallback)(() => {
72
- if (!validatedLocation) {
76
+ if (!validatedLocation || !defaultEditorId || !canOpenInEditor) {
73
77
  return;
74
78
  }
75
- (0, open_in_editor_1.openOriginalPositionInEditor)(validatedLocation, null).catch((err) => {
79
+ (0, open_in_editor_1.openOriginalPositionInEditor)(validatedLocation, defaultEditorId).catch((err) => {
76
80
  (0, NotificationCenter_1.showNotification)(err.message, 2000);
77
81
  });
78
- }, [validatedLocation]);
82
+ }, [canOpenInEditor, defaultEditorId, validatedLocation]);
79
83
  const openComponentLocation = (0, react_1.useCallback)(() => {
80
- if (!componentLocation) {
84
+ if (!componentLocation || !defaultEditorId || !canOpenInEditor) {
81
85
  return;
82
86
  }
83
- (0, open_in_editor_1.openOriginalPositionInEditor)(componentLocation, null).catch((err) => {
87
+ (0, open_in_editor_1.openOriginalPositionInEditor)(componentLocation, defaultEditorId).catch((err) => {
84
88
  (0, NotificationCenter_1.showNotification)(err.message, 2000);
85
89
  });
86
- }, [componentLocation]);
90
+ }, [canOpenInEditor, componentLocation, defaultEditorId]);
87
91
  const renderCompositionIcon = (0, react_1.useCallback)((color) => {
88
92
  if (!video) {
89
93
  return null;
@@ -91,8 +95,8 @@ const CompositionInspectorHeader = () => {
91
95
  return (0, is_composition_still_1.isCompositionStill)(video) ? (jsx_runtime_1.jsx(still_1.StillIcon, { color: color, style: sourceLocationIconStyle })) : (jsx_runtime_1.jsx(video_1.FilmIcon, { color: color, style: sourceLocationIconStyle }));
92
96
  }, [video]);
93
97
  return (jsx_runtime_1.jsx(InspectorInfoHeader_1.InspectorInfoHeader, { minHeight: COMPOSITION_INSPECTOR_HEADER_HEIGHT, padding: "4px 0", children: video ? (jsx_runtime_1.jsxs(InspectorLocationCopy_1.InspectorLocationCopy, { location: validatedLocation, name: video.id, openInEditorLocation: componentLocation, children: [
94
- jsx_runtime_1.jsx(InlineCompositionName_1.InlineCompositionName, { compositionId: video.id, stack: (_e = currentComposition === null || currentComposition === void 0 ? void 0 : currentComposition.stack) !== null && _e !== void 0 ? _e : null, compositions: compositions }, video.id), jsx_runtime_1.jsx(InspectorSourceLocation_1.InspectorSourceLocation, { location: validatedLocation, canOpen: validatedLocation !== null, onOpen: openFileLocation, renderIcon: renderCompositionIcon, size: "inline-action" }), compositionComponentInfo === null &&
98
+ jsx_runtime_1.jsx(InlineCompositionName_1.InlineCompositionName, { compositionId: video.id, stack: (_e = currentComposition === null || currentComposition === void 0 ? void 0 : currentComposition.stack) !== null && _e !== void 0 ? _e : null, compositions: compositions }, video.id), jsx_runtime_1.jsx(InspectorSourceLocation_1.InspectorSourceLocation, { location: validatedLocation, canOpen: validatedLocation !== null && canOpenInEditor, onOpen: openFileLocation, renderIcon: renderCompositionIcon, size: "inline-action" }), compositionComponentInfo === null &&
95
99
  compositionFile !== null &&
96
- compositionId !== null ? (jsx_runtime_1.jsx("div", { "aria-hidden": true, style: componentLocationPlaceholder })) : (jsx_runtime_1.jsx(InspectorSourceLocation_1.InspectorSourceLocation, { location: componentLocation, canOpen: componentLocation !== null, onOpen: openComponentLocation, renderIcon: renderReactIcon, size: "inline-action" }))] })) : null }));
100
+ compositionId !== null ? (jsx_runtime_1.jsx("div", { "aria-hidden": true, style: componentLocationPlaceholder })) : (jsx_runtime_1.jsx(InspectorSourceLocation_1.InspectorSourceLocation, { location: componentLocation, canOpen: componentLocation !== null && canOpenInEditor, onOpen: openComponentLocation, renderIcon: renderReactIcon, size: "inline-action" }))] })) : null }));
97
101
  };
98
102
  exports.CompositionInspectorHeader = CompositionInspectorHeader;
@@ -13,6 +13,7 @@ const CompositionOrStillIcon_1 = require("../CompositionOrStillIcon");
13
13
  const ContextMenu_1 = require("../ContextMenu");
14
14
  const InitialCompositionLoader_1 = require("../InitialCompositionLoader");
15
15
  const use_resolved_stack_1 = require("../Timeline/use-resolved-stack");
16
+ const use_default_editor_info_1 = require("../use-default-editor-info");
16
17
  const common_1 = require("./common");
17
18
  const compositionIconStyle = {
18
19
  height: 18,
@@ -43,15 +44,25 @@ const ConnectedCompositionRow = ({ composition }) => {
43
44
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.SetSelectedModalContext);
44
45
  const connectionStatus = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx)
45
46
  .previewServerState.type;
47
+ const { defaultEditorId, defaultEditorName } = (0, use_default_editor_info_1.useEditorOpening)(connectionStatus === 'connected');
46
48
  const resolvedLocation = (0, use_resolved_stack_1.useResolvedStack)(composition.stack);
47
49
  const getContextMenuItems = (0, react_1.useCallback)(() => (0, composition_menu_items_1.getCompositionContextMenuItems)({
48
50
  closeMenu: noop_1.noop,
49
51
  composition,
50
52
  connectionStatus,
53
+ editorId: defaultEditorId,
54
+ editorName: defaultEditorName,
51
55
  includeCompositionManagementItems: false,
52
56
  readOnlyStudio: window.remotion_isReadOnlyStudio,
53
57
  resolvedLocation,
54
58
  setSelectedModal,
55
- }), [composition, connectionStatus, resolvedLocation, setSelectedModal]);
59
+ }), [
60
+ composition,
61
+ connectionStatus,
62
+ defaultEditorId,
63
+ defaultEditorName,
64
+ resolvedLocation,
65
+ setSelectedModal,
66
+ ]);
56
67
  return (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { getItems: getContextMenuItems, style: compositionContextMenuStyle, children: jsx_runtime_1.jsx(common_1.InspectorInlineAction, { disabled: false, onClick: () => selectComposition(composition, true), renderIcon: (color) => (jsx_runtime_1.jsx(CompositionOrStillIcon_1.CompositionOrStillIcon, { color: color, composition: composition, style: compositionIconStyle })), children: composition.id }) }));
57
68
  };
@@ -12,6 +12,7 @@ const render_frame_1 = require("../../state/render-frame");
12
12
  const is_menu_item_1 = require("../Menu/is-menu-item");
13
13
  const call_add_keyframe_1 = require("../Timeline/call-add-keyframe");
14
14
  const EasingEditorModal_1 = require("../Timeline/EasingEditorModal");
15
+ const get_timeline_keyframes_1 = require("../Timeline/get-timeline-keyframes");
15
16
  const TimelineSelection_1 = require("../Timeline/TimelineSelection");
16
17
  const update_selected_easing_1 = require("../Timeline/update-selected-easing");
17
18
  const common_1 = require("./common");
@@ -117,6 +118,12 @@ const EasingInspector = ({ selection }) => {
117
118
  segmentIndex: easingUpdate.segmentIndex,
118
119
  });
119
120
  }, [easingUpdate, selection.nodePathInfo, track]);
121
+ const easingKeyframeDisplayOffset = easingUpdate === null || track === null
122
+ ? 0
123
+ : (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
124
+ propStatus: easingUpdate.propStatus,
125
+ keyframeDisplayOffset: track.keyframeDisplayOffset,
126
+ });
120
127
  const state = (0, react_1.useMemo)(() => {
121
128
  if (initialEasing === null || currentEasingSelection === null) {
122
129
  return null;
@@ -147,7 +154,7 @@ const EasingInspector = ({ selection }) => {
147
154
  previewServerState.type !== 'connected') {
148
155
  return;
149
156
  }
150
- const sourceFrame = timelinePosition - track.keyframeDisplayOffset;
157
+ const sourceFrame = timelinePosition - easingKeyframeDisplayOffset;
151
158
  const value = remotion_1.Internals.getEffectiveVisualModeValue({
152
159
  propStatus: easingUpdate.propStatus,
153
160
  dragOverrideValue: easingDetails.dragOverrideValue,
@@ -196,11 +203,12 @@ const EasingInspector = ({ selection }) => {
196
203
  setPropStatuses,
197
204
  timelinePosition,
198
205
  track,
206
+ easingKeyframeDisplayOffset,
199
207
  ]);
200
208
  const renderHeader = (0, react_1.useCallback)(() => (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
201
209
  jsx_runtime_1.jsx(common_1.InspectorBackAction, { disabled: parentSelection === null, onClick: onSelectParent, title: "Back to property", children: fieldLabel }), jsx_runtime_1.jsx(common_1.InspectorSectionDivider, {}), easingUpdate === null || track === null ? null : (jsx_runtime_1.jsx(KeyframeEasingNavigator_1.KeyframeEasingNavigator, { currentSelection: currentEasingSelection !== null && currentEasingSelection !== void 0 ? currentEasingSelection : selection, includeEasings: true, keyframes: easingUpdate.propStatus.keyframes.map((keyframe) => ({
202
210
  ...keyframe,
203
- frame: keyframe.frame + track.keyframeDisplayOffset,
211
+ frame: keyframe.frame + easingKeyframeDisplayOffset,
204
212
  })), nodePathInfo: selection.nodePathInfo }))] })), [
205
213
  currentEasingSelection,
206
214
  easingUpdate,
@@ -209,6 +217,7 @@ const EasingInspector = ({ selection }) => {
209
217
  parentSelection,
210
218
  selection,
211
219
  track,
220
+ easingKeyframeDisplayOffset,
212
221
  ]);
213
222
  if (state === null ||
214
223
  track === null ||
@@ -13,6 +13,7 @@ const InputDragger_1 = require("../NewComposition/InputDragger");
13
13
  const call_delete_keyframe_1 = require("../Timeline/call-delete-keyframe");
14
14
  const call_move_keyframe_1 = require("../Timeline/call-move-keyframe");
15
15
  const get_easing_selection_after_keyframe_delete_1 = require("../Timeline/get-easing-selection-after-keyframe-delete");
16
+ const get_timeline_keyframes_1 = require("../Timeline/get-timeline-keyframes");
16
17
  const imperative_state_1 = require("../Timeline/imperative-state");
17
18
  const parse_keyframe_field_from_node_path_1 = require("../Timeline/parse-keyframe-field-from-node-path");
18
19
  const TimelineEffectPropItem_1 = require("../Timeline/TimelineEffectPropItem");
@@ -80,7 +81,6 @@ const KeyframeInspector = ({ selection }) => {
80
81
  }
81
82
  const nodePath = selection.nodePathInfo.sequenceSubscriptionKey;
82
83
  const { keyframeDisplayOffset } = track;
83
- const sourceFrame = selection.frame - keyframeDisplayOffset;
84
84
  if (keyframeField.type === 'sequence') {
85
85
  const sequenceFields = (0, timeline_layout_1.getFieldsToShow)({
86
86
  schema: track.sequence.controls.schema,
@@ -100,11 +100,18 @@ const KeyframeInspector = ({ selection }) => {
100
100
  field: sequenceField,
101
101
  fieldLabel: (_d = sequenceField.description) !== null && _d !== void 0 ? _d : sequenceField.key,
102
102
  fileName: nodePath.absolutePath,
103
- keyframeDisplayOffset,
103
+ keyframeDisplayOffset: (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
104
+ propStatus: sequencePropStatus,
105
+ keyframeDisplayOffset,
106
+ }),
104
107
  nodePath,
105
108
  propStatus: sequencePropStatus,
106
109
  schema: track.sequence.controls.schema,
107
- sourceFrame,
110
+ sourceFrame: selection.frame -
111
+ (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
112
+ propStatus: sequencePropStatus,
113
+ keyframeDisplayOffset,
114
+ }),
108
115
  };
109
116
  }
110
117
  const effect = track.sequence.effects[keyframeField.effectIndex];
@@ -136,11 +143,18 @@ const KeyframeInspector = ({ selection }) => {
136
143
  field: effectField,
137
144
  fieldLabel: (_g = effectField.description) !== null && _g !== void 0 ? _g : effectField.key,
138
145
  fileName: nodePath.absolutePath,
139
- keyframeDisplayOffset,
146
+ keyframeDisplayOffset: (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
147
+ propStatus: effectPropStatus,
148
+ keyframeDisplayOffset,
149
+ }),
140
150
  nodePath,
141
151
  propStatus: effectPropStatus,
142
152
  schema: effect.schema,
143
- sourceFrame,
153
+ sourceFrame: selection.frame -
154
+ (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
155
+ propStatus: effectPropStatus,
156
+ keyframeDisplayOffset,
157
+ }),
144
158
  validatedLocation: {
145
159
  source: nodePath.absolutePath,
146
160
  line: 1,
@@ -1,17 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getEasingSelectionFromCurrentKeyframes = void 0;
4
+ const get_timeline_keyframes_1 = require("../Timeline/get-timeline-keyframes");
4
5
  const getEasingSelectionFromCurrentKeyframes = ({ keyframeDisplayOffset, nodePathInfo, propStatus, segmentIndex, }) => {
5
6
  const fromKeyframe = propStatus.keyframes[segmentIndex];
6
7
  const toKeyframe = propStatus.keyframes[segmentIndex + 1];
7
8
  if (!fromKeyframe || !toKeyframe) {
8
9
  return null;
9
10
  }
11
+ const resolvedKeyframeDisplayOffset = (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
12
+ propStatus,
13
+ keyframeDisplayOffset,
14
+ });
10
15
  return {
11
16
  type: 'easing',
12
17
  nodePathInfo,
13
- fromFrame: fromKeyframe.frame + keyframeDisplayOffset,
14
- toFrame: toKeyframe.frame + keyframeDisplayOffset,
18
+ fromFrame: fromKeyframe.frame + resolvedKeyframeDisplayOffset,
19
+ toFrame: toKeyframe.frame + resolvedKeyframeDisplayOffset,
15
20
  segmentIndex,
16
21
  };
17
22
  };
@@ -4,6 +4,7 @@ export type SmartCollapsibleInspectorGroup = Extract<SchemaFieldGroup, 'backgrou
4
4
  export type InspectorSectionActivity = 'active' | 'inactive' | 'unknown';
5
5
  type InspectorSectionPropStatus = {
6
6
  readonly status: 'static';
7
+ readonly keyframeDisplayOffsetAdjustment: number | null;
7
8
  readonly codeValue: unknown;
8
9
  } | {
9
10
  readonly status: 'computed' | 'keyframed';
@@ -68,8 +68,7 @@ const use_select_asset_1 = require("./use-select-asset");
68
68
  const SelectedOutlineElementUnmemoized = ({ compositionHeight, compositionWidth, dragging, getAllDragOutlines, getAllDragTargets, getAllRotationDragTargets, getAllScaleDragTargets, getLatestTargetByKey, layoutTarget, outline, onDraggingChange, onContextMenuOpenChange, onSnapPointsChange, onSelect, scale, }) => {
69
69
  var _a;
70
70
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
71
- const canConfigureApps = (0, use_default_editor_info_1.canUseEditorPicker)(previewServerState.type === 'connected');
72
- const editorInfo = (0, use_default_editor_info_1.useDefaultEditorInfo)(canConfigureApps);
71
+ const { canConfigureApps, canOpenInEditor: editorAvailable, defaultEditorId, editorInfo, } = (0, use_default_editor_info_1.useEditorOpening)(previewServerState.type === 'connected');
73
72
  const codingAgentInfo = (0, use_default_editor_info_1.useDefaultCodingAgentInfo)(canConfigureApps);
74
73
  const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
75
74
  const updateResolvedStackTrace = (0, react_1.useContext)(remotion_1.Internals.SequenceStackTracesUpdateContext);
@@ -138,8 +137,7 @@ const SelectedOutlineElementUnmemoized = ({ compositionHeight, compositionWidth,
138
137
  });
139
138
  const action = (0, get_sequence_double_click_action_1.getSequenceDoubleClickAction)({
140
139
  button,
141
- canOpenInEditor: previewServerState.type === 'connected' &&
142
- Boolean(window.remotion_editorName),
140
+ canOpenInEditor: editorAvailable,
143
141
  numberOfConnectedCompositions: connectedCompositions.length,
144
142
  });
145
143
  if (action === null) {
@@ -151,10 +149,10 @@ const SelectedOutlineElementUnmemoized = ({ compositionHeight, compositionWidth,
151
149
  }
152
150
  const openTargetInEditor = async () => {
153
151
  const originalLocation = await resolveOriginalLocation(doubleClickTarget);
154
- if (originalLocation === null) {
152
+ if (originalLocation === null || defaultEditorId === null) {
155
153
  return;
156
154
  }
157
- await (0, open_in_editor_1.openOriginalPositionInEditor)(originalLocation, null);
155
+ await (0, open_in_editor_1.openOriginalPositionInEditor)(originalLocation, defaultEditorId);
158
156
  };
159
157
  openTargetInEditor().catch((err) => {
160
158
  (0, NotificationCenter_1.showNotification)(err.message, 2000);
@@ -162,7 +160,8 @@ const SelectedOutlineElementUnmemoized = ({ compositionHeight, compositionWidth,
162
160
  return true;
163
161
  }, [
164
162
  compositions,
165
- previewServerState.type,
163
+ defaultEditorId,
164
+ editorAvailable,
166
165
  resolveOriginalLocation,
167
166
  selectComposition,
168
167
  ]);
@@ -185,7 +184,7 @@ const SelectedOutlineElementUnmemoized = ({ compositionHeight, compositionWidth,
185
184
  ? contextMenuTarget.sequence.src
186
185
  : null;
187
186
  const assetLinkInfo = mediaSrc ? (0, timeline_asset_link_1.getTimelineAssetLinkInfo)(mediaSrc) : null;
188
- const canOpenInEditor = Boolean(window.remotion_editorName && originalLocation);
187
+ const canOpenInEditor = Boolean(originalLocation && editorAvailable);
189
188
  const sourceEditingEnabled = (0, interactivity_enabled_1.isStudioInteractivityEnabled)();
190
189
  const disableInteractivityDisabled = !sourceEditingEnabled || !contextMenuTarget.sequence.showInTimeline;
191
190
  const sourceEditDisabled = !sourceEditingEnabled ||
@@ -281,10 +280,11 @@ const SelectedOutlineElementUnmemoized = ({ compositionHeight, compositionWidth,
281
280
  });
282
281
  },
283
282
  openInEditor: (editorId) => {
284
- if (!originalLocation) {
283
+ const resolvedEditorId = editorId !== null && editorId !== void 0 ? editorId : defaultEditorId;
284
+ if (!originalLocation || !resolvedEditorId || !editorAvailable) {
285
285
  return;
286
286
  }
287
- (0, open_in_editor_1.openOriginalPositionInEditor)(originalLocation, editorId).catch((err) => {
287
+ (0, open_in_editor_1.openOriginalPositionInEditor)(originalLocation, resolvedEditorId).catch((err) => {
288
288
  (0, NotificationCenter_1.showNotification)(err.message, 2000);
289
289
  });
290
290
  },
@@ -383,6 +383,8 @@ const SelectedOutlineElementUnmemoized = ({ compositionHeight, compositionWidth,
383
383
  editorInfo,
384
384
  getTarget,
385
385
  onSelect,
386
+ defaultEditorId,
387
+ editorAvailable,
386
388
  previewServerState,
387
389
  resolveOriginalLocation,
388
390
  setManuallyEnabled,
@@ -55,6 +55,7 @@ Object.defineProperty(exports, "orderOutlinesForRendering", { enumerable: true,
55
55
  const selected_outline_types_1 = require("./selected-outline-types");
56
56
  const SelectedOutlineKeyboardControls_1 = require("./SelectedOutlineKeyboardControls");
57
57
  const SelectedOutlineRenderer_1 = require("./SelectedOutlineRenderer");
58
+ const get_timeline_keyframes_1 = require("./Timeline/get-timeline-keyframes");
58
59
  const TimelineSelection_1 = require("./Timeline/TimelineSelection");
59
60
  const transform_3d_mode_2 = require("./Timeline/transform-3d-mode");
60
61
  const selected_outline_drag_2 = require("./selected-outline-drag");
@@ -181,7 +182,12 @@ const calculateOutlineTargets = ({ connectedClientId, editorShowOutlines, getDra
181
182
  }
182
183
  const { controls } = sequence;
183
184
  const nodePropStatuses = remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePath);
184
- const sourceFrame = targetTimelinePosition - keyframeDisplayOffset;
185
+ const firstKeyframedStatus = Object.values(nodePropStatuses !== null && nodePropStatuses !== void 0 ? nodePropStatuses : {}).find((status) => status.status === 'keyframed');
186
+ const nodeKeyframeDisplayOffset = (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
187
+ propStatus: firstKeyframedStatus,
188
+ keyframeDisplayOffset,
189
+ });
190
+ const sourceFrame = targetTimelinePosition - nodeKeyframeDisplayOffset;
185
191
  const dragOverrides = (_a = getDragOverrides(nodePath)) !== null && _a !== void 0 ? _a : {};
186
192
  const runtimeValues = controls
187
193
  ? ((_b = runtimeValuesByStore.get(controls.runtimeValues)) !== null && _b !== void 0 ? _b : controls.runtimeValues.getSnapshot())
@@ -257,7 +263,7 @@ const calculateOutlineTargets = ({ connectedClientId, editorShowOutlines, getDra
257
263
  key,
258
264
  containsSelection,
259
265
  crop,
260
- keyframeDisplayOffset,
266
+ keyframeDisplayOffset: nodeKeyframeDisplayOffset,
261
267
  nodePathInfo,
262
268
  ref: sequence.refForOutline,
263
269
  selected,
@@ -316,7 +322,11 @@ const calculateOutlineTargets = ({ connectedClientId, editorShowOutlines, getDra
316
322
  const transformOriginSourceFrame = (selectedTransformOriginInfo === null || selectedTransformOriginInfo === void 0 ? void 0 : selectedTransformOriginInfo.displayFrame) === null ||
317
323
  (selectedTransformOriginInfo === null || selectedTransformOriginInfo === void 0 ? void 0 : selectedTransformOriginInfo.displayFrame) === undefined
318
324
  ? sourceFrame
319
- : selectedTransformOriginInfo.displayFrame - keyframeDisplayOffset;
325
+ : selectedTransformOriginInfo.displayFrame -
326
+ (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
327
+ propStatus: transformOriginPropStatus,
328
+ keyframeDisplayOffset,
329
+ });
320
330
  const canTransformOriginStatus = (transformOriginPropStatus === null || transformOriginPropStatus === void 0 ? void 0 : transformOriginPropStatus.status) === 'static' ||
321
331
  ((transformOriginPropStatus === null || transformOriginPropStatus === void 0 ? void 0 : transformOriginPropStatus.status) === 'keyframed' &&
322
332
  transformOriginPropStatus.interpolationFunction === 'interpolate');
@@ -333,7 +343,7 @@ const calculateOutlineTargets = ({ connectedClientId, editorShowOutlines, getDra
333
343
  const cropSourceFrame = (selectedCropInfo === null || selectedCropInfo === void 0 ? void 0 : selectedCropInfo.displayFrame) === null ||
334
344
  (selectedCropInfo === null || selectedCropInfo === void 0 ? void 0 : selectedCropInfo.displayFrame) === undefined
335
345
  ? sourceFrame
336
- : selectedCropInfo.displayFrame - keyframeDisplayOffset;
346
+ : selectedCropInfo.displayFrame - nodeKeyframeDisplayOffset;
337
347
  const canCropDrag = previewInteractive &&
338
348
  selectedForCrop &&
339
349
  controls !== null &&
@@ -364,7 +374,10 @@ const calculateOutlineTargets = ({ connectedClientId, editorShowOutlines, getDra
364
374
  propStatus,
365
375
  clientId: connectedClientId,
366
376
  fieldDefault: fieldSchema.default,
367
- keyframeDisplayOffset,
377
+ keyframeDisplayOffset: (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
378
+ propStatus,
379
+ keyframeDisplayOffset,
380
+ }),
368
381
  nodePath,
369
382
  schema: controls.schema,
370
383
  }
@@ -375,7 +388,10 @@ const calculateOutlineTargets = ({ connectedClientId, editorShowOutlines, getDra
375
388
  clientId: connectedClientId,
376
389
  fieldDefault: scaleFieldSchema.default,
377
390
  fieldSchema: scaleFieldSchema,
378
- keyframeDisplayOffset,
391
+ keyframeDisplayOffset: (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
392
+ propStatus: scalePropStatus,
393
+ keyframeDisplayOffset,
394
+ }),
379
395
  linked: getScaleLockState({
380
396
  nodePath,
381
397
  fieldKey: selected_outline_types_1.scaleFieldKey,
@@ -401,7 +417,10 @@ const calculateOutlineTargets = ({ connectedClientId, editorShowOutlines, getDra
401
417
  clientId: connectedClientId,
402
418
  fieldDefault: rotationFieldSchema.default,
403
419
  fieldSchema: rotationFieldSchema,
404
- keyframeDisplayOffset,
420
+ keyframeDisplayOffset: (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
421
+ propStatus: rotationPropStatus,
422
+ keyframeDisplayOffset,
423
+ }),
405
424
  nodePath,
406
425
  schema: controls.schema,
407
426
  transform3DMode,
@@ -411,7 +430,10 @@ const calculateOutlineTargets = ({ connectedClientId, editorShowOutlines, getDra
411
430
  transformOriginDrag: canTransformOriginDrag
412
431
  ? {
413
432
  clientId: connectedClientId,
414
- keyframeDisplayOffset,
433
+ keyframeDisplayOffset: (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
434
+ propStatus: transformOriginPropStatus,
435
+ keyframeDisplayOffset,
436
+ }),
415
437
  nodePath,
416
438
  originDefault: transformOriginFieldSchema.default,
417
439
  originPropStatus: transformOriginPropStatus,
@@ -155,6 +155,7 @@ const ItemEditor = ({ field, arrayField, items, index, onSave, onDragValueChange
155
155
  }, [arrayField, fallback, field, index]);
156
156
  const propStatus = (0, react_1.useMemo)(() => ({
157
157
  status: 'static',
158
+ keyframeDisplayOffsetAdjustment: null,
158
159
  codeValue: value,
159
160
  }), [value]);
160
161
  const onSaveItem = (0, react_1.useCallback)((next) => onSave(replaceAtIndex(items, index, next)), [index, items, onSave]);