@remotion/studio 4.0.491 → 4.0.493
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ResolveCompositionConfigInStudio.js +16 -6
- package/dist/components/AssetSelectorItem.js +7 -4
- package/dist/components/Canvas.js +1 -0
- package/dist/components/CompositionOrStillIcon.d.ts +7 -0
- package/dist/components/CompositionOrStillIcon.js +11 -0
- package/dist/components/CompositionSelector.js +14 -2
- package/dist/components/CompositionSelectorItem.js +34 -6
- package/dist/components/CurrentAsset.d.ts +6 -0
- package/dist/components/CurrentAsset.js +14 -8
- package/dist/components/CurrentComposition.d.ts +1 -1
- package/dist/components/CurrentComposition.js +3 -4
- package/dist/components/InlineEditableTitle.d.ts +1 -0
- package/dist/components/InlineEditableTitle.js +12 -7
- package/dist/components/InspectorInfoHeader.d.ts +2 -0
- package/dist/components/InspectorInfoHeader.js +12 -4
- package/dist/components/InspectorPanel/CompositionDimensions.d.ts +6 -0
- package/dist/components/InspectorPanel/CompositionDimensions.js +173 -0
- package/dist/components/InspectorPanel/ConnectedCompositionsSection.d.ts +9 -0
- package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +32 -0
- package/dist/components/InspectorPanel/DefaultInspector.js +6 -3
- package/dist/components/InspectorPanel/EasingInspector.js +3 -3
- package/dist/components/InspectorPanel/KeyframeInspector.js +6 -4
- package/dist/components/InspectorPanel/KeyframeSettings.js +1 -1
- package/dist/components/InspectorPanel/SequenceInspectorHeader.d.ts +1 -1
- package/dist/components/InspectorPanel/SequenceInspectorHeader.js +9 -5
- package/dist/components/InspectorPanel/SequenceSelectionInspector.js +5 -1
- package/dist/components/InspectorPanel/common.d.ts +2 -1
- package/dist/components/InspectorPanel/common.js +11 -7
- package/dist/components/InspectorPanel/optimistic-composition-metadata.d.ts +22 -0
- package/dist/components/InspectorPanel/optimistic-composition-metadata.js +41 -0
- package/dist/components/InspectorPanel/styles.d.ts +2 -0
- package/dist/components/InspectorPanel/styles.js +7 -2
- package/dist/components/InspectorSequenceSection.js +58 -7
- package/dist/components/NewComposition/NewComposition.js +11 -4
- package/dist/components/NewComposition/get-new-composition-defaults.d.ts +4 -0
- package/dist/components/NewComposition/get-new-composition-defaults.js +13 -0
- package/dist/components/SelectedOutlineElement.js +21 -2
- package/dist/components/SelectedOutlineOverlay.d.ts +1 -1
- package/dist/components/SelectedOutlineOverlay.js +4 -3
- package/dist/components/Timeline/Timeline.js +8 -1
- package/dist/components/Timeline/TimelineAssetField.d.ts +14 -0
- package/dist/components/Timeline/TimelineAssetField.js +125 -0
- package/dist/components/Timeline/TimelineClipboardKeybindings.js +133 -1
- package/dist/components/Timeline/TimelineExpandedSection.js +1 -0
- package/dist/components/Timeline/TimelineFieldLabel.js +4 -2
- package/dist/components/Timeline/TimelineKeyframeControls.js +1 -0
- package/dist/components/Timeline/TimelineList.js +2 -1
- package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +5 -3
- package/dist/components/Timeline/TimelineRowChrome.js +8 -6
- package/dist/components/Timeline/TimelineRowLayoutContext.d.ts +7 -0
- package/dist/components/Timeline/TimelineRowLayoutContext.js +13 -0
- package/dist/components/Timeline/TimelineSelection.js +20 -5
- package/dist/components/Timeline/TimelineSequenceItem.d.ts +2 -1
- package/dist/components/Timeline/TimelineSequenceItem.js +32 -8
- package/dist/components/Timeline/TimelineSequenceName.js +4 -0
- package/dist/components/Timeline/get-sequence-context-menu-items.js +3 -3
- package/dist/components/Timeline/keyframe-clipboard.d.ts +34 -0
- package/dist/components/Timeline/keyframe-clipboard.js +278 -0
- package/dist/components/Timeline/sequence-props-subscription-store.js +5 -1
- package/dist/components/Timeline/timeline-asset-link.d.ts +6 -0
- package/dist/components/Timeline/timeline-asset-link.js +27 -1
- package/dist/components/Timeline/timeline-field-display-utils.js +3 -1
- package/dist/components/Timeline/timeline-field-row-layout.d.ts +1 -1
- package/dist/components/Timeline/timeline-field-row-layout.js +2 -2
- package/dist/components/Timeline/timeline-row-layout.d.ts +3 -2
- package/dist/components/Timeline/timeline-row-layout.js +6 -5
- package/dist/components/Timeline/update-selected-easing.d.ts +1 -1
- package/dist/components/Timeline/update-selected-easing.js +4 -5
- package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +4 -4
- package/dist/components/Timeline/use-timeline-expanded-tree.d.ts +2 -1
- package/dist/components/Timeline/use-timeline-expanded-tree.js +3 -1
- package/dist/components/Timeline/use-timeline-height.js +1 -0
- package/dist/components/import-assets.d.ts +10 -2
- package/dist/components/import-assets.js +20 -6
- package/dist/components/root-composition-menu-items.d.ts +8 -0
- package/dist/components/root-composition-menu-items.js +45 -0
- package/dist/components/selected-outline-measurement.d.ts +2 -5
- package/dist/components/selected-outline-measurement.js +3 -4
- package/dist/esm/{chunk-9wh9k3jj.js → chunk-mndqr3zx.js} +7439 -6121
- package/dist/esm/internals.mjs +7439 -6121
- package/dist/esm/previewEntry.mjs +7371 -6057
- package/dist/esm/renderEntry.mjs +1 -1
- package/dist/helpers/calculate-timeline.d.ts +2 -1
- package/dist/helpers/calculate-timeline.js +36 -5
- package/dist/helpers/get-connected-compositions.d.ts +6 -0
- package/dist/helpers/get-connected-compositions.js +11 -0
- package/dist/helpers/get-file-manager-name.d.ts +1 -0
- package/dist/helpers/get-file-manager-name.js +13 -0
- package/dist/helpers/get-sequence-double-click-action.d.ts +6 -0
- package/dist/helpers/get-sequence-double-click-action.js +13 -0
- package/dist/helpers/get-timeline-sequence-sort-key.d.ts +2 -1
- package/dist/helpers/timeline-layout.d.ts +2 -1
- package/dist/helpers/timeline-layout.js +5 -1
- package/dist/helpers/url-state.d.ts +1 -0
- package/dist/helpers/url-state.js +8 -6
- package/dist/helpers/use-menu-structure.js +4 -2
- package/package.json +11 -11
|
@@ -41,11 +41,16 @@ const colors_1 = require("../helpers/colors");
|
|
|
41
41
|
const timeline_layout_1 = require("../helpers/timeline-layout");
|
|
42
42
|
const plus_1 = require("../icons/plus");
|
|
43
43
|
const modals_1 = require("../state/modals");
|
|
44
|
+
const CurrentAsset_1 = require("./CurrentAsset");
|
|
44
45
|
const InlineAction_1 = require("./InlineAction");
|
|
45
46
|
const styles_1 = require("./InspectorPanel/styles");
|
|
47
|
+
const InspectorPanelLayout_1 = require("./InspectorPanelLayout");
|
|
48
|
+
const timeline_asset_link_1 = require("./Timeline/timeline-asset-link");
|
|
46
49
|
const TimelineExpandedRow_1 = require("./Timeline/TimelineExpandedRow");
|
|
50
|
+
const TimelineRowLayoutContext_1 = require("./Timeline/TimelineRowLayoutContext");
|
|
47
51
|
const TimelineSelection_1 = require("./Timeline/TimelineSelection");
|
|
48
52
|
const use_timeline_expanded_tree_1 = require("./Timeline/use-timeline-expanded-tree");
|
|
53
|
+
const use_select_asset_1 = require("./use-select-asset");
|
|
49
54
|
const container = {
|
|
50
55
|
color: colors_1.WHITE,
|
|
51
56
|
display: 'flex',
|
|
@@ -72,6 +77,38 @@ const plusIcon = {
|
|
|
72
77
|
width: 15,
|
|
73
78
|
height: 15,
|
|
74
79
|
};
|
|
80
|
+
const remoteSourceLabel = {
|
|
81
|
+
color: colors_1.LIGHT_TEXT,
|
|
82
|
+
display: 'flex',
|
|
83
|
+
fontFamily: 'Arial, Helvetica, sans-serif',
|
|
84
|
+
fontSize: 12,
|
|
85
|
+
lineHeight: '18px',
|
|
86
|
+
minWidth: 0,
|
|
87
|
+
overflow: 'hidden',
|
|
88
|
+
padding: `6px ${InspectorPanelLayout_1.INSPECTOR_PANEL_HORIZONTAL_PADDING}px`,
|
|
89
|
+
whiteSpace: 'nowrap',
|
|
90
|
+
};
|
|
91
|
+
const remoteSourceLeading = {
|
|
92
|
+
color: colors_1.LIGHT_TEXT,
|
|
93
|
+
fontFamily: 'Arial, Helvetica, sans-serif',
|
|
94
|
+
fontSize: 12,
|
|
95
|
+
lineHeight: '18px',
|
|
96
|
+
minWidth: 0,
|
|
97
|
+
overflow: 'hidden',
|
|
98
|
+
textOverflow: 'ellipsis',
|
|
99
|
+
whiteSpace: 'nowrap',
|
|
100
|
+
};
|
|
101
|
+
const remoteSourceTrailing = {
|
|
102
|
+
color: colors_1.LIGHT_TEXT,
|
|
103
|
+
flexShrink: 0,
|
|
104
|
+
fontFamily: 'Arial, Helvetica, sans-serif',
|
|
105
|
+
fontSize: 12,
|
|
106
|
+
lineHeight: '18px',
|
|
107
|
+
maxWidth: '55%',
|
|
108
|
+
overflow: 'hidden',
|
|
109
|
+
textOverflow: 'ellipsis',
|
|
110
|
+
whiteSpace: 'nowrap',
|
|
111
|
+
};
|
|
75
112
|
const isEffectsRoot = (node) => {
|
|
76
113
|
if (node.kind !== 'group' || node.effectInfo !== null) {
|
|
77
114
|
return false;
|
|
@@ -138,10 +175,22 @@ const InspectorSequenceSection = ({ sequence, validatedLocation, nodePathInfo, k
|
|
|
138
175
|
sequence,
|
|
139
176
|
nodePathInfo,
|
|
140
177
|
includeTextContent: true,
|
|
178
|
+
includeSourceControls: true,
|
|
141
179
|
});
|
|
142
180
|
const [collapsedKeys, setCollapsedKeys] = (0, react_1.useState)(loadInspectorCollapsedKeys);
|
|
143
181
|
const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
|
|
144
182
|
const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
|
|
183
|
+
const selectAsset = (0, use_select_asset_1.useSelectAsset)();
|
|
184
|
+
const mediaSrc = (0, timeline_asset_link_1.getTimelineAssetSrcFromSchema)(sequence.controls);
|
|
185
|
+
const assetLinkInfo = (0, react_1.useMemo)(() => (mediaSrc ? (0, timeline_asset_link_1.getTimelineAssetLinkInfo)(mediaSrc) : null), [mediaSrc]);
|
|
186
|
+
const localAsset = (assetLinkInfo === null || assetLinkInfo === void 0 ? void 0 : assetLinkInfo.kind) === 'local' ? assetLinkInfo : null;
|
|
187
|
+
const remoteAsset = (assetLinkInfo === null || assetLinkInfo === void 0 ? void 0 : assetLinkInfo.kind) === 'remote' ? assetLinkInfo : null;
|
|
188
|
+
const remoteSourceParts = (0, react_1.useMemo)(() => remoteAsset ? (0, timeline_asset_link_1.splitRemoteSourceForMiddleEllipsis)(remoteAsset.href) : null, [remoteAsset]);
|
|
189
|
+
const jumpToAsset = (0, react_1.useCallback)(() => {
|
|
190
|
+
if (localAsset) {
|
|
191
|
+
(0, timeline_asset_link_1.openTimelineAssetLink)(localAsset, selectAsset);
|
|
192
|
+
}
|
|
193
|
+
}, [localAsset, selectAsset]);
|
|
145
194
|
const getIsExpanded = (0, react_1.useCallback)((candidate) => {
|
|
146
195
|
return !collapsedKeys.has(getInspectorExpansionKey(candidate));
|
|
147
196
|
}, [collapsedKeys]);
|
|
@@ -183,7 +232,10 @@ const InspectorSequenceSection = ({ sequence, validatedLocation, nodePathInfo, k
|
|
|
183
232
|
}),
|
|
184
233
|
};
|
|
185
234
|
}, [getIsExpanded, tree]);
|
|
186
|
-
const controlSelectableItems = (0, react_1.useMemo)(() => (0, exports.getInspectorSelectableItems)(controlRows)
|
|
235
|
+
const controlSelectableItems = (0, react_1.useMemo)(() => (0, exports.getInspectorSelectableItems)(controlRows.filter(({ node }) => {
|
|
236
|
+
var _a;
|
|
237
|
+
return node.kind !== 'field' || ((_a = node.field) === null || _a === void 0 ? void 0 : _a.key) !== 'src';
|
|
238
|
+
})), [controlRows]);
|
|
187
239
|
const effectSelectableItems = (0, react_1.useMemo)(() => (0, exports.getInspectorSelectableItems)(effectRows), [effectRows]);
|
|
188
240
|
const controlGroups = (0, react_1.useMemo)(() => getInspectorControlGroups(controlRows), [controlRows]);
|
|
189
241
|
const { schema } = sequence.controls;
|
|
@@ -214,14 +266,13 @@ const InspectorSequenceSection = ({ sequence, validatedLocation, nodePathInfo, k
|
|
|
214
266
|
jsx_runtime_1.jsx("div", { style: effectsHeaderTitle, children: "Effects" }), jsx_runtime_1.jsx(InlineAction_1.InlineAction, { disabled: !canAddEffect, onClick: onAddEffect, title: canAddEffect ? 'Add effect' : undefined, renderAction: (color) => jsx_runtime_1.jsx(plus_1.Plus, { color: color, style: plusIcon }) })] }));
|
|
215
267
|
};
|
|
216
268
|
const renderRow = ({ node, depth }) => {
|
|
217
|
-
return (jsx_runtime_1.jsx(TimelineExpandedRow_1.TimelineExpandedRow, { node: node, depth: depth, nestedDepth: 0, rowDepthBase: 0, getIsExpanded: getIsExpanded, toggleTrack: toggleTrack, validatedLocation: validatedLocation, nodePath: nodePathInfo.sequenceSubscriptionKey, schema: schema, keyframeDisplayOffset: keyframeDisplayOffset, keyframeControlsMode: "inspector" }, JSON.stringify(node.nodePathInfo)));
|
|
269
|
+
return (jsx_runtime_1.jsx(TimelineRowLayoutContext_1.TimelineRowLayoutContext.Provider, { value: TimelineRowLayoutContext_1.INSPECTOR_TIMELINE_ROW_LAYOUT, children: jsx_runtime_1.jsx(TimelineExpandedRow_1.TimelineExpandedRow, { node: node, depth: depth, nestedDepth: 0, rowDepthBase: 0, getIsExpanded: getIsExpanded, toggleTrack: toggleTrack, validatedLocation: validatedLocation, nodePath: nodePathInfo.sequenceSubscriptionKey, schema: schema, keyframeDisplayOffset: keyframeDisplayOffset, keyframeControlsMode: "inspector" }) }, JSON.stringify(node.nodePathInfo)));
|
|
218
270
|
};
|
|
219
271
|
if (controlRows.length === 0 && !showEffectsSection) {
|
|
220
|
-
return (jsx_runtime_1.
|
|
221
|
-
jsx_runtime_1.jsx("div", { style: styles_1.sequenceHeaderDivider }), jsx_runtime_1.jsx("div", { style: emptyState, children: "No schema" })
|
|
222
|
-
] }));
|
|
272
|
+
return (jsx_runtime_1.jsx("div", { style: container, children: jsx_runtime_1.jsx("div", { style: emptyState, children: "No schema" }) }));
|
|
223
273
|
}
|
|
224
|
-
return (jsx_runtime_1.jsxs("div", { style: container, children: [
|
|
225
|
-
|
|
274
|
+
return (jsx_runtime_1.jsxs("div", { style: container, children: [controlRows.length > 0 ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionOrderProvider, { items: controlSelectableItems, children: controlGroups.map((group, i) => (jsx_runtime_1.jsxs(react_1.default.Fragment, { children: [i === 0 ? null : jsx_runtime_1.jsx("div", { style: controlsEffectsDivider }), renderSectionHeader(group.label), group.id === 'source' && localAsset ? (jsx_runtime_1.jsx(CurrentAsset_1.AssetInfo, { assetName: localAsset.assetPath, contentSized: true, onAssetClick: jumpToAsset, readOnlyStudio: true })) : null, group.id === 'source' && remoteAsset && remoteSourceParts ? (jsx_runtime_1.jsxs("div", { style: remoteSourceLabel, title: remoteAsset.href, children: [
|
|
275
|
+
jsx_runtime_1.jsx("span", { style: remoteSourceLeading, children: remoteSourceParts.leading }), jsx_runtime_1.jsx("span", { style: remoteSourceTrailing, children: remoteSourceParts.trailing })
|
|
276
|
+
] })) : null, group.id === 'transforms' ? renderTransformControls() : null, group.id === 'source' ? null : group.rows.map(renderRow)] }, group.id))) })) : null, showEffectsSection ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [showControlsEffectsDivider ? (jsx_runtime_1.jsx("div", { style: controlsEffectsDivider })) : null, renderEffectsHeader(), effectRows.length > 0 ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionOrderProvider, { items: effectSelectableItems, children: effectRows.map(renderRow) })) : null] })) : null] }));
|
|
226
277
|
};
|
|
227
278
|
exports.InspectorSequenceSection = InspectorSequenceSection;
|
|
@@ -11,6 +11,7 @@ const ModalHeader_1 = require("../ModalHeader");
|
|
|
11
11
|
const layout_2 = require("../RenderModal/layout");
|
|
12
12
|
const CodemodFooter_1 = require("./CodemodFooter");
|
|
13
13
|
const DismissableModal_1 = require("./DismissableModal");
|
|
14
|
+
const get_new_composition_defaults_1 = require("./get-new-composition-defaults");
|
|
14
15
|
const InputAndValidationContainer_1 = require("./InputAndValidationContainer");
|
|
15
16
|
const InputDragger_1 = require("./InputDragger");
|
|
16
17
|
const NewCompDuration_1 = require("./NewCompDuration");
|
|
@@ -28,13 +29,19 @@ const folderPathStyle = {
|
|
|
28
29
|
};
|
|
29
30
|
const NewCompositionLoaded = ({ folderName, parentName, stack }) => {
|
|
30
31
|
const { compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
|
32
|
+
const resolvedComposition = remotion_1.Internals.useResolvedVideoConfig(null);
|
|
33
|
+
const initialComposition = (resolvedComposition === null || resolvedComposition === void 0 ? void 0 : resolvedComposition.type) === 'success' ||
|
|
34
|
+
(resolvedComposition === null || resolvedComposition === void 0 ? void 0 : resolvedComposition.type) === 'success-and-refreshing'
|
|
35
|
+
? resolvedComposition.result
|
|
36
|
+
: null;
|
|
37
|
+
const initialDimensions = (0, get_new_composition_defaults_1.getNewCompositionDefaults)(initialComposition);
|
|
31
38
|
const [newId, setName] = (0, react_1.useState)(() => (0, use_create_composition_1.getUniqueCompositionName)(compositions));
|
|
32
|
-
const [selectedFrameRate, setFrameRate] = (0, react_1.useState)(
|
|
39
|
+
const [selectedFrameRate, setFrameRate] = (0, react_1.useState)(initialDimensions.fps);
|
|
33
40
|
const [size, setSize] = (0, react_1.useState)(() => ({
|
|
34
|
-
width:
|
|
35
|
-
height:
|
|
41
|
+
width: initialDimensions.width,
|
|
42
|
+
height: initialDimensions.height,
|
|
36
43
|
}));
|
|
37
|
-
const [durationInFrames, setDurationInFrames] = (0, react_1.useState)(
|
|
44
|
+
const [durationInFrames, setDurationInFrames] = (0, react_1.useState)(initialDimensions.durationInFrames);
|
|
38
45
|
const onWidthChanged = (0, react_1.useCallback)((newValue) => {
|
|
39
46
|
setSize((s) => {
|
|
40
47
|
return {
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { VideoConfig } from 'remotion';
|
|
2
|
+
type CompositionDimensions = Pick<VideoConfig, 'width' | 'height' | 'fps' | 'durationInFrames'>;
|
|
3
|
+
export declare const getNewCompositionDefaults: (composition: CompositionDimensions | null) => CompositionDimensions;
|
|
4
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getNewCompositionDefaults = void 0;
|
|
4
|
+
const defaultCompositionDimensions = {
|
|
5
|
+
width: 1920,
|
|
6
|
+
height: 1080,
|
|
7
|
+
fps: 30,
|
|
8
|
+
durationInFrames: 150,
|
|
9
|
+
};
|
|
10
|
+
const getNewCompositionDefaults = (composition) => {
|
|
11
|
+
return composition !== null && composition !== void 0 ? composition : defaultCompositionDimensions;
|
|
12
|
+
};
|
|
13
|
+
exports.getNewCompositionDefaults = getNewCompositionDefaults;
|
|
@@ -41,6 +41,8 @@ const no_react_1 = require("remotion/no-react");
|
|
|
41
41
|
const client_id_1 = require("../helpers/client-id");
|
|
42
42
|
const colors_1 = require("../helpers/colors");
|
|
43
43
|
const format_file_location_1 = require("../helpers/format-file-location");
|
|
44
|
+
const get_connected_compositions_1 = require("../helpers/get-connected-compositions");
|
|
45
|
+
const get_sequence_double_click_action_1 = require("../helpers/get-sequence-double-click-action");
|
|
44
46
|
const open_in_editor_1 = require("../helpers/open-in-editor");
|
|
45
47
|
const editor_snapping_1 = require("../state/editor-snapping");
|
|
46
48
|
const modals_1 = require("../state/modals");
|
|
@@ -49,6 +51,7 @@ const ConfirmationDialog_1 = require("./ConfirmationDialog");
|
|
|
49
51
|
const ContextMenu_1 = require("./ContextMenu");
|
|
50
52
|
const effect_drag_and_drop_1 = require("./effect-drag-and-drop");
|
|
51
53
|
const ForceSpecificCursor_1 = require("./ForceSpecificCursor");
|
|
54
|
+
const InitialCompositionLoader_1 = require("./InitialCompositionLoader");
|
|
52
55
|
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
|
|
53
56
|
const selected_outline_drag_1 = require("./selected-outline-drag");
|
|
54
57
|
const selected_outline_measurement_1 = require("./selected-outline-measurement");
|
|
@@ -981,6 +984,8 @@ const SelectedOutlineElement = ({ allDragTargets, allDragOutlines, allRotationDr
|
|
|
981
984
|
const updateResolvedStackTrace = (0, react_1.useContext)(remotion_1.Internals.SequenceStackTracesUpdateContext);
|
|
982
985
|
const confirm = (0, ConfirmationDialog_1.useConfirmationDialog)();
|
|
983
986
|
const selectAsset = (0, use_select_asset_1.useSelectAsset)();
|
|
987
|
+
const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
|
|
988
|
+
const { compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
|
984
989
|
const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
|
|
985
990
|
const resolveOriginalLocation = react_1.default.useCallback(async (resolveTarget) => {
|
|
986
991
|
const stack = resolveTarget.sequence.getStack();
|
|
@@ -998,14 +1003,23 @@ const SelectedOutlineElement = ({ allDragTargets, allDragOutlines, allRotationDr
|
|
|
998
1003
|
return originalLocation;
|
|
999
1004
|
}, [updateResolvedStackTrace]);
|
|
1000
1005
|
const onDoubleClickTarget = react_1.default.useCallback((doubleClickTarget, button) => {
|
|
1001
|
-
const
|
|
1006
|
+
const connectedCompositions = (0, get_connected_compositions_1.getConnectedCompositions)({
|
|
1007
|
+
compositions,
|
|
1008
|
+
singleChildComponent: doubleClickTarget.sequence.singleChildComponent,
|
|
1009
|
+
});
|
|
1010
|
+
const action = (0, get_sequence_double_click_action_1.getSequenceDoubleClickAction)({
|
|
1002
1011
|
button,
|
|
1003
1012
|
canOpenInEditor: previewServerState.type === 'connected' &&
|
|
1004
1013
|
Boolean(window.remotion_editorName),
|
|
1014
|
+
numberOfConnectedCompositions: connectedCompositions.length,
|
|
1005
1015
|
});
|
|
1006
1016
|
if (action === null) {
|
|
1007
1017
|
return false;
|
|
1008
1018
|
}
|
|
1019
|
+
if (action === 'open-connected-composition') {
|
|
1020
|
+
selectComposition(connectedCompositions[0], true);
|
|
1021
|
+
return true;
|
|
1022
|
+
}
|
|
1009
1023
|
const openTargetInEditor = async () => {
|
|
1010
1024
|
const originalLocation = await resolveOriginalLocation(doubleClickTarget);
|
|
1011
1025
|
if (originalLocation === null) {
|
|
@@ -1017,7 +1031,12 @@ const SelectedOutlineElement = ({ allDragTargets, allDragOutlines, allRotationDr
|
|
|
1017
1031
|
(0, NotificationCenter_1.showNotification)(err.message, 2000);
|
|
1018
1032
|
});
|
|
1019
1033
|
return true;
|
|
1020
|
-
}, [
|
|
1034
|
+
}, [
|
|
1035
|
+
compositions,
|
|
1036
|
+
previewServerState.type,
|
|
1037
|
+
resolveOriginalLocation,
|
|
1038
|
+
selectComposition,
|
|
1039
|
+
]);
|
|
1021
1040
|
const onContextMenuOpen = react_1.default.useCallback(async () => {
|
|
1022
1041
|
if (target === undefined || previewServerState.type !== 'connected') {
|
|
1023
1042
|
return false;
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { type SelectedOutline } from './selected-outline-geometry';
|
|
3
3
|
import { type SelectedOutlineTarget } from './selected-outline-types';
|
|
4
4
|
export { applySelectedOutlineDragAxisLock, applySelectedOutlineTransformOriginAxisLock, compensateTranslateForTransformOrigin, getSelectedOutlineActiveSchema, getSelectedOutlineDragChanges, getSelectedOutlineDragValues, getSelectedOutlineKeyboardNudgeDelta, getSelectedOutlineKeyboardNudgeDeltas, getSelectedOutlineRotationDragChanges, getSelectedOutlineRotationDragStates, getSelectedOutlineRotationDragValues, getSelectedOutlineScaleDragChanges, getSelectedOutlineScaleDragStates, getSelectedOutlineScaleDragValues, getSelectedOutlineScaleEdgeInfo, getSelectedOutlineTransformOriginLockedAxis, isSelectedOutlineDragPastThreshold, selectedOutlineTransformOriginSnapThresholdPx, selectedOutlineUvSnapThresholdPx, snapSelectedOutlineRotationDeltaDegrees, snapSelectedOutlineTransformOriginUv, snapSelectedOutlineUv, } from './selected-outline-drag';
|
|
5
|
-
export {
|
|
5
|
+
export { getOutlineSelectionInteraction, getSelectedEffectFieldsBySequenceKey, getSelectedOutlineRotationCornerInfo, getSelectedOutlineRotationDeltaDegrees, getSelectedOutlineRotationPivot, getSelectedSequenceKeys, getSequencesWithSelectableOutlines, getTransformedSvgViewportPoints, } from './selected-outline-measurement';
|
|
6
6
|
export { selectedOutlineDragThresholdPx } from './selected-outline-types';
|
|
7
7
|
export type { SelectedOutlineDragState, SelectedOutlineRotationDragState, SelectedOutlineScaleDragState, } from './selected-outline-types';
|
|
8
8
|
type OutlineSequenceParent = {
|
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.SelectedOutlineOverlay = exports.orderOutlinesForRendering = exports.selectedOutlineDragThresholdPx = exports.getTransformedSvgViewportPoints = exports.getSequencesWithSelectableOutlines = exports.getSelectedSequenceKeys = exports.getSelectedOutlineRotationPivot = exports.getSelectedOutlineRotationDeltaDegrees = exports.getSelectedOutlineRotationCornerInfo = exports.getSelectedEffectFieldsBySequenceKey = exports.getOutlineSelectionInteraction = exports.
|
|
36
|
+
exports.SelectedOutlineOverlay = exports.orderOutlinesForRendering = exports.selectedOutlineDragThresholdPx = exports.getTransformedSvgViewportPoints = exports.getSequencesWithSelectableOutlines = exports.getSelectedSequenceKeys = exports.getSelectedOutlineRotationPivot = exports.getSelectedOutlineRotationDeltaDegrees = exports.getSelectedOutlineRotationCornerInfo = exports.getSelectedEffectFieldsBySequenceKey = exports.getOutlineSelectionInteraction = exports.snapSelectedOutlineUv = exports.snapSelectedOutlineTransformOriginUv = exports.snapSelectedOutlineRotationDeltaDegrees = exports.selectedOutlineUvSnapThresholdPx = exports.selectedOutlineTransformOriginSnapThresholdPx = exports.isSelectedOutlineDragPastThreshold = exports.getSelectedOutlineTransformOriginLockedAxis = exports.getSelectedOutlineScaleEdgeInfo = exports.getSelectedOutlineScaleDragValues = exports.getSelectedOutlineScaleDragStates = exports.getSelectedOutlineScaleDragChanges = exports.getSelectedOutlineRotationDragValues = exports.getSelectedOutlineRotationDragStates = exports.getSelectedOutlineRotationDragChanges = exports.getSelectedOutlineKeyboardNudgeDeltas = exports.getSelectedOutlineKeyboardNudgeDelta = exports.getSelectedOutlineDragValues = exports.getSelectedOutlineDragChanges = exports.getSelectedOutlineActiveSchema = exports.compensateTranslateForTransformOrigin = exports.applySelectedOutlineTransformOriginAxisLock = exports.applySelectedOutlineDragAxisLock = void 0;
|
|
37
37
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
38
38
|
const player_1 = require("@remotion/player");
|
|
39
39
|
const react_1 = __importStar(require("react"));
|
|
@@ -82,7 +82,6 @@ Object.defineProperty(exports, "snapSelectedOutlineRotationDeltaDegrees", { enum
|
|
|
82
82
|
Object.defineProperty(exports, "snapSelectedOutlineTransformOriginUv", { enumerable: true, get: function () { return selected_outline_drag_2.snapSelectedOutlineTransformOriginUv; } });
|
|
83
83
|
Object.defineProperty(exports, "snapSelectedOutlineUv", { enumerable: true, get: function () { return selected_outline_drag_2.snapSelectedOutlineUv; } });
|
|
84
84
|
const selected_outline_measurement_2 = require("./selected-outline-measurement");
|
|
85
|
-
Object.defineProperty(exports, "getOutlineDoubleClickAction", { enumerable: true, get: function () { return selected_outline_measurement_2.getOutlineDoubleClickAction; } });
|
|
86
85
|
Object.defineProperty(exports, "getOutlineSelectionInteraction", { enumerable: true, get: function () { return selected_outline_measurement_2.getOutlineSelectionInteraction; } });
|
|
87
86
|
Object.defineProperty(exports, "getSelectedEffectFieldsBySequenceKey", { enumerable: true, get: function () { return selected_outline_measurement_2.getSelectedEffectFieldsBySequenceKey; } });
|
|
88
87
|
Object.defineProperty(exports, "getSelectedOutlineRotationCornerInfo", { enumerable: true, get: function () { return selected_outline_measurement_2.getSelectedOutlineRotationCornerInfo; } });
|
|
@@ -363,7 +362,7 @@ exports.orderOutlinesForRendering = orderOutlinesForRendering;
|
|
|
363
362
|
const SelectedOutlineOverlay = ({ compositionHeight, compositionWidth, scale, translationX, translationY, }) => {
|
|
364
363
|
const { selectedItems, selectItem } = (0, TimelineSelection_1.useTimelineSelection)();
|
|
365
364
|
const { sequences } = (0, react_1.useContext)(remotion_1.Internals.SequenceManager);
|
|
366
|
-
const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
|
365
|
+
const { canvasContent, compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
|
367
366
|
const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
|
|
368
367
|
const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
|
|
369
368
|
const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
|
|
@@ -411,6 +410,7 @@ const SelectedOutlineOverlay = ({ compositionHeight, compositionWidth, scale, tr
|
|
|
411
410
|
return (0, selected_outline_measurement_1.getSequencesWithSelectableOutlines)({
|
|
412
411
|
sequences,
|
|
413
412
|
overrideIdsToNodePaths: overrideIdToNodePathMappings,
|
|
413
|
+
compositions,
|
|
414
414
|
}).map(({ key, keyframeDisplayOffset, nodePathInfo, sequence }) => {
|
|
415
415
|
var _a, _b, _c, _d, _e, _f;
|
|
416
416
|
if (sequence.refForOutline === null) {
|
|
@@ -629,6 +629,7 @@ const SelectedOutlineOverlay = ({ compositionHeight, compositionWidth, scale, tr
|
|
|
629
629
|
previewServerState,
|
|
630
630
|
selectedItems,
|
|
631
631
|
sequences,
|
|
632
|
+
compositions,
|
|
632
633
|
timelinePosition,
|
|
633
634
|
]);
|
|
634
635
|
(0, react_1.useEffect)(() => {
|
|
@@ -204,6 +204,7 @@ const TimelineContextMenuArea = ({ children }) => {
|
|
|
204
204
|
const TimelineInner = () => {
|
|
205
205
|
var _a;
|
|
206
206
|
const { sequences } = (0, react_1.useContext)(remotion_1.Internals.SequenceManager);
|
|
207
|
+
const { compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
|
207
208
|
const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
|
|
208
209
|
const isStill = (0, is_current_selected_still_1.useIsStill)();
|
|
209
210
|
const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
|
|
@@ -218,8 +219,14 @@ const TimelineInner = () => {
|
|
|
218
219
|
return (0, calculate_timeline_1.calculateTimeline)({
|
|
219
220
|
sequences,
|
|
220
221
|
overrideIdsToNodePaths: overrideIdToNodePathMappings,
|
|
222
|
+
compositions,
|
|
221
223
|
});
|
|
222
|
-
}, [
|
|
224
|
+
}, [
|
|
225
|
+
sequences,
|
|
226
|
+
videoConfigIsNull,
|
|
227
|
+
overrideIdToNodePathMappings,
|
|
228
|
+
compositions,
|
|
229
|
+
]);
|
|
223
230
|
const durationInFrames = (_a = videoConfig === null || videoConfig === void 0 ? void 0 : videoConfig.durationInFrames) !== null && _a !== void 0 ? _a : 0;
|
|
224
231
|
const filtered = (0, react_1.useMemo)(() => {
|
|
225
232
|
return timeline.filter((t) => (0, should_show_track_in_timeline_1.shouldShowTrackInTimeline)(t, durationInFrames));
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { CanUpdateSequencePropStatusStatic } from 'remotion';
|
|
3
|
+
import type { SchemaFieldInfo, TimelineFieldOnDragValueChange, TimelineFieldOnSave } from '../../helpers/timeline-layout';
|
|
4
|
+
type TimelineAssetFieldProps = {
|
|
5
|
+
readonly field: SchemaFieldInfo;
|
|
6
|
+
readonly propStatus: CanUpdateSequencePropStatusStatic;
|
|
7
|
+
readonly effectiveValue: unknown;
|
|
8
|
+
readonly onSave: TimelineFieldOnSave;
|
|
9
|
+
readonly onDragValueChange: TimelineFieldOnDragValueChange;
|
|
10
|
+
readonly onDragEnd: () => void;
|
|
11
|
+
};
|
|
12
|
+
export declare const isStaticFileAssetValue: (value: unknown) => value is string;
|
|
13
|
+
export declare const TimelineAssetField: React.FC<TimelineAssetFieldProps>;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TimelineAssetField = exports.isStaticFileAssetValue = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const no_react_1 = require("remotion/no-react");
|
|
7
|
+
const write_static_file_1 = require("../../api/write-static-file");
|
|
8
|
+
const Checkmark_1 = require("../../icons/Checkmark");
|
|
9
|
+
const import_assets_1 = require("../import-assets");
|
|
10
|
+
const ComboBox_1 = require("../NewComposition/ComboBox");
|
|
11
|
+
const NotificationCenter_1 = require("../Notifications/NotificationCenter");
|
|
12
|
+
const use_static_files_1 = require("../use-static-files");
|
|
13
|
+
const comboboxStyle = {
|
|
14
|
+
marginLeft: 8,
|
|
15
|
+
maxWidth: 180,
|
|
16
|
+
};
|
|
17
|
+
const remoteAssetStyle = {
|
|
18
|
+
display: 'inline-block',
|
|
19
|
+
marginLeft: 8,
|
|
20
|
+
maxWidth: 180,
|
|
21
|
+
overflow: 'hidden',
|
|
22
|
+
textOverflow: 'ellipsis',
|
|
23
|
+
verticalAlign: 'middle',
|
|
24
|
+
whiteSpace: 'nowrap',
|
|
25
|
+
};
|
|
26
|
+
const toFileToken = (name) => {
|
|
27
|
+
return `${no_react_1.NoReactInternals.FILE_TOKEN}${name
|
|
28
|
+
.split('/')
|
|
29
|
+
.map(encodeURIComponent)
|
|
30
|
+
.join('/')}`;
|
|
31
|
+
};
|
|
32
|
+
const toStaticFileUrl = (fileToken) => {
|
|
33
|
+
return `${window.remotion_staticBase}/${fileToken.slice(no_react_1.NoReactInternals.FILE_TOKEN.length)}`;
|
|
34
|
+
};
|
|
35
|
+
const isStaticFileAssetValue = (value) => {
|
|
36
|
+
return (typeof value === 'string' && value.startsWith(no_react_1.NoReactInternals.FILE_TOKEN));
|
|
37
|
+
};
|
|
38
|
+
exports.isStaticFileAssetValue = isStaticFileAssetValue;
|
|
39
|
+
const TimelineStaticFileAssetField = ({ propStatus, effectiveValue, onSave, onDragValueChange, onDragEnd, }) => {
|
|
40
|
+
const staticFiles = (0, use_static_files_1.useStaticFiles)();
|
|
41
|
+
const current = String(effectiveValue !== null && effectiveValue !== void 0 ? effectiveValue : '');
|
|
42
|
+
const onSelect = (0, react_1.useCallback)((sourceValue, previewValue) => {
|
|
43
|
+
if (sourceValue === propStatus.codeValue) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
onDragValueChange(previewValue);
|
|
47
|
+
onSave(sourceValue).finally(() => {
|
|
48
|
+
onDragEnd();
|
|
49
|
+
});
|
|
50
|
+
}, [propStatus.codeValue, onDragValueChange, onSave, onDragEnd]);
|
|
51
|
+
const upload = (0, react_1.useCallback)(async () => {
|
|
52
|
+
const [file] = await (0, import_assets_1.pickFilesToImport)({ multiple: false });
|
|
53
|
+
if (!file) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const existing = staticFiles.find((candidate) => candidate.name === file.name);
|
|
57
|
+
if (existing && existing.sizeInBytes !== file.size) {
|
|
58
|
+
(0, NotificationCenter_1.showNotification)(`File with name ${file.name} already exists and is different`, 4000);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
if (!existing) {
|
|
63
|
+
await (0, write_static_file_1.writeStaticFile)({
|
|
64
|
+
contents: await file.arrayBuffer(),
|
|
65
|
+
filePath: file.name,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
const fileToken = toFileToken(file.name);
|
|
69
|
+
onSelect(fileToken, toStaticFileUrl(fileToken));
|
|
70
|
+
if (!existing) {
|
|
71
|
+
(0, NotificationCenter_1.showNotification)(`Created ${file.name} in public folder`, 3000);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
(0, NotificationCenter_1.showNotification)(`Could not upload asset: ${error instanceof Error ? error.message : String(error)}`, 4000);
|
|
76
|
+
}
|
|
77
|
+
}, [onSelect, staticFiles]);
|
|
78
|
+
const items = (0, react_1.useMemo)(() => {
|
|
79
|
+
const publicFileItems = staticFiles.map((file) => {
|
|
80
|
+
const fileToken = toFileToken(file.name);
|
|
81
|
+
return {
|
|
82
|
+
type: 'item',
|
|
83
|
+
id: fileToken,
|
|
84
|
+
value: fileToken,
|
|
85
|
+
label: file.name,
|
|
86
|
+
onClick: () => onSelect(fileToken, file.src),
|
|
87
|
+
keyHint: null,
|
|
88
|
+
leftItem: fileToken === current ? jsx_runtime_1.jsx(Checkmark_1.Checkmark, {}) : null,
|
|
89
|
+
subMenu: null,
|
|
90
|
+
quickSwitcherLabel: null,
|
|
91
|
+
};
|
|
92
|
+
});
|
|
93
|
+
return [
|
|
94
|
+
...publicFileItems,
|
|
95
|
+
{ type: 'divider', id: 'upload-asset-divider' },
|
|
96
|
+
{
|
|
97
|
+
type: 'item',
|
|
98
|
+
id: 'upload-asset',
|
|
99
|
+
value: 'upload-asset',
|
|
100
|
+
label: 'Upload…',
|
|
101
|
+
onClick: () => {
|
|
102
|
+
upload().catch(() => undefined);
|
|
103
|
+
},
|
|
104
|
+
keyHint: null,
|
|
105
|
+
leftItem: null,
|
|
106
|
+
subMenu: null,
|
|
107
|
+
quickSwitcherLabel: null,
|
|
108
|
+
disabled: window.remotion_isReadOnlyStudio,
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
}, [current, onSelect, staticFiles, upload]);
|
|
112
|
+
return (jsx_runtime_1.jsx(ComboBox_1.Combobox, { small: true, title: current, selectedId: current, values: items, style: comboboxStyle }));
|
|
113
|
+
};
|
|
114
|
+
const TimelineAssetField = (props) => {
|
|
115
|
+
var _a;
|
|
116
|
+
if (props.field.fieldSchema.type !== 'asset') {
|
|
117
|
+
throw new Error('TimelineAssetField rendered for non-asset field');
|
|
118
|
+
}
|
|
119
|
+
if (!(0, exports.isStaticFileAssetValue)(props.effectiveValue)) {
|
|
120
|
+
const remote = String((_a = props.effectiveValue) !== null && _a !== void 0 ? _a : '');
|
|
121
|
+
return (jsx_runtime_1.jsx("span", { style: remoteAssetStyle, title: remote, children: remote }));
|
|
122
|
+
}
|
|
123
|
+
return jsx_runtime_1.jsx(TimelineStaticFileAssetField, { ...props });
|
|
124
|
+
};
|
|
125
|
+
exports.TimelineAssetField = TimelineAssetField;
|
|
@@ -9,9 +9,13 @@ const use_keybinding_1 = require("../../helpers/use-keybinding");
|
|
|
9
9
|
const call_api_1 = require("../call-api");
|
|
10
10
|
const ConfirmationDialog_1 = require("../ConfirmationDialog");
|
|
11
11
|
const NotificationCenter_1 = require("../Notifications/NotificationCenter");
|
|
12
|
+
const call_add_keyframe_1 = require("./call-add-keyframe");
|
|
13
|
+
const call_delete_keyframe_1 = require("./call-delete-keyframe");
|
|
14
|
+
const call_update_keyframe_settings_1 = require("./call-update-keyframe-settings");
|
|
12
15
|
const delete_selected_timeline_item_1 = require("./delete-selected-timeline-item");
|
|
13
16
|
const effects_clipboard_1 = require("./effects-clipboard");
|
|
14
17
|
const find_track_for_node_path_info_1 = require("./find-track-for-node-path-info");
|
|
18
|
+
const keyframe_clipboard_1 = require("./keyframe-clipboard");
|
|
15
19
|
const save_effect_prop_1 = require("./save-effect-prop");
|
|
16
20
|
const TimelineSelection_1 = require("./TimelineSelection");
|
|
17
21
|
const update_selected_easing_1 = require("./update-selected-easing");
|
|
@@ -352,6 +356,9 @@ const getPasteEffectPropTarget = ({ selectedItems, payload, propStatuses, sequen
|
|
|
352
356
|
exports.getPasteEffectPropTarget = getPasteEffectPropTarget;
|
|
353
357
|
const TimelineClipboardKeybindings = () => {
|
|
354
358
|
const keybindings = (0, use_keybinding_1.useKeybinding)();
|
|
359
|
+
const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
|
|
360
|
+
const timelinePositionRef = (0, react_1.useRef)(timelinePosition);
|
|
361
|
+
timelinePositionRef.current = timelinePosition;
|
|
355
362
|
const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
|
|
356
363
|
const { canSelect } = (0, TimelineSelection_1.useTimelineSelection)();
|
|
357
364
|
const currentSelection = (0, TimelineSelection_1.useCurrentTimelineSelectionStateAsRef)();
|
|
@@ -376,6 +383,30 @@ const TimelineClipboardKeybindings = () => {
|
|
|
376
383
|
if (selectedItems.length === 0) {
|
|
377
384
|
return;
|
|
378
385
|
}
|
|
386
|
+
const keyframeSelections = selectedItems.filter((selection) => selection.type === 'keyframe');
|
|
387
|
+
if (keyframeSelections.length > 0) {
|
|
388
|
+
e.preventDefault();
|
|
389
|
+
if (selectedItems.some((selection) => selection.type !== 'keyframe' && selection.type !== 'easing')) {
|
|
390
|
+
(0, NotificationCenter_1.showNotification)('Select only keyframes and easings to copy', 3000);
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
const payload = (0, keyframe_clipboard_1.getKeyframeClipboardDataFromSelections)({
|
|
394
|
+
selections: selectedItems,
|
|
395
|
+
sequences,
|
|
396
|
+
overrideIdsToNodePaths: overrideIdToNodePathMappings,
|
|
397
|
+
propStatuses,
|
|
398
|
+
});
|
|
399
|
+
if (payload === null) {
|
|
400
|
+
(0, NotificationCenter_1.showNotification)('Select a continuous keyframe range from one property to copy', 3000);
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
navigator.clipboard
|
|
404
|
+
.writeText(makeClipboardText(payload))
|
|
405
|
+
.catch((err) => {
|
|
406
|
+
(0, NotificationCenter_1.showNotification)(`Could not copy keyframe: ${err.message}`, 2000);
|
|
407
|
+
});
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
379
410
|
const easingSelections = (0, update_selected_easing_1.getEasingSelections)(selectedItems);
|
|
380
411
|
if (easingSelections.length > 0) {
|
|
381
412
|
e.preventDefault();
|
|
@@ -543,6 +574,106 @@ const TimelineClipboardKeybindings = () => {
|
|
|
543
574
|
.then(() => {
|
|
544
575
|
const propStatuses = propStatusesRef.current;
|
|
545
576
|
const sequences = sequencesRef.current;
|
|
577
|
+
const keyframeResult = (0, studio_shared_1.parseKeyframeClipboardDataResult)(text);
|
|
578
|
+
if (keyframeResult.status !== 'invalid') {
|
|
579
|
+
if (keyframeResult.status === 'unsupported-version') {
|
|
580
|
+
(0, NotificationCenter_1.showNotification)('Cannot paste keyframe copied from a different Remotion Studio version', 4000);
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
const keyframeTarget = (0, keyframe_clipboard_1.getPasteKeyframeTarget)({
|
|
584
|
+
selectedItems,
|
|
585
|
+
payload: keyframeResult.data,
|
|
586
|
+
timelinePosition: timelinePositionRef.current,
|
|
587
|
+
sequences,
|
|
588
|
+
overrideIdsToNodePaths: overrideIdToNodePathMappings,
|
|
589
|
+
propStatuses,
|
|
590
|
+
});
|
|
591
|
+
if (keyframeTarget.type !== 'valid') {
|
|
592
|
+
switch (keyframeTarget.type) {
|
|
593
|
+
case 'none':
|
|
594
|
+
(0, NotificationCenter_1.showNotification)('Select a property or keyframe to paste onto', 3000);
|
|
595
|
+
return;
|
|
596
|
+
case 'multiple':
|
|
597
|
+
(0, NotificationCenter_1.showNotification)('Select one property or keyframe to paste onto', 3000);
|
|
598
|
+
return;
|
|
599
|
+
case 'uncopyable':
|
|
600
|
+
(0, NotificationCenter_1.showNotification)('Cannot paste onto a property that cannot be updated', 3000);
|
|
601
|
+
return;
|
|
602
|
+
case 'incompatible':
|
|
603
|
+
(0, NotificationCenter_1.showNotification)('The copied keyframe is not compatible with this property', 3000);
|
|
604
|
+
return;
|
|
605
|
+
default:
|
|
606
|
+
throw new Error(`Unexpected paste target: ${keyframeTarget}`);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
const changes = keyframeTarget.keyframes.map((keyframe) => ({
|
|
610
|
+
fileName: keyframeTarget.fileName,
|
|
611
|
+
nodePath: keyframeTarget.nodePath,
|
|
612
|
+
fieldKey: keyframeTarget.fieldKey,
|
|
613
|
+
sourceFrame: keyframe.sourceFrame,
|
|
614
|
+
value: keyframe.value,
|
|
615
|
+
schema: keyframeTarget.schema,
|
|
616
|
+
}));
|
|
617
|
+
const { effectIndex } = keyframeTarget;
|
|
618
|
+
const deletions = keyframeTarget.keyframesToDelete.map((sourceFrame) => ({
|
|
619
|
+
fileName: keyframeTarget.fileName,
|
|
620
|
+
nodePath: keyframeTarget.nodePath,
|
|
621
|
+
fieldKey: keyframeTarget.fieldKey,
|
|
622
|
+
sourceFrame,
|
|
623
|
+
schema: keyframeTarget.schema,
|
|
624
|
+
}));
|
|
625
|
+
return (0, call_delete_keyframe_1.callDeleteKeyframes)({
|
|
626
|
+
sequenceKeyframes: effectIndex === null ? deletions : [],
|
|
627
|
+
effectKeyframes: effectIndex === null
|
|
628
|
+
? []
|
|
629
|
+
: deletions.map((deletion) => ({
|
|
630
|
+
...deletion,
|
|
631
|
+
effectIndex,
|
|
632
|
+
})),
|
|
633
|
+
setPropStatuses,
|
|
634
|
+
clientId,
|
|
635
|
+
})
|
|
636
|
+
.then(() => (0, call_add_keyframe_1.callAddKeyframes)({
|
|
637
|
+
sequenceKeyframes: effectIndex === null ? changes : [],
|
|
638
|
+
effectKeyframes: effectIndex === null
|
|
639
|
+
? []
|
|
640
|
+
: changes.map((change) => ({ ...change, effectIndex })),
|
|
641
|
+
setPropStatuses,
|
|
642
|
+
clientId,
|
|
643
|
+
}))
|
|
644
|
+
.then(async () => {
|
|
645
|
+
for (const [index, easing] of keyframeTarget.easing.entries()) {
|
|
646
|
+
const settings = {
|
|
647
|
+
type: 'easing',
|
|
648
|
+
segmentIndex: keyframeTarget.firstEasingSegmentIndex + index,
|
|
649
|
+
easing,
|
|
650
|
+
};
|
|
651
|
+
if (effectIndex === null) {
|
|
652
|
+
await (0, call_update_keyframe_settings_1.callUpdateSequenceKeyframeSettings)({
|
|
653
|
+
fileName: keyframeTarget.fileName,
|
|
654
|
+
nodePath: keyframeTarget.nodePath,
|
|
655
|
+
fieldKey: keyframeTarget.fieldKey,
|
|
656
|
+
settings,
|
|
657
|
+
schema: keyframeTarget.schema,
|
|
658
|
+
setPropStatuses,
|
|
659
|
+
clientId,
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
|
+
else {
|
|
663
|
+
await (0, call_update_keyframe_settings_1.callUpdateEffectKeyframeSettings)({
|
|
664
|
+
fileName: keyframeTarget.fileName,
|
|
665
|
+
nodePath: keyframeTarget.nodePath,
|
|
666
|
+
effectIndex,
|
|
667
|
+
fieldKey: keyframeTarget.fieldKey,
|
|
668
|
+
settings,
|
|
669
|
+
schema: keyframeTarget.schema,
|
|
670
|
+
setPropStatuses,
|
|
671
|
+
clientId,
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
});
|
|
676
|
+
}
|
|
546
677
|
const easingResult = (0, studio_shared_1.parseEasingClipboardDataResult)(text);
|
|
547
678
|
if (easingResult.status !== 'invalid') {
|
|
548
679
|
e.preventDefault();
|
|
@@ -685,7 +816,7 @@ const TimelineClipboardKeybindings = () => {
|
|
|
685
816
|
});
|
|
686
817
|
})
|
|
687
818
|
.catch((err) => {
|
|
688
|
-
(0, NotificationCenter_1.showNotification)(`Could not paste
|
|
819
|
+
(0, NotificationCenter_1.showNotification)(`Could not paste: ${err.message}`, 3000);
|
|
689
820
|
});
|
|
690
821
|
};
|
|
691
822
|
// Reading ClipboardEvent data avoids the permission prompt caused by
|
|
@@ -708,6 +839,7 @@ const TimelineClipboardKeybindings = () => {
|
|
|
708
839
|
previewServerState,
|
|
709
840
|
sequencesRef,
|
|
710
841
|
setPropStatuses,
|
|
842
|
+
timelinePositionRef,
|
|
711
843
|
]);
|
|
712
844
|
return null;
|
|
713
845
|
};
|
|
@@ -57,6 +57,7 @@ const TimelineExpandedSection = ({ sequence, validatedLocation, nodePathInfo, ne
|
|
|
57
57
|
sequence,
|
|
58
58
|
nodePathInfo,
|
|
59
59
|
includeTextContent: false,
|
|
60
|
+
includeSourceControls: false,
|
|
60
61
|
});
|
|
61
62
|
const flat = (0, react_1.useMemo)(() => (0, timeline_layout_1.flattenVisibleTreeNodes)({ nodes: filteredTree, getIsExpanded }), [filteredTree, getIsExpanded]);
|
|
62
63
|
const expandedHeight = (0, react_1.useMemo)(() => {
|