@remotion/studio 4.0.464 → 4.0.465
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/components/NewComposition/CodemodFooter.d.ts +1 -0
- package/dist/components/NewComposition/CodemodFooter.js +35 -23
- package/dist/components/NewComposition/DeleteComposition.js +3 -1
- package/dist/components/NewComposition/DiffPreview.js +1 -1
- package/dist/components/NewComposition/DuplicateComposition.js +3 -1
- package/dist/components/NewComposition/RenameComposition.js +4 -2
- package/dist/components/RenderQueue/actions.d.ts +2 -1
- package/dist/components/RenderQueue/actions.js +2 -1
- package/dist/components/Timeline/TimelineEffectGroupRow.js +53 -1
- package/dist/components/Timeline/TimelineTimeIndicators.js +4 -11
- package/dist/components/Timeline/TimelineVideoInfo.js +25 -8
- package/dist/components/Timeline/get-timeline-video-info-widths.d.ts +9 -0
- package/dist/components/Timeline/get-timeline-video-info-widths.js +11 -0
- package/dist/components/Timeline/use-resolved-stack.d.ts +1 -0
- package/dist/components/Timeline/use-resolved-stack.js +10 -1
- package/dist/esm/{chunk-mawnnpzg.js → chunk-pqk2qd0d.js} +294 -172
- package/dist/esm/internals.mjs +294 -172
- package/dist/esm/previewEntry.mjs +294 -172
- package/dist/esm/renderEntry.mjs +1 -1
- package/dist/helpers/resolved-stack-to-symbolicated.d.ts +3 -0
- package/dist/helpers/resolved-stack-to-symbolicated.js +16 -0
- package/package.json +10 -10
|
@@ -3,6 +3,7 @@ import React from 'react';
|
|
|
3
3
|
export declare const CodemodFooter: React.FC<{
|
|
4
4
|
readonly valid: boolean;
|
|
5
5
|
readonly codemod: RecastCodemod;
|
|
6
|
+
readonly stack: string | null;
|
|
6
7
|
readonly loadingNotification: React.ReactNode;
|
|
7
8
|
readonly successNotification: React.ReactNode;
|
|
8
9
|
readonly errorNotification: string;
|
|
@@ -4,33 +4,25 @@ exports.CodemodFooter = void 0;
|
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const react_1 = require("react");
|
|
6
6
|
const ShortcutHint_1 = require("../../error-overlay/remotion-overlay/ShortcutHint");
|
|
7
|
+
const resolved_stack_to_symbolicated_1 = require("../../helpers/resolved-stack-to-symbolicated");
|
|
7
8
|
const use_keybinding_1 = require("../../helpers/use-keybinding");
|
|
8
9
|
const modals_1 = require("../../state/modals");
|
|
9
10
|
const layout_1 = require("../layout");
|
|
10
11
|
const ModalButton_1 = require("../ModalButton");
|
|
11
12
|
const NotificationCenter_1 = require("../Notifications/NotificationCenter");
|
|
12
13
|
const actions_1 = require("../RenderQueue/actions");
|
|
14
|
+
const use_resolved_stack_1 = require("../Timeline/use-resolved-stack");
|
|
13
15
|
const DiffPreview_1 = require("./DiffPreview");
|
|
14
|
-
const CodemodFooter = ({ codemod, valid, loadingNotification, successNotification, errorNotification, genericSubmitLabel, submitLabel, onSuccess, }) => {
|
|
16
|
+
const CodemodFooter = ({ codemod, stack, valid, loadingNotification, successNotification, errorNotification, genericSubmitLabel, submitLabel, onSuccess, }) => {
|
|
17
|
+
var _a;
|
|
15
18
|
const [submitting, setSubmitting] = (0, react_1.useState)(false);
|
|
16
19
|
const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
|
|
17
20
|
const [codemodStatus, setCanApplyCodemod] = (0, react_1.useState)({
|
|
18
21
|
type: 'loading',
|
|
19
22
|
});
|
|
20
|
-
const
|
|
21
|
-
(0, react_1.
|
|
22
|
-
|
|
23
|
-
(0, actions_1.getProjectInfo)(controller.signal)
|
|
24
|
-
.then((info) => {
|
|
25
|
-
setProjectInfo(info.projectInfo);
|
|
26
|
-
})
|
|
27
|
-
.catch((err) => {
|
|
28
|
-
(0, NotificationCenter_1.showNotification)(`Could not get project info: ${err.message}. Unable to duplicate composition`, 3000);
|
|
29
|
-
});
|
|
30
|
-
return () => {
|
|
31
|
-
controller.abort();
|
|
32
|
-
};
|
|
33
|
-
}, []);
|
|
23
|
+
const resolvedLocation = (0, use_resolved_stack_1.useResolvedStack)(stack);
|
|
24
|
+
const symbolicatedStack = (0, react_1.useMemo)(() => (0, resolved_stack_to_symbolicated_1.resolvedStackToSymbolicated)(resolvedLocation), [resolvedLocation]);
|
|
25
|
+
const relativeFilePath = (_a = symbolicatedStack === null || symbolicatedStack === void 0 ? void 0 : symbolicatedStack.originalFileName) !== null && _a !== void 0 ? _a : null;
|
|
34
26
|
const trigger = (0, react_1.useCallback)(() => {
|
|
35
27
|
setSubmitting(true);
|
|
36
28
|
setSelectedModal(null);
|
|
@@ -38,6 +30,7 @@ const CodemodFooter = ({ codemod, valid, loadingNotification, successNotificatio
|
|
|
38
30
|
(0, actions_1.applyCodemod)({
|
|
39
31
|
codemod,
|
|
40
32
|
dryRun: false,
|
|
33
|
+
symbolicatedStack,
|
|
41
34
|
signal: new AbortController().signal,
|
|
42
35
|
})
|
|
43
36
|
.then(() => {
|
|
@@ -54,11 +47,13 @@ const CodemodFooter = ({ codemod, valid, loadingNotification, successNotificatio
|
|
|
54
47
|
onSuccess,
|
|
55
48
|
setSelectedModal,
|
|
56
49
|
successNotification,
|
|
50
|
+
symbolicatedStack,
|
|
57
51
|
]);
|
|
58
52
|
const getCanApplyCodemod = (0, react_1.useCallback)(async (signal) => {
|
|
59
53
|
const res = await (0, actions_1.applyCodemod)({
|
|
60
54
|
codemod,
|
|
61
55
|
dryRun: true,
|
|
56
|
+
symbolicatedStack,
|
|
62
57
|
signal,
|
|
63
58
|
});
|
|
64
59
|
if (res.success) {
|
|
@@ -70,8 +65,25 @@ const CodemodFooter = ({ codemod, valid, loadingNotification, successNotificatio
|
|
|
70
65
|
error: res.reason,
|
|
71
66
|
});
|
|
72
67
|
}
|
|
73
|
-
}, [codemod]);
|
|
68
|
+
}, [codemod, symbolicatedStack]);
|
|
74
69
|
(0, react_1.useEffect)(() => {
|
|
70
|
+
if (!stack) {
|
|
71
|
+
setCanApplyCodemod({
|
|
72
|
+
type: 'fail',
|
|
73
|
+
error: 'Could not determine where this composition is defined',
|
|
74
|
+
});
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (!(0, use_resolved_stack_1.hasResolvedStack)(stack)) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (!symbolicatedStack) {
|
|
81
|
+
setCanApplyCodemod({
|
|
82
|
+
type: 'fail',
|
|
83
|
+
error: 'Could not resolve the source location of this composition',
|
|
84
|
+
});
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
75
87
|
const abortController = new AbortController();
|
|
76
88
|
let aborted = false;
|
|
77
89
|
getCanApplyCodemod(abortController.signal)
|
|
@@ -80,16 +92,16 @@ const CodemodFooter = ({ codemod, valid, loadingNotification, successNotificatio
|
|
|
80
92
|
if (aborted) {
|
|
81
93
|
return;
|
|
82
94
|
}
|
|
83
|
-
(0, NotificationCenter_1.showNotification)(
|
|
95
|
+
(0, NotificationCenter_1.showNotification)(`${errorNotification}: ${err.message}`, 3000);
|
|
84
96
|
});
|
|
85
97
|
return () => {
|
|
86
98
|
aborted = true;
|
|
87
99
|
abortController.abort();
|
|
88
100
|
};
|
|
89
|
-
}, [getCanApplyCodemod]);
|
|
101
|
+
}, [errorNotification, getCanApplyCodemod, stack, symbolicatedStack]);
|
|
90
102
|
const disabled = !valid ||
|
|
91
103
|
submitting ||
|
|
92
|
-
|
|
104
|
+
symbolicatedStack === null ||
|
|
93
105
|
codemodStatus.type !== 'success';
|
|
94
106
|
const { registerKeybinding } = (0, use_keybinding_1.useKeybinding)();
|
|
95
107
|
(0, react_1.useEffect)(() => {
|
|
@@ -100,7 +112,7 @@ const CodemodFooter = ({ codemod, valid, loadingNotification, successNotificatio
|
|
|
100
112
|
callback() {
|
|
101
113
|
trigger();
|
|
102
114
|
},
|
|
103
|
-
commandCtrlKey:
|
|
115
|
+
commandCtrlKey: false,
|
|
104
116
|
key: 'Enter',
|
|
105
117
|
event: 'keydown',
|
|
106
118
|
preventDefault: true,
|
|
@@ -112,9 +124,9 @@ const CodemodFooter = ({ codemod, valid, loadingNotification, successNotificatio
|
|
|
112
124
|
};
|
|
113
125
|
}, [disabled, registerKeybinding, trigger, valid]);
|
|
114
126
|
return (jsx_runtime_1.jsxs(layout_1.Row, { align: "center", children: [
|
|
115
|
-
jsx_runtime_1.jsx(DiffPreview_1.CodemodDiffPreview, { status: codemodStatus }), jsx_runtime_1.jsx(layout_1.Flex, {}), jsx_runtime_1.jsx(layout_1.Spacing, { block: true, x: 2 }), jsx_runtime_1.jsxs(ModalButton_1.ModalButton, { onClick: trigger, disabled: disabled, children: [
|
|
116
|
-
? submitLabel({ relativeRootPath:
|
|
117
|
-
: genericSubmitLabel, jsx_runtime_1.jsx(ShortcutHint_1.ShortcutHint, { keyToPress: "\u21B5", cmdOrCtrl:
|
|
127
|
+
jsx_runtime_1.jsx(DiffPreview_1.CodemodDiffPreview, { status: codemodStatus }), jsx_runtime_1.jsx(layout_1.Flex, {}), jsx_runtime_1.jsx(layout_1.Spacing, { block: true, x: 2 }), jsx_runtime_1.jsxs(ModalButton_1.ModalButton, { onClick: trigger, disabled: disabled, children: [relativeFilePath
|
|
128
|
+
? submitLabel({ relativeRootPath: relativeFilePath })
|
|
129
|
+
: genericSubmitLabel, jsx_runtime_1.jsx(ShortcutHint_1.ShortcutHint, { keyToPress: "\u21B5", cmdOrCtrl: false })
|
|
118
130
|
] })
|
|
119
131
|
] }));
|
|
120
132
|
};
|
|
@@ -16,11 +16,13 @@ const content = {
|
|
|
16
16
|
minWidth: 500,
|
|
17
17
|
};
|
|
18
18
|
const DeleteCompositionLoaded = ({ compositionId }) => {
|
|
19
|
+
var _a;
|
|
19
20
|
const context = (0, react_1.useContext)(ResolveCompositionBeforeModal_1.ResolvedCompositionContext);
|
|
20
21
|
if (!context) {
|
|
21
22
|
throw new Error('Resolved composition context');
|
|
22
23
|
}
|
|
23
24
|
const { unresolved } = context;
|
|
25
|
+
const compositionStack = (_a = unresolved.stack) !== null && _a !== void 0 ? _a : null;
|
|
24
26
|
const codemod = (0, react_1.useMemo)(() => {
|
|
25
27
|
return {
|
|
26
28
|
type: 'delete-composition',
|
|
@@ -36,7 +38,7 @@ const DeleteCompositionLoaded = ({ compositionId }) => {
|
|
|
36
38
|
jsx_runtime_1.jsx("br", {}),
|
|
37
39
|
"The associated ",
|
|
38
40
|
jsx_runtime_1.jsx("code", { style: styles_1.inlineCodeSnippet, children: "component" }),
|
|
39
|
-
" will remain in your code."] }), jsx_runtime_1.jsx(ModalFooter_1.ModalFooterContainer, { children: jsx_runtime_1.jsx(CodemodFooter_1.CodemodFooter, { errorNotification: `Could not delete composition`, loadingNotification: 'Deleting', successNotification: `Deleted ${unresolved.id}`, genericSubmitLabel: `Delete`, submitLabel: ({ relativeRootPath }) => `Delete from ${relativeRootPath}`, codemod: codemod, valid: true, onSuccess: null }) })
|
|
41
|
+
" will remain in your code."] }), jsx_runtime_1.jsx(ModalFooter_1.ModalFooterContainer, { children: jsx_runtime_1.jsx(CodemodFooter_1.CodemodFooter, { errorNotification: `Could not delete composition`, loadingNotification: 'Deleting', successNotification: `Deleted ${unresolved.id}`, genericSubmitLabel: `Delete`, submitLabel: ({ relativeRootPath }) => `Delete from ${relativeRootPath}`, codemod: codemod, stack: compositionStack, valid: true, onSuccess: null }) })
|
|
40
42
|
] })
|
|
41
43
|
] }));
|
|
42
44
|
};
|
|
@@ -11,7 +11,7 @@ const CodemodDiffPreview = ({ status }) => {
|
|
|
11
11
|
return (jsx_runtime_1.jsx("span", { style: { color: colors_1.FAIL_COLOR, fontSize: 13, lineHeight: 1.2 }, children: status.error }));
|
|
12
12
|
}
|
|
13
13
|
return (jsx_runtime_1.jsxs("div", { style: { lineHeight: 1.2 }, children: [
|
|
14
|
-
jsx_runtime_1.jsx("span", { style: { color: colors_1.LIGHT_TEXT, fontSize: 13, lineHeight: 1.2 }, children: "This will edit your
|
|
14
|
+
jsx_runtime_1.jsx("span", { style: { color: colors_1.LIGHT_TEXT, fontSize: 13, lineHeight: 1.2 }, children: "This will edit your codebase." }), jsx_runtime_1.jsx("br", {}), jsx_runtime_1.jsxs("span", { style: { color: colors_1.BLUE, fontSize: 13, lineHeight: 1.2 }, children: [status.diff.additions, " addition", status.diff.additions === 1 ? '' : 's', ","] }), ' ', jsx_runtime_1.jsxs("span", { style: {
|
|
15
15
|
color: colors_1.SELECTED_GUIDE,
|
|
16
16
|
fontSize: 13,
|
|
17
17
|
lineHeight: 1.2,
|
|
@@ -29,11 +29,13 @@ const comboBoxStyle = {
|
|
|
29
29
|
width: 190,
|
|
30
30
|
};
|
|
31
31
|
const DuplicateCompositionLoaded = ({ initialType }) => {
|
|
32
|
+
var _a;
|
|
32
33
|
const context = (0, react_1.useContext)(ResolveCompositionBeforeModal_1.ResolvedCompositionContext);
|
|
33
34
|
if (!context) {
|
|
34
35
|
throw new Error('Resolved composition context');
|
|
35
36
|
}
|
|
36
37
|
const { resolved, unresolved } = context;
|
|
38
|
+
const compositionStack = (_a = unresolved.stack) !== null && _a !== void 0 ? _a : null;
|
|
37
39
|
const [initialCompType] = (0, react_1.useState)(initialType);
|
|
38
40
|
const hadDimensionsDefined = unresolved.width && unresolved.height;
|
|
39
41
|
const hadFpsDefined = unresolved.fps !== undefined;
|
|
@@ -199,7 +201,7 @@ const DuplicateCompositionLoaded = ({ initialType }) => {
|
|
|
199
201
|
] })
|
|
200
202
|
] })) : null, type === 'composition' && hadDurationDefined ? (jsx_runtime_1.jsx(NewCompDuration_1.NewCompDuration, { durationInFrames: durationInFrames, setDurationInFrames: setDurationInFrames })) : null, type === 'composition' && hadFpsDefined ? (jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [
|
|
201
203
|
jsx_runtime_1.jsx("div", { style: layout_2.label, children: "FPS" }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: selectedFrameRate, onTextChange: onTextFpsChange, placeholder: "Frame rate (fps)", name: "fps", min: 1, required: true, status: "ok", max: 240, step: 0.01, onValueChange: onFpsChange, rightAlign: false }) })
|
|
202
|
-
] })) : null] }), jsx_runtime_1.jsx(ModalFooter_1.ModalFooterContainer, { children: jsx_runtime_1.jsx(CodemodFooter_1.CodemodFooter, { loadingNotification: 'Duplicating...', errorNotification: 'Could not duplicate composition', successNotification: `Duplicated ${unresolved.id} as ${newId}`, genericSubmitLabel: 'Duplicate', submitLabel: ({ relativeRootPath }) => `Add to ${relativeRootPath}`, codemod: codemod, valid: valid, onSuccess: onDuplicateSuccess }) })
|
|
204
|
+
] })) : null] }), jsx_runtime_1.jsx(ModalFooter_1.ModalFooterContainer, { children: jsx_runtime_1.jsx(CodemodFooter_1.CodemodFooter, { loadingNotification: 'Duplicating...', errorNotification: 'Could not duplicate composition', successNotification: `Duplicated ${unresolved.id} as ${newId}`, genericSubmitLabel: 'Duplicate', submitLabel: ({ relativeRootPath }) => `Add to ${relativeRootPath}`, codemod: codemod, stack: compositionStack, valid: valid, onSuccess: onDuplicateSuccess }) })
|
|
203
205
|
] })
|
|
204
206
|
] }));
|
|
205
207
|
};
|
|
@@ -22,11 +22,13 @@ const content = {
|
|
|
22
22
|
minWidth: 500,
|
|
23
23
|
};
|
|
24
24
|
const RenameCompositionLoaded = () => {
|
|
25
|
+
var _a;
|
|
25
26
|
const context = (0, react_1.useContext)(ResolveCompositionBeforeModal_1.ResolvedCompositionContext);
|
|
26
27
|
if (!context) {
|
|
27
28
|
throw new Error('Resolved composition context');
|
|
28
29
|
}
|
|
29
|
-
const { resolved } = context;
|
|
30
|
+
const { resolved, unresolved } = context;
|
|
31
|
+
const compositionStack = (_a = unresolved.stack) !== null && _a !== void 0 ? _a : null;
|
|
30
32
|
const { compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
|
31
33
|
const [newId, setName] = (0, react_1.useState)(() => {
|
|
32
34
|
return resolved.result.id;
|
|
@@ -55,7 +57,7 @@ const RenameCompositionLoaded = () => {
|
|
|
55
57
|
jsx_runtime_1.jsx(RemInput_1.RemotionInput, { value: newId, onChange: onNameChange, type: "text", autoFocus: true, placeholder: "Composition ID", status: "ok", rightAlign: true }), compNameErrMessage ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
|
|
56
58
|
jsx_runtime_1.jsx(layout_1.Spacing, { y: 1, block: true }), jsx_runtime_1.jsx(ValidationMessage_1.ValidationMessage, { align: "flex-start", message: compNameErrMessage, type: "error" })
|
|
57
59
|
] })) : null] }) })
|
|
58
|
-
] }) }), jsx_runtime_1.jsx(ModalFooter_1.ModalFooterContainer, { children: jsx_runtime_1.jsx(CodemodFooter_1.CodemodFooter, { loadingNotification: 'Renaming...', errorNotification: 'Could not rename composition', successNotification: `Renamed to ${newId}`, genericSubmitLabel: 'Rename', submitLabel: ({ relativeRootPath }) => `Modify ${relativeRootPath}`, codemod: codemod, valid: valid, onSuccess: null }) })
|
|
60
|
+
] }) }), jsx_runtime_1.jsx(ModalFooter_1.ModalFooterContainer, { children: jsx_runtime_1.jsx(CodemodFooter_1.CodemodFooter, { loadingNotification: 'Renaming...', errorNotification: 'Could not rename composition', successNotification: `Renamed to ${newId}`, genericSubmitLabel: 'Rename', submitLabel: ({ relativeRootPath }) => `Modify ${relativeRootPath}`, codemod: codemod, stack: compositionStack, valid: valid, onSuccess: null }) })
|
|
59
61
|
] })
|
|
60
62
|
] }));
|
|
61
63
|
};
|
|
@@ -97,9 +97,10 @@ export declare const subscribeToFileExistenceWatcher: ({ file, clientId, }: {
|
|
|
97
97
|
export declare const openInFileExplorer: ({ directory }: {
|
|
98
98
|
directory: string;
|
|
99
99
|
}) => Promise<void>;
|
|
100
|
-
export declare const applyCodemod: ({ codemod, dryRun, signal, }: {
|
|
100
|
+
export declare const applyCodemod: ({ codemod, dryRun, symbolicatedStack, signal, }: {
|
|
101
101
|
codemod: RecastCodemod;
|
|
102
102
|
dryRun: boolean;
|
|
103
|
+
symbolicatedStack: import("@remotion/studio-shared").SymbolicatedStackFrame | null;
|
|
103
104
|
signal: AbortSignal;
|
|
104
105
|
}) => Promise<import("@remotion/studio-shared").ApplyCodemodResponse>;
|
|
105
106
|
export declare const removeRenderJob: (job: RenderJob) => Promise<undefined>;
|
|
@@ -133,10 +133,11 @@ const openInFileExplorer = ({ directory }) => {
|
|
|
133
133
|
return (0, call_api_1.callApi)('/api/open-in-file-explorer', body);
|
|
134
134
|
};
|
|
135
135
|
exports.openInFileExplorer = openInFileExplorer;
|
|
136
|
-
const applyCodemod = ({ codemod, dryRun, signal, }) => {
|
|
136
|
+
const applyCodemod = ({ codemod, dryRun, symbolicatedStack, signal, }) => {
|
|
137
137
|
const body = {
|
|
138
138
|
codemod,
|
|
139
139
|
dryRun,
|
|
140
|
+
symbolicatedStack,
|
|
140
141
|
};
|
|
141
142
|
return (0, call_api_1.callApi)('/api/apply-codemod', body, signal);
|
|
142
143
|
};
|
|
@@ -6,6 +6,9 @@ const react_1 = require("react");
|
|
|
6
6
|
const remotion_1 = require("remotion");
|
|
7
7
|
const client_id_1 = require("../../helpers/client-id");
|
|
8
8
|
const timeline_layout_1 = require("../../helpers/timeline-layout");
|
|
9
|
+
const call_api_1 = require("../call-api");
|
|
10
|
+
const ContextMenu_1 = require("../ContextMenu");
|
|
11
|
+
const NotificationCenter_1 = require("../Notifications/NotificationCenter");
|
|
9
12
|
const save_effect_prop_1 = require("./save-effect-prop");
|
|
10
13
|
const TimelineExpandArrowButton_1 = require("./TimelineExpandArrowButton");
|
|
11
14
|
const TimelineLayerEye_1 = require("./TimelineLayerEye");
|
|
@@ -37,6 +40,54 @@ const TimelineEffectGroupRow = ({ label, nodePathInfo, effectIndex, effectSchema
|
|
|
37
40
|
return false;
|
|
38
41
|
}, [disabledStatus]);
|
|
39
42
|
const canToggle = previewConnected && disabledStatus !== null && disabledStatus.canUpdate;
|
|
43
|
+
const deleteDisabled = !previewConnected ||
|
|
44
|
+
effectStatus.type !== 'can-update-effect' ||
|
|
45
|
+
!validatedLocation.source;
|
|
46
|
+
const onDeleteEffectFromSource = (0, react_1.useCallback)(async () => {
|
|
47
|
+
if (deleteDisabled) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
const result = await (0, call_api_1.callApi)('/api/delete-effect', {
|
|
52
|
+
fileName: validatedLocation.source,
|
|
53
|
+
sequenceNodePath: nodePath,
|
|
54
|
+
effectIndex,
|
|
55
|
+
});
|
|
56
|
+
if (result.success) {
|
|
57
|
+
(0, NotificationCenter_1.showNotification)('Removed effect from source file', 2000);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
(0, NotificationCenter_1.showNotification)(result.reason, 4000);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
(0, NotificationCenter_1.showNotification)(err.message, 4000);
|
|
65
|
+
}
|
|
66
|
+
}, [deleteDisabled, effectIndex, nodePath, validatedLocation.source]);
|
|
67
|
+
const contextMenuValues = (0, react_1.useMemo)(() => {
|
|
68
|
+
if (!previewConnected) {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
return [
|
|
72
|
+
{
|
|
73
|
+
type: 'item',
|
|
74
|
+
id: 'delete-effect',
|
|
75
|
+
keyHint: null,
|
|
76
|
+
label: 'Delete',
|
|
77
|
+
leftItem: null,
|
|
78
|
+
disabled: deleteDisabled,
|
|
79
|
+
onClick: () => {
|
|
80
|
+
if (deleteDisabled) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
onDeleteEffectFromSource();
|
|
84
|
+
},
|
|
85
|
+
quickSwitcherLabel: null,
|
|
86
|
+
subMenu: null,
|
|
87
|
+
value: 'delete-effect',
|
|
88
|
+
},
|
|
89
|
+
];
|
|
90
|
+
}, [deleteDisabled, onDeleteEffectFromSource, previewConnected]);
|
|
40
91
|
const onToggle = (0, react_1.useCallback)((type) => {
|
|
41
92
|
if (!canToggle || previewServerState.type !== 'connected') {
|
|
42
93
|
return;
|
|
@@ -71,6 +122,7 @@ const TimelineEffectGroupRow = ({ label, nodePathInfo, effectIndex, effectSchema
|
|
|
71
122
|
height: timeline_layout_1.TREE_GROUP_ROW_HEIGHT,
|
|
72
123
|
paddingRight: timeline_layout_1.EXPANDED_SECTION_PADDING_RIGHT,
|
|
73
124
|
}), []);
|
|
74
|
-
|
|
125
|
+
const row = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: canToggle ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: "effect", hidden: isDisabled, onInvoked: onToggle })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowButton, { isExpanded: isExpanded, onClick: () => toggleTrack(nodePathInfo), label: `${label} section`, disabled: false }), style: rowStyle, children: jsx_runtime_1.jsx("span", { style: rowLabel, children: label }) }));
|
|
126
|
+
return previewConnected ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, children: row })) : (row);
|
|
75
127
|
};
|
|
76
128
|
exports.TimelineEffectGroupRow = TimelineEffectGroupRow;
|
|
@@ -7,14 +7,13 @@ const remotion_1 = require("remotion");
|
|
|
7
7
|
const colors_1 = require("../../helpers/colors");
|
|
8
8
|
const timeline_layout_1 = require("../../helpers/timeline-layout");
|
|
9
9
|
const render_frame_1 = require("../../state/render-frame");
|
|
10
|
-
const SplitterHandle_1 = require("../Splitter/SplitterHandle");
|
|
11
10
|
const TimeValue_1 = require("../TimeValue");
|
|
12
11
|
const timeline_refs_1 = require("./timeline-refs");
|
|
13
12
|
const timeline_scroll_logic_1 = require("./timeline-scroll-logic");
|
|
14
13
|
const TimelineWidthProvider_1 = require("./TimelineWidthProvider");
|
|
15
14
|
exports.TIMELINE_TIME_INDICATOR_HEIGHT = 39;
|
|
16
15
|
const container = {
|
|
17
|
-
height: exports.TIMELINE_TIME_INDICATOR_HEIGHT
|
|
16
|
+
height: exports.TIMELINE_TIME_INDICATOR_HEIGHT,
|
|
18
17
|
boxShadow: `0 0 4px ${colors_1.TIMELINE_BACKGROUND}`,
|
|
19
18
|
position: 'absolute',
|
|
20
19
|
backgroundColor: colors_1.TIMELINE_BACKGROUND,
|
|
@@ -94,10 +93,8 @@ const TimelineTimeIndicatorsInner = ({ windowWidth, durationInFrames, fps }) =>
|
|
|
94
93
|
const style = (0, react_1.useMemo)(() => {
|
|
95
94
|
return {
|
|
96
95
|
...container,
|
|
97
|
-
width: windowWidth
|
|
96
|
+
width: windowWidth,
|
|
98
97
|
overflow: 'hidden',
|
|
99
|
-
// Since
|
|
100
|
-
marginLeft: SplitterHandle_1.SPLITTER_HANDLE_SIZE / 2,
|
|
101
98
|
pointerEvents: 'none',
|
|
102
99
|
};
|
|
103
100
|
}, [windowWidth]);
|
|
@@ -119,9 +116,7 @@ const TimelineTimeIndicatorsInner = ({ windowWidth, durationInFrames, fps }) =>
|
|
|
119
116
|
frame: index * fps,
|
|
120
117
|
style: {
|
|
121
118
|
...secondTick,
|
|
122
|
-
left: frameInterval * index * fps +
|
|
123
|
-
timeline_layout_1.TIMELINE_PADDING -
|
|
124
|
-
SplitterHandle_1.SPLITTER_HANDLE_SIZE / 2,
|
|
119
|
+
left: frameInterval * index * fps + timeline_layout_1.TIMELINE_PADDING,
|
|
125
120
|
},
|
|
126
121
|
showTime: index > 0,
|
|
127
122
|
};
|
|
@@ -134,9 +129,7 @@ const TimelineTimeIndicatorsInner = ({ windowWidth, durationInFrames, fps }) =>
|
|
|
134
129
|
frame: index,
|
|
135
130
|
style: {
|
|
136
131
|
...tick,
|
|
137
|
-
left: frameInterval * index +
|
|
138
|
-
timeline_layout_1.TIMELINE_PADDING -
|
|
139
|
-
SplitterHandle_1.SPLITTER_HANDLE_SIZE / 2,
|
|
132
|
+
left: frameInterval * index + timeline_layout_1.TIMELINE_PADDING,
|
|
140
133
|
height: index % fps === 0
|
|
141
134
|
? 10
|
|
142
135
|
: (index / frameMarkerEveryNth) % 2 === 0
|
|
@@ -7,6 +7,7 @@ const react_1 = require("react");
|
|
|
7
7
|
const remotion_1 = require("remotion");
|
|
8
8
|
const timeline_layout_1 = require("../../helpers/timeline-layout");
|
|
9
9
|
const AudioWaveform_1 = require("../AudioWaveform");
|
|
10
|
+
const get_timeline_video_info_widths_1 = require("./get-timeline-video-info-widths");
|
|
10
11
|
const FILMSTRIP_HEIGHT = timeline_layout_1.TIMELINE_LAYER_HEIGHT_IMAGE - 2;
|
|
11
12
|
const outerStyle = {
|
|
12
13
|
width: '100%',
|
|
@@ -16,7 +17,6 @@ const outerStyle = {
|
|
|
16
17
|
};
|
|
17
18
|
const filmstripContainerStyle = {
|
|
18
19
|
height: FILMSTRIP_HEIGHT,
|
|
19
|
-
width: '100%',
|
|
20
20
|
backgroundColor: 'rgba(0, 0, 0, 0.3)',
|
|
21
21
|
display: 'flex',
|
|
22
22
|
borderTopLeftRadius: 2,
|
|
@@ -28,6 +28,14 @@ const TimelineVideoInfo = ({ src, visualizationWidth, naturalWidth, trimBefore,
|
|
|
28
28
|
const ref = (0, react_1.useRef)(null);
|
|
29
29
|
const [error, setError] = (0, react_1.useState)(null);
|
|
30
30
|
const aspectRatio = (0, react_1.useRef)((0, timeline_utils_1.getAspectRatioFromCache)(src));
|
|
31
|
+
const { mediaVisualizationWidth, mediaNaturalWidth } = (0, react_1.useMemo)(() => {
|
|
32
|
+
return (0, get_timeline_video_info_widths_1.getTimelineVideoInfoWidths)({
|
|
33
|
+
visualizationWidth,
|
|
34
|
+
naturalWidth,
|
|
35
|
+
premountWidth,
|
|
36
|
+
postmountWidth,
|
|
37
|
+
});
|
|
38
|
+
}, [naturalWidth, postmountWidth, premountWidth, visualizationWidth]);
|
|
31
39
|
// for rendering frames
|
|
32
40
|
(0, react_1.useEffect)(() => {
|
|
33
41
|
if (error) {
|
|
@@ -39,7 +47,7 @@ const TimelineVideoInfo = ({ src, visualizationWidth, naturalWidth, trimBefore,
|
|
|
39
47
|
}
|
|
40
48
|
const controller = new AbortController();
|
|
41
49
|
const canvas = document.createElement('canvas');
|
|
42
|
-
canvas.width =
|
|
50
|
+
canvas.width = mediaVisualizationWidth;
|
|
43
51
|
canvas.height = FILMSTRIP_HEIGHT;
|
|
44
52
|
const ctx = canvas.getContext('2d');
|
|
45
53
|
if (!ctx) {
|
|
@@ -47,7 +55,7 @@ const TimelineVideoInfo = ({ src, visualizationWidth, naturalWidth, trimBefore,
|
|
|
47
55
|
}
|
|
48
56
|
current.appendChild(canvas);
|
|
49
57
|
const loopWidth = (0, timeline_utils_1.getLoopDisplayWidth)({
|
|
50
|
-
visualizationWidth:
|
|
58
|
+
visualizationWidth: mediaNaturalWidth,
|
|
51
59
|
loopDisplay,
|
|
52
60
|
});
|
|
53
61
|
const shouldRepeatVideo = (0, timeline_utils_1.shouldTileLoopDisplay)(loopDisplay);
|
|
@@ -85,7 +93,9 @@ const TimelineVideoInfo = ({ src, visualizationWidth, naturalWidth, trimBefore,
|
|
|
85
93
|
// Trim is applied first, then playbackRate. Each composition frame
|
|
86
94
|
// advances the source video by `playbackRate` source frames.
|
|
87
95
|
const toSeconds = fromSeconds + (visibleDurationInFrames * playbackRate) / fps;
|
|
88
|
-
const targetWidth = shouldRepeatVideo
|
|
96
|
+
const targetWidth = shouldRepeatVideo
|
|
97
|
+
? targetCanvas.width
|
|
98
|
+
: mediaNaturalWidth;
|
|
89
99
|
if (aspectRatio.current !== null) {
|
|
90
100
|
(0, timeline_utils_1.ensureSlots)({
|
|
91
101
|
filledSlots,
|
|
@@ -207,13 +217,20 @@ const TimelineVideoInfo = ({ src, visualizationWidth, naturalWidth, trimBefore,
|
|
|
207
217
|
error,
|
|
208
218
|
fps,
|
|
209
219
|
loopDisplay,
|
|
210
|
-
|
|
220
|
+
mediaNaturalWidth,
|
|
221
|
+
mediaVisualizationWidth,
|
|
211
222
|
playbackRate,
|
|
212
223
|
src,
|
|
213
224
|
trimBefore,
|
|
214
|
-
visualizationWidth,
|
|
215
225
|
]);
|
|
216
|
-
const audioWidth =
|
|
226
|
+
const audioWidth = mediaVisualizationWidth;
|
|
227
|
+
const filmstripStyle = (0, react_1.useMemo)(() => {
|
|
228
|
+
return {
|
|
229
|
+
...filmstripContainerStyle,
|
|
230
|
+
width: mediaVisualizationWidth,
|
|
231
|
+
marginLeft: premountWidth,
|
|
232
|
+
};
|
|
233
|
+
}, [mediaVisualizationWidth, premountWidth]);
|
|
217
234
|
const audioStyle = (0, react_1.useMemo)(() => {
|
|
218
235
|
return {
|
|
219
236
|
height: timeline_layout_1.TIMELINE_LAYER_HEIGHT_AUDIO,
|
|
@@ -223,7 +240,7 @@ const TimelineVideoInfo = ({ src, visualizationWidth, naturalWidth, trimBefore,
|
|
|
223
240
|
};
|
|
224
241
|
}, [audioWidth, premountWidth]);
|
|
225
242
|
return (jsx_runtime_1.jsxs("div", { style: outerStyle, children: [
|
|
226
|
-
jsx_runtime_1.jsx("div", { ref: ref, style:
|
|
243
|
+
jsx_runtime_1.jsx("div", { ref: ref, style: filmstripStyle }), jsx_runtime_1.jsx("div", { style: audioStyle, children: jsx_runtime_1.jsx(AudioWaveform_1.AudioWaveform, { src: src, visualizationWidth: audioWidth, startFrom: trimBefore, durationInFrames: durationInFrames, volume: volume, doesVolumeChange: doesVolumeChange, playbackRate: playbackRate, loopDisplay: loopDisplay }) })
|
|
227
244
|
] }));
|
|
228
245
|
};
|
|
229
246
|
exports.TimelineVideoInfo = TimelineVideoInfo;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const getTimelineVideoInfoWidths: ({ visualizationWidth, naturalWidth, premountWidth, postmountWidth, }: {
|
|
2
|
+
visualizationWidth: number;
|
|
3
|
+
naturalWidth: number;
|
|
4
|
+
premountWidth: number;
|
|
5
|
+
postmountWidth: number;
|
|
6
|
+
}) => {
|
|
7
|
+
mediaVisualizationWidth: number;
|
|
8
|
+
mediaNaturalWidth: number;
|
|
9
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getTimelineVideoInfoWidths = void 0;
|
|
4
|
+
const getTimelineVideoInfoWidths = ({ visualizationWidth, naturalWidth, premountWidth, postmountWidth, }) => {
|
|
5
|
+
const mountWidth = premountWidth + postmountWidth;
|
|
6
|
+
return {
|
|
7
|
+
mediaVisualizationWidth: Math.max(0, visualizationWidth - mountWidth),
|
|
8
|
+
mediaNaturalWidth: Math.max(0, naturalWidth - mountWidth),
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
exports.getTimelineVideoInfoWidths = getTimelineVideoInfoWidths;
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useResolvedStack = void 0;
|
|
3
|
+
exports.useResolvedStack = exports.hasResolvedStack = void 0;
|
|
4
4
|
const react_1 = require("react");
|
|
5
5
|
const remotion_1 = require("remotion");
|
|
6
6
|
const get_stack_1 = require("./TimelineStack/get-stack");
|
|
7
7
|
const resolvedCache = new Map();
|
|
8
|
+
const hasResolvedStack = (stack) => {
|
|
9
|
+
if (!stack) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
return resolvedCache.has(stack);
|
|
13
|
+
};
|
|
14
|
+
exports.hasResolvedStack = hasResolvedStack;
|
|
8
15
|
const inFlight = new Set();
|
|
9
16
|
const subscribers = new Map();
|
|
10
17
|
const useResolvedStack = (stack) => {
|
|
@@ -40,6 +47,8 @@ const useResolvedStack = (stack) => {
|
|
|
40
47
|
.catch((err) => {
|
|
41
48
|
// eslint-disable-next-line no-console
|
|
42
49
|
console.error('Could not get original location of Sequence', err);
|
|
50
|
+
resolvedCache.set(stack, null);
|
|
51
|
+
subs.forEach((fn) => fn(null));
|
|
43
52
|
})
|
|
44
53
|
.finally(() => {
|
|
45
54
|
inFlight.delete(stack);
|