@remotion/studio 4.0.438 → 4.0.440
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/Studio.js +2 -2
- package/dist/api/helpers/calc-new-props.js +5 -8
- package/dist/api/update-default-props.d.ts +7 -3
- package/dist/api/update-default-props.js +7 -21
- package/dist/api/visual-control.js +6 -0
- package/dist/components/DefaultPropsEditor.d.ts +8 -0
- package/dist/components/DefaultPropsEditor.js +15 -0
- package/dist/components/Editor.js +0 -14
- package/dist/components/EditorContexts.js +6 -3
- package/dist/components/KeyboardShortcutsExplainer.js +6 -2
- package/dist/components/MenuBuildIndicator.js +1 -0
- package/dist/components/MenuToolbar.js +3 -1
- package/dist/components/NewComposition/InputDragger.js +2 -2
- package/dist/components/NewComposition/RemTextarea.js +4 -0
- package/dist/components/ObserveDefaultPropsContext.d.ts +11 -0
- package/dist/components/ObserveDefaultPropsContext.js +120 -0
- package/dist/components/OptionsPanel.js +90 -28
- package/dist/components/RenderModal/CrfSetting.d.ts +1 -1
- package/dist/components/RenderModal/DataEditor.d.ts +4 -5
- package/dist/components/RenderModal/DataEditor.js +9 -111
- package/dist/components/RenderModal/RenderModalJSONPropsEditor.d.ts +1 -1
- package/dist/components/RenderModal/RenderModalJSONPropsEditor.js +52 -48
- package/dist/components/RenderModal/SchemaEditor/Fieldset.d.ts +0 -1
- package/dist/components/RenderModal/SchemaEditor/SchemaEditor.d.ts +4 -9
- package/dist/components/RenderModal/SchemaEditor/SchemaEditor.js +2 -61
- package/dist/components/RenderModal/SchemaEditor/SchemaErrorMessages.d.ts +0 -1
- package/dist/components/RenderModal/SchemaEditor/SchemaErrorMessages.js +2 -3
- package/dist/components/RenderModal/SchemaEditor/SchemaLabel.d.ts +0 -6
- package/dist/components/RenderModal/SchemaEditor/SchemaLabel.js +2 -5
- package/dist/components/RenderModal/SchemaEditor/SchemaSeparationLine.d.ts +3 -1
- package/dist/components/RenderModal/SchemaEditor/SchemaSeparationLine.js +1 -1
- package/dist/components/RenderModal/SchemaEditor/ZodArrayEditor.d.ts +1 -6
- package/dist/components/RenderModal/SchemaEditor/ZodArrayEditor.js +15 -26
- package/dist/components/RenderModal/SchemaEditor/ZodArrayItemEditor.d.ts +0 -5
- package/dist/components/RenderModal/SchemaEditor/ZodArrayItemEditor.js +7 -12
- package/dist/components/RenderModal/SchemaEditor/ZodBooleanEditor.d.ts +0 -7
- package/dist/components/RenderModal/SchemaEditor/ZodBooleanEditor.js +5 -15
- package/dist/components/RenderModal/SchemaEditor/ZodColorEditor.d.ts +1 -6
- package/dist/components/RenderModal/SchemaEditor/ZodColorEditor.js +30 -28
- package/dist/components/RenderModal/SchemaEditor/ZodDateEditor.d.ts +1 -6
- package/dist/components/RenderModal/SchemaEditor/ZodDateEditor.js +13 -17
- package/dist/components/RenderModal/SchemaEditor/ZodDefaultEditor.d.ts +0 -5
- package/dist/components/RenderModal/SchemaEditor/ZodDefaultEditor.js +2 -2
- package/dist/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.d.ts +1 -6
- package/dist/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.js +13 -28
- package/dist/components/RenderModal/SchemaEditor/ZodEffectEditor.d.ts +1 -5
- package/dist/components/RenderModal/SchemaEditor/ZodEffectEditor.js +11 -12
- package/dist/components/RenderModal/SchemaEditor/ZodEnumEditor.d.ts +1 -5
- package/dist/components/RenderModal/SchemaEditor/ZodEnumEditor.js +12 -16
- package/dist/components/RenderModal/SchemaEditor/ZodFieldValidation.d.ts +2 -2
- package/dist/components/RenderModal/SchemaEditor/ZodFieldValidation.js +1 -2
- package/dist/components/RenderModal/SchemaEditor/ZodMatrixEditor.d.ts +1 -6
- package/dist/components/RenderModal/SchemaEditor/ZodMatrixEditor.js +20 -30
- package/dist/components/RenderModal/SchemaEditor/ZodNonEditableValue.d.ts +0 -2
- package/dist/components/RenderModal/SchemaEditor/ZodNonEditableValue.js +3 -6
- package/dist/components/RenderModal/SchemaEditor/ZodNullableEditor.d.ts +0 -5
- package/dist/components/RenderModal/SchemaEditor/ZodNullableEditor.js +2 -2
- package/dist/components/RenderModal/SchemaEditor/ZodNumberEditor.d.ts +1 -6
- package/dist/components/RenderModal/SchemaEditor/ZodNumberEditor.js +16 -21
- package/dist/components/RenderModal/SchemaEditor/ZodObjectEditor.d.ts +2 -7
- package/dist/components/RenderModal/SchemaEditor/ZodObjectEditor.js +27 -49
- package/dist/components/RenderModal/SchemaEditor/ZodOptionalEditor.d.ts +0 -5
- package/dist/components/RenderModal/SchemaEditor/ZodOptionalEditor.js +2 -2
- package/dist/components/RenderModal/SchemaEditor/ZodOrNullishEditor.d.ts +1 -6
- package/dist/components/RenderModal/SchemaEditor/ZodOrNullishEditor.js +8 -15
- package/dist/components/RenderModal/SchemaEditor/ZodStaticFileEditor.d.ts +1 -6
- package/dist/components/RenderModal/SchemaEditor/ZodStaticFileEditor.js +10 -15
- package/dist/components/RenderModal/SchemaEditor/ZodStringEditor.d.ts +1 -6
- package/dist/components/RenderModal/SchemaEditor/ZodStringEditor.js +13 -17
- package/dist/components/RenderModal/SchemaEditor/ZodSwitch.d.ts +3 -6
- package/dist/components/RenderModal/SchemaEditor/ZodSwitch.js +27 -27
- package/dist/components/RenderModal/SchemaEditor/ZodTextareaEditor.d.ts +0 -5
- package/dist/components/RenderModal/SchemaEditor/ZodTextareaEditor.js +45 -17
- package/dist/components/RenderModal/SchemaEditor/ZodTupleEditor.d.ts +1 -6
- package/dist/components/RenderModal/SchemaEditor/ZodTupleEditor.js +15 -26
- package/dist/components/RenderModal/SchemaEditor/ZodTupleItemEditor.d.ts +0 -5
- package/dist/components/RenderModal/SchemaEditor/ZodTupleItemEditor.js +4 -11
- package/dist/components/RenderModal/SchemaEditor/ZodUnionEditor.d.ts +0 -5
- package/dist/components/RenderModal/SchemaEditor/ZodUnionEditor.js +6 -6
- package/dist/components/RenderModal/ServerRenderModal.js +9 -3
- package/dist/components/RenderModal/WebRenderModal.js +9 -3
- package/dist/components/RenderModal/get-default-codecs.d.ts +5 -5
- package/dist/components/RenderModal/get-render-modal-warnings.d.ts +1 -2
- package/dist/components/RenderModal/get-render-modal-warnings.js +4 -6
- package/dist/components/RenderModal/human-readable-codec.d.ts +1 -1
- package/dist/components/RenderModal/human-readable-codec.js +3 -0
- package/dist/components/RenderModal/out-name-checker.d.ts +1 -1
- package/dist/components/RenderQueue/actions.d.ts +2 -3
- package/dist/components/RenderQueue/actions.js +1 -13
- package/dist/components/Timeline/Timeline.js +1 -1
- package/dist/components/Timeline/TimelineExpandedSection.js +7 -1
- package/dist/components/Timeline/TimelineFieldRow.d.ts +1 -0
- package/dist/components/Timeline/TimelineFieldRow.js +25 -3
- package/dist/components/Timeline/TimelineImageInfo.d.ts +5 -0
- package/dist/components/Timeline/TimelineImageInfo.js +61 -0
- package/dist/components/Timeline/TimelineListItem.js +1 -2
- package/dist/components/Timeline/TimelineNumberField.js +4 -6
- package/dist/components/Timeline/TimelineRotationField.js +4 -6
- package/dist/components/Timeline/TimelineSequence.js +9 -4
- package/dist/components/Timeline/TimelineStack/index.js +3 -1
- package/dist/components/Timeline/TimelineTracks.js +1 -1
- package/dist/components/Timeline/TimelineTranslateField.js +28 -13
- package/dist/components/TopPanel.js +10 -5
- package/dist/components/UndoRedoButtons.d.ts +2 -0
- package/dist/components/UndoRedoButtons.js +116 -0
- package/dist/components/VisualControls/VisualControlHandle.js +18 -18
- package/dist/components/VisualControls/VisualControlsUndoSync.d.ts +2 -0
- package/dist/components/VisualControls/VisualControlsUndoSync.js +23 -0
- package/dist/error-overlay/react-overlay/listen-to-runtime-errors.js +0 -1
- package/dist/esm/{chunk-ba0scebn.js → chunk-1x2ychmc.js} +4466 -5252
- package/dist/esm/index.mjs +25 -28
- package/dist/esm/internals.mjs +4466 -5252
- package/dist/esm/previewEntry.mjs +4652 -5497
- package/dist/esm/renderEntry.mjs +6 -6
- package/dist/helpers/client-id.js +13 -1
- package/dist/helpers/document-title.d.ts +0 -1
- package/dist/helpers/document-title.js +1 -17
- package/dist/helpers/render-modal-sections.d.ts +1 -1
- package/dist/helpers/timeline-layout.d.ts +1 -1
- package/dist/helpers/timeline-layout.js +1 -1
- package/dist/hot-middleware-client/client.d.ts +1 -6
- package/dist/hot-middleware-client/client.js +22 -73
- package/dist/hot-middleware-client/process-update.d.ts +0 -2
- package/dist/hot-middleware-client/process-update.js +6 -14
- package/dist/icons/redo.d.ts +3 -0
- package/dist/icons/redo.js +8 -0
- package/dist/icons/undo.d.ts +3 -0
- package/dist/icons/undo.js +8 -0
- package/dist/renderEntry.js +7 -6
- package/dist/visual-controls/VisualControls.js +9 -5
- package/dist/visual-controls/get-current-edited-value.js +5 -4
- package/dist/visual-controls/visual-control-store.d.ts +7 -0
- package/dist/visual-controls/visual-control-store.js +22 -0
- package/package.json +9 -9
- package/dist/components/GlobalPropsEditorUpdateButton.d.ts +0 -5
- package/dist/components/GlobalPropsEditorUpdateButton.js +0 -78
- package/dist/components/RenderModal/SchemaEditor/SchemaSaveButton.d.ts +0 -5
- package/dist/components/RenderModal/SchemaEditor/SchemaSaveButton.js +0 -18
- package/dist/components/RenderModal/SchemaEditor/local-state.d.ts +0 -25
- package/dist/components/RenderModal/SchemaEditor/local-state.js +0 -107
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { RenderType } from './RenderModalAdvanced';
|
|
2
2
|
export declare const validateOutnameGui: ({ outName, codec, audioCodec, renderMode, stillImageFormat, separateAudioTo, }: {
|
|
3
3
|
outName: string;
|
|
4
|
-
codec: "aac" | "gif" | "h264" | "h264-mkv" | "h264-ts" | "h265" | "mp3" | "prores" | "vp8" | "vp9" | "wav";
|
|
4
|
+
codec: "aac" | "av1" | "gif" | "h264" | "h264-mkv" | "h264-ts" | "h265" | "mp3" | "prores" | "vp8" | "vp9" | "wav";
|
|
5
5
|
audioCodec: "aac" | "mp3" | "opus" | "pcm-16";
|
|
6
6
|
renderMode: RenderType;
|
|
7
7
|
stillImageFormat: "jpeg" | "pdf" | "png" | "webp" | null;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { EnumPath, RecastCodemod, RenderJob, VisualControlChange } from '@remotion/studio-shared';
|
|
2
2
|
export declare const addStillRenderJob: ({ compositionId, outName, imageFormat, jpegQuality, frame, scale, logLevel, chromiumOptions, delayRenderTimeout, envVariables, inputProps, offthreadVideoCacheSizeInBytes, offthreadVideoThreads, multiProcessOnLinux, beepOnFinish, metadata, chromeMode, mediaCacheSizeInBytes, }: {
|
|
3
3
|
compositionId: string;
|
|
4
4
|
outName: string;
|
|
@@ -50,7 +50,7 @@ export declare const addVideoRenderJob: ({ compositionId, outName, imageFormat,
|
|
|
50
50
|
jpegQuality: number | null;
|
|
51
51
|
scale: number;
|
|
52
52
|
logLevel: "error" | "info" | "trace" | "verbose" | "warn";
|
|
53
|
-
codec: "aac" | "gif" | "h264" | "h264-mkv" | "h264-ts" | "h265" | "mp3" | "prores" | "vp8" | "vp9" | "wav";
|
|
53
|
+
codec: "aac" | "av1" | "gif" | "h264" | "h264-mkv" | "h264-ts" | "h265" | "mp3" | "prores" | "vp8" | "vp9" | "wav";
|
|
54
54
|
concurrency: number;
|
|
55
55
|
crf: number | null;
|
|
56
56
|
startFrame: number;
|
|
@@ -106,7 +106,6 @@ export declare const cancelRenderJob: (job: RenderJob) => Promise<import("@remot
|
|
|
106
106
|
export declare const updateAvailable: (signal: AbortSignal) => Promise<import("@remotion/studio-shared").UpdateAvailableResponse>;
|
|
107
107
|
export declare const getProjectInfo: (signal: AbortSignal) => Promise<import("@remotion/studio-shared").ProjectInfoResponse>;
|
|
108
108
|
export declare const callUpdateDefaultPropsApi: (compositionId: string, defaultProps: Record<string, unknown>, enumPaths: EnumPath[]) => Promise<import("@remotion/studio-shared").UpdateDefaultPropsResponse>;
|
|
109
|
-
export declare const canUpdateDefaultProps: (compositionId: string, readOnlyStudio: boolean) => Promise<CanUpdateDefaultPropsResponse>;
|
|
110
109
|
export declare const applyVisualControlChange: ({ fileName, changes, }: {
|
|
111
110
|
fileName: string;
|
|
112
111
|
changes: VisualControlChange[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.applyVisualControlChange = exports.
|
|
3
|
+
exports.applyVisualControlChange = exports.callUpdateDefaultPropsApi = exports.getProjectInfo = exports.updateAvailable = exports.cancelRenderJob = exports.removeRenderJob = exports.applyCodemod = exports.openInFileExplorer = exports.subscribeToFileExistenceWatcher = exports.unsubscribeFromFileExistenceWatcher = exports.addVideoRenderJob = exports.addSequenceRenderJob = exports.addStillRenderJob = void 0;
|
|
4
4
|
const no_react_1 = require("remotion/no-react");
|
|
5
5
|
const call_api_1 = require("../call-api");
|
|
6
6
|
const addStillRenderJob = ({ compositionId, outName, imageFormat, jpegQuality, frame, scale, logLevel, chromiumOptions, delayRenderTimeout, envVariables, inputProps, offthreadVideoCacheSizeInBytes, offthreadVideoThreads, multiProcessOnLinux, beepOnFinish, metadata, chromeMode, mediaCacheSizeInBytes, }) => {
|
|
@@ -172,18 +172,6 @@ const callUpdateDefaultPropsApi = (compositionId, defaultProps, enumPaths) => {
|
|
|
172
172
|
});
|
|
173
173
|
};
|
|
174
174
|
exports.callUpdateDefaultPropsApi = callUpdateDefaultPropsApi;
|
|
175
|
-
const canUpdateDefaultProps = (compositionId, readOnlyStudio) => {
|
|
176
|
-
if (readOnlyStudio) {
|
|
177
|
-
return Promise.resolve({
|
|
178
|
-
canUpdate: false,
|
|
179
|
-
reason: 'Read-only studio',
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
return (0, call_api_1.callApi)('/api/can-update-default-props', {
|
|
183
|
-
compositionId,
|
|
184
|
-
});
|
|
185
|
-
};
|
|
186
|
-
exports.canUpdateDefaultProps = canUpdateDefaultProps;
|
|
187
175
|
const applyVisualControlChange = ({ fileName, changes, }) => {
|
|
188
176
|
return (0, call_api_1.callApi)('/api/apply-visual-control-change', {
|
|
189
177
|
fileName,
|
|
@@ -100,7 +100,7 @@ const TimelineInner = () => {
|
|
|
100
100
|
var _a;
|
|
101
101
|
const isExpanded = visualModeEnabled && ((_a = expandedTracks[track.sequence.id]) !== null && _a !== void 0 ? _a : false);
|
|
102
102
|
return (acc +
|
|
103
|
-
(0, timeline_layout_1.getTimelineLayerHeight)(track.sequence.type
|
|
103
|
+
(0, timeline_layout_1.getTimelineLayerHeight)(track.sequence.type) +
|
|
104
104
|
Number(timeline_layout_1.TIMELINE_ITEM_BORDER_BOTTOM) +
|
|
105
105
|
(isExpanded
|
|
106
106
|
? (0, timeline_layout_1.getExpandedTrackHeight)(track.sequence.controls) +
|
|
@@ -78,9 +78,15 @@ const TimelineExpandedSection = ({ sequence, originalLocation, nestedDepth, node
|
|
|
78
78
|
height: expandedHeight,
|
|
79
79
|
};
|
|
80
80
|
}, [expandedHeight]);
|
|
81
|
+
const keysToObserve = (0, react_1.useMemo)(() => {
|
|
82
|
+
if (!schemaFields) {
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
return schemaFields.map((f) => f.key);
|
|
86
|
+
}, [schemaFields]);
|
|
81
87
|
return (jsx_runtime_1.jsx("div", { style: style, children: schemaFields
|
|
82
88
|
? schemaFields.map((field, i) => {
|
|
83
|
-
return (jsx_runtime_1.jsxs(react_1.default.Fragment, { children: [i > 0 ? jsx_runtime_1.jsx("div", { style: separator }) : null, jsx_runtime_1.jsx(TimelineFieldRow_1.TimelineFieldRow, { field: field, overrideId: overrideId, validatedLocation: validatedLocation, nestedDepth: nestedDepth, nodePath: nodePath })
|
|
89
|
+
return (jsx_runtime_1.jsxs(react_1.default.Fragment, { children: [i > 0 ? jsx_runtime_1.jsx("div", { style: separator }) : null, jsx_runtime_1.jsx(TimelineFieldRow_1.TimelineFieldRow, { field: field, overrideId: overrideId, validatedLocation: validatedLocation, nestedDepth: nestedDepth, nodePath: nodePath, keysToObserve: keysToObserve })
|
|
84
90
|
] }, field.key));
|
|
85
91
|
})
|
|
86
92
|
: 'No schema' }));
|
|
@@ -18,6 +18,7 @@ const fieldRowBase = {
|
|
|
18
18
|
const fieldName = {
|
|
19
19
|
fontSize: 12,
|
|
20
20
|
color: 'rgba(255, 255, 255, 0.8)',
|
|
21
|
+
userSelect: 'none',
|
|
21
22
|
};
|
|
22
23
|
const fieldLabelRow = {
|
|
23
24
|
flex: '0 0 50%',
|
|
@@ -26,7 +27,7 @@ const fieldLabelRow = {
|
|
|
26
27
|
alignItems: 'center',
|
|
27
28
|
gap: 6,
|
|
28
29
|
};
|
|
29
|
-
const TimelineFieldRow = ({ field, overrideId, validatedLocation, nestedDepth, nodePath }) => {
|
|
30
|
+
const TimelineFieldRow = ({ field, overrideId, validatedLocation, nestedDepth, nodePath, keysToObserve, }) => {
|
|
30
31
|
var _a, _b, _c, _d;
|
|
31
32
|
const { setDragOverrides, clearDragOverrides, dragOverrides, codeValues: allPropStatuses, } = (0, react_1.useContext)(remotion_1.Internals.VisualModeOverridesContext);
|
|
32
33
|
const propStatuses = ((_a = allPropStatuses[overrideId]) !== null && _a !== void 0 ? _a : null);
|
|
@@ -42,6 +43,7 @@ const TimelineFieldRow = ({ field, overrideId, validatedLocation, nestedDepth, n
|
|
|
42
43
|
defaultValue: field.fieldSchema.default,
|
|
43
44
|
shouldResortToDefaultValueIfUndefined: true,
|
|
44
45
|
});
|
|
46
|
+
const { setCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeOverridesContext);
|
|
45
47
|
const onSave = (0, react_1.useCallback)((key, value) => {
|
|
46
48
|
if (!propStatuses || !validatedLocation || !nodePath) {
|
|
47
49
|
return Promise.reject(new Error('Cannot save'));
|
|
@@ -59,8 +61,28 @@ const TimelineFieldRow = ({ field, overrideId, validatedLocation, nestedDepth, n
|
|
|
59
61
|
key,
|
|
60
62
|
value: JSON.stringify(value),
|
|
61
63
|
defaultValue,
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
observedKeys: keysToObserve,
|
|
65
|
+
}).then((data) => {
|
|
66
|
+
if (data.success) {
|
|
67
|
+
if (data.newStatus.canUpdate) {
|
|
68
|
+
setCodeValues(overrideId, data.newStatus.props);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
setCodeValues(overrideId, null);
|
|
72
|
+
}
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
return Promise.reject(new Error(data.reason));
|
|
76
|
+
});
|
|
77
|
+
}, [
|
|
78
|
+
field.fieldSchema.default,
|
|
79
|
+
keysToObserve,
|
|
80
|
+
nodePath,
|
|
81
|
+
overrideId,
|
|
82
|
+
propStatuses,
|
|
83
|
+
setCodeValues,
|
|
84
|
+
validatedLocation,
|
|
85
|
+
]);
|
|
64
86
|
const onDragValueChange = (0, react_1.useCallback)((key, value) => {
|
|
65
87
|
setDragOverrides(overrideId, key, value);
|
|
66
88
|
}, [setDragOverrides, overrideId]);
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TimelineImageInfo = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const timeline_layout_1 = require("../../helpers/timeline-layout");
|
|
7
|
+
const HEIGHT = (0, timeline_layout_1.getTimelineLayerHeight)('image') - 2;
|
|
8
|
+
const containerStyle = {
|
|
9
|
+
height: HEIGHT,
|
|
10
|
+
width: '100%',
|
|
11
|
+
backgroundColor: 'rgba(0, 0, 0, 0.3)',
|
|
12
|
+
display: 'flex',
|
|
13
|
+
borderTopLeftRadius: 2,
|
|
14
|
+
borderBottomLeftRadius: 2,
|
|
15
|
+
};
|
|
16
|
+
const TimelineImageInfo = ({ src, visualizationWidth }) => {
|
|
17
|
+
const ref = (0, react_1.useRef)(null);
|
|
18
|
+
(0, react_1.useEffect)(() => {
|
|
19
|
+
const { current } = ref;
|
|
20
|
+
if (!current) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const canvas = document.createElement('canvas');
|
|
24
|
+
canvas.width = visualizationWidth * window.devicePixelRatio;
|
|
25
|
+
canvas.height = HEIGHT * window.devicePixelRatio;
|
|
26
|
+
canvas.style.width = visualizationWidth + 'px';
|
|
27
|
+
canvas.style.height = HEIGHT + 'px';
|
|
28
|
+
const ctx = canvas.getContext('2d');
|
|
29
|
+
if (!ctx) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
current.appendChild(canvas);
|
|
33
|
+
const img = new Image();
|
|
34
|
+
img.crossOrigin = 'anonymous';
|
|
35
|
+
img.onload = () => {
|
|
36
|
+
const scale = (HEIGHT * window.devicePixelRatio) / img.naturalHeight;
|
|
37
|
+
const scaledWidth = img.naturalWidth * scale;
|
|
38
|
+
const scaledHeight = HEIGHT * window.devicePixelRatio;
|
|
39
|
+
const offscreen = document.createElement('canvas');
|
|
40
|
+
offscreen.width = scaledWidth;
|
|
41
|
+
offscreen.height = scaledHeight;
|
|
42
|
+
const offCtx = offscreen.getContext('2d');
|
|
43
|
+
if (!offCtx) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
offCtx.drawImage(img, 0, 0, scaledWidth, scaledHeight);
|
|
47
|
+
const pattern = ctx.createPattern(offscreen, 'repeat-x');
|
|
48
|
+
if (!pattern) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
ctx.fillStyle = pattern;
|
|
52
|
+
ctx.fillRect(0, 0, visualizationWidth * window.devicePixelRatio, HEIGHT * window.devicePixelRatio);
|
|
53
|
+
};
|
|
54
|
+
img.src = src;
|
|
55
|
+
return () => {
|
|
56
|
+
current.removeChild(canvas);
|
|
57
|
+
};
|
|
58
|
+
}, [src, visualizationWidth]);
|
|
59
|
+
return jsx_runtime_1.jsx("div", { ref: ref, style: containerStyle });
|
|
60
|
+
};
|
|
61
|
+
exports.TimelineImageInfo = TimelineImageInfo;
|
|
@@ -69,8 +69,7 @@ const TimelineListItem = ({ nestedDepth, sequence, isCompact }) => {
|
|
|
69
69
|
}, [sequence.id, setHidden]);
|
|
70
70
|
const outer = (0, react_1.useMemo)(() => {
|
|
71
71
|
return {
|
|
72
|
-
height: (0, timeline_layout_1.getTimelineLayerHeight)(sequence.type
|
|
73
|
-
timeline_layout_1.TIMELINE_ITEM_BORDER_BOTTOM,
|
|
72
|
+
height: (0, timeline_layout_1.getTimelineLayerHeight)(sequence.type) + timeline_layout_1.TIMELINE_ITEM_BORDER_BOTTOM,
|
|
74
73
|
color: 'white',
|
|
75
74
|
fontFamily: 'Arial, Helvetica, sans-serif',
|
|
76
75
|
display: 'flex',
|
|
@@ -12,20 +12,18 @@ const TimelineNumberField = ({ field, effectiveValue, canUpdate, onSave, onDragV
|
|
|
12
12
|
setDragValue(newVal);
|
|
13
13
|
onDragValueChange(field.key, newVal);
|
|
14
14
|
}, [onDragValueChange, field.key]);
|
|
15
|
-
(0, react_1.useEffect)(() => {
|
|
16
|
-
setDragValue(null);
|
|
17
|
-
onDragEnd();
|
|
18
|
-
}, [field.currentValue, onDragEnd]);
|
|
19
15
|
const onValueChangeEnd = (0, react_1.useCallback)((newVal) => {
|
|
20
16
|
if (canUpdate && newVal !== codeValue) {
|
|
21
|
-
onSave(field.key, newVal).
|
|
17
|
+
onSave(field.key, newVal).finally(() => {
|
|
22
18
|
setDragValue(null);
|
|
19
|
+
onDragEnd();
|
|
23
20
|
});
|
|
24
21
|
}
|
|
25
22
|
else {
|
|
26
23
|
setDragValue(null);
|
|
24
|
+
onDragEnd();
|
|
27
25
|
}
|
|
28
|
-
}, [canUpdate, onSave, field.key, codeValue]);
|
|
26
|
+
}, [canUpdate, onSave, field.key, codeValue, onDragEnd]);
|
|
29
27
|
const onTextChange = (0, react_1.useCallback)((newVal) => {
|
|
30
28
|
if (canUpdate) {
|
|
31
29
|
const parsed = Number(newVal);
|
|
@@ -22,21 +22,19 @@ const TimelineRotationField = ({ field, effectiveValue, codeValue, canUpdate, on
|
|
|
22
22
|
setDragValue(newVal);
|
|
23
23
|
onDragValueChange(field.key, `${newVal}deg`);
|
|
24
24
|
}, [onDragValueChange, field.key]);
|
|
25
|
-
(0, react_1.useEffect)(() => {
|
|
26
|
-
setDragValue(null);
|
|
27
|
-
onDragEnd();
|
|
28
|
-
}, [field.currentValue, onDragEnd]);
|
|
29
25
|
const onValueChangeEnd = (0, react_1.useCallback)((newVal) => {
|
|
30
26
|
const newStr = `${newVal}deg`;
|
|
31
27
|
if (canUpdate && newStr !== codeValue) {
|
|
32
|
-
onSave(field.key, newStr).
|
|
28
|
+
onSave(field.key, newStr).finally(() => {
|
|
33
29
|
setDragValue(null);
|
|
30
|
+
onDragEnd();
|
|
34
31
|
});
|
|
35
32
|
}
|
|
36
33
|
else {
|
|
37
34
|
setDragValue(null);
|
|
35
|
+
onDragEnd();
|
|
38
36
|
}
|
|
39
|
-
}, [canUpdate, onSave, field.key, codeValue]);
|
|
37
|
+
}, [canUpdate, onSave, field.key, codeValue, onDragEnd]);
|
|
40
38
|
const onTextChange = (0, react_1.useCallback)((newVal) => {
|
|
41
39
|
if (canUpdate) {
|
|
42
40
|
const parsed = Number(newVal);
|
|
@@ -10,11 +10,13 @@ const timeline_layout_1 = require("../../helpers/timeline-layout");
|
|
|
10
10
|
const use_max_media_duration_1 = require("../../helpers/use-max-media-duration");
|
|
11
11
|
const AudioWaveform_1 = require("../AudioWaveform");
|
|
12
12
|
const LoopedTimelineIndicators_1 = require("./LoopedTimelineIndicators");
|
|
13
|
+
const TimelineImageInfo_1 = require("./TimelineImageInfo");
|
|
13
14
|
const TimelineSequenceFrame_1 = require("./TimelineSequenceFrame");
|
|
14
15
|
const TimelineVideoInfo_1 = require("./TimelineVideoInfo");
|
|
15
16
|
const TimelineWidthProvider_1 = require("./TimelineWidthProvider");
|
|
16
17
|
const AUDIO_GRADIENT = 'linear-gradient(rgb(16 171 58), rgb(43 165 63) 60%)';
|
|
17
18
|
const VIDEO_GRADIENT = 'linear-gradient(to top, #8e44ad, #9b59b6)';
|
|
19
|
+
const IMAGE_GRADIENT = 'linear-gradient(to top, #2980b9, #3498db)';
|
|
18
20
|
const TimelineSequence = ({ s }) => {
|
|
19
21
|
const windowWidth = (0, react_1.useContext)(TimelineWidthProvider_1.TimelineWidthContext);
|
|
20
22
|
if (windowWidth === null) {
|
|
@@ -51,7 +53,7 @@ const Inner = ({ s, windowWidth }) => {
|
|
|
51
53
|
? s.loopDisplay.durationInFrames * s.loopDisplay.numberOfTimes
|
|
52
54
|
: s.duration,
|
|
53
55
|
startFrom: s.loopDisplay ? s.from + s.loopDisplay.startOffset : s.from,
|
|
54
|
-
startFromMedia: s.type === 'sequence' ? 0 : s.startMediaFrom,
|
|
56
|
+
startFromMedia: s.type === 'sequence' || s.type === 'image' ? 0 : s.startMediaFrom,
|
|
55
57
|
maxMediaDuration,
|
|
56
58
|
video,
|
|
57
59
|
windowWidth,
|
|
@@ -65,11 +67,13 @@ const Inner = ({ s, windowWidth }) => {
|
|
|
65
67
|
? AUDIO_GRADIENT
|
|
66
68
|
: s.type === 'video'
|
|
67
69
|
? VIDEO_GRADIENT
|
|
68
|
-
:
|
|
70
|
+
: s.type === 'image'
|
|
71
|
+
? IMAGE_GRADIENT
|
|
72
|
+
: colors_1.BLUE,
|
|
69
73
|
border: get_timeline_sequence_layout_1.SEQUENCE_BORDER_WIDTH + 'px solid rgba(255, 255, 255, 0.2)',
|
|
70
74
|
borderRadius: 2,
|
|
71
75
|
position: 'absolute',
|
|
72
|
-
height: (0, timeline_layout_1.getTimelineLayerHeight)(s.type
|
|
76
|
+
height: (0, timeline_layout_1.getTimelineLayerHeight)(s.type),
|
|
73
77
|
marginLeft,
|
|
74
78
|
width,
|
|
75
79
|
color: 'white',
|
|
@@ -103,8 +107,9 @@ const Inner = ({ s, windowWidth }) => {
|
|
|
103
107
|
)`,
|
|
104
108
|
position: 'absolute',
|
|
105
109
|
right: 0,
|
|
106
|
-
} })) : null, s.type === 'audio' ? (jsx_runtime_1.jsx(AudioWaveform_1.AudioWaveform, { src: s.src, doesVolumeChange: s.doesVolumeChange, visualizationWidth: width, startFrom: s.startMediaFrom, durationInFrames: s.duration, volume: s.volume, playbackRate: s.playbackRate })) : null, s.type === 'video' ? (jsx_runtime_1.jsx(TimelineVideoInfo_1.TimelineVideoInfo, { src: s.src, visualizationWidth: width, naturalWidth: naturalWidth, trimBefore: s.startMediaFrom, durationInFrames: s.duration, playbackRate: s.playbackRate })) : null, s.loopDisplay === undefined ? null : (jsx_runtime_1.jsx(LoopedTimelineIndicators_1.LoopedTimelineIndicator, { loops: s.loopDisplay.numberOfTimes })), s.type !== 'audio' &&
|
|
110
|
+
} })) : null, s.type === 'audio' ? (jsx_runtime_1.jsx(AudioWaveform_1.AudioWaveform, { src: s.src, doesVolumeChange: s.doesVolumeChange, visualizationWidth: width, startFrom: s.startMediaFrom, durationInFrames: s.duration, volume: s.volume, playbackRate: s.playbackRate })) : null, s.type === 'video' ? (jsx_runtime_1.jsx(TimelineVideoInfo_1.TimelineVideoInfo, { src: s.src, visualizationWidth: width, naturalWidth: naturalWidth, trimBefore: s.startMediaFrom, durationInFrames: s.duration, playbackRate: s.playbackRate })) : null, s.type === 'image' ? (jsx_runtime_1.jsx(TimelineImageInfo_1.TimelineImageInfo, { src: s.src, visualizationWidth: width })) : null, s.loopDisplay === undefined ? null : (jsx_runtime_1.jsx(LoopedTimelineIndicators_1.LoopedTimelineIndicator, { loops: s.loopDisplay.numberOfTimes })), s.type !== 'audio' &&
|
|
107
111
|
s.type !== 'video' &&
|
|
112
|
+
s.type !== 'image' &&
|
|
108
113
|
s.loopDisplay === undefined &&
|
|
109
114
|
(isInRange || isPremounting || isPostmounting) ? (jsx_runtime_1.jsx("div", { style: {
|
|
110
115
|
paddingLeft: 5 + (premountWidth !== null && premountWidth !== void 0 ? premountWidth : 0),
|
|
@@ -31,7 +31,9 @@ const TimelineStack = ({ isCompact, sequence, originalLocation }) => {
|
|
|
31
31
|
const connectionStatus = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx)
|
|
32
32
|
.previewServerState.type;
|
|
33
33
|
const assetPath = (0, react_1.useMemo)(() => {
|
|
34
|
-
if (sequence.type !== 'video' &&
|
|
34
|
+
if (sequence.type !== 'video' &&
|
|
35
|
+
sequence.type !== 'audio' &&
|
|
36
|
+
sequence.type !== 'image') {
|
|
35
37
|
return null;
|
|
36
38
|
}
|
|
37
39
|
const isStatic = sequence.src.startsWith(window.remotion_staticBase);
|
|
@@ -42,7 +42,7 @@ const TimelineTracks = ({ timeline, hasBeenCut }) => {
|
|
|
42
42
|
const isExpanded = (_a = expandedTracks[track.sequence.id]) !== null && _a !== void 0 ? _a : false;
|
|
43
43
|
return (jsx_runtime_1.jsxs("div", { children: [
|
|
44
44
|
jsx_runtime_1.jsx("div", { style: {
|
|
45
|
-
height: (0, timeline_layout_1.getTimelineLayerHeight)(track.sequence.type
|
|
45
|
+
height: (0, timeline_layout_1.getTimelineLayerHeight)(track.sequence.type),
|
|
46
46
|
marginBottom: timeline_layout_1.TIMELINE_ITEM_BORDER_BOTTOM,
|
|
47
47
|
}, children: jsx_runtime_1.jsx(TimelineSequence_1.TimelineSequence, { s: track.sequence }) }), visualModeEnabled && isExpanded ? (jsx_runtime_1.jsx("div", { style: getExpandedPlaceholderStyle(track.sequence.controls) })) : null] }, track.sequence.id));
|
|
48
48
|
})] }), hasBeenCut ? jsx_runtime_1.jsx(MaxTimelineTracks_1.MaxTimelineTracksReached, {}) : null] }));
|
|
@@ -29,11 +29,6 @@ const TimelineTranslateField = ({ field, codeValue, effectiveValue, canUpdate, o
|
|
|
29
29
|
const [dragY, setDragY] = (0, react_1.useState)(null);
|
|
30
30
|
const [codeX, codeY] = (0, react_1.useMemo)(() => parseTranslate(String(effectiveValue !== null && effectiveValue !== void 0 ? effectiveValue : '0px 0px')), [effectiveValue]);
|
|
31
31
|
const makeString = (0, react_1.useCallback)((x, y) => `${x}px ${y}px`, []);
|
|
32
|
-
(0, react_1.useEffect)(() => {
|
|
33
|
-
setDragX(null);
|
|
34
|
-
setDragY(null);
|
|
35
|
-
onDragEnd();
|
|
36
|
-
}, [field.currentValue, onDragEnd]);
|
|
37
32
|
const step = field.fieldSchema.type === 'translate' ? ((_a = field.fieldSchema.step) !== null && _a !== void 0 ? _a : 1) : 1;
|
|
38
33
|
const stepDecimals = (0, react_1.useMemo)(() => (0, timeline_field_utils_1.getDecimalPlaces)(step), [step]);
|
|
39
34
|
const formatter = (0, react_1.useCallback)((v) => {
|
|
@@ -52,14 +47,25 @@ const TimelineTranslateField = ({ field, codeValue, effectiveValue, canUpdate, o
|
|
|
52
47
|
const currentY = dragY !== null && dragY !== void 0 ? dragY : codeY;
|
|
53
48
|
const newStr = makeString(newVal, currentY);
|
|
54
49
|
if (canUpdate && newStr !== codeValue) {
|
|
55
|
-
onSave(field.key, newStr).
|
|
50
|
+
onSave(field.key, newStr).finally(() => {
|
|
56
51
|
setDragX(null);
|
|
52
|
+
onDragEnd();
|
|
57
53
|
});
|
|
58
54
|
}
|
|
59
55
|
else {
|
|
60
56
|
setDragX(null);
|
|
57
|
+
onDragEnd();
|
|
61
58
|
}
|
|
62
|
-
}, [
|
|
59
|
+
}, [
|
|
60
|
+
dragY,
|
|
61
|
+
codeY,
|
|
62
|
+
makeString,
|
|
63
|
+
canUpdate,
|
|
64
|
+
codeValue,
|
|
65
|
+
onSave,
|
|
66
|
+
field.key,
|
|
67
|
+
onDragEnd,
|
|
68
|
+
]);
|
|
63
69
|
const onXTextChange = (0, react_1.useCallback)((newVal) => {
|
|
64
70
|
if (canUpdate) {
|
|
65
71
|
const parsed = Number(newVal);
|
|
@@ -68,13 +74,11 @@ const TimelineTranslateField = ({ field, codeValue, effectiveValue, canUpdate, o
|
|
|
68
74
|
const newStr = makeString(parsed, currentY);
|
|
69
75
|
if (newStr !== codeValue) {
|
|
70
76
|
setDragX(parsed);
|
|
71
|
-
onSave(field.key, newStr)
|
|
72
|
-
setDragX(null);
|
|
73
|
-
});
|
|
77
|
+
onSave(field.key, newStr);
|
|
74
78
|
}
|
|
75
79
|
}
|
|
76
80
|
}
|
|
77
|
-
}, [canUpdate,
|
|
81
|
+
}, [canUpdate, dragY, codeY, makeString, codeValue, onSave, field.key]);
|
|
78
82
|
// --- Y callbacks ---
|
|
79
83
|
const onYChange = (0, react_1.useCallback)((newVal) => {
|
|
80
84
|
setDragY(newVal);
|
|
@@ -85,14 +89,25 @@ const TimelineTranslateField = ({ field, codeValue, effectiveValue, canUpdate, o
|
|
|
85
89
|
const currentX = dragX !== null && dragX !== void 0 ? dragX : codeX;
|
|
86
90
|
const newStr = makeString(currentX, newVal);
|
|
87
91
|
if (canUpdate && newStr !== codeValue) {
|
|
88
|
-
onSave(field.key, newStr).
|
|
92
|
+
onSave(field.key, newStr).finally(() => {
|
|
89
93
|
setDragY(null);
|
|
94
|
+
onDragEnd();
|
|
90
95
|
});
|
|
91
96
|
}
|
|
92
97
|
else {
|
|
93
98
|
setDragY(null);
|
|
99
|
+
onDragEnd();
|
|
94
100
|
}
|
|
95
|
-
}, [
|
|
101
|
+
}, [
|
|
102
|
+
dragX,
|
|
103
|
+
codeX,
|
|
104
|
+
makeString,
|
|
105
|
+
canUpdate,
|
|
106
|
+
codeValue,
|
|
107
|
+
onSave,
|
|
108
|
+
field.key,
|
|
109
|
+
onDragEnd,
|
|
110
|
+
]);
|
|
96
111
|
const onYTextChange = (0, react_1.useCallback)((newVal) => {
|
|
97
112
|
if (canUpdate) {
|
|
98
113
|
const parsed = Number(newVal);
|
|
@@ -39,6 +39,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
39
39
|
exports.TopPanel = exports.useResponsiveSidebarStatus = void 0;
|
|
40
40
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
41
41
|
const react_1 = __importStar(require("react"));
|
|
42
|
+
const remotion_1 = require("remotion");
|
|
42
43
|
const mobile_layout_1 = require("../helpers/mobile-layout");
|
|
43
44
|
const use_breakpoint_1 = require("../helpers/use-breakpoint");
|
|
44
45
|
const editor_rulers_1 = require("../state/editor-rulers");
|
|
@@ -48,6 +49,7 @@ const CurrentCompositionSideEffects_1 = require("./CurrentCompositionSideEffects
|
|
|
48
49
|
const use_is_ruler_visible_1 = require("./EditorRuler/use-is-ruler-visible");
|
|
49
50
|
const ExplorerPanel_1 = require("./ExplorerPanel");
|
|
50
51
|
const MobilePanel_1 = __importDefault(require("./MobilePanel"));
|
|
52
|
+
const ObserveDefaultPropsContext_1 = require("./ObserveDefaultPropsContext");
|
|
51
53
|
const OptionsPanel_1 = require("./OptionsPanel");
|
|
52
54
|
const PreviewToolbar_1 = require("./PreviewToolbar");
|
|
53
55
|
const SplitterContainer_1 = require("./Splitter/SplitterContainer");
|
|
@@ -84,6 +86,7 @@ exports.useResponsiveSidebarStatus = useResponsiveSidebarStatus;
|
|
|
84
86
|
const TopPanelInner = ({ readOnlyStudio, onMounted, drawRef, bufferStateDelayInMilliseconds }) => {
|
|
85
87
|
const { setSidebarCollapsedState, sidebarCollapsedStateRight } = (0, react_1.useContext)(sidebar_1.SidebarContext);
|
|
86
88
|
const rulersAreVisible = (0, use_is_ruler_visible_1.useIsRulerVisible)();
|
|
89
|
+
const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
|
87
90
|
const actualStateLeft = (0, exports.useResponsiveSidebarStatus)();
|
|
88
91
|
const actualStateRight = (0, react_1.useMemo)(() => {
|
|
89
92
|
if (sidebarCollapsedStateRight === 'collapsed') {
|
|
@@ -107,10 +110,12 @@ const TopPanelInner = ({ readOnlyStudio, onMounted, drawRef, bufferStateDelayInM
|
|
|
107
110
|
setSidebarCollapsedState({ left: null, right: 'collapsed' });
|
|
108
111
|
}, [setSidebarCollapsedState]);
|
|
109
112
|
const isMobileLayout = (0, mobile_layout_1.useMobileLayout)();
|
|
110
|
-
return (jsx_runtime_1.
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
113
|
+
return (jsx_runtime_1.jsx(ObserveDefaultPropsContext_1.ObserveDefaultProps, { compositionId: (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition'
|
|
114
|
+
? canvasContent.compositionId
|
|
115
|
+
: null, readOnlyStudio: readOnlyStudio, children: jsx_runtime_1.jsxs("div", { style: container, children: [
|
|
116
|
+
jsx_runtime_1.jsx("div", { style: row, children: jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { minFlex: 0.15, maxFlex: 0.4, defaultFlex: 0.2, id: "sidebar-to-preview", orientation: "vertical", children: [actualStateLeft === 'expanded' ? (isMobileLayout ? (jsx_runtime_1.jsx(MobilePanel_1.default, { onClose: onCollapseLeft, children: jsx_runtime_1.jsx(ExplorerPanel_1.ExplorerPanel, { readOnlyStudio: readOnlyStudio }) })) : (jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { sticky: null, type: "flexer", children: jsx_runtime_1.jsx(ExplorerPanel_1.ExplorerPanel, { readOnlyStudio: readOnlyStudio }) }))) : null, actualStateLeft === 'expanded' ? (jsx_runtime_1.jsx(SplitterHandle_1.SplitterHandle, { allowToCollapse: "left", onCollapse: onCollapseLeft })) : null, jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { sticky: null, type: "anti-flexer", children: jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { minFlex: 0.5, maxFlex: 0.8, defaultFlex: 0.7, id: "canvas-to-right-sidebar", orientation: "vertical", children: [
|
|
117
|
+
jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { sticky: null, type: "flexer", children: jsx_runtime_1.jsx("div", { ref: drawRef, style: canvasContainerStyle, children: jsx_runtime_1.jsx(CanvasIfSizeIsAvailable_1.CanvasIfSizeIsAvailable, {}) }) }), actualStateRight === 'expanded' ? (jsx_runtime_1.jsx(SplitterHandle_1.SplitterHandle, { allowToCollapse: "right", onCollapse: onCollapseRight })) : null, actualStateRight === 'expanded' ? (isMobileLayout ? (jsx_runtime_1.jsx(MobilePanel_1.default, { onClose: onCollapseRight, children: jsx_runtime_1.jsx(OptionsPanel_1.OptionsPanel, { readOnlyStudio: readOnlyStudio }) })) : (jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { sticky: null, type: "anti-flexer", children: jsx_runtime_1.jsx(OptionsPanel_1.OptionsPanel, { readOnlyStudio: readOnlyStudio }) }))) : null] }) })
|
|
118
|
+
] }) }), jsx_runtime_1.jsx(PreviewToolbar_1.PreviewToolbar, { bufferStateDelayInMilliseconds: bufferStateDelayInMilliseconds, readOnlyStudio: readOnlyStudio }), jsx_runtime_1.jsx(CurrentCompositionSideEffects_1.CurrentCompositionKeybindings, { readOnlyStudio: readOnlyStudio }), jsx_runtime_1.jsx(CurrentCompositionSideEffects_1.TitleUpdater, {})
|
|
119
|
+
] }) }));
|
|
115
120
|
};
|
|
116
121
|
exports.TopPanel = react_1.default.memo(TopPanelInner);
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UndoRedoButtons = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const ShortcutHint_1 = require("../error-overlay/remotion-overlay/ShortcutHint");
|
|
7
|
+
const client_id_1 = require("../helpers/client-id");
|
|
8
|
+
const use_keybinding_1 = require("../helpers/use-keybinding");
|
|
9
|
+
const redo_1 = require("../icons/redo");
|
|
10
|
+
const undo_1 = require("../icons/undo");
|
|
11
|
+
const call_api_1 = require("./call-api");
|
|
12
|
+
const InlineAction_1 = require("./InlineAction");
|
|
13
|
+
const iconStyle = {
|
|
14
|
+
width: 16,
|
|
15
|
+
height: 16,
|
|
16
|
+
};
|
|
17
|
+
const UndoRedoButtons = () => {
|
|
18
|
+
const [undoFile, setUndoFile] = (0, react_1.useState)(null);
|
|
19
|
+
const [redoFile, setRedoFile] = (0, react_1.useState)(null);
|
|
20
|
+
const { subscribeToEvent } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
|
|
21
|
+
const keybindings = (0, use_keybinding_1.useKeybinding)();
|
|
22
|
+
const undoInFlight = (0, react_1.useRef)(false);
|
|
23
|
+
const redoInFlight = (0, react_1.useRef)(false);
|
|
24
|
+
(0, react_1.useEffect)(() => {
|
|
25
|
+
const unsub = subscribeToEvent('undo-redo-stack-changed', (event) => {
|
|
26
|
+
if (event.type !== 'undo-redo-stack-changed') {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
setUndoFile(event.undoFile);
|
|
30
|
+
setRedoFile(event.redoFile);
|
|
31
|
+
});
|
|
32
|
+
return () => unsub();
|
|
33
|
+
}, [subscribeToEvent]);
|
|
34
|
+
const onUndo = (0, react_1.useCallback)(() => {
|
|
35
|
+
if (undoInFlight.current) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
undoInFlight.current = true;
|
|
39
|
+
(0, call_api_1.callApi)('/api/undo', {})
|
|
40
|
+
.catch(() => {
|
|
41
|
+
// Ignore errors
|
|
42
|
+
})
|
|
43
|
+
.finally(() => {
|
|
44
|
+
undoInFlight.current = false;
|
|
45
|
+
});
|
|
46
|
+
}, []);
|
|
47
|
+
const onRedo = (0, react_1.useCallback)(() => {
|
|
48
|
+
if (redoInFlight.current) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
redoInFlight.current = true;
|
|
52
|
+
(0, call_api_1.callApi)('/api/redo', {})
|
|
53
|
+
.catch(() => {
|
|
54
|
+
// Ignore errors
|
|
55
|
+
})
|
|
56
|
+
.finally(() => {
|
|
57
|
+
redoInFlight.current = false;
|
|
58
|
+
});
|
|
59
|
+
}, []);
|
|
60
|
+
(0, react_1.useEffect)(() => {
|
|
61
|
+
const undo = keybindings.registerKeybinding({
|
|
62
|
+
event: 'keydown',
|
|
63
|
+
key: 'z',
|
|
64
|
+
commandCtrlKey: true,
|
|
65
|
+
callback: (e) => {
|
|
66
|
+
if (e.shiftKey) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (undoFile) {
|
|
70
|
+
onUndo();
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
preventDefault: true,
|
|
74
|
+
triggerIfInputFieldFocused: false,
|
|
75
|
+
keepRegisteredWhenNotHighestContext: false,
|
|
76
|
+
});
|
|
77
|
+
const redo = keybindings.registerKeybinding({
|
|
78
|
+
event: 'keydown',
|
|
79
|
+
key: 'y',
|
|
80
|
+
commandCtrlKey: true,
|
|
81
|
+
callback: () => {
|
|
82
|
+
if (redoFile) {
|
|
83
|
+
onRedo();
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
preventDefault: true,
|
|
87
|
+
triggerIfInputFieldFocused: false,
|
|
88
|
+
keepRegisteredWhenNotHighestContext: false,
|
|
89
|
+
});
|
|
90
|
+
return () => {
|
|
91
|
+
undo.unregister();
|
|
92
|
+
redo.unregister();
|
|
93
|
+
};
|
|
94
|
+
}, [keybindings, onRedo, onUndo, redoFile, undoFile]);
|
|
95
|
+
const undoTooltip = (0, use_keybinding_1.areKeyboardShortcutsDisabled)()
|
|
96
|
+
? 'Undo'
|
|
97
|
+
: `Undo (${ShortcutHint_1.cmdOrCtrlCharacter}+Z)`;
|
|
98
|
+
const redoTooltip = (0, use_keybinding_1.areKeyboardShortcutsDisabled)()
|
|
99
|
+
? 'Redo'
|
|
100
|
+
: `Redo (${ShortcutHint_1.cmdOrCtrlCharacter}+Y)`;
|
|
101
|
+
const renderUndo = (0, react_1.useCallback)((color) => {
|
|
102
|
+
return (jsx_runtime_1.jsx(undo_1.UndoIcon, { style: { ...iconStyle, color, opacity: undoFile ? 1 : 0.5 } }));
|
|
103
|
+
}, [undoFile]);
|
|
104
|
+
const renderRedo = (0, react_1.useCallback)((color) => {
|
|
105
|
+
return (jsx_runtime_1.jsx(redo_1.RedoIcon, { style: { ...iconStyle, color, opacity: redoFile ? 1 : 0.5 } }));
|
|
106
|
+
}, [redoFile]);
|
|
107
|
+
const canUndo = undoFile !== null;
|
|
108
|
+
const canRedo = redoFile !== null;
|
|
109
|
+
if (!canUndo && !canRedo) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
|
|
113
|
+
jsx_runtime_1.jsx(InlineAction_1.InlineAction, { onClick: onUndo, renderAction: renderUndo, title: undoTooltip, disabled: !canUndo }), jsx_runtime_1.jsx(InlineAction_1.InlineAction, { onClick: onRedo, renderAction: renderRedo, title: redoTooltip, disabled: !canRedo })
|
|
114
|
+
] }));
|
|
115
|
+
};
|
|
116
|
+
exports.UndoRedoButtons = UndoRedoButtons;
|