@remotion/studio
Version:
APIs for interacting with the Remotion Studio
243 lines (242 loc) • 11.8 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AssetFolderTree = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = __importStar(require("react"));
const remotion_1 = require("remotion");
const no_react_1 = require("remotion/no-react");
const colors_1 = require("../helpers/colors");
const copy_text_1 = require("../helpers/copy-text");
const mobile_layout_1 = require("../helpers/mobile-layout");
const url_state_1 = require("../helpers/url-state");
const use_asset_drag_events_1 = __importDefault(require("../helpers/use-asset-drag-events"));
const clipboard_1 = require("../icons/clipboard");
const file_1 = require("../icons/file");
const folder_1 = require("../icons/folder");
const sidebar_1 = require("../state/sidebar");
const InlineAction_1 = require("./InlineAction");
const layout_1 = require("./layout");
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
const actions_1 = require("./RenderQueue/actions");
const ASSET_ITEM_HEIGHT = 32;
const iconStyle = {
width: 18,
height: 18,
flexShrink: 0,
};
const itemStyle = {
paddingRight: 10,
paddingTop: 6,
paddingBottom: 6,
fontSize: 13,
display: 'flex',
textDecoration: 'none',
cursor: 'default',
alignItems: 'center',
marginBottom: 1,
appearance: 'none',
border: 'none',
width: '100%',
textAlign: 'left',
backgroundColor: colors_1.BACKGROUND,
height: ASSET_ITEM_HEIGHT,
userSelect: 'none',
WebkitUserSelect: 'none',
};
const labelStyle = {
textAlign: 'left',
textDecoration: 'none',
fontSize: 13,
flex: '1 1 0%',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
};
const revealIconStyle = {
height: 12,
color: 'currentColor',
};
const AssetFolderItem = ({ tabIndex, item, level, parentFolder, toggleFolder, dropLocation, setDropLocation, readOnlyStudio, }) => {
const [hovered, setHovered] = (0, react_1.useState)(false);
const openFolderTimerRef = (0, react_1.useRef)(null);
const { isDropDiv, onDragEnter, onDragLeave } = (0, use_asset_drag_events_1.default)({
name: item.name,
parentFolder,
dropLocation,
setDropLocation,
});
const onPointerEnter = (0, react_1.useCallback)(() => {
setHovered(true);
}, []);
const onPointerLeave = (0, react_1.useCallback)(() => {
setHovered(false);
}, []);
const folderStyle = (0, react_1.useMemo)(() => {
return {
...itemStyle,
paddingLeft: 4 + level * 8,
backgroundColor: hovered ? colors_1.CLEAR_HOVER : 'transparent',
};
}, [hovered, level]);
const label = (0, react_1.useMemo)(() => {
return {
...labelStyle,
color: hovered ? 'white' : colors_1.LIGHT_TEXT,
};
}, [hovered]);
const onClick = (0, react_1.useCallback)(() => {
toggleFolder(item.name, parentFolder);
}, [item.name, parentFolder, toggleFolder]);
const Icon = item.expanded ? folder_1.ExpandedFolderIcon : folder_1.CollapsedFolderIcon;
return (jsx_runtime_1.jsxs("div", { onDragEnter: onDragEnter, onDragLeave: onDragLeave, style: {
backgroundColor: isDropDiv ? colors_1.CLEAR_HOVER : colors_1.BACKGROUND,
}, children: [
jsx_runtime_1.jsx("div", { style: folderStyle, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, tabIndex: tabIndex, title: item.name, onClick: onClick, onDragEnter: () => {
if (!item.expanded) {
openFolderTimerRef.current = window.setTimeout(() => {
toggleFolder(item.name, parentFolder);
}, 1000);
}
}, onDragLeave: () => {
if (openFolderTimerRef.current) {
clearTimeout(openFolderTimerRef.current);
}
}, children: jsx_runtime_1.jsxs(layout_1.Row, { children: [
jsx_runtime_1.jsx(Icon, { style: iconStyle, color: hovered ? 'white' : colors_1.LIGHT_TEXT }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("div", { style: label, children: item.name })
] }) }), item.expanded ? (jsx_runtime_1.jsx(exports.AssetFolderTree, { item: item.items, name: item.name, level: level, parentFolder: parentFolder, tabIndex: tabIndex, toggleFolder: toggleFolder, dropLocation: dropLocation, setDropLocation: setDropLocation, readOnlyStudio: readOnlyStudio }, item.name)) : null] }));
};
const AssetFolderTree = ({ item, level, name, parentFolder, toggleFolder, tabIndex, dropLocation, setDropLocation, readOnlyStudio, }) => {
const combinedParents = (0, react_1.useMemo)(() => {
return [parentFolder, name].filter(no_react_1.NoReactInternals.truthy).join('/');
}, [name, parentFolder]);
return (jsx_runtime_1.jsxs("div", { children: [item.folders.map((folder) => {
return (jsx_runtime_1.jsx(AssetFolderItem, { item: folder, tabIndex: tabIndex, level: level + 1, parentFolder: combinedParents, toggleFolder: toggleFolder, dropLocation: dropLocation, setDropLocation: setDropLocation, readOnlyStudio: readOnlyStudio }, folder.name));
}), item.files.map((file) => {
return (jsx_runtime_1.jsx(AssetSelectorItem, { item: file, tabIndex: tabIndex, level: level, parentFolder: combinedParents, readOnlyStudio: readOnlyStudio }, file.src));
})] }));
};
exports.AssetFolderTree = AssetFolderTree;
const AssetSelectorItem = ({ item, tabIndex, level, parentFolder, readOnlyStudio }) => {
const isMobileLayout = (0, mobile_layout_1.useMobileLayout)();
const [hovered, setHovered] = (0, react_1.useState)(false);
const { setSidebarCollapsedState } = (0, react_1.useContext)(sidebar_1.SidebarContext);
const onPointerEnter = (0, react_1.useCallback)(() => {
setHovered(true);
}, []);
const { setCanvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionSetters);
const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
const relativePath = (0, react_1.useMemo)(() => {
return parentFolder ? parentFolder + '/' + item.name : item.name;
}, [parentFolder, item.name]);
const selected = (0, react_1.useMemo)(() => {
if (canvasContent && canvasContent.type === 'asset') {
return canvasContent.asset === relativePath;
}
return false;
}, [canvasContent, relativePath]);
const onPointerLeave = (0, react_1.useCallback)(() => {
setHovered(false);
}, []);
const onClick = (0, react_1.useCallback)(() => {
setCanvasContent({ type: 'asset', asset: relativePath });
(0, url_state_1.pushUrl)(`/assets/${relativePath}`);
if (isMobileLayout) {
setSidebarCollapsedState({ left: 'collapsed', right: 'collapsed' });
}
}, [
isMobileLayout,
relativePath,
setCanvasContent,
setSidebarCollapsedState,
]);
const style = (0, react_1.useMemo)(() => {
return {
...itemStyle,
color: hovered || selected ? 'white' : colors_1.LIGHT_TEXT,
backgroundColor: hovered
? selected
? colors_1.SELECTED_BACKGROUND
: colors_1.CLEAR_HOVER
: selected
? colors_1.SELECTED_BACKGROUND
: 'transparent',
paddingLeft: 12 + level * 8,
};
}, [hovered, level, selected]);
const label = (0, react_1.useMemo)(() => {
return {
...labelStyle,
color: hovered || selected ? 'white' : colors_1.LIGHT_TEXT,
};
}, [hovered, selected]);
const renderFileExplorerAction = (0, react_1.useCallback)((color) => {
return jsx_runtime_1.jsx(folder_1.ExpandedFolderIcon, { style: revealIconStyle, color: color });
}, []);
const renderCopyAction = (0, react_1.useCallback)((color) => {
return jsx_runtime_1.jsx(clipboard_1.ClipboardIcon, { style: revealIconStyle, color: color });
}, []);
const revealInExplorer = react_1.default.useCallback((e) => {
e.stopPropagation();
(0, actions_1.openInFileExplorer)({
directory: window.remotion_publicFolderExists +
'/' +
parentFolder +
'/' +
item.name,
}).catch((err) => {
(0, NotificationCenter_1.showNotification)(`Could not open file: ${err.message}`, 2000);
});
}, [item.name, parentFolder]);
const copyToClipboard = (0, react_1.useCallback)((e) => {
e.stopPropagation();
const content = `staticFile("${[parentFolder, item.name].join('/')}")`;
(0, copy_text_1.copyText)(content)
.then(() => {
(0, NotificationCenter_1.showNotification)(`Copied '${content}' to clipboard`, 1000);
})
.catch((err) => {
(0, NotificationCenter_1.showNotification)(`Could not copy: ${err.message}`, 2000);
});
}, [item.name, parentFolder]);
return (jsx_runtime_1.jsx(layout_1.Row, { align: "center", children: jsx_runtime_1.jsxs("div", { style: style, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, onClick: onClick, tabIndex: tabIndex, title: item.name, children: [
jsx_runtime_1.jsx(file_1.FileIcon, { style: iconStyle, color: colors_1.LIGHT_TEXT }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("div", { style: label, children: item.name }), hovered ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(InlineAction_1.InlineAction, { title: "Copy staticFile() name", renderAction: renderCopyAction, onClick: copyToClipboard }), readOnlyStudio ? null : (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(InlineAction_1.InlineAction, { title: "Open in Explorer", renderAction: renderFileExplorerAction, onClick: revealInExplorer })
] }))] })) : null] }) }));
};