@remotion/studio 4.0.520 → 4.0.521
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/api/shut-down-studio.d.ts +6 -0
- package/dist/api/shut-down-studio.js +23 -0
- package/dist/components/AudioWaveform.js +10 -6
- package/dist/components/Canvas.js +84 -12
- package/dist/components/CaptionInspector.d.ts +1 -0
- package/dist/components/CaptionInspector.js +43 -2
- package/dist/components/CaptionTextEditor.js +1 -1
- package/dist/components/CompositionSelector.js +41 -30
- package/dist/components/CompositionSelectorItem.d.ts +7 -0
- package/dist/components/CompositionSelectorItem.js +343 -67
- package/dist/components/ElementInstallConfirmation.js +74 -64
- package/dist/components/ElementLibraryModal.js +3 -1
- package/dist/components/InlineCaptionInspector.js +37 -1
- package/dist/components/InspectorPanel/ElementLibraryButton.js +3 -18
- package/dist/components/InspectorSequenceSection.js +1 -4
- package/dist/components/Menu/MenuSubItem.js +1 -1
- package/dist/components/ModalContainer.d.ts +1 -0
- package/dist/components/ModalContainer.js +2 -2
- package/dist/components/ModalHeader.js +5 -1
- package/dist/components/QuickSwitcher/asset-search.d.ts +0 -1
- package/dist/components/QuickSwitcher/asset-search.js +1 -16
- package/dist/components/RenderButton.js +2 -2
- package/dist/components/RenderModal/RenderStatusModal.js +7 -1
- package/dist/components/RenderModal/ServerRenderModal.js +1 -1
- package/dist/components/RenderModal/WebRenderModal.js +1 -1
- package/dist/components/RenderQueue/ClientRenderQueueProcessor.js +1 -1
- package/dist/components/SettingsModal.js +8 -5
- package/dist/components/TimeValue.js +36 -7
- package/dist/components/Timeline/Timeline.d.ts +1 -1
- package/dist/components/Timeline/Timeline.js +31 -19
- package/dist/components/Timeline/TimelineAssetField.d.ts +0 -1
- package/dist/components/Timeline/TimelineAssetField.js +16 -9
- package/dist/components/Timeline/TimelineCollapseToggle.js +1 -1
- package/dist/components/Timeline/TimelineFontWeightField.d.ts +11 -0
- package/dist/components/Timeline/TimelineFontWeightField.js +65 -0
- package/dist/components/Timeline/TimelineLayerChildren.d.ts +21 -0
- package/dist/components/Timeline/TimelineLayerChildren.js +129 -0
- package/dist/components/Timeline/TimelineNumberField.js +13 -5
- package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +4 -0
- package/dist/components/Timeline/TimelineSequence.js +38 -32
- package/dist/components/Timeline/TimelineSequenceItem.js +2 -1
- package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +19 -7
- package/dist/components/Timeline/TimelineTickFormatProvider.d.ts +8 -0
- package/dist/components/Timeline/TimelineTickFormatProvider.js +16 -0
- package/dist/components/Timeline/TimelineTimeIndicators.js +7 -3
- package/dist/components/Timeline/TimelineVideoInfo.js +7 -3
- package/dist/components/Timeline/timeline-field-display-utils.js +1 -0
- package/dist/components/UpdateStatusContext.d.ts +5 -0
- package/dist/components/UpdateStatusContext.js +53 -2
- package/dist/components/UpdatesSettings.js +25 -4
- package/dist/components/WebMcp.js +26 -0
- package/dist/components/composition-selector-drag-data.d.ts +27 -0
- package/dist/components/composition-selector-drag-data.js +80 -0
- package/dist/components/import-assets.d.ts +2 -1
- package/dist/components/import-assets.js +11 -1
- package/dist/components/parse-caption-file.d.ts +5 -0
- package/dist/components/parse-caption-file.js +63 -0
- package/dist/esm/chunk-emw4k5b0.js +99527 -0
- package/dist/esm/{chunk-np6q13k5.js → chunk-vkrvnx2h.js} +5913 -4699
- package/dist/esm/index.mjs +23 -8
- package/dist/esm/internals.mjs +6729 -5366
- package/dist/esm/previewEntry.mjs +6779 -5416
- package/dist/esm/renderEntry.mjs +1 -1
- package/dist/helpers/get-preview-file-type.js +22 -3
- package/dist/helpers/inserted-element-selection.d.ts +2 -1
- package/dist/helpers/use-menu-structure.js +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -1
- package/dist/state/modals.d.ts +0 -2
- package/package.json +16 -16
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description Shuts down the Remotion Studio.
|
|
3
|
+
* @see [Documentation](https://www.remotion.dev/docs/studio/shut-down-studio)
|
|
4
|
+
*/
|
|
5
|
+
import type { ShutdownStudioResponse } from '@remotion/studio-shared';
|
|
6
|
+
export declare const shutDownStudio: () => Promise<ShutdownStudioResponse>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @description Shuts down the Remotion Studio.
|
|
4
|
+
* @see [Documentation](https://www.remotion.dev/docs/studio/shut-down-studio)
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.shutDownStudio = void 0;
|
|
8
|
+
const remotion_1 = require("remotion");
|
|
9
|
+
const call_api_1 = require("../components/call-api");
|
|
10
|
+
const browser_studio_operations_1 = require("../helpers/browser-studio-operations");
|
|
11
|
+
const shutDownStudio = () => {
|
|
12
|
+
if (!(0, remotion_1.getRemotionEnvironment)().isStudio) {
|
|
13
|
+
throw new Error('shutDownStudio() is only available in the Studio');
|
|
14
|
+
}
|
|
15
|
+
if ((0, browser_studio_operations_1.getBrowserStudioOperations)() !== null) {
|
|
16
|
+
throw new Error('shutDownStudio() is not supported in Browser Studio');
|
|
17
|
+
}
|
|
18
|
+
if (window.remotion_isReadOnlyStudio) {
|
|
19
|
+
throw new Error('shutDownStudio() is not available in read-only Studio');
|
|
20
|
+
}
|
|
21
|
+
return (0, call_api_1.callApi)('/api/shutdown-studio', {});
|
|
22
|
+
};
|
|
23
|
+
exports.shutDownStudio = shutDownStudio;
|
|
@@ -50,17 +50,15 @@ const getContainerStyle = (height) => {
|
|
|
50
50
|
position: 'relative',
|
|
51
51
|
width: '100%',
|
|
52
52
|
height,
|
|
53
|
+
overflow: 'hidden',
|
|
53
54
|
};
|
|
54
55
|
};
|
|
55
56
|
const waveformCanvasStyle = {
|
|
56
57
|
pointerEvents: 'none',
|
|
57
|
-
|
|
58
|
-
height: '100%',
|
|
58
|
+
flexShrink: 0,
|
|
59
59
|
};
|
|
60
60
|
const volumeCanvasStyle = {
|
|
61
61
|
position: 'absolute',
|
|
62
|
-
width: '100%',
|
|
63
|
-
height: '100%',
|
|
64
62
|
};
|
|
65
63
|
const parseVolume = (volume) => {
|
|
66
64
|
if (typeof volume === 'number') {
|
|
@@ -146,14 +144,17 @@ const AudioWaveformInner = ({ src, height, startFrom, durationInFrames, displayO
|
|
|
146
144
|
const pixelRatio = window.devicePixelRatio;
|
|
147
145
|
const h = Math.ceil(height * pixelRatio);
|
|
148
146
|
const w = Math.ceil(visualizationWidth * pixelRatio);
|
|
147
|
+
const drawingWidth = visualizationWidth * pixelRatio;
|
|
149
148
|
canvasElement.width = w;
|
|
150
149
|
canvasElement.height = h;
|
|
150
|
+
canvasElement.style.width = w / pixelRatio + 'px';
|
|
151
|
+
canvasElement.style.height = h / pixelRatio + 'px';
|
|
151
152
|
(0, timeline_utils_1.drawBars)({
|
|
152
153
|
canvas: canvasElement,
|
|
153
154
|
peaks: portionPeaks !== null && portionPeaks !== void 0 ? portionPeaks : EMPTY_PEAKS,
|
|
154
155
|
color: colors_1.WHITE_ALPHA_60,
|
|
155
156
|
volume: visibleVolume,
|
|
156
|
-
width:
|
|
157
|
+
width: drawingWidth,
|
|
157
158
|
});
|
|
158
159
|
}, [height, portionPeaks, visibleVolume, visualizationWidth]);
|
|
159
160
|
(0, react_1.useLayoutEffect)(() => {
|
|
@@ -167,12 +168,15 @@ const AudioWaveformInner = ({ src, height, startFrom, durationInFrames, displayO
|
|
|
167
168
|
const pixelRatio = window.devicePixelRatio;
|
|
168
169
|
const h = Math.ceil(height * pixelRatio);
|
|
169
170
|
const w = Math.ceil(visualizationWidth * pixelRatio);
|
|
171
|
+
const drawingWidth = visualizationWidth * pixelRatio;
|
|
170
172
|
const context = volumeCanvasElement.getContext('2d');
|
|
171
173
|
if (!context) {
|
|
172
174
|
return;
|
|
173
175
|
}
|
|
174
176
|
volumeCanvasElement.width = w;
|
|
175
177
|
volumeCanvasElement.height = h;
|
|
178
|
+
volumeCanvasElement.style.width = w / pixelRatio + 'px';
|
|
179
|
+
volumeCanvasElement.style.height = h / pixelRatio + 'px';
|
|
176
180
|
context.clearRect(0, 0, w, h);
|
|
177
181
|
if (!Array.isArray(visibleVolume)) {
|
|
178
182
|
return;
|
|
@@ -182,7 +186,7 @@ const AudioWaveformInner = ({ src, height, startFrom, durationInFrames, displayO
|
|
|
182
186
|
visibleVolume.forEach((v, index) => {
|
|
183
187
|
const x = visibleVolume.length <= 1
|
|
184
188
|
? 0
|
|
185
|
-
: (index / (visibleVolume.length - 1)) *
|
|
189
|
+
: (index / (visibleVolume.length - 1)) * drawingWidth;
|
|
186
190
|
const y = (1 - v) * (h - timeline_layout_1.TIMELINE_BORDER * 2 * pixelRatio) + pixelRatio;
|
|
187
191
|
if (index === 0) {
|
|
188
192
|
context.moveTo(x, y);
|
|
@@ -47,7 +47,6 @@ const ResetZoomButton_1 = require("./ResetZoomButton");
|
|
|
47
47
|
const SvgImportDialog_1 = require("./SvgImportDialog");
|
|
48
48
|
const imperative_state_1 = require("./Timeline/imperative-state");
|
|
49
49
|
const use_resolved_stack_1 = require("./Timeline/use-resolved-stack");
|
|
50
|
-
const elementInstallDependencyIgnoreList = ['react', 'react-dom', 'remotion'];
|
|
51
50
|
const getCanvasDragPreviewMetadata = (mimeTypes) => {
|
|
52
51
|
var _a, _b, _c;
|
|
53
52
|
const composition = (0, composition_drag_data_1.getCompositionDragPreviewMetadata)(mimeTypes);
|
|
@@ -624,24 +623,103 @@ const Canvas = ({ canvasContent, size }) => {
|
|
|
624
623
|
(0, element_install_request_1.enqueueElementInstallRequest)(event.request);
|
|
625
624
|
});
|
|
626
625
|
}, [previewServerClientId, subscribeToEvent]);
|
|
626
|
+
(0, react_1.useEffect)(() => {
|
|
627
|
+
const onMessage = (event) => {
|
|
628
|
+
var _a, _b;
|
|
629
|
+
const elementLibrary = document.querySelector('iframe[data-remotion-element-library]');
|
|
630
|
+
if (event.source !== (elementLibrary === null || elementLibrary === void 0 ? void 0 : elementLibrary.contentWindow) ||
|
|
631
|
+
!studio_protocol_1.StudioProtocolInternals.isAllowedStudioProtocolPageOrigin(event.origin)) {
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
const payload = studio_protocol_1.StudioProtocolInternals.parseStudioProtocolIframeInstallRequest(event.data);
|
|
635
|
+
const responsePort = event.ports[0];
|
|
636
|
+
if (payload === null || responsePort === undefined) {
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
const canInstall = canReceiveElementInstallRequest &&
|
|
640
|
+
compositionFile !== null &&
|
|
641
|
+
currentCompositionId !== null &&
|
|
642
|
+
previewServerClientId !== null;
|
|
643
|
+
const request = canInstall
|
|
644
|
+
? {
|
|
645
|
+
clientId: previewServerClientId,
|
|
646
|
+
compositionFile,
|
|
647
|
+
compositionId: currentCompositionId,
|
|
648
|
+
createdAt: Date.now(),
|
|
649
|
+
element: {
|
|
650
|
+
...payload.element,
|
|
651
|
+
durationInFrames: (_a = payload.element.durationInFrames) !== null && _a !== void 0 ? _a : null,
|
|
652
|
+
installationMode: (_b = payload.element.installationMode) !== null && _b !== void 0 ? _b : null,
|
|
653
|
+
},
|
|
654
|
+
from: null,
|
|
655
|
+
id: crypto.randomUUID(),
|
|
656
|
+
position: null,
|
|
657
|
+
source: { origin: event.origin, type: 'studio-protocol' },
|
|
658
|
+
}
|
|
659
|
+
: null;
|
|
660
|
+
const result = canInstall
|
|
661
|
+
? {
|
|
662
|
+
success: true,
|
|
663
|
+
status: 'awaiting-confirmation',
|
|
664
|
+
target: {
|
|
665
|
+
compositionId: currentCompositionId,
|
|
666
|
+
projectName: window.remotion_projectName,
|
|
667
|
+
studioOrigin: window.location.origin,
|
|
668
|
+
studioVersion: window.remotion_version,
|
|
669
|
+
},
|
|
670
|
+
}
|
|
671
|
+
: {
|
|
672
|
+
success: false,
|
|
673
|
+
code: 'no-installable-target',
|
|
674
|
+
message: 'Focus a composition in a Remotion Studio that is not read-only, then try again.',
|
|
675
|
+
};
|
|
676
|
+
const timeout = window.setTimeout(() => responsePort.close(), 1000);
|
|
677
|
+
responsePort.onmessage = () => {
|
|
678
|
+
window.clearTimeout(timeout);
|
|
679
|
+
responsePort.close();
|
|
680
|
+
if (request !== null) {
|
|
681
|
+
(0, element_install_request_1.enqueueElementInstallRequest)(request);
|
|
682
|
+
}
|
|
683
|
+
};
|
|
684
|
+
responsePort.postMessage(result);
|
|
685
|
+
};
|
|
686
|
+
window.addEventListener('message', onMessage);
|
|
687
|
+
return () => window.removeEventListener('message', onMessage);
|
|
688
|
+
}, [
|
|
689
|
+
canReceiveElementInstallRequest,
|
|
690
|
+
compositionFile,
|
|
691
|
+
currentCompositionId,
|
|
692
|
+
previewServerClientId,
|
|
693
|
+
]);
|
|
627
694
|
(0, react_1.useEffect)(() => {
|
|
628
695
|
return (0, element_install_request_1.subscribeToElementInstallRequests)((request) => {
|
|
629
|
-
|
|
696
|
+
var _a, _b;
|
|
697
|
+
const isDragAndDrop = request.source.type === 'drag-and-drop';
|
|
698
|
+
const requestWithDefaults = isDragAndDrop
|
|
630
699
|
? request
|
|
631
700
|
: {
|
|
632
701
|
...request,
|
|
633
|
-
from: (0, import_assets_1.getFromForDrop)({
|
|
702
|
+
from: (_a = request.from) !== null && _a !== void 0 ? _a : (0, import_assets_1.getFromForDrop)({
|
|
634
703
|
durationInFrames: request.element.durationInFrames,
|
|
635
704
|
from: (0, imperative_state_1.getCurrentFrame)(),
|
|
636
705
|
preferCompositionStart: true,
|
|
637
706
|
}),
|
|
707
|
+
position: (_b = request.position) !== null && _b !== void 0 ? _b : (0, import_assets_1.getElementPositionForDrop)({
|
|
708
|
+
dimensions: request.element.dimensions,
|
|
709
|
+
dropPosition: contentDimensions === null || contentDimensions === 'none'
|
|
710
|
+
? null
|
|
711
|
+
: {
|
|
712
|
+
centerX: contentDimensions.width / 2,
|
|
713
|
+
centerY: contentDimensions.height / 2,
|
|
714
|
+
},
|
|
715
|
+
}),
|
|
638
716
|
};
|
|
639
717
|
setPendingElementInstallRequests((requests) => [
|
|
640
718
|
...requests,
|
|
641
|
-
|
|
719
|
+
requestWithDefaults,
|
|
642
720
|
]);
|
|
643
721
|
});
|
|
644
|
-
}, []);
|
|
722
|
+
}, [contentDimensions]);
|
|
645
723
|
(0, react_1.useEffect)(() => {
|
|
646
724
|
var _a;
|
|
647
725
|
var _b;
|
|
@@ -719,12 +797,7 @@ const Canvas = ({ canvasContent, size }) => {
|
|
|
719
797
|
return;
|
|
720
798
|
}
|
|
721
799
|
const declaredDependencies = Array.from(new Map(activeElementInstallRequest.element.dependencies.map((dependency) => [dependency.name, dependency])).values());
|
|
722
|
-
const missingPackages = (0, install_required_package_1.getMissingPackages)(declaredDependencies).map((dependency) => dependency.
|
|
723
|
-
const ignoredDependencies = declaredDependencies.filter((dependency) => elementInstallDependencyIgnoreList.includes(dependency.name) &&
|
|
724
|
-
!missingPackages.includes(dependency.name));
|
|
725
|
-
const dependenciesToReview = declaredDependencies
|
|
726
|
-
.filter((dependency) => !ignoredDependencies.includes(dependency))
|
|
727
|
-
.map((dependency) => dependency.version === null
|
|
800
|
+
const missingPackages = (0, install_required_package_1.getMissingPackages)(declaredDependencies).map((dependency) => dependency.version === null
|
|
728
801
|
? dependency.name
|
|
729
802
|
: `${dependency.name}@${dependency.version}`);
|
|
730
803
|
const { source } = activeElementInstallRequest;
|
|
@@ -741,7 +814,6 @@ const Canvas = ({ canvasContent, size }) => {
|
|
|
741
814
|
setSelectedModal({
|
|
742
815
|
type: 'element-install',
|
|
743
816
|
currentPlan,
|
|
744
|
-
dependenciesToReview,
|
|
745
817
|
missingPackages,
|
|
746
818
|
newPlan: newPreflight.plan,
|
|
747
819
|
onClose: closeElementInstallDialog,
|
|
@@ -6,6 +6,7 @@ export declare const CaptionInspector: React.FC<{
|
|
|
6
6
|
readonly onTextChange: (captions: Caption[]) => void;
|
|
7
7
|
readonly onTextSave: ((captions: Caption[]) => void) | null;
|
|
8
8
|
readonly onTextCancel: (() => void) | null;
|
|
9
|
+
readonly onReplaceCaptions: ((captions: Caption[]) => void) | null;
|
|
9
10
|
readonly onToggle: () => void;
|
|
10
11
|
readonly readOnly: boolean;
|
|
11
12
|
readonly readOnlyTitle: string | null;
|
|
@@ -2,11 +2,19 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CaptionInspector = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
5
6
|
const colors_1 = require("../helpers/colors");
|
|
7
|
+
const upload_1 = require("../icons/upload");
|
|
8
|
+
const Button_1 = require("./Button");
|
|
6
9
|
const CaptionTextEditor_1 = require("./CaptionTextEditor");
|
|
7
10
|
const CollapsibleInspectorSectionHeader_1 = require("./InspectorPanel/CollapsibleInspectorSectionHeader");
|
|
8
11
|
const common_1 = require("./InspectorPanel/common");
|
|
9
12
|
const styles_1 = require("./InspectorPanel/styles");
|
|
13
|
+
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
|
|
14
|
+
const parse_caption_file_1 = require("./parse-caption-file");
|
|
15
|
+
const importTooltip = `Import captions
|
|
16
|
+
|
|
17
|
+
Supports Remotion Caption[] JSON. Files are processed locally.`;
|
|
10
18
|
const readOnlyStatus = {
|
|
11
19
|
color: colors_1.LIGHT_TEXT,
|
|
12
20
|
fontFamily: 'sans-serif',
|
|
@@ -15,8 +23,41 @@ const readOnlyStatus = {
|
|
|
15
23
|
lineHeight: '16px',
|
|
16
24
|
marginLeft: 12,
|
|
17
25
|
};
|
|
18
|
-
const CaptionInspector = ({ captions, expanded, onTextChange, onTextSave, onTextCancel, onToggle, readOnly, readOnlyTitle, }) => {
|
|
26
|
+
const CaptionInspector = ({ captions, expanded, onTextChange, onTextSave, onTextCancel, onReplaceCaptions, onToggle, readOnly, readOnlyTitle, }) => {
|
|
27
|
+
const fileInput = (0, react_1.useRef)(null);
|
|
28
|
+
const [isImporting, setIsImporting] = (0, react_1.useState)(false);
|
|
29
|
+
const importCaptions = (0, react_1.useCallback)(async (event) => {
|
|
30
|
+
var _a;
|
|
31
|
+
const file = (_a = event.currentTarget.files) === null || _a === void 0 ? void 0 : _a[0];
|
|
32
|
+
event.currentTarget.value = '';
|
|
33
|
+
if (!file || onReplaceCaptions === null) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
setIsImporting(true);
|
|
37
|
+
try {
|
|
38
|
+
onReplaceCaptions((0, parse_caption_file_1.parseCaptionFile)({
|
|
39
|
+
fileName: file.name,
|
|
40
|
+
contents: await file.text(),
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
(0, NotificationCenter_1.showNotification)(`Could not import ${file.name}: ${error instanceof Error ? error.message : String(error)}`, 5000);
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
setIsImporting(false);
|
|
48
|
+
}
|
|
49
|
+
}, [onReplaceCaptions]);
|
|
19
50
|
return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
|
|
20
|
-
jsx_runtime_1.jsx(common_1.InspectorSectionHeader, { children: jsx_runtime_1.jsx(CollapsibleInspectorSectionHeader_1.CollapsibleInspectorSectionHeader, { action: jsx_runtime_1.
|
|
51
|
+
jsx_runtime_1.jsx(common_1.InspectorSectionHeader, { children: jsx_runtime_1.jsx(CollapsibleInspectorSectionHeader_1.CollapsibleInspectorSectionHeader, { action: jsx_runtime_1.jsxs("div", { style: styles_1.sectionHeaderEnd, children: [onReplaceCaptions === null ? null : (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
|
|
52
|
+
jsx_runtime_1.jsx("input", { ref: fileInput, accept: ".json", "aria-label": "Import captions file", hidden: true, onChange: importCaptions, type: "file" }), jsx_runtime_1.jsxs(Button_1.Button, { buttonContainerStyle: {
|
|
53
|
+
alignItems: 'center',
|
|
54
|
+
display: 'flex',
|
|
55
|
+
gap: 4,
|
|
56
|
+
}, disabled: isImporting, onClick: () => {
|
|
57
|
+
var _a;
|
|
58
|
+
return (_a = fileInput.current) === null || _a === void 0 ? void 0 : _a.click();
|
|
59
|
+
}, size: "condensed", title: importTooltip, children: [
|
|
60
|
+
jsx_runtime_1.jsx(upload_1.UploadIcon, { "aria-hidden": "true", color: colors_1.CURRENT_COLOR, focusable: "false", style: { height: 12, width: 12 } }), isImporting ? 'Importing…' : 'Import'] })
|
|
61
|
+
] })), readOnly ? (jsx_runtime_1.jsx("div", { style: readOnlyStatus, title: readOnlyTitle !== null && readOnlyTitle !== void 0 ? readOnlyTitle : undefined, children: "Read only" })) : null] }), expanded: expanded, label: "Captions", onToggle: onToggle }) }), expanded ? (jsx_runtime_1.jsx(CaptionTextEditor_1.CaptionTextEditor, { captions: captions, onChange: onTextChange, onSave: onTextSave, onCancel: onTextCancel, readOnly: readOnly })) : null] }));
|
|
21
62
|
};
|
|
22
63
|
exports.CaptionInspector = CaptionInspector;
|
|
@@ -119,7 +119,7 @@ const CaptionTextEditor = ({ captions, onChange, onSave, onCancel, readOnly }) =
|
|
|
119
119
|
? `Remove page break after caption ${index + 1}`
|
|
120
120
|
: `Add page break after caption ${index + 1}`;
|
|
121
121
|
return (jsx_runtime_1.jsxs("div", { style: row, children: [
|
|
122
|
-
jsx_runtime_1.jsxs("div", { style: timing, children: [formatMilliseconds(caption.startMs), " \u2192", ' ', formatMilliseconds(caption.endMs), " ms"] }), jsx_runtime_1.jsx(RemInput_1.RemotionInput, { "data-caption-index": index, disabled: readOnly, onBlur: (event) => {
|
|
122
|
+
jsx_runtime_1.jsxs("div", { style: timing, children: [formatMilliseconds(caption.startMs), " \u2192", ' ', formatMilliseconds(caption.endMs), " ms"] }), jsx_runtime_1.jsx(RemInput_1.RemotionInput, { "aria-label": `Caption ${index + 1}`, "data-caption-index": index, disabled: readOnly, onBlur: (event) => {
|
|
123
123
|
if (cancelledBlurIndexes.current.delete(index)) {
|
|
124
124
|
return;
|
|
125
125
|
}
|
|
@@ -11,7 +11,7 @@ const persist_open_folders_1 = require("../helpers/persist-open-folders");
|
|
|
11
11
|
const folders_1 = require("../state/folders");
|
|
12
12
|
const modals_1 = require("../state/modals");
|
|
13
13
|
const z_index_1 = require("../state/z-index");
|
|
14
|
-
const
|
|
14
|
+
const composition_selector_drag_data_1 = require("./composition-selector-drag-data");
|
|
15
15
|
const CompositionSelectorItem_1 = require("./CompositionSelectorItem");
|
|
16
16
|
const ContextMenu_1 = require("./ContextMenu");
|
|
17
17
|
const InitialCompositionLoader_1 = require("./InitialCompositionLoader");
|
|
@@ -63,6 +63,19 @@ const container = {
|
|
|
63
63
|
overflow: 'hidden',
|
|
64
64
|
backgroundColor: colors_1.BACKGROUND,
|
|
65
65
|
};
|
|
66
|
+
const list = {
|
|
67
|
+
flex: 1,
|
|
68
|
+
overflowY: 'auto',
|
|
69
|
+
paddingTop: 4,
|
|
70
|
+
paddingBottom: 4,
|
|
71
|
+
backgroundColor: colors_1.BACKGROUND,
|
|
72
|
+
};
|
|
73
|
+
const rootReorderLine = {
|
|
74
|
+
backgroundColor: colors_1.TIMELINE_BLUE,
|
|
75
|
+
height: 2,
|
|
76
|
+
pointerEvents: 'none',
|
|
77
|
+
width: '100%',
|
|
78
|
+
};
|
|
66
79
|
const autoScrollThreshold = 70;
|
|
67
80
|
const maxAutoScrollSpeed = 18;
|
|
68
81
|
const getAutoScrollSpeed = ({ clientY, element, }) => {
|
|
@@ -105,6 +118,7 @@ const CompositionSelector = () => {
|
|
|
105
118
|
setSelectedModal,
|
|
106
119
|
]);
|
|
107
120
|
const [rootDragHovered, setRootDragHovered] = (0, react_1.useState)(false);
|
|
121
|
+
const activeDragRef = (0, react_1.useRef)(null);
|
|
108
122
|
const listRef = (0, react_1.useRef)(null);
|
|
109
123
|
const autoScrollAnimation = (0, react_1.useRef)(null);
|
|
110
124
|
const autoScrollSpeed = (0, react_1.useRef)(0);
|
|
@@ -116,15 +130,6 @@ const CompositionSelector = () => {
|
|
|
116
130
|
? (0, create_folder_tree_1.sortFolderTreeAlphabetically)(tree)
|
|
117
131
|
: tree;
|
|
118
132
|
}, [compositionSortOrder, compositions, folders, foldersExpanded]);
|
|
119
|
-
const list = (0, react_1.useMemo)(() => {
|
|
120
|
-
return {
|
|
121
|
-
flex: 1,
|
|
122
|
-
overflowY: 'auto',
|
|
123
|
-
paddingTop: 4,
|
|
124
|
-
paddingBottom: 4,
|
|
125
|
-
backgroundColor: rootDragHovered ? colors_1.WHITE_ALPHA_12 : colors_1.BACKGROUND,
|
|
126
|
-
};
|
|
127
|
-
}, [rootDragHovered]);
|
|
128
133
|
const toggleFolder = (0, react_1.useCallback)((folderName, parentName) => {
|
|
129
134
|
var _a;
|
|
130
135
|
(_a = remotion_1.Internals.compositionSelectorRef.current) === null || _a === void 0 ? void 0 : _a.toggleFolder(folderName, parentName);
|
|
@@ -166,7 +171,7 @@ const CompositionSelector = () => {
|
|
|
166
171
|
}, [runCompositionListAutoScroll, stopCompositionListAutoScroll]);
|
|
167
172
|
const onCompositionListDragOverCapture = (0, react_1.useCallback)((event) => {
|
|
168
173
|
if (window.remotion_isReadOnlyStudio ||
|
|
169
|
-
(0,
|
|
174
|
+
!(0, composition_selector_drag_data_1.hasCompositionSelectorDragData)(event.dataTransfer.types)) {
|
|
170
175
|
stopCompositionListAutoScroll();
|
|
171
176
|
return;
|
|
172
177
|
}
|
|
@@ -182,7 +187,12 @@ const CompositionSelector = () => {
|
|
|
182
187
|
}, [stopCompositionListAutoScroll]);
|
|
183
188
|
const onRootDragOver = (0, react_1.useCallback)((event) => {
|
|
184
189
|
if (window.remotion_isReadOnlyStudio ||
|
|
185
|
-
(0,
|
|
190
|
+
!(0, composition_selector_drag_data_1.hasCompositionSelectorDragData)(event.dataTransfer.types)) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (activeDragRef.current === null ||
|
|
194
|
+
activeDragRef.current.parentFolderPath === null) {
|
|
195
|
+
setRootDragHovered(false);
|
|
186
196
|
return;
|
|
187
197
|
}
|
|
188
198
|
event.preventDefault();
|
|
@@ -202,31 +212,32 @@ const CompositionSelector = () => {
|
|
|
202
212
|
if (window.remotion_isReadOnlyStudio) {
|
|
203
213
|
return;
|
|
204
214
|
}
|
|
205
|
-
const
|
|
206
|
-
if (
|
|
215
|
+
const dragData = (0, composition_selector_drag_data_1.parseCompositionSelectorDragData)(event.dataTransfer);
|
|
216
|
+
if (dragData === null) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (activeDragRef.current === null ||
|
|
220
|
+
activeDragRef.current.parentFolderPath === null) {
|
|
221
|
+
event.stopPropagation();
|
|
222
|
+
setRootDragHovered(false);
|
|
207
223
|
return;
|
|
208
224
|
}
|
|
209
225
|
event.preventDefault();
|
|
210
226
|
event.stopPropagation();
|
|
211
227
|
stopCompositionListAutoScroll();
|
|
212
228
|
setRootDragHovered(false);
|
|
213
|
-
const
|
|
214
|
-
if (!composition || composition.folderName === null) {
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
const notification = (0, NotificationCenter_1.showNotification)(`Moving ${compositionDragData.compositionId}...`, null);
|
|
229
|
+
const notification = (0, NotificationCenter_1.showNotification)(`Moving ${dragData.item.type === 'composition' ? dragData.item.compositionId : dragData.item.folderName}...`, null);
|
|
218
230
|
const controller = new AbortController();
|
|
219
231
|
try {
|
|
220
232
|
const result = await (0, actions_1.applyCodemod)({
|
|
221
233
|
codemod: {
|
|
222
|
-
type: 'move-composition-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
parentName: null,
|
|
234
|
+
type: 'move-composition-or-folder',
|
|
235
|
+
source: dragData.item,
|
|
236
|
+
destination: { type: 'root' },
|
|
226
237
|
},
|
|
227
238
|
dryRun: false,
|
|
228
239
|
signal: controller.signal,
|
|
229
|
-
symbolicatedStack: (0,
|
|
240
|
+
symbolicatedStack: (0, composition_selector_drag_data_1.compositionSelectorDragDataToSymbolicatedStack)(dragData),
|
|
230
241
|
});
|
|
231
242
|
if (result.success) {
|
|
232
243
|
notification.dismiss();
|
|
@@ -238,13 +249,13 @@ const CompositionSelector = () => {
|
|
|
238
249
|
catch (err) {
|
|
239
250
|
notification.replaceContent(err instanceof Error ? err.message : String(err), 4000);
|
|
240
251
|
}
|
|
241
|
-
}, [
|
|
252
|
+
}, [stopCompositionListAutoScroll]);
|
|
242
253
|
return (jsx_runtime_1.jsxs("div", { style: container, children: [
|
|
243
|
-
jsx_runtime_1.jsx(ContextMenu_1.ContextMenuForTarget, { triggerRef: listRef, getItems: getRootContextMenuItems }), jsx_runtime_1.jsx(ExplorerQuickSwitcherTrigger_1.ExplorerQuickSwitcherTrigger, { mode: "compositions", showShortcut: true, tabIndex: tabIndex, getActions: getRootContextMenuItems }), jsx_runtime_1.
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
254
|
+
jsx_runtime_1.jsx(ContextMenu_1.ContextMenuForTarget, { triggerRef: listRef, getItems: getRootContextMenuItems }), jsx_runtime_1.jsx(ExplorerQuickSwitcherTrigger_1.ExplorerQuickSwitcherTrigger, { mode: "compositions", showShortcut: true, tabIndex: tabIndex, getActions: getRootContextMenuItems }), jsx_runtime_1.jsxs("div", { ref: listRef, className: "__remotion-vertical-scrollbar", style: list, onDragOverCapture: onCompositionListDragOverCapture, onDragEndCapture: stopCompositionListAutoScroll, onDragOver: onRootDragOver, onDragLeave: onRootDragLeave, onDropCapture: stopCompositionListAutoScroll, onDrop: onRootDrop, children: [items.map((c, index) => {
|
|
255
|
+
return (jsx_runtime_1.jsx(CompositionSelectorItem_1.CompositionSelectorItem, { level: 0, currentComposition: canvasContent && canvasContent.type === 'composition'
|
|
256
|
+
? canvasContent.compositionId
|
|
257
|
+
: null, selectComposition: selectComposition, toggleFolder: toggleFolder, clearRootDragHover: clearRootDragHover, canReorder: compositionSortOrder === 'registration', tabIndex: tabIndex, item: c, activeDragRef: activeDragRef, parentFolderPath: null, previousSibling: index === 0 ? null : items[index - 1], nextSibling: index === items.length - 1 ? null : items[index + 1] }, c.key + c.type));
|
|
258
|
+
}), rootDragHovered ? (jsx_runtime_1.jsx("div", { "data-composition-root-reorder-line": true, style: rootReorderLine })) : null] })
|
|
248
259
|
] }));
|
|
249
260
|
};
|
|
250
261
|
exports.CompositionSelector = CompositionSelector;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import type { MutableRefObject } from 'react';
|
|
1
2
|
import React from 'react';
|
|
2
3
|
import { type _InternalTypes } from 'remotion';
|
|
4
|
+
import { type CompositionSelectorActiveDrag } from './composition-selector-drag-data';
|
|
3
5
|
export type CompositionSelectorItemType = {
|
|
4
6
|
key: string;
|
|
5
7
|
type: 'composition';
|
|
@@ -20,5 +22,10 @@ export declare const CompositionSelectorItem: React.FC<{
|
|
|
20
22
|
readonly selectComposition: (c: _InternalTypes['AnyComposition'], push: boolean) => void;
|
|
21
23
|
readonly toggleFolder: (folderName: string, parentName: string | null) => void;
|
|
22
24
|
readonly clearRootDragHover: () => void;
|
|
25
|
+
readonly canReorder: boolean;
|
|
23
26
|
readonly level: number;
|
|
27
|
+
readonly activeDragRef: MutableRefObject<CompositionSelectorActiveDrag | null>;
|
|
28
|
+
readonly parentFolderPath: string | null;
|
|
29
|
+
readonly previousSibling: CompositionSelectorItemType | null;
|
|
30
|
+
readonly nextSibling: CompositionSelectorItemType | null;
|
|
24
31
|
}>;
|