@remotion/studio 4.0.470 → 4.0.472
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/AssetSelector.js +10 -1
- package/dist/components/Canvas.js +98 -0
- package/dist/components/CompositionSelectorItem.d.ts +1 -0
- package/dist/components/CompositionSelectorItem.js +12 -4
- package/dist/components/ContextMenu.d.ts +7 -2
- package/dist/components/ContextMenu.js +91 -43
- package/dist/components/Editor.js +14 -6
- package/dist/components/Modals.js +3 -1
- package/dist/components/NewComposition/CodemodFooter.js +2 -2
- package/dist/components/NewComposition/DeleteFolder.d.ts +6 -0
- package/dist/components/NewComposition/DeleteFolder.js +39 -0
- package/dist/components/NewComposition/RenameFolder.d.ts +6 -0
- package/dist/components/NewComposition/RenameFolder.js +60 -0
- package/dist/components/Preview.js +2 -1
- package/dist/components/SelectedOutlineOverlay.d.ts +109 -1
- package/dist/components/SelectedOutlineOverlay.js +489 -73
- package/dist/components/Splitter/SplitterContainer.js +9 -0
- package/dist/components/Splitter/SplitterHandle.js +63 -70
- package/dist/components/Timeline/Timeline.js +121 -1
- package/dist/components/Timeline/TimelineArrayField.d.ts +9 -0
- package/dist/components/Timeline/TimelineArrayField.js +210 -0
- package/dist/components/Timeline/TimelineBooleanField.d.ts +2 -2
- package/dist/components/Timeline/TimelineBooleanField.js +2 -2
- package/dist/components/Timeline/TimelineClipboardKeybindings.d.ts +20 -0
- package/dist/components/Timeline/TimelineClipboardKeybindings.js +265 -0
- package/dist/components/Timeline/TimelineColorField.d.ts +2 -2
- package/dist/components/Timeline/TimelineColorField.js +2 -8
- package/dist/components/Timeline/TimelineDeleteKeybindings.js +15 -0
- package/dist/components/Timeline/TimelineDragHandler.js +1 -0
- package/dist/components/Timeline/TimelineEffectItem.js +159 -6
- package/dist/components/Timeline/TimelineEffectPropItem.js +95 -25
- package/dist/components/Timeline/TimelineEnumField.d.ts +2 -2
- package/dist/components/Timeline/TimelineEnumField.js +3 -3
- package/dist/components/Timeline/TimelineKeyframeControls.d.ts +4 -3
- package/dist/components/Timeline/TimelineKeyframeControls.js +52 -33
- package/dist/components/Timeline/TimelineKeyframedValue.d.ts +7 -2
- package/dist/components/Timeline/TimelineKeyframedValue.js +22 -8
- package/dist/components/Timeline/TimelineLayerEye.d.ts +1 -0
- package/dist/components/Timeline/TimelineLayerEye.js +8 -3
- package/dist/components/Timeline/TimelineNumberField.d.ts +2 -2
- package/dist/components/Timeline/TimelineNumberField.js +7 -11
- package/dist/components/Timeline/TimelinePrimitiveFieldValue.d.ts +17 -0
- package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +53 -0
- package/dist/components/Timeline/TimelineRotationField.d.ts +2 -2
- package/dist/components/Timeline/TimelineRotationField.js +41 -24
- package/dist/components/Timeline/TimelineRowChrome.d.ts +3 -0
- package/dist/components/Timeline/TimelineRowChrome.js +11 -10
- package/dist/components/Timeline/TimelineScaleField.d.ts +20 -0
- package/dist/components/Timeline/TimelineScaleField.js +314 -0
- package/dist/components/Timeline/TimelineSchemaField.d.ts +3 -2
- package/dist/components/Timeline/TimelineSchemaField.js +8 -42
- package/dist/components/Timeline/TimelineSelection.js +3 -2
- package/dist/components/Timeline/TimelineSequence.d.ts +1 -0
- package/dist/components/Timeline/TimelineSequence.js +51 -10
- package/dist/components/Timeline/TimelineSequenceFrame.js +1 -0
- package/dist/components/Timeline/TimelineSequenceItem.js +97 -7
- package/dist/components/Timeline/TimelineSequencePropItem.js +82 -21
- package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +58 -0
- package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +528 -0
- package/dist/components/Timeline/TimelineTrack.js +1 -1
- package/dist/components/Timeline/TimelineTranslateField.d.ts +2 -2
- package/dist/components/Timeline/TimelineTranslateField.js +21 -25
- package/dist/components/Timeline/TimelineUvCoordinateField.d.ts +2 -2
- package/dist/components/Timeline/TimelineUvCoordinateField.js +20 -26
- package/dist/components/Timeline/call-add-keyframe.js +2 -0
- package/dist/components/Timeline/call-delete-keyframe.d.ts +16 -0
- package/dist/components/Timeline/call-delete-keyframe.js +86 -14
- package/dist/components/Timeline/delete-selected-keyframe.d.ts +10 -0
- package/dist/components/Timeline/delete-selected-keyframe.js +48 -7
- package/dist/components/Timeline/delete-selected-timeline-item.js +6 -11
- package/dist/components/Timeline/get-node-keyframes.d.ts +5 -2
- package/dist/components/Timeline/get-node-keyframes.js +38 -5
- package/dist/components/Timeline/get-timeline-keyframes.js +4 -4
- package/dist/components/Timeline/reset-selected-timeline-props.d.ts +38 -0
- package/dist/components/Timeline/reset-selected-timeline-props.js +156 -0
- package/dist/components/Timeline/sequence-props-subscription-store.d.ts +3 -2
- package/dist/components/Timeline/sequence-props-subscription-store.js +2 -1
- package/dist/components/Timeline/timeline-field-utils.d.ts +1 -0
- package/dist/components/Timeline/timeline-field-utils.js +5 -1
- package/dist/components/Timeline/timeline-scroll-logic.js +3 -3
- package/dist/components/Timeline/timeline-translate-utils.js +6 -2
- package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +7 -0
- package/dist/components/Timeline/use-sequence-props-subscription.js +2 -1
- package/dist/components/TopPanel.d.ts +1 -1
- package/dist/components/folder-menu-items.d.ts +12 -0
- package/dist/components/folder-menu-items.js +147 -0
- package/dist/components/import-assets.d.ts +6 -0
- package/dist/components/import-assets.js +157 -0
- package/dist/esm/{chunk-dny42qnq.js → chunk-48grt472.js} +9717 -5925
- package/dist/esm/internals.mjs +9717 -5925
- package/dist/esm/previewEntry.mjs +9531 -5737
- package/dist/esm/renderEntry.mjs +1 -1
- package/dist/helpers/calculate-timeline.js +7 -3
- package/dist/helpers/create-folder-tree.js +1 -0
- package/dist/helpers/detect-file-type.d.ts +69 -0
- package/dist/helpers/detect-file-type.js +278 -0
- package/dist/helpers/get-folder-id.d.ts +4 -0
- package/dist/helpers/get-folder-id.js +7 -0
- package/dist/helpers/get-left-of-timeline-slider.js +1 -1
- package/dist/helpers/get-timeline-sequence-layout.js +10 -11
- package/dist/helpers/get-timeline-sequence-sort-key.d.ts +2 -0
- package/dist/helpers/open-in-editor.d.ts +19 -1
- package/dist/helpers/open-in-editor.js +42 -4
- package/dist/helpers/timeline-layout.js +5 -1
- package/dist/helpers/use-menu-structure.js +0 -1
- package/dist/helpers/validate-folder-rename.d.ts +6 -0
- package/dist/helpers/validate-folder-rename.js +19 -0
- package/dist/state/modals.d.ts +10 -0
- package/dist/state/scale-lock.d.ts +18 -0
- package/dist/state/scale-lock.js +59 -0
- package/dist/state/z-index.js +5 -2
- package/package.json +10 -10
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import type { SequenceSchema } from 'remotion';
|
|
1
|
+
import type { SequenceNodePath, SequenceSchema } from 'remotion';
|
|
2
2
|
import { callApi } from '../call-api';
|
|
3
3
|
type SubscribeResult = Awaited<ReturnType<typeof callApi<'/api/subscribe-to-sequence-props'>>>;
|
|
4
4
|
type ApplyResult = (result: SubscribeResult) => void;
|
|
5
|
-
export declare const acquireSequencePropsSubscription: ({ fileName, line, column, schema, effects, clientId, applyOnce, applyEach, }: {
|
|
5
|
+
export declare const acquireSequencePropsSubscription: ({ fileName, line, column, schema, effects, nodePath, clientId, applyOnce, applyEach, }: {
|
|
6
6
|
fileName: string;
|
|
7
7
|
line: number;
|
|
8
8
|
column: number;
|
|
9
9
|
schema: SequenceSchema;
|
|
10
10
|
effects: SequenceSchema[];
|
|
11
|
+
nodePath: SequenceNodePath | null;
|
|
11
12
|
clientId: string;
|
|
12
13
|
applyOnce: ApplyResult;
|
|
13
14
|
applyEach: ApplyResult;
|
|
@@ -6,7 +6,7 @@ const remotion_1 = require("remotion");
|
|
|
6
6
|
const call_api_1 = require("../call-api");
|
|
7
7
|
const makeKey = (fileName, line, column, sequenceKeys, effectKeys) => `${fileName}\0${line}\0${column}\0${sequenceKeys.join('\0')}\0${effectKeys.map((keys) => keys.join('\0')).join('\0\0')}`;
|
|
8
8
|
const entries = new Map();
|
|
9
|
-
const acquireSequencePropsSubscription = ({ fileName, line, column, schema, effects, clientId, applyOnce, applyEach, }) => {
|
|
9
|
+
const acquireSequencePropsSubscription = ({ fileName, line, column, schema, effects, nodePath, clientId, applyOnce, applyEach, }) => {
|
|
10
10
|
const sequenceKeys = (0, studio_shared_1.getAllSchemaKeys)(schema);
|
|
11
11
|
const effectKeys = effects.map((effect) => (0, studio_shared_1.getAllSchemaKeys)(effect));
|
|
12
12
|
const key = makeKey(fileName, line, column, sequenceKeys, effectKeys);
|
|
@@ -16,6 +16,7 @@ const acquireSequencePropsSubscription = ({ fileName, line, column, schema, effe
|
|
|
16
16
|
fileName,
|
|
17
17
|
line,
|
|
18
18
|
column,
|
|
19
|
+
nodePath,
|
|
19
20
|
keys: (0, studio_shared_1.getAllSchemaKeys)(schema),
|
|
20
21
|
effects: effectKeys,
|
|
21
22
|
clientId,
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.draggerStyle = exports.getDecimalPlaces = void 0;
|
|
3
|
+
exports.draggerStyle = exports.normalizeTimelineNumber = exports.getDecimalPlaces = void 0;
|
|
4
4
|
const getDecimalPlaces = (num) => {
|
|
5
5
|
const str = String(num);
|
|
6
6
|
const decimalIndex = str.indexOf('.');
|
|
7
7
|
return decimalIndex === -1 ? 0 : str.length - decimalIndex - 1;
|
|
8
8
|
};
|
|
9
9
|
exports.getDecimalPlaces = getDecimalPlaces;
|
|
10
|
+
const normalizeTimelineNumber = (value) => {
|
|
11
|
+
return Math.round(value * 1000000) / 1000000;
|
|
12
|
+
};
|
|
13
|
+
exports.normalizeTimelineNumber = normalizeTimelineNumber;
|
|
10
14
|
exports.draggerStyle = {
|
|
11
15
|
width: 80,
|
|
12
16
|
};
|
|
@@ -172,7 +172,7 @@ const getFrameIncrement = (durationInFrames) => {
|
|
|
172
172
|
return (0, exports.getFrameIncrementFromWidth)(durationInFrames, width);
|
|
173
173
|
};
|
|
174
174
|
const getFrameIncrementFromWidth = (durationInFrames, width) => {
|
|
175
|
-
return (width - timeline_layout_1.TIMELINE_PADDING * 2) /
|
|
175
|
+
return (width - timeline_layout_1.TIMELINE_PADDING * 2) / durationInFrames;
|
|
176
176
|
};
|
|
177
177
|
exports.getFrameIncrementFromWidth = getFrameIncrementFromWidth;
|
|
178
178
|
const getFrameWhileScrollingRight = ({ durationInFrames, width, }) => {
|
|
@@ -193,10 +193,10 @@ const getFrameWhileScrollingRight = ({ durationInFrames, width, }) => {
|
|
|
193
193
|
exports.getFrameWhileScrollingRight = getFrameWhileScrollingRight;
|
|
194
194
|
const getFrameFromX = ({ clientX, durationInFrames, width, extrapolate, }) => {
|
|
195
195
|
const pos = clientX - timeline_layout_1.TIMELINE_PADDING;
|
|
196
|
-
const frame = Math.round((0, remotion_1.interpolate)(pos, [0, width - timeline_layout_1.TIMELINE_PADDING * 2], [0, durationInFrames
|
|
196
|
+
const frame = Math.min(durationInFrames - 1, Math.round((0, remotion_1.interpolate)(pos, [0, width - timeline_layout_1.TIMELINE_PADDING * 2], [0, durationInFrames], {
|
|
197
197
|
extrapolateLeft: extrapolate,
|
|
198
198
|
extrapolateRight: extrapolate,
|
|
199
|
-
}));
|
|
199
|
+
})));
|
|
200
200
|
return frame;
|
|
201
201
|
};
|
|
202
202
|
exports.getFrameFromX = getFrameFromX;
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.serializeTranslate = exports.parseTranslate = void 0;
|
|
4
|
+
const timeline_field_utils_1 = require("./timeline-field-utils");
|
|
4
5
|
const PIXEL_PATTERN = /^(-?\d+(?:\.\d+)?)px(?:\s+(-?\d+(?:\.\d+)?)px)?$/;
|
|
5
6
|
const parseTranslate = (value) => {
|
|
6
7
|
const m = value.match(PIXEL_PATTERN);
|
|
7
8
|
if (!m) {
|
|
8
9
|
return [0, 0];
|
|
9
10
|
}
|
|
10
|
-
return [
|
|
11
|
+
return [
|
|
12
|
+
(0, timeline_field_utils_1.normalizeTimelineNumber)(Number(m[1])),
|
|
13
|
+
m[2] !== undefined ? (0, timeline_field_utils_1.normalizeTimelineNumber)(Number(m[2])) : 0,
|
|
14
|
+
];
|
|
11
15
|
};
|
|
12
16
|
exports.parseTranslate = parseTranslate;
|
|
13
17
|
const formatTranslateCoordinate = (value) => {
|
|
14
|
-
const rounded =
|
|
18
|
+
const rounded = (0, timeline_field_utils_1.normalizeTimelineNumber)(value);
|
|
15
19
|
return String(Object.is(rounded, -0) ? 0 : rounded);
|
|
16
20
|
};
|
|
17
21
|
const serializeTranslate = (x, y) => {
|
|
@@ -11,6 +11,7 @@ const useExpandedTrackKeyframeRows = ({ sequence, nodePathInfo, keyframeDisplayO
|
|
|
11
11
|
const { getIsExpanded } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksGetterContext);
|
|
12
12
|
const { codeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeCodeValuesContext);
|
|
13
13
|
const { getDragOverrides, getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
|
|
14
|
+
const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
|
|
14
15
|
const tree = (0, react_1.useMemo)(() => (0, timeline_layout_1.buildTimelineTree)({
|
|
15
16
|
sequence,
|
|
16
17
|
nodePathInfo,
|
|
@@ -38,14 +39,20 @@ const useExpandedTrackKeyframeRows = ({ sequence, nodePathInfo, keyframeDisplayO
|
|
|
38
39
|
nodePath: nodePathInfo.sequenceSubscriptionKey,
|
|
39
40
|
codeValues,
|
|
40
41
|
keyframeDisplayOffset,
|
|
42
|
+
getDragOverrides,
|
|
43
|
+
getEffectDragOverrides,
|
|
44
|
+
timelinePosition,
|
|
41
45
|
}),
|
|
42
46
|
rowKey: (0, timeline_node_path_key_1.timelineNodePathInfoToKey)(node.nodePathInfo),
|
|
43
47
|
nodePathInfo: node.nodePathInfo,
|
|
44
48
|
})), [
|
|
45
49
|
codeValues,
|
|
46
50
|
flat,
|
|
51
|
+
getDragOverrides,
|
|
52
|
+
getEffectDragOverrides,
|
|
47
53
|
keyframeDisplayOffset,
|
|
48
54
|
nodePathInfo.sequenceSubscriptionKey,
|
|
55
|
+
timelinePosition,
|
|
49
56
|
]);
|
|
50
57
|
return { rows, expandedHeight };
|
|
51
58
|
};
|
|
@@ -36,7 +36,7 @@ const useSequencePropsSubscription = ({ originalLocation, overrideId, schema, ef
|
|
|
36
36
|
const locationLine = (_b = validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.line) !== null && _b !== void 0 ? _b : null;
|
|
37
37
|
const locationColumn = (_c = validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.column) !== null && _c !== void 0 ? _c : null;
|
|
38
38
|
(0, react_1.useEffect)(() => {
|
|
39
|
-
var _a;
|
|
39
|
+
var _a, _b;
|
|
40
40
|
if (!clientId ||
|
|
41
41
|
!locationSource ||
|
|
42
42
|
!locationLine ||
|
|
@@ -51,6 +51,7 @@ const useSequencePropsSubscription = ({ originalLocation, overrideId, schema, ef
|
|
|
51
51
|
column: locationColumn,
|
|
52
52
|
schema,
|
|
53
53
|
effects,
|
|
54
|
+
nodePath: (_b = nodePathAtResubscribe === null || nodePathAtResubscribe === void 0 ? void 0 : nodePathAtResubscribe.nodePath) !== null && _b !== void 0 ? _b : null,
|
|
54
55
|
clientId,
|
|
55
56
|
applyOnce: (result) => {
|
|
56
57
|
if (!result.success) {
|
|
@@ -3,6 +3,6 @@ export declare const useResponsiveSidebarStatus: () => "collapsed" | "expanded";
|
|
|
3
3
|
export declare const TopPanel: React.NamedExoticComponent<{
|
|
4
4
|
readonly readOnlyStudio: boolean;
|
|
5
5
|
readonly onMounted: () => void;
|
|
6
|
-
readonly drawRef: React.
|
|
6
|
+
readonly drawRef: React.Ref<HTMLDivElement>;
|
|
7
7
|
readonly bufferStateDelayInMilliseconds: number;
|
|
8
8
|
}>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SetStateAction } from 'react';
|
|
2
|
+
import type { ResolvedStackLocation } from 'remotion';
|
|
3
|
+
import type { ModalState } from '../state/modals';
|
|
4
|
+
import type { ComboboxValue } from './NewComposition/ComboBox';
|
|
5
|
+
export declare const getFolderMenuItems: ({ closeMenu, connectionStatus, folder, readOnlyStudio, resolvedLocation, setSelectedModal, }: {
|
|
6
|
+
closeMenu: () => void;
|
|
7
|
+
connectionStatus: "connected" | "disconnected" | "init";
|
|
8
|
+
folder: import("remotion").TFolder;
|
|
9
|
+
readOnlyStudio: boolean;
|
|
10
|
+
resolvedLocation: ResolvedStackLocation | null;
|
|
11
|
+
setSelectedModal: (value: SetStateAction<ModalState | null>) => void;
|
|
12
|
+
}) => ComboboxValue[];
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getFolderMenuItems = void 0;
|
|
4
|
+
const no_react_1 = require("remotion/no-react");
|
|
5
|
+
const format_file_location_1 = require("../helpers/format-file-location");
|
|
6
|
+
const get_folder_id_1 = require("../helpers/get-folder-id");
|
|
7
|
+
const open_in_editor_1 = require("../helpers/open-in-editor");
|
|
8
|
+
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
|
|
9
|
+
const getFolderMenuItems = ({ closeMenu, connectionStatus, folder, readOnlyStudio, resolvedLocation, setSelectedModal, }) => {
|
|
10
|
+
const editorName = window.remotion_editorName;
|
|
11
|
+
const folderId = (0, get_folder_id_1.getFolderId)({
|
|
12
|
+
folderName: folder.name,
|
|
13
|
+
parentName: folder.parent,
|
|
14
|
+
});
|
|
15
|
+
const fileLocation = (0, format_file_location_1.formatFileLocation)({
|
|
16
|
+
location: resolvedLocation,
|
|
17
|
+
root: window.remotion_cwd,
|
|
18
|
+
});
|
|
19
|
+
const showInEditorDisabled = connectionStatus !== 'connected' || !resolvedLocation;
|
|
20
|
+
const copyFileLocationDisabled = !fileLocation;
|
|
21
|
+
const codemodDisabled = readOnlyStudio || !folder.stack;
|
|
22
|
+
return [
|
|
23
|
+
editorName
|
|
24
|
+
? {
|
|
25
|
+
id: 'show-folder-in-editor',
|
|
26
|
+
keyHint: null,
|
|
27
|
+
label: `Show folder in ${editorName}`,
|
|
28
|
+
leftItem: null,
|
|
29
|
+
onClick: async () => {
|
|
30
|
+
closeMenu();
|
|
31
|
+
if (!resolvedLocation) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
await (0, open_in_editor_1.openOriginalPositionInEditor)(resolvedLocation);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
(0, NotificationCenter_1.showNotification)(err.message, 2000);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
quickSwitcherLabel: `Show folder in ${editorName}`,
|
|
42
|
+
subMenu: null,
|
|
43
|
+
type: 'item',
|
|
44
|
+
value: 'show-folder-in-editor',
|
|
45
|
+
disabled: showInEditorDisabled,
|
|
46
|
+
}
|
|
47
|
+
: null,
|
|
48
|
+
{
|
|
49
|
+
id: 'copy-folder-file-location',
|
|
50
|
+
keyHint: null,
|
|
51
|
+
label: `Copy file location`,
|
|
52
|
+
leftItem: null,
|
|
53
|
+
onClick: () => {
|
|
54
|
+
closeMenu();
|
|
55
|
+
if (!fileLocation) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
navigator.clipboard
|
|
59
|
+
.writeText(fileLocation)
|
|
60
|
+
.then(() => {
|
|
61
|
+
(0, NotificationCenter_1.showNotification)('Copied file location to clipboard', 1000);
|
|
62
|
+
})
|
|
63
|
+
.catch((err) => {
|
|
64
|
+
(0, NotificationCenter_1.showNotification)(`Could not copy to clipboard: ${err.message}`, 1000);
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
quickSwitcherLabel: 'Copy folder file location',
|
|
68
|
+
subMenu: null,
|
|
69
|
+
type: 'item',
|
|
70
|
+
value: 'copy-folder-file-location',
|
|
71
|
+
disabled: copyFileLocationDisabled,
|
|
72
|
+
},
|
|
73
|
+
editorName || fileLocation
|
|
74
|
+
? {
|
|
75
|
+
type: 'divider',
|
|
76
|
+
id: 'show-folder-in-editor-divider',
|
|
77
|
+
}
|
|
78
|
+
: null,
|
|
79
|
+
{
|
|
80
|
+
id: 'rename-folder',
|
|
81
|
+
keyHint: null,
|
|
82
|
+
label: `Rename...`,
|
|
83
|
+
leftItem: null,
|
|
84
|
+
onClick: () => {
|
|
85
|
+
closeMenu();
|
|
86
|
+
setSelectedModal({
|
|
87
|
+
type: 'rename-folder',
|
|
88
|
+
folderName: folder.name,
|
|
89
|
+
parentName: folder.parent,
|
|
90
|
+
stack: folder.stack,
|
|
91
|
+
});
|
|
92
|
+
},
|
|
93
|
+
quickSwitcherLabel: 'Rename folder...',
|
|
94
|
+
subMenu: null,
|
|
95
|
+
type: 'item',
|
|
96
|
+
value: 'rename-folder',
|
|
97
|
+
disabled: codemodDisabled,
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: 'delete-folder',
|
|
101
|
+
keyHint: null,
|
|
102
|
+
label: `Delete...`,
|
|
103
|
+
leftItem: null,
|
|
104
|
+
onClick: () => {
|
|
105
|
+
closeMenu();
|
|
106
|
+
setSelectedModal({
|
|
107
|
+
type: 'delete-folder',
|
|
108
|
+
folderName: folder.name,
|
|
109
|
+
parentName: folder.parent,
|
|
110
|
+
stack: folder.stack,
|
|
111
|
+
});
|
|
112
|
+
},
|
|
113
|
+
quickSwitcherLabel: 'Delete folder...',
|
|
114
|
+
subMenu: null,
|
|
115
|
+
type: 'item',
|
|
116
|
+
value: 'delete-folder',
|
|
117
|
+
disabled: codemodDisabled,
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
type: 'divider',
|
|
121
|
+
id: 'copy-folder-id-divider',
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
id: 'copy-folder-id',
|
|
125
|
+
keyHint: null,
|
|
126
|
+
label: `Copy ID`,
|
|
127
|
+
leftItem: null,
|
|
128
|
+
onClick: () => {
|
|
129
|
+
closeMenu();
|
|
130
|
+
navigator.clipboard
|
|
131
|
+
.writeText(folderId)
|
|
132
|
+
.then(() => {
|
|
133
|
+
(0, NotificationCenter_1.showNotification)('Copied to clipboard', 1000);
|
|
134
|
+
})
|
|
135
|
+
.catch((err) => {
|
|
136
|
+
(0, NotificationCenter_1.showNotification)(`Could not copy to clipboard: ${err.message}`, 1000);
|
|
137
|
+
});
|
|
138
|
+
},
|
|
139
|
+
quickSwitcherLabel: 'Copy folder ID',
|
|
140
|
+
subMenu: null,
|
|
141
|
+
type: 'item',
|
|
142
|
+
value: 'copy-folder-id',
|
|
143
|
+
disabled: false,
|
|
144
|
+
},
|
|
145
|
+
].filter(no_react_1.NoReactInternals.truthy);
|
|
146
|
+
};
|
|
147
|
+
exports.getFolderMenuItems = getFolderMenuItems;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.importAssets = exports.pickFilesToImport = void 0;
|
|
4
|
+
const get_static_files_1 = require("../api/get-static-files");
|
|
5
|
+
const write_static_file_1 = require("../api/write-static-file");
|
|
6
|
+
const detect_file_type_1 = require("../helpers/detect-file-type");
|
|
7
|
+
const call_api_1 = require("./call-api");
|
|
8
|
+
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
|
|
9
|
+
const getAssetElement = ({ fileType, src, }) => {
|
|
10
|
+
if (fileType.type === 'png' ||
|
|
11
|
+
fileType.type === 'jpeg' ||
|
|
12
|
+
fileType.type === 'webp' ||
|
|
13
|
+
fileType.type === 'bmp') {
|
|
14
|
+
return {
|
|
15
|
+
type: 'asset',
|
|
16
|
+
assetType: 'image',
|
|
17
|
+
src,
|
|
18
|
+
dimensions: fileType.dimensions,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
if (fileType.type === 'gif') {
|
|
22
|
+
return {
|
|
23
|
+
type: 'asset',
|
|
24
|
+
assetType: 'gif',
|
|
25
|
+
src,
|
|
26
|
+
dimensions: fileType.dimensions,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
if (fileType.type === 'riff' ||
|
|
30
|
+
fileType.type === 'webm' ||
|
|
31
|
+
fileType.type === 'iso-base-media' ||
|
|
32
|
+
fileType.type === 'transport-stream') {
|
|
33
|
+
return {
|
|
34
|
+
type: 'asset',
|
|
35
|
+
assetType: 'video',
|
|
36
|
+
src,
|
|
37
|
+
dimensions: null,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
};
|
|
42
|
+
const getAssetLabel = (element) => {
|
|
43
|
+
if (element.type !== 'asset') {
|
|
44
|
+
throw new Error('Expected asset element');
|
|
45
|
+
}
|
|
46
|
+
if (element.assetType === 'image') {
|
|
47
|
+
return '<Img>';
|
|
48
|
+
}
|
|
49
|
+
if (element.assetType === 'video') {
|
|
50
|
+
return '<Video>';
|
|
51
|
+
}
|
|
52
|
+
return '<Gif>';
|
|
53
|
+
};
|
|
54
|
+
const pickFilesToImport = () => {
|
|
55
|
+
return new Promise((resolve) => {
|
|
56
|
+
const input = document.createElement('input');
|
|
57
|
+
input.type = 'file';
|
|
58
|
+
input.multiple = true;
|
|
59
|
+
input.style.display = 'none';
|
|
60
|
+
let didResolve = false;
|
|
61
|
+
const resolveOnce = (files) => {
|
|
62
|
+
if (didResolve) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
didResolve = true;
|
|
66
|
+
input.removeEventListener('change', onChange);
|
|
67
|
+
input.removeEventListener('cancel', onCancel);
|
|
68
|
+
input.remove();
|
|
69
|
+
resolve(files);
|
|
70
|
+
};
|
|
71
|
+
const onChange = () => {
|
|
72
|
+
var _a;
|
|
73
|
+
return resolveOnce(Array.from((_a = input.files) !== null && _a !== void 0 ? _a : []));
|
|
74
|
+
};
|
|
75
|
+
const onCancel = () => resolveOnce([]);
|
|
76
|
+
input.addEventListener('change', onChange);
|
|
77
|
+
input.addEventListener('cancel', onCancel);
|
|
78
|
+
document.body.appendChild(input);
|
|
79
|
+
input.click();
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
exports.pickFilesToImport = pickFilesToImport;
|
|
83
|
+
const importAssets = async ({ compositionFile, compositionId, files, }) => {
|
|
84
|
+
if (files.length === 0) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const staticFiles = (0, get_static_files_1.getStaticFiles)();
|
|
88
|
+
const differentExistingFile = files.find((file) => {
|
|
89
|
+
return staticFiles.some((staticFile) => staticFile.name === file.name && staticFile.sizeInBytes !== file.size);
|
|
90
|
+
});
|
|
91
|
+
if (differentExistingFile) {
|
|
92
|
+
(0, NotificationCenter_1.showNotification)(`File with name ${differentExistingFile.name} already exists and is different`, 4000);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const insertedLabels = [];
|
|
96
|
+
const addedStaticFiles = [];
|
|
97
|
+
const unsupportedFiles = [];
|
|
98
|
+
const notifyAddedStaticFiles = () => {
|
|
99
|
+
if (addedStaticFiles.length === 1) {
|
|
100
|
+
(0, NotificationCenter_1.showNotification)(`Created ${addedStaticFiles[0]} in public folder`, 3000);
|
|
101
|
+
}
|
|
102
|
+
else if (addedStaticFiles.length > 1) {
|
|
103
|
+
(0, NotificationCenter_1.showNotification)(`Added ${addedStaticFiles.length} files to public folder`, 3000);
|
|
104
|
+
}
|
|
105
|
+
addedStaticFiles.length = 0;
|
|
106
|
+
};
|
|
107
|
+
try {
|
|
108
|
+
for (const file of files) {
|
|
109
|
+
const contents = await file.arrayBuffer();
|
|
110
|
+
const fileType = (0, detect_file_type_1.detectFileType)(new Uint8Array(contents));
|
|
111
|
+
const element = getAssetElement({
|
|
112
|
+
fileType,
|
|
113
|
+
src: file.name,
|
|
114
|
+
});
|
|
115
|
+
if (element === null) {
|
|
116
|
+
unsupportedFiles.push(file.name);
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
const alreadyExists = staticFiles.some((staticFile) => staticFile.name === file.name && staticFile.sizeInBytes === file.size);
|
|
120
|
+
if (!alreadyExists) {
|
|
121
|
+
await (0, write_static_file_1.writeStaticFile)({
|
|
122
|
+
contents,
|
|
123
|
+
filePath: file.name,
|
|
124
|
+
});
|
|
125
|
+
addedStaticFiles.push(file.name);
|
|
126
|
+
}
|
|
127
|
+
const result = await (0, call_api_1.callApi)('/api/insert-jsx-element', {
|
|
128
|
+
compositionFile,
|
|
129
|
+
compositionId,
|
|
130
|
+
element,
|
|
131
|
+
});
|
|
132
|
+
if (!result.success) {
|
|
133
|
+
notifyAddedStaticFiles();
|
|
134
|
+
(0, NotificationCenter_1.showNotification)(result.reason, 4000);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
insertedLabels.push(getAssetLabel(element));
|
|
138
|
+
}
|
|
139
|
+
notifyAddedStaticFiles();
|
|
140
|
+
if (insertedLabels.length === 1) {
|
|
141
|
+
(0, NotificationCenter_1.showNotification)(`Added ${insertedLabels[0]} to source file`, 2000);
|
|
142
|
+
}
|
|
143
|
+
else if (insertedLabels.length > 1) {
|
|
144
|
+
(0, NotificationCenter_1.showNotification)(`Added ${insertedLabels.length} assets to source file`, 2000);
|
|
145
|
+
}
|
|
146
|
+
if (unsupportedFiles.length === 1) {
|
|
147
|
+
(0, NotificationCenter_1.showNotification)(`Cannot add ${unsupportedFiles[0]}: Unsupported file type`, 3000);
|
|
148
|
+
}
|
|
149
|
+
else if (unsupportedFiles.length > 1) {
|
|
150
|
+
(0, NotificationCenter_1.showNotification)(`Skipped ${unsupportedFiles.length} unsupported files`, 3000);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
(0, NotificationCenter_1.showNotification)(`Could not add asset: ${error instanceof Error ? error.message : String(error)}`, 4000);
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
exports.importAssets = importAssets;
|