Add .gitignore to exclude all node packages and lock files
This commit is contained in:
Generated
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
import React from 'react';
|
||||
type AskAiModalRef = {
|
||||
toggle: () => void;
|
||||
};
|
||||
export declare const askAiModalRef: React.RefObject<AskAiModalRef | null>;
|
||||
export declare const AskAiModal: React.FC;
|
||||
export {};
|
||||
Generated
Vendored
+68
@@ -0,0 +1,68 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AskAiModal = exports.askAiModalRef = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const remotion_1 = require("remotion");
|
||||
const ModalContainer_1 = require("./ModalContainer");
|
||||
const ModalHeader_1 = require("./ModalHeader");
|
||||
const container = {
|
||||
height: 'calc(100vh - 100px)',
|
||||
width: 'calc(100vw - 160px)',
|
||||
maxWidth: 800,
|
||||
maxHeight: 900,
|
||||
display: 'block',
|
||||
};
|
||||
exports.askAiModalRef = (0, react_1.createRef)();
|
||||
const AskAiModal = () => {
|
||||
const [state, setState] = (0, react_1.useState)('never-opened');
|
||||
const iframe = (0, react_1.useRef)(null);
|
||||
(0, react_1.useImperativeHandle)(exports.askAiModalRef, () => ({
|
||||
toggle: () => {
|
||||
setState((s) => {
|
||||
var _a, _b, _c;
|
||||
if (s === 'visible') {
|
||||
(_a = iframe.current) === null || _a === void 0 ? void 0 : _a.blur();
|
||||
(_c = (_b = iframe.current) === null || _b === void 0 ? void 0 : _b.contentWindow) === null || _c === void 0 ? void 0 : _c.blur();
|
||||
}
|
||||
return s === 'visible' ? 'hidden' : 'visible';
|
||||
});
|
||||
},
|
||||
}), []);
|
||||
(0, react_1.useEffect)(() => {
|
||||
const onMessage = (event) => {
|
||||
var _a;
|
||||
try {
|
||||
const json = typeof event.data === 'string' ? JSON.parse(event.data) : event.data;
|
||||
if (json.type === 'cmd-i') {
|
||||
(_a = exports.askAiModalRef.current) === null || _a === void 0 ? void 0 : _a.toggle();
|
||||
}
|
||||
}
|
||||
catch (_b) { }
|
||||
};
|
||||
window.addEventListener('message', onMessage);
|
||||
return () => {
|
||||
window.removeEventListener('message', onMessage);
|
||||
};
|
||||
}, []);
|
||||
const onQuit = (0, react_1.useCallback)(() => {
|
||||
setState('hidden');
|
||||
}, [setState]);
|
||||
// When re-toggling the modal, focus the text box
|
||||
(0, react_1.useEffect)(() => {
|
||||
var _a;
|
||||
if (!iframe.current) {
|
||||
return;
|
||||
}
|
||||
if (state === 'visible') {
|
||||
(_a = iframe.current.contentWindow) === null || _a === void 0 ? void 0 : _a.postMessage({
|
||||
type: 'focus',
|
||||
}, '*');
|
||||
}
|
||||
}, [state]);
|
||||
if (state === 'never-opened') {
|
||||
return null;
|
||||
}
|
||||
return ((0, jsx_runtime_1.jsx)(remotion_1.AbsoluteFill, { style: { display: state === 'visible' ? 'block' : 'none' }, children: (0, jsx_runtime_1.jsxs)(ModalContainer_1.ModalContainer, { noZIndex: state === 'hidden', onOutsideClick: onQuit, onEscape: onQuit, children: [(0, jsx_runtime_1.jsx)(ModalHeader_1.ModalHeader, { title: "Ask AI", onClose: onQuit }), (0, jsx_runtime_1.jsx)("iframe", { ref: iframe, frameBorder: 0, style: container, src: "https://www.remotion.dev/ai-embed", allow: "clipboard-read; clipboard-write" })] }) }));
|
||||
};
|
||||
exports.AskAiModal = AskAiModal;
|
||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
import React from 'react';
|
||||
export declare const AssetSelector: React.FC<{
|
||||
readonly readOnlyStudio: boolean;
|
||||
}>;
|
||||
Generated
Vendored
+165
@@ -0,0 +1,165 @@
|
||||
"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.AssetSelector = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = __importStar(require("react"));
|
||||
const get_static_files_1 = require("../api/get-static-files");
|
||||
const write_static_file_1 = require("../api/write-static-file");
|
||||
const client_id_1 = require("../helpers/client-id");
|
||||
const colors_1 = require("../helpers/colors");
|
||||
const create_folder_tree_1 = require("../helpers/create-folder-tree");
|
||||
const persist_open_folders_1 = require("../helpers/persist-open-folders");
|
||||
const use_asset_drag_events_1 = __importDefault(require("../helpers/use-asset-drag-events"));
|
||||
const folders_1 = require("../state/folders");
|
||||
const z_index_1 = require("../state/z-index");
|
||||
const AssetSelectorItem_1 = require("./AssetSelectorItem");
|
||||
const styles_1 = require("./Menu/styles");
|
||||
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
|
||||
const container = {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flex: 1,
|
||||
overflow: 'hidden',
|
||||
backgroundColor: colors_1.BACKGROUND,
|
||||
};
|
||||
// Some redundancy with packages/cli/src/editor/components/RenderModal/SchemaEditor/SchemaErrorMessages.tsx
|
||||
const emptyState = {
|
||||
display: 'flex',
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
textAlign: 'center',
|
||||
padding: '0 12px',
|
||||
};
|
||||
const label = {
|
||||
color: colors_1.LIGHT_TEXT,
|
||||
lineHeight: 1.5,
|
||||
fontSize: 14,
|
||||
};
|
||||
const list = {
|
||||
height: '100%',
|
||||
overflowY: 'auto',
|
||||
};
|
||||
const AssetSelector = ({ readOnlyStudio }) => {
|
||||
const { tabIndex } = (0, z_index_1.useZIndex)();
|
||||
const { assetFoldersExpanded, setAssetFoldersExpanded } = (0, react_1.useContext)(folders_1.FolderContext);
|
||||
const [dropLocation, setDropLocation] = (0, react_1.useState)(null);
|
||||
const { subscribeToEvent } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
|
||||
const connectionStatus = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx)
|
||||
.previewServerState.type;
|
||||
const shouldAllowUpload = connectionStatus === 'connected' && !readOnlyStudio;
|
||||
const [{ publicFolderExists, staticFiles }, setState] = react_1.default.useState(() => {
|
||||
return {
|
||||
staticFiles: (0, get_static_files_1.getStaticFiles)(),
|
||||
publicFolderExists: window.remotion_publicFolderExists,
|
||||
};
|
||||
});
|
||||
const assetTree = (0, react_1.useMemo)(() => {
|
||||
return (0, create_folder_tree_1.buildAssetFolderStructure)(staticFiles, null, assetFoldersExpanded);
|
||||
}, [assetFoldersExpanded, staticFiles]);
|
||||
(0, react_1.useEffect)(() => {
|
||||
const onUpdate = () => {
|
||||
setState({
|
||||
staticFiles: (0, get_static_files_1.getStaticFiles)(),
|
||||
publicFolderExists: window.remotion_publicFolderExists,
|
||||
});
|
||||
};
|
||||
const unsub = subscribeToEvent('new-public-folder', onUpdate);
|
||||
return () => {
|
||||
unsub();
|
||||
};
|
||||
}, [subscribeToEvent]);
|
||||
const toggleFolder = (0, react_1.useCallback)((folderName, parentName) => {
|
||||
setAssetFoldersExpanded((p) => {
|
||||
var _a;
|
||||
const key = [parentName, folderName].filter(Boolean).join('/');
|
||||
const prev = (_a = p[key]) !== null && _a !== void 0 ? _a : false;
|
||||
const foldersExpandedState = {
|
||||
...p,
|
||||
[key]: !prev,
|
||||
};
|
||||
(0, persist_open_folders_1.persistExpandedFolders)('assets', foldersExpandedState);
|
||||
return foldersExpandedState;
|
||||
});
|
||||
}, [setAssetFoldersExpanded]);
|
||||
const { isDropDiv, onDragEnter, onDragLeave } = (0, use_asset_drag_events_1.default)({
|
||||
name: null,
|
||||
parentFolder: null,
|
||||
dropLocation,
|
||||
setDropLocation,
|
||||
});
|
||||
const onDragOver = (0, react_1.useCallback)((e) => {
|
||||
e.preventDefault();
|
||||
}, []);
|
||||
const onDrop = (0, react_1.useCallback)(async (e) => {
|
||||
try {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const { files } = e.dataTransfer;
|
||||
const assetPath = dropLocation !== null && dropLocation !== void 0 ? dropLocation : null;
|
||||
const makePath = (file) => {
|
||||
return [assetPath, file.name].filter(Boolean).join('/');
|
||||
};
|
||||
for (const file of files) {
|
||||
const body = await file.arrayBuffer();
|
||||
await (0, write_static_file_1.writeStaticFile)({
|
||||
contents: body,
|
||||
filePath: makePath(file),
|
||||
});
|
||||
}
|
||||
if (files.length === 1) {
|
||||
(0, NotificationCenter_1.showNotification)(`Created ${makePath(files[0])}`, 3000);
|
||||
}
|
||||
else {
|
||||
(0, NotificationCenter_1.showNotification)(`Added ${files.length} files to ${assetPath}`, 3000);
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
(0, NotificationCenter_1.showNotification)(`Error during upload: ${error}`, 3000);
|
||||
}
|
||||
finally {
|
||||
setDropLocation(null);
|
||||
}
|
||||
}, [dropLocation]);
|
||||
return ((0, jsx_runtime_1.jsx)("div", { style: container, onDragOver: shouldAllowUpload ? onDragOver : undefined, onDrop: shouldAllowUpload ? onDrop : undefined, children: staticFiles.length === 0 ? (publicFolderExists ? ((0, jsx_runtime_1.jsx)("div", { style: emptyState, children: (0, jsx_runtime_1.jsxs)("div", { style: label, children: ["To add assets, place a file in the", ' ', (0, jsx_runtime_1.jsx)("code", { style: styles_1.inlineCodeSnippet, children: "public" }), " folder of your project or drag and drop a file here."] }) })) : ((0, jsx_runtime_1.jsx)("div", { style: emptyState, children: (0, jsx_runtime_1.jsxs)("div", { style: label, children: ["To add assets, create a folder called", ' ', (0, jsx_runtime_1.jsx)("code", { style: styles_1.inlineCodeSnippet, children: "public" }), " in the root of your project and place a file in it."] }) }))) : ((0, jsx_runtime_1.jsx)("div", { className: "__remotion-vertical-scrollbar", style: {
|
||||
...list,
|
||||
backgroundColor: isDropDiv ? colors_1.CLEAR_HOVER : colors_1.BACKGROUND,
|
||||
}, onDragEnter: onDragEnter, onDragLeave: onDragLeave, children: (0, jsx_runtime_1.jsx)(AssetSelectorItem_1.AssetFolderTree, { item: assetTree, level: 0, parentFolder: null, name: null, tabIndex: tabIndex, toggleFolder: toggleFolder, dropLocation: dropLocation, setDropLocation: setDropLocation }) })) }));
|
||||
};
|
||||
exports.AssetSelector = AssetSelector;
|
||||
Generated
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import type { AssetStructure } from '../helpers/create-folder-tree';
|
||||
export declare const AssetFolderTree: React.FC<{
|
||||
readonly item: AssetStructure;
|
||||
readonly name: string | null;
|
||||
readonly parentFolder: string | null;
|
||||
readonly level: number;
|
||||
readonly tabIndex: number;
|
||||
readonly toggleFolder: (folderName: string, parentName: string | null) => void;
|
||||
readonly dropLocation: string | null;
|
||||
readonly setDropLocation: React.Dispatch<React.SetStateAction<string | null>>;
|
||||
}>;
|
||||
Generated
Vendored
+237
@@ -0,0 +1,237 @@
|
||||
"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 NotificationCenter_1 = require("./Notifications/NotificationCenter");
|
||||
const actions_1 = require("./RenderQueue/actions");
|
||||
const layout_1 = require("./layout");
|
||||
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, }) => {
|
||||
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 ((0, jsx_runtime_1.jsxs)("div", { onDragEnter: onDragEnter, onDragLeave: onDragLeave, style: {
|
||||
backgroundColor: isDropDiv ? colors_1.CLEAR_HOVER : colors_1.BACKGROUND,
|
||||
}, children: [(0, 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: (0, jsx_runtime_1.jsxs)(layout_1.Row, { children: [(0, jsx_runtime_1.jsx)(Icon, { style: iconStyle, color: hovered ? 'white' : colors_1.LIGHT_TEXT }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, jsx_runtime_1.jsx)("div", { style: label, children: item.name })] }) }), item.expanded ? ((0, jsx_runtime_1.jsx)(exports.AssetFolderTree, { item: item.items, name: item.name, level: level, parentFolder: parentFolder, tabIndex: tabIndex, toggleFolder: toggleFolder, dropLocation: dropLocation, setDropLocation: setDropLocation }, item.name)) : null] }));
|
||||
};
|
||||
const AssetFolderTree = ({ item, level, name, parentFolder, toggleFolder, tabIndex, dropLocation, setDropLocation, }) => {
|
||||
const combinedParents = (0, react_1.useMemo)(() => {
|
||||
return [parentFolder, name].filter(no_react_1.NoReactInternals.truthy).join('/');
|
||||
}, [name, parentFolder]);
|
||||
return ((0, jsx_runtime_1.jsxs)("div", { children: [item.folders.map((folder) => {
|
||||
return ((0, jsx_runtime_1.jsx)(AssetFolderItem, { item: folder, tabIndex: tabIndex, level: level + 1, parentFolder: combinedParents, toggleFolder: toggleFolder, dropLocation: dropLocation, setDropLocation: setDropLocation }, folder.name));
|
||||
}), item.files.map((file) => {
|
||||
return ((0, jsx_runtime_1.jsx)(AssetSelectorItem, { item: file, tabIndex: tabIndex, level: level, parentFolder: combinedParents }, file.src));
|
||||
})] }));
|
||||
};
|
||||
exports.AssetFolderTree = AssetFolderTree;
|
||||
const AssetSelectorItem = ({ item, tabIndex, level, parentFolder }) => {
|
||||
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 selected = (0, react_1.useMemo)(() => {
|
||||
if (canvasContent && canvasContent.type === 'asset') {
|
||||
const nameWOParent = canvasContent.asset.split('/').pop();
|
||||
return nameWOParent === item.name;
|
||||
}
|
||||
return false;
|
||||
}, [canvasContent, item.name]);
|
||||
const onPointerLeave = (0, react_1.useCallback)(() => {
|
||||
setHovered(false);
|
||||
}, []);
|
||||
const onClick = (0, react_1.useCallback)(() => {
|
||||
const relativePath = parentFolder
|
||||
? parentFolder + '/' + item.name
|
||||
: item.name;
|
||||
setCanvasContent({ type: 'asset', asset: relativePath });
|
||||
(0, url_state_1.pushUrl)(`/assets/${relativePath}`);
|
||||
if (isMobileLayout) {
|
||||
setSidebarCollapsedState({ left: 'collapsed', right: 'collapsed' });
|
||||
}
|
||||
}, [
|
||||
isMobileLayout,
|
||||
item.name,
|
||||
parentFolder,
|
||||
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 (0, jsx_runtime_1.jsx)(folder_1.ExpandedFolderIcon, { style: revealIconStyle, color: color });
|
||||
}, []);
|
||||
const renderCopyAction = (0, react_1.useCallback)((color) => {
|
||||
return (0, 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 ((0, jsx_runtime_1.jsx)(layout_1.Row, { align: "center", children: (0, jsx_runtime_1.jsxs)("div", { style: style, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, onClick: onClick, tabIndex: tabIndex, title: item.name, children: [(0, jsx_runtime_1.jsx)(file_1.FileIcon, { style: iconStyle, color: colors_1.LIGHT_TEXT }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, jsx_runtime_1.jsx)("div", { style: label, children: item.name }), hovered ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.5 }), (0, jsx_runtime_1.jsx)(InlineAction_1.InlineAction, { title: "Copy staticFile() name", renderAction: renderCopyAction, onClick: copyToClipboard }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.5 }), (0, jsx_runtime_1.jsx)(InlineAction_1.InlineAction, { title: "Open in Explorer", renderAction: renderFileExplorerAction, onClick: revealInExplorer })] })) : null] }) }));
|
||||
};
|
||||
Generated
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
export declare const AudioWaveform: React.FC<{
|
||||
readonly src: string;
|
||||
readonly visualizationWidth: number;
|
||||
readonly startFrom: number;
|
||||
readonly durationInFrames: number;
|
||||
readonly volume: string | number;
|
||||
readonly doesVolumeChange: boolean;
|
||||
readonly playbackRate: number;
|
||||
}>;
|
||||
Generated
Vendored
+122
@@ -0,0 +1,122 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AudioWaveform = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const media_utils_1 = require("@remotion/media-utils");
|
||||
const react_1 = require("react");
|
||||
const remotion_1 = require("remotion");
|
||||
const colors_1 = require("../helpers/colors");
|
||||
const timeline_layout_1 = require("../helpers/timeline-layout");
|
||||
const AudioWaveformBar_1 = require("./AudioWaveformBar");
|
||||
const container = {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-end',
|
||||
position: 'absolute',
|
||||
height: (0, timeline_layout_1.getTimelineLayerHeight)('other'),
|
||||
};
|
||||
const errorMessage = {
|
||||
fontSize: 13,
|
||||
paddingTop: 6,
|
||||
paddingBottom: 6,
|
||||
paddingLeft: 12,
|
||||
paddingRight: 12,
|
||||
alignSelf: 'flex-start',
|
||||
maxWidth: 450,
|
||||
opacity: 0.75,
|
||||
};
|
||||
const canvasStyle = {
|
||||
position: 'absolute',
|
||||
};
|
||||
const AudioWaveform = ({ src, startFrom, durationInFrames, visualizationWidth, volume, doesVolumeChange, playbackRate, }) => {
|
||||
const [metadata, setMetadata] = (0, react_1.useState)(null);
|
||||
const [error, setError] = (0, react_1.useState)(null);
|
||||
const mountState = (0, react_1.useRef)({ isMounted: true });
|
||||
const vidConf = remotion_1.Internals.useUnsafeVideoConfig();
|
||||
if (vidConf === null) {
|
||||
throw new Error('Expected video config');
|
||||
}
|
||||
const canvas = (0, react_1.useRef)(null);
|
||||
(0, react_1.useEffect)(() => {
|
||||
const { current } = mountState;
|
||||
current.isMounted = true;
|
||||
return () => {
|
||||
current.isMounted = false;
|
||||
};
|
||||
}, []);
|
||||
(0, react_1.useEffect)(() => {
|
||||
if (!canvas.current) {
|
||||
return;
|
||||
}
|
||||
const context = canvas.current.getContext('2d');
|
||||
if (!context) {
|
||||
return;
|
||||
}
|
||||
context.clearRect(0, 0, visualizationWidth, (0, timeline_layout_1.getTimelineLayerHeight)('other'));
|
||||
if (!doesVolumeChange || typeof volume === 'number') {
|
||||
// The volume is a number, meaning it could change on each frame-
|
||||
// User did not use the (f: number) => number syntax, so we can't draw
|
||||
// a visualization.
|
||||
return;
|
||||
}
|
||||
const volumes = volume.split(',').map((v) => Number(v));
|
||||
context.beginPath();
|
||||
context.moveTo(0, (0, timeline_layout_1.getTimelineLayerHeight)('other'));
|
||||
volumes.forEach((v, index) => {
|
||||
const x = (index / (volumes.length - 1)) * visualizationWidth;
|
||||
const y = (1 - v) * ((0, timeline_layout_1.getTimelineLayerHeight)('other') - timeline_layout_1.TIMELINE_BORDER * 2) + 1;
|
||||
if (index === 0) {
|
||||
context.moveTo(x, y);
|
||||
}
|
||||
else {
|
||||
context.lineTo(x, y);
|
||||
}
|
||||
});
|
||||
context.strokeStyle = colors_1.LIGHT_TRANSPARENT;
|
||||
context.stroke();
|
||||
}, [visualizationWidth, metadata, startFrom, volume, doesVolumeChange]);
|
||||
(0, react_1.useEffect)(() => {
|
||||
setError(null);
|
||||
(0, media_utils_1.getAudioData)(src)
|
||||
.then((data) => {
|
||||
if (mountState.current.isMounted) {
|
||||
setMetadata(data);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
if (mountState.current.isMounted) {
|
||||
setError(err);
|
||||
}
|
||||
});
|
||||
}, [src, vidConf.fps]);
|
||||
const normalized = (0, react_1.useMemo)(() => {
|
||||
if (!metadata || metadata.numberOfChannels === 0) {
|
||||
return [];
|
||||
}
|
||||
const numberOfSamples = Math.floor(visualizationWidth / (AudioWaveformBar_1.WAVEFORM_BAR_LENGTH + AudioWaveformBar_1.WAVEFORM_BAR_MARGIN));
|
||||
return (0, media_utils_1.getWaveformPortion)({
|
||||
audioData: metadata,
|
||||
startTimeInSeconds: startFrom / vidConf.fps,
|
||||
durationInSeconds: Math.min((durationInFrames / vidConf.fps) * playbackRate, metadata.durationInSeconds),
|
||||
numberOfSamples,
|
||||
normalize: false,
|
||||
});
|
||||
}, [
|
||||
durationInFrames,
|
||||
vidConf.fps,
|
||||
metadata,
|
||||
playbackRate,
|
||||
startFrom,
|
||||
visualizationWidth,
|
||||
]);
|
||||
if (error) {
|
||||
return ((0, jsx_runtime_1.jsx)("div", { style: container, children: (0, jsx_runtime_1.jsx)("div", { style: errorMessage, children: "No waveform available. Audio might not support CORS." }) }));
|
||||
}
|
||||
if (!metadata) {
|
||||
return null;
|
||||
}
|
||||
return ((0, jsx_runtime_1.jsxs)("div", { style: container, children: [normalized.map((w) => {
|
||||
return ((0, jsx_runtime_1.jsx)(AudioWaveformBar_1.AudioWaveformBar, { amplitude: w.amplitude * (typeof volume === 'number' ? volume : 1) }, w.index));
|
||||
}), (0, jsx_runtime_1.jsx)("canvas", { ref: canvas, style: canvasStyle, width: visualizationWidth, height: (0, timeline_layout_1.getTimelineLayerHeight)('other') })] }));
|
||||
};
|
||||
exports.AudioWaveform = AudioWaveform;
|
||||
Generated
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
export declare const WAVEFORM_BAR_LENGTH = 2;
|
||||
export declare const WAVEFORM_BAR_MARGIN = 1;
|
||||
/**
|
||||
*
|
||||
* consider a sinus wave with an amplitude going from [-1, 1].
|
||||
* if we sample it infinitely, and convert all negative samples from negative to positive
|
||||
* what is the average of all samples?
|
||||
*
|
||||
* Answer: 2 / Math.PI = 0.6366
|
||||
*/
|
||||
export declare const AudioWaveformBar: React.FC<{
|
||||
readonly amplitude: number;
|
||||
}>;
|
||||
Generated
Vendored
+33
@@ -0,0 +1,33 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AudioWaveformBar = exports.WAVEFORM_BAR_MARGIN = exports.WAVEFORM_BAR_LENGTH = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const timeline_layout_1 = require("../helpers/timeline-layout");
|
||||
exports.WAVEFORM_BAR_LENGTH = 2;
|
||||
exports.WAVEFORM_BAR_MARGIN = 1;
|
||||
const container = {
|
||||
width: exports.WAVEFORM_BAR_LENGTH,
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.6)',
|
||||
marginLeft: exports.WAVEFORM_BAR_MARGIN,
|
||||
borderRadius: 2,
|
||||
};
|
||||
// Sonnet:
|
||||
/**
|
||||
*
|
||||
* consider a sinus wave with an amplitude going from [-1, 1].
|
||||
* if we sample it infinitely, and convert all negative samples from negative to positive
|
||||
* what is the average of all samples?
|
||||
*
|
||||
* Answer: 2 / Math.PI = 0.6366
|
||||
*/
|
||||
const AudioWaveformBar = ({ amplitude }) => {
|
||||
const style = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
...container,
|
||||
height: (0, timeline_layout_1.getTimelineLayerHeight)('other') * amplitude * (1 / 0.6366),
|
||||
};
|
||||
}, [amplitude]);
|
||||
return (0, jsx_runtime_1.jsx)("div", { style: style });
|
||||
};
|
||||
exports.AudioWaveformBar = AudioWaveformBar;
|
||||
Generated
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
export type ButtonProps = {
|
||||
readonly onClick: () => void;
|
||||
readonly disabled?: boolean;
|
||||
readonly children: React.ReactNode;
|
||||
readonly style?: React.CSSProperties;
|
||||
readonly buttonContainerStyle?: React.CSSProperties;
|
||||
readonly autoFocus?: boolean;
|
||||
readonly title?: string;
|
||||
readonly id?: string;
|
||||
};
|
||||
export declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
||||
Generated
Vendored
+35
@@ -0,0 +1,35 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Button = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const colors_1 = require("../helpers/colors");
|
||||
const button = {
|
||||
border: `1px solid ${colors_1.INPUT_BORDER_COLOR_UNHOVERED}`,
|
||||
borderRadius: 4,
|
||||
backgroundColor: colors_1.INPUT_BACKGROUND,
|
||||
appearance: 'none',
|
||||
fontFamily: 'inherit',
|
||||
fontSize: 14,
|
||||
color: 'white',
|
||||
flexDirection: 'row',
|
||||
};
|
||||
const ButtonRefForwardFunction = ({ children, onClick, title, disabled, style, id, autoFocus, buttonContainerStyle, }, ref) => {
|
||||
const combined = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
...button,
|
||||
...(style !== null && style !== void 0 ? style : {}),
|
||||
};
|
||||
}, [style]);
|
||||
const buttonContainer = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
padding: 10,
|
||||
cursor: disabled ? 'inherit' : 'pointer',
|
||||
fontSize: 14,
|
||||
opacity: disabled ? 0.7 : 1,
|
||||
...(buttonContainerStyle !== null && buttonContainerStyle !== void 0 ? buttonContainerStyle : {}),
|
||||
};
|
||||
}, [buttonContainerStyle, disabled]);
|
||||
return ((0, jsx_runtime_1.jsx)("button", { ref: ref, id: id, style: combined, type: "button", disabled: disabled, onClick: onClick, autoFocus: autoFocus, title: title, children: (0, jsx_runtime_1.jsx)("div", { className: "css-reset", style: buttonContainer, children: children }) }));
|
||||
};
|
||||
exports.Button = (0, react_1.forwardRef)(ButtonRefForwardFunction);
|
||||
Generated
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
import type { Size } from '@remotion/player';
|
||||
import React from 'react';
|
||||
import type { CanvasContent } from 'remotion';
|
||||
export declare const Canvas: React.FC<{
|
||||
readonly canvasContent: CanvasContent;
|
||||
readonly size: Size;
|
||||
}>;
|
||||
Generated
Vendored
+267
@@ -0,0 +1,267 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Canvas = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const remotion_1 = require("remotion");
|
||||
const colors_1 = require("../helpers/colors");
|
||||
const get_asset_metadata_1 = require("../helpers/get-asset-metadata");
|
||||
const get_effective_translation_1 = require("../helpers/get-effective-translation");
|
||||
const smooth_zoom_1 = require("../helpers/smooth-zoom");
|
||||
const use_keybinding_1 = require("../helpers/use-keybinding");
|
||||
const canvas_ref_1 = require("../state/canvas-ref");
|
||||
const editor_guides_1 = require("../state/editor-guides");
|
||||
const editor_zoom_gestures_1 = require("../state/editor-zoom-gestures");
|
||||
const EditorGuides_1 = __importDefault(require("./EditorGuides"));
|
||||
const EditorRuler_1 = require("./EditorRuler");
|
||||
const use_is_ruler_visible_1 = require("./EditorRuler/use-is-ruler-visible");
|
||||
const Preview_1 = require("./Preview");
|
||||
const ResetZoomButton_1 = require("./ResetZoomButton");
|
||||
const layout_1 = require("./layout");
|
||||
const container = {
|
||||
flex: 1,
|
||||
display: 'flex',
|
||||
overflow: 'hidden',
|
||||
position: 'relative',
|
||||
backgroundColor: colors_1.BACKGROUND,
|
||||
};
|
||||
const resetZoom = {
|
||||
position: 'absolute',
|
||||
top: layout_1.SPACING_UNIT * 2,
|
||||
right: layout_1.SPACING_UNIT * 2,
|
||||
};
|
||||
const ZOOM_PX_FACTOR = 0.003;
|
||||
const Canvas = ({ canvasContent, size }) => {
|
||||
const { setSize, size: previewSize } = (0, react_1.useContext)(remotion_1.Internals.PreviewSizeContext);
|
||||
const { editorZoomGestures } = (0, react_1.useContext)(editor_zoom_gestures_1.EditorZoomGesturesContext);
|
||||
const keybindings = (0, use_keybinding_1.useKeybinding)();
|
||||
const config = remotion_1.Internals.useUnsafeVideoConfig();
|
||||
const areRulersVisible = (0, use_is_ruler_visible_1.useIsRulerVisible)();
|
||||
const { editorShowGuides } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
|
||||
const [assetResolution, setAssetResolution] = (0, react_1.useState)(null);
|
||||
const contentDimensions = (0, react_1.useMemo)(() => {
|
||||
if ((canvasContent.type === 'asset' ||
|
||||
canvasContent.type === 'output' ||
|
||||
canvasContent.type === 'output-blob') &&
|
||||
assetResolution &&
|
||||
assetResolution.type === 'found') {
|
||||
return assetResolution.dimensions;
|
||||
}
|
||||
if (config) {
|
||||
return { width: config.width, height: config.height };
|
||||
}
|
||||
return null;
|
||||
}, [assetResolution, config, canvasContent]);
|
||||
const isFit = previewSize.size === 'auto';
|
||||
const onWheel = (0, react_1.useCallback)((e) => {
|
||||
if (!editorZoomGestures) {
|
||||
return;
|
||||
}
|
||||
if (!size) {
|
||||
return;
|
||||
}
|
||||
if (!contentDimensions || contentDimensions === 'none') {
|
||||
return;
|
||||
}
|
||||
const wantsToZoom = e.ctrlKey || e.metaKey;
|
||||
if (!wantsToZoom && isFit) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
setSize((prevSize) => {
|
||||
const scale = remotion_1.Internals.calculateScale({
|
||||
canvasSize: size,
|
||||
compositionHeight: contentDimensions.height,
|
||||
compositionWidth: contentDimensions.width,
|
||||
previewSize: prevSize.size,
|
||||
});
|
||||
// Zoom in/out
|
||||
if (wantsToZoom) {
|
||||
const oldSize = prevSize.size === 'auto' ? scale : prevSize.size;
|
||||
const smoothened = (0, smooth_zoom_1.smoothenZoom)(oldSize);
|
||||
const added = smoothened + e.deltaY * ZOOM_PX_FACTOR;
|
||||
const unsmoothened = (0, smooth_zoom_1.unsmoothenZoom)(added);
|
||||
const { centerX, centerY } = (0, get_effective_translation_1.getCenterPointWhileScrolling)({
|
||||
size,
|
||||
clientX: e.clientX,
|
||||
clientY: e.clientY,
|
||||
compositionWidth: contentDimensions.width,
|
||||
compositionHeight: contentDimensions.height,
|
||||
scale,
|
||||
translation: prevSize.translation,
|
||||
});
|
||||
const zoomDifference = unsmoothened - oldSize;
|
||||
const uvCoordinatesX = centerX / contentDimensions.width;
|
||||
const uvCoordinatesY = centerY / contentDimensions.height;
|
||||
const correctionLeft = -uvCoordinatesX * (zoomDifference * contentDimensions.width) +
|
||||
(1 - uvCoordinatesX) * zoomDifference * contentDimensions.width;
|
||||
const correctionTop = -uvCoordinatesY * (zoomDifference * contentDimensions.height) +
|
||||
(1 - uvCoordinatesY) * zoomDifference * contentDimensions.height;
|
||||
return {
|
||||
translation: (0, get_effective_translation_1.getEffectiveTranslation)({
|
||||
translation: {
|
||||
x: prevSize.translation.x - correctionLeft / 2,
|
||||
y: prevSize.translation.y - correctionTop / 2,
|
||||
},
|
||||
canvasSize: size,
|
||||
compositionHeight: contentDimensions.height,
|
||||
compositionWidth: contentDimensions.width,
|
||||
scale,
|
||||
}),
|
||||
size: unsmoothened,
|
||||
};
|
||||
}
|
||||
const effectiveTranslation = (0, get_effective_translation_1.getEffectiveTranslation)({
|
||||
translation: prevSize.translation,
|
||||
canvasSize: size,
|
||||
compositionHeight: contentDimensions.height,
|
||||
compositionWidth: contentDimensions.width,
|
||||
scale,
|
||||
});
|
||||
// Pan
|
||||
return {
|
||||
...prevSize,
|
||||
translation: (0, get_effective_translation_1.getEffectiveTranslation)({
|
||||
translation: {
|
||||
x: effectiveTranslation.x + e.deltaX,
|
||||
y: effectiveTranslation.y + e.deltaY,
|
||||
},
|
||||
canvasSize: size,
|
||||
compositionHeight: contentDimensions.height,
|
||||
compositionWidth: contentDimensions.width,
|
||||
scale,
|
||||
}),
|
||||
};
|
||||
});
|
||||
}, [editorZoomGestures, contentDimensions, isFit, setSize, size]);
|
||||
(0, react_1.useEffect)(() => {
|
||||
const { current } = canvas_ref_1.canvasRef;
|
||||
if (!current) {
|
||||
return;
|
||||
}
|
||||
current.addEventListener('wheel', onWheel, { passive: false });
|
||||
return () =>
|
||||
// @ts-expect-error
|
||||
current.removeEventListener('wheel', onWheel, {
|
||||
passive: false,
|
||||
});
|
||||
}, [onWheel]);
|
||||
const onReset = (0, react_1.useCallback)(() => {
|
||||
setSize(() => {
|
||||
return {
|
||||
translation: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
size: 'auto',
|
||||
};
|
||||
});
|
||||
}, [setSize]);
|
||||
const onZoomIn = (0, react_1.useCallback)(() => {
|
||||
if (!contentDimensions || contentDimensions === 'none') {
|
||||
return;
|
||||
}
|
||||
if (!size) {
|
||||
return;
|
||||
}
|
||||
setSize((prevSize) => {
|
||||
const scale = remotion_1.Internals.calculateScale({
|
||||
canvasSize: size,
|
||||
compositionHeight: contentDimensions.height,
|
||||
compositionWidth: contentDimensions.width,
|
||||
previewSize: prevSize.size,
|
||||
});
|
||||
return {
|
||||
translation: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
size: Math.min(smooth_zoom_1.MAX_ZOOM, scale * 2),
|
||||
};
|
||||
});
|
||||
}, [contentDimensions, setSize, size]);
|
||||
const onZoomOut = (0, react_1.useCallback)(() => {
|
||||
if (!contentDimensions || contentDimensions === 'none') {
|
||||
return;
|
||||
}
|
||||
if (!size) {
|
||||
return;
|
||||
}
|
||||
setSize((prevSize) => {
|
||||
const scale = remotion_1.Internals.calculateScale({
|
||||
canvasSize: size,
|
||||
compositionHeight: contentDimensions.height,
|
||||
compositionWidth: contentDimensions.width,
|
||||
previewSize: prevSize.size,
|
||||
});
|
||||
return {
|
||||
translation: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
size: Math.max(smooth_zoom_1.MIN_ZOOM, scale / 2),
|
||||
};
|
||||
});
|
||||
}, [contentDimensions, setSize, size]);
|
||||
(0, react_1.useEffect)(() => {
|
||||
const resetBinding = keybindings.registerKeybinding({
|
||||
event: 'keydown',
|
||||
key: '0',
|
||||
commandCtrlKey: false,
|
||||
callback: onReset,
|
||||
preventDefault: true,
|
||||
triggerIfInputFieldFocused: false,
|
||||
keepRegisteredWhenNotHighestContext: false,
|
||||
});
|
||||
const zoomIn = keybindings.registerKeybinding({
|
||||
event: 'keydown',
|
||||
key: '+',
|
||||
commandCtrlKey: false,
|
||||
callback: onZoomIn,
|
||||
preventDefault: true,
|
||||
triggerIfInputFieldFocused: false,
|
||||
keepRegisteredWhenNotHighestContext: false,
|
||||
});
|
||||
const zoomOut = keybindings.registerKeybinding({
|
||||
event: 'keydown',
|
||||
key: '-',
|
||||
commandCtrlKey: false,
|
||||
callback: onZoomOut,
|
||||
preventDefault: true,
|
||||
triggerIfInputFieldFocused: false,
|
||||
keepRegisteredWhenNotHighestContext: false,
|
||||
});
|
||||
return () => {
|
||||
resetBinding.unregister();
|
||||
zoomIn.unregister();
|
||||
zoomOut.unregister();
|
||||
};
|
||||
}, [keybindings, onReset, onZoomIn, onZoomOut]);
|
||||
const fetchMetadata = (0, react_1.useCallback)(async () => {
|
||||
setAssetResolution(null);
|
||||
if (canvasContent.type === 'composition') {
|
||||
return;
|
||||
}
|
||||
const metadata = await (0, get_asset_metadata_1.getAssetMetadata)(canvasContent, canvasContent.type === 'asset');
|
||||
setAssetResolution(metadata);
|
||||
}, [canvasContent]);
|
||||
(0, react_1.useEffect)(() => {
|
||||
if (canvasContent.type !== 'asset') {
|
||||
return;
|
||||
}
|
||||
const file = (0, remotion_1.watchStaticFile)(canvasContent.asset, () => {
|
||||
fetchMetadata();
|
||||
});
|
||||
return () => {
|
||||
file.cancel();
|
||||
};
|
||||
}, [canvasContent, fetchMetadata]);
|
||||
(0, react_1.useEffect)(() => {
|
||||
fetchMetadata();
|
||||
}, [fetchMetadata]);
|
||||
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { ref: canvas_ref_1.canvasRef, style: container, children: [size ? ((0, jsx_runtime_1.jsx)(Preview_1.VideoPreview, { canvasContent: canvasContent, contentDimensions: contentDimensions, canvasSize: size, assetMetadata: assetResolution })) : null, isFit ? null : ((0, jsx_runtime_1.jsx)("div", { style: resetZoom, className: "css-reset", children: (0, jsx_runtime_1.jsx)(ResetZoomButton_1.ResetZoomButton, { onClick: onReset }) })), editorShowGuides && canvasContent.type === 'composition' && ((0, jsx_runtime_1.jsx)(EditorGuides_1.default, { canvasSize: size, contentDimensions: contentDimensions, assetMetadata: assetResolution }))] }), areRulersVisible && ((0, jsx_runtime_1.jsx)(EditorRuler_1.EditorRulers, { contentDimensions: contentDimensions, canvasSize: size, assetMetadata: assetResolution, containerRef: canvas_ref_1.canvasRef }))] }));
|
||||
};
|
||||
exports.Canvas = Canvas;
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
export declare const CanvasIfSizeIsAvailable: React.FC;
|
||||
Generated
Vendored
+32
@@ -0,0 +1,32 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CanvasIfSizeIsAvailable = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const remotion_1 = require("remotion");
|
||||
const editor_rulers_1 = require("../state/editor-rulers");
|
||||
const CanvasOrLoading_1 = require("./CanvasOrLoading");
|
||||
const use_is_ruler_visible_1 = require("./EditorRuler/use-is-ruler-visible");
|
||||
const CanvasIfSizeIsAvailable = () => {
|
||||
const rulersAreVisible = (0, use_is_ruler_visible_1.useIsRulerVisible)();
|
||||
const context = (0, react_1.useContext)(remotion_1.Internals.CurrentScaleContext);
|
||||
const sizeWithRulersApplied = (0, react_1.useMemo)(() => {
|
||||
const size = context && context.type === 'canvas-size' ? context.canvasSize : null;
|
||||
if (!rulersAreVisible) {
|
||||
return size;
|
||||
}
|
||||
if (!size) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
...size,
|
||||
width: size.width - editor_rulers_1.RULER_WIDTH,
|
||||
height: size.height - editor_rulers_1.RULER_WIDTH,
|
||||
};
|
||||
}, [context, rulersAreVisible]);
|
||||
if (!sizeWithRulersApplied) {
|
||||
return null;
|
||||
}
|
||||
return (0, jsx_runtime_1.jsx)(CanvasOrLoading_1.CanvasOrLoading, { size: sizeWithRulersApplied });
|
||||
};
|
||||
exports.CanvasIfSizeIsAvailable = CanvasIfSizeIsAvailable;
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
import type { Size } from '@remotion/player';
|
||||
import React from 'react';
|
||||
export declare const CanvasOrLoading: React.FC<{
|
||||
readonly size: Size;
|
||||
}>;
|
||||
Generated
Vendored
+77
@@ -0,0 +1,77 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CanvasOrLoading = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const remotion_1 = require("remotion");
|
||||
const ErrorLoader_1 = require("../error-overlay/remotion-overlay/ErrorLoader");
|
||||
const colors_1 = require("../helpers/colors");
|
||||
const timeline_zoom_1 = require("../state/timeline-zoom");
|
||||
const Canvas_1 = require("./Canvas");
|
||||
const FramePersistor_1 = require("./FramePersistor");
|
||||
const is_menu_item_1 = require("./Menu/is-menu-item");
|
||||
const RefreshCompositionOverlay_1 = require("./RefreshCompositionOverlay");
|
||||
const RunningCalculateMetadata_1 = require("./RunningCalculateMetadata");
|
||||
const imperative_state_1 = require("./Timeline/imperative-state");
|
||||
const timeline_scroll_logic_1 = require("./Timeline/timeline-scroll-logic");
|
||||
const ZoomPersistor_1 = require("./ZoomPersistor");
|
||||
const container = {
|
||||
color: 'white',
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
backgroundColor: colors_1.BACKGROUND,
|
||||
flexDirection: 'column',
|
||||
};
|
||||
const CanvasOrLoading = ({ size }) => {
|
||||
const resolved = remotion_1.Internals.useResolvedVideoConfig(null);
|
||||
const { setZoom } = (0, react_1.useContext)(timeline_zoom_1.TimelineZoomCtx);
|
||||
const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
||||
(0, react_1.useEffect)(() => {
|
||||
if ((resolved === null || resolved === void 0 ? void 0 : resolved.type) !== 'success' &&
|
||||
(resolved === null || resolved === void 0 ? void 0 : resolved.type) !== 'success-and-refreshing') {
|
||||
return;
|
||||
}
|
||||
const c = resolved.result;
|
||||
setTimeout(() => {
|
||||
(0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
|
||||
direction: 'center',
|
||||
frame: (0, imperative_state_1.getCurrentFrame)(),
|
||||
durationInFrames: c.durationInFrames,
|
||||
});
|
||||
});
|
||||
}, [resolved, setZoom]);
|
||||
if (!canvasContent) {
|
||||
const compname = window.location.pathname.replace('/', '');
|
||||
return ((0, jsx_runtime_1.jsx)("div", { style: container, className: "css-reset", children: (0, jsx_runtime_1.jsxs)("div", { style: RunningCalculateMetadata_1.loaderLabel, children: ["Composition with ID ", compname, " not found."] }) }));
|
||||
}
|
||||
const content = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ZoomPersistor_1.ZoomPersistor, {}), (0, jsx_runtime_1.jsx)(Canvas_1.Canvas, { size: size, canvasContent: canvasContent }), (resolved === null || resolved === void 0 ? void 0 : resolved.type) === 'success-and-refreshing' ? ((0, jsx_runtime_1.jsx)(RefreshCompositionOverlay_1.RefreshCompositionOverlay, {})) : null] }));
|
||||
if (canvasContent.type === 'asset' ||
|
||||
canvasContent.type === 'output' ||
|
||||
canvasContent.type === 'output-blob') {
|
||||
return content;
|
||||
}
|
||||
if (!resolved) {
|
||||
return null;
|
||||
}
|
||||
if (resolved.type === 'loading') {
|
||||
return ((0, jsx_runtime_1.jsx)("div", { style: container, className: "css-reset", children: (0, jsx_runtime_1.jsx)(RunningCalculateMetadata_1.RunningCalculateMetadata, {}) }));
|
||||
}
|
||||
if (resolved.type === 'error') {
|
||||
return (0, jsx_runtime_1.jsx)(ErrorLoading, { error: resolved.error });
|
||||
}
|
||||
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(FramePersistor_1.FramePersistor, {}), " ", content] }));
|
||||
};
|
||||
exports.CanvasOrLoading = CanvasOrLoading;
|
||||
const loaderContainer = {
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto',
|
||||
width: '100%',
|
||||
position: 'absolute',
|
||||
height: '100%',
|
||||
overflowY: 'auto',
|
||||
};
|
||||
const ErrorLoading = ({ error }) => {
|
||||
return ((0, jsx_runtime_1.jsx)("div", { style: loaderContainer, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: (0, jsx_runtime_1.jsx)(ErrorLoader_1.ErrorLoader, { canHaveDismissButton: false, keyboardShortcuts: false, error: error, onRetry: () => { var _a; return (_a = remotion_1.Internals.resolveCompositionsRef.current) === null || _a === void 0 ? void 0 : _a.reloadCurrentlySelectedComposition(); }, calculateMetadata: true }, error.stack) }));
|
||||
};
|
||||
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
import React from 'react';
|
||||
export declare const CheckboardToggle: React.FC;
|
||||
Generated
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CheckboardToggle = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const no_react_1 = require("remotion/no-react");
|
||||
const colors_1 = require("../helpers/colors");
|
||||
const use_keybinding_1 = require("../helpers/use-keybinding");
|
||||
const checkerboard_1 = require("../state/checkerboard");
|
||||
const ControlButton_1 = require("./ControlButton");
|
||||
const accessibilityLabel = [
|
||||
'Show transparency as checkerboard',
|
||||
(0, use_keybinding_1.areKeyboardShortcutsDisabled)() ? null : '(T)',
|
||||
]
|
||||
.filter(no_react_1.NoReactInternals.truthy)
|
||||
.join(' ');
|
||||
const CheckboardToggle = () => {
|
||||
const { checkerboard, setCheckerboard } = (0, react_1.useContext)(checkerboard_1.CheckerboardContext);
|
||||
const onClick = (0, react_1.useCallback)(() => {
|
||||
setCheckerboard((c) => {
|
||||
return !c;
|
||||
});
|
||||
}, [setCheckerboard]);
|
||||
return ((0, jsx_runtime_1.jsx)(ControlButton_1.ControlButton, { title: accessibilityLabel, "aria-label": accessibilityLabel, onClick: onClick, children: (0, jsx_runtime_1.jsx)("svg", { "aria-hidden": "true", focusable: "false", "data-prefix": "fas", "data-icon": "game-board-alt", className: "svg-inline--fa fa-game-board-alt fa-w-16", role: "img", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 512 512", style: { width: 16, height: 16 }, children: (0, jsx_runtime_1.jsx)("path", { fill: checkerboard ? colors_1.BLUE : 'white', d: "M480 0H32A32 32 0 0 0 0 32v448a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32V32a32 32 0 0 0-32-32zm-32 256H256v192H64V256h192V64h192z" }) }) }));
|
||||
};
|
||||
exports.CheckboardToggle = CheckboardToggle;
|
||||
Generated
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
export declare const Checkbox: React.FC<{
|
||||
readonly checked: boolean;
|
||||
readonly onChange: React.ChangeEventHandler<HTMLInputElement>;
|
||||
readonly name: string;
|
||||
readonly rounded?: boolean;
|
||||
readonly disabled?: boolean;
|
||||
}>;
|
||||
Generated
Vendored
+54
@@ -0,0 +1,54 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Checkbox = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const colors_1 = require("../helpers/colors");
|
||||
const Checkmark_1 = require("../icons/Checkmark");
|
||||
const size = 20;
|
||||
const background = {
|
||||
height: size,
|
||||
width: size,
|
||||
position: 'relative',
|
||||
};
|
||||
const bullet = {
|
||||
width: 10,
|
||||
height: 10,
|
||||
backgroundColor: colors_1.LIGHT_TEXT,
|
||||
borderRadius: '50%',
|
||||
};
|
||||
const box = {
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
position: 'absolute',
|
||||
height: size,
|
||||
width: size,
|
||||
top: 0,
|
||||
left: 0,
|
||||
pointerEvents: 'none',
|
||||
color: 'white',
|
||||
};
|
||||
const Checkbox = ({ checked, onChange, disabled, name, rounded }) => {
|
||||
const ref = (0, react_1.useRef)(null);
|
||||
const input = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
appearance: 'none',
|
||||
background: disabled ? 'transparent' : colors_1.INPUT_BACKGROUND,
|
||||
border: '1px solid ' + colors_1.INPUT_BORDER_COLOR_UNHOVERED,
|
||||
height: size,
|
||||
width: size,
|
||||
top: 0,
|
||||
left: 0,
|
||||
position: 'absolute',
|
||||
margin: 0,
|
||||
};
|
||||
}, [disabled]);
|
||||
(0, react_1.useEffect)(() => {
|
||||
if (ref.current) {
|
||||
ref.current.style.setProperty('border-radius', rounded ? '50%' : '0%', 'important');
|
||||
}
|
||||
}, [rounded]);
|
||||
return ((0, jsx_runtime_1.jsxs)("div", { style: background, children: [(0, jsx_runtime_1.jsx)("input", { ref: ref, style: input, type: 'checkbox', checked: checked, onChange: onChange, disabled: disabled, name: name }), (0, jsx_runtime_1.jsx)("div", { style: box, children: checked ? rounded ? (0, jsx_runtime_1.jsx)("div", { style: bullet }) : (0, jsx_runtime_1.jsx)(Checkmark_1.Checkmark, {}) : null })] }));
|
||||
};
|
||||
exports.Checkbox = Checkbox;
|
||||
skills/remotion-prompt-video/node_modules/@remotion/studio/dist/components/CheckerboardProvider.d.ts
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
import React from 'react';
|
||||
export declare const CheckerboardProvider: React.FC<{
|
||||
readonly children: React.ReactNode;
|
||||
}>;
|
||||
Generated
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CheckerboardProvider = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const checkerboard_1 = require("../state/checkerboard");
|
||||
const CheckerboardProvider = ({ children }) => {
|
||||
const [checkerboard, setCheckerboardState] = (0, react_1.useState)(() => (0, checkerboard_1.loadCheckerboardOption)());
|
||||
const setCheckerboard = (0, react_1.useCallback)((newValue) => {
|
||||
setCheckerboardState((prevState) => {
|
||||
const newVal = newValue(prevState);
|
||||
(0, checkerboard_1.persistCheckerboardOption)(newVal);
|
||||
return newVal;
|
||||
});
|
||||
}, []);
|
||||
const checkerboardCtx = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
checkerboard,
|
||||
setCheckerboard,
|
||||
};
|
||||
}, [checkerboard, setCheckerboard]);
|
||||
return ((0, jsx_runtime_1.jsx)(checkerboard_1.CheckerboardContext.Provider, { value: checkerboardCtx, children: children }));
|
||||
};
|
||||
exports.CheckerboardProvider = CheckerboardProvider;
|
||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
import type React from 'react';
|
||||
export declare const CompSelectorRef: React.FC<{
|
||||
readonly children: React.ReactNode;
|
||||
}>;
|
||||
Generated
Vendored
+82
@@ -0,0 +1,82 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CompSelectorRef = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const remotion_1 = require("remotion");
|
||||
const persist_open_folders_1 = require("../helpers/persist-open-folders");
|
||||
const InitialCompositionLoader_1 = require("./InitialCompositionLoader");
|
||||
const CompSelectorRef = ({ children }) => {
|
||||
const { compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
||||
const [foldersExpanded, setFoldersExpanded] = (0, react_1.useState)((0, persist_open_folders_1.loadExpandedFolders)('compositions'));
|
||||
const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
|
||||
const toggleFolder = (0, react_1.useCallback)((folderName, parentName) => {
|
||||
setFoldersExpanded((p) => {
|
||||
var _a;
|
||||
const key = (0, persist_open_folders_1.openFolderKey)({ folderName, parentName });
|
||||
const prev = (_a = p[key]) !== null && _a !== void 0 ? _a : false;
|
||||
const foldersExpandedState = {
|
||||
...p,
|
||||
[key]: !prev,
|
||||
};
|
||||
(0, persist_open_folders_1.persistExpandedFolders)('compositions', foldersExpandedState);
|
||||
return foldersExpandedState;
|
||||
});
|
||||
}, []);
|
||||
(0, react_1.useImperativeHandle)(remotion_1.Internals.compositionSelectorRef, () => {
|
||||
return {
|
||||
expandComposition: (compName) => {
|
||||
const compositionToExpand = compositions.find((c) => c.id === compName);
|
||||
if (!compositionToExpand) {
|
||||
return;
|
||||
}
|
||||
const { folderName, parentFolderName } = compositionToExpand;
|
||||
if (folderName === null) {
|
||||
return;
|
||||
}
|
||||
setFoldersExpanded((previousState) => {
|
||||
const foldersExpandedState = {
|
||||
...previousState,
|
||||
};
|
||||
const currentFolder = folderName;
|
||||
const currentParentName = parentFolderName;
|
||||
const key = (0, persist_open_folders_1.openFolderKey)({
|
||||
folderName: currentFolder,
|
||||
parentName: currentParentName,
|
||||
});
|
||||
const splitted = key.split('/');
|
||||
for (let i = 0; i < splitted.length - 1; i++) {
|
||||
const allExceptLast = i === 0
|
||||
? (0, persist_open_folders_1.openFolderKey)({
|
||||
folderName: splitted.filter((s) => s !== 'no-parent')[0],
|
||||
parentName: null,
|
||||
})
|
||||
: splitted.slice(0, i + 1).join('/');
|
||||
foldersExpandedState[allExceptLast] = true;
|
||||
}
|
||||
(0, persist_open_folders_1.persistExpandedFolders)('compositions', foldersExpandedState);
|
||||
return foldersExpandedState;
|
||||
});
|
||||
},
|
||||
selectComposition: (compName) => {
|
||||
const comp = compositions.find((c) => c.id === compName);
|
||||
if (!comp) {
|
||||
throw new Error(`Composition ${compName} not found`);
|
||||
}
|
||||
selectComposition(comp, true);
|
||||
},
|
||||
toggleFolder: (folderName, parentName) => {
|
||||
toggleFolder(folderName, parentName);
|
||||
},
|
||||
};
|
||||
}, [compositions, selectComposition, toggleFolder]);
|
||||
const contextValue = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
foldersExpanded,
|
||||
setFoldersExpanded,
|
||||
toggleFolder,
|
||||
};
|
||||
}, [foldersExpanded, setFoldersExpanded, toggleFolder]);
|
||||
return ((0, jsx_runtime_1.jsx)(persist_open_folders_1.ExpandedFoldersContext.Provider, { value: contextValue, children: children }));
|
||||
};
|
||||
exports.CompSelectorRef = CompSelectorRef;
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
import React from 'react';
|
||||
import type { ComboboxValue } from './NewComposition/ComboBox';
|
||||
export declare const CompositionContextButton: React.FC<{
|
||||
readonly visible: boolean;
|
||||
readonly values: ComboboxValue[];
|
||||
}>;
|
||||
Generated
Vendored
+27
@@ -0,0 +1,27 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CompositionContextButton = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const client_id_1 = require("../helpers/client-id");
|
||||
const ellipsis_1 = require("../icons/ellipsis");
|
||||
const InlineDropdown_1 = require("./InlineDropdown");
|
||||
const CompositionContextButton = ({ visible, values }) => {
|
||||
const iconStyle = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
style: {
|
||||
height: 12,
|
||||
},
|
||||
};
|
||||
}, []);
|
||||
const connectionStatus = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx)
|
||||
.previewServerState.type;
|
||||
const renderAction = (0, react_1.useCallback)((color) => {
|
||||
return (0, jsx_runtime_1.jsx)(ellipsis_1.EllipsisIcon, { fill: color, svgProps: iconStyle });
|
||||
}, [iconStyle]);
|
||||
if (!visible || connectionStatus !== 'connected') {
|
||||
return null;
|
||||
}
|
||||
return (0, jsx_runtime_1.jsx)(InlineDropdown_1.InlineDropdown, { renderAction: renderAction, values: values });
|
||||
};
|
||||
exports.CompositionContextButton = CompositionContextButton;
|
||||
Generated
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
import React from 'react';
|
||||
export declare const useCompositionNavigation: () => {
|
||||
navigateToNextComposition: () => void;
|
||||
navigateToPreviousComposition: () => void;
|
||||
};
|
||||
export declare const getKeysToExpand: (initialFolderName: string, parentFolderName: string | null, initial?: string[]) => string[];
|
||||
export declare const CompositionSelector: React.FC;
|
||||
Generated
Vendored
+95
@@ -0,0 +1,95 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CompositionSelector = exports.getKeysToExpand = exports.useCompositionNavigation = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const remotion_1 = require("remotion");
|
||||
const colors_1 = require("../helpers/colors");
|
||||
const create_folder_tree_1 = require("../helpers/create-folder-tree");
|
||||
const persist_open_folders_1 = require("../helpers/persist-open-folders");
|
||||
const z_index_1 = require("../state/z-index");
|
||||
const CompositionSelectorItem_1 = require("./CompositionSelectorItem");
|
||||
const CurrentComposition_1 = require("./CurrentComposition");
|
||||
const InitialCompositionLoader_1 = require("./InitialCompositionLoader");
|
||||
const useCompositionNavigation = () => {
|
||||
const { compositions, canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
||||
const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
|
||||
const navigateToNextComposition = (0, react_1.useCallback)(() => {
|
||||
if (!canvasContent ||
|
||||
canvasContent.type !== 'composition' ||
|
||||
compositions.length <= 1) {
|
||||
return;
|
||||
}
|
||||
const currentIndex = compositions.findIndex((c) => c.id === canvasContent.compositionId);
|
||||
if (currentIndex === -1) {
|
||||
return;
|
||||
}
|
||||
const nextIndex = (currentIndex + 1) % compositions.length;
|
||||
const nextComposition = compositions[nextIndex];
|
||||
selectComposition(nextComposition, true);
|
||||
}, [canvasContent, compositions, selectComposition]);
|
||||
const navigateToPreviousComposition = (0, react_1.useCallback)(() => {
|
||||
if (!canvasContent ||
|
||||
canvasContent.type !== 'composition' ||
|
||||
compositions.length <= 1) {
|
||||
return;
|
||||
}
|
||||
const currentIndex = compositions.findIndex((c) => c.id === canvasContent.compositionId);
|
||||
if (currentIndex === -1) {
|
||||
return;
|
||||
}
|
||||
const previousIndex = (currentIndex - 1 + compositions.length) % compositions.length;
|
||||
const previousComposition = compositions[previousIndex];
|
||||
selectComposition(previousComposition, true);
|
||||
}, [canvasContent, compositions, selectComposition]);
|
||||
return (0, react_1.useMemo)(() => ({
|
||||
navigateToNextComposition,
|
||||
navigateToPreviousComposition,
|
||||
}), [navigateToNextComposition, navigateToPreviousComposition]);
|
||||
};
|
||||
exports.useCompositionNavigation = useCompositionNavigation;
|
||||
const container = {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flex: 1,
|
||||
overflow: 'hidden',
|
||||
backgroundColor: colors_1.BACKGROUND,
|
||||
};
|
||||
const getKeysToExpand = (initialFolderName, parentFolderName, initial = []) => {
|
||||
initial.push((0, persist_open_folders_1.openFolderKey)({
|
||||
folderName: initialFolderName,
|
||||
parentName: parentFolderName,
|
||||
}));
|
||||
const { name, parent } = (0, create_folder_tree_1.splitParentIntoNameAndParent)(parentFolderName);
|
||||
if (!name) {
|
||||
return initial;
|
||||
}
|
||||
return (0, exports.getKeysToExpand)(name, parent, initial);
|
||||
};
|
||||
exports.getKeysToExpand = getKeysToExpand;
|
||||
const CompositionSelector = () => {
|
||||
const { compositions, canvasContent, folders } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
||||
const { foldersExpanded } = (0, react_1.useContext)(persist_open_folders_1.ExpandedFoldersContext);
|
||||
const { tabIndex } = (0, z_index_1.useZIndex)();
|
||||
const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
|
||||
const items = (0, react_1.useMemo)(() => {
|
||||
return (0, create_folder_tree_1.createFolderTree)(compositions, folders, foldersExpanded);
|
||||
}, [compositions, folders, foldersExpanded]);
|
||||
const showCurrentComposition = canvasContent && canvasContent.type === 'composition';
|
||||
const list = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
height: showCurrentComposition
|
||||
? `calc(100% - ${CurrentComposition_1.CURRENT_COMPOSITION_HEIGHT}px)`
|
||||
: '100%',
|
||||
overflowY: 'auto',
|
||||
};
|
||||
}, [showCurrentComposition]);
|
||||
const toggleFolder = (0, react_1.useCallback)((folderName, parentName) => {
|
||||
var _a;
|
||||
(_a = remotion_1.Internals.compositionSelectorRef.current) === null || _a === void 0 ? void 0 : _a.toggleFolder(folderName, parentName);
|
||||
}, []);
|
||||
return ((0, jsx_runtime_1.jsxs)("div", { style: container, children: [showCurrentComposition ? (0, jsx_runtime_1.jsx)(CurrentComposition_1.CurrentComposition, {}) : null, (0, jsx_runtime_1.jsx)("div", { className: "__remotion-vertical-scrollbar", style: list, children: items.map((c) => {
|
||||
return ((0, jsx_runtime_1.jsx)(CompositionSelectorItem_1.CompositionSelectorItem, { level: 0, currentComposition: showCurrentComposition ? canvasContent.compositionId : null, selectComposition: selectComposition, toggleFolder: toggleFolder, tabIndex: tabIndex, item: c }, c.key + c.type));
|
||||
}) })] }));
|
||||
};
|
||||
exports.CompositionSelector = CompositionSelector;
|
||||
Generated
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
import React from 'react';
|
||||
import { type _InternalTypes } from 'remotion';
|
||||
export type CompositionSelectorItemType = {
|
||||
key: string;
|
||||
type: 'composition';
|
||||
composition: _InternalTypes['AnyComposition'];
|
||||
} | {
|
||||
key: string;
|
||||
type: 'folder';
|
||||
folderName: string;
|
||||
parentName: string | null;
|
||||
items: CompositionSelectorItemType[];
|
||||
expanded: boolean;
|
||||
};
|
||||
export declare const CompositionSelectorItem: React.FC<{
|
||||
readonly item: CompositionSelectorItemType;
|
||||
readonly currentComposition: string | null;
|
||||
readonly tabIndex: number;
|
||||
readonly selectComposition: (c: _InternalTypes['AnyComposition'], push: boolean) => void;
|
||||
readonly toggleFolder: (folderName: string, parentName: string | null) => void;
|
||||
readonly level: number;
|
||||
}>;
|
||||
Generated
Vendored
+182
@@ -0,0 +1,182 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CompositionSelectorItem = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const colors_1 = require("../helpers/colors");
|
||||
const is_composition_still_1 = require("../helpers/is-composition-still");
|
||||
const folder_1 = require("../icons/folder");
|
||||
const still_1 = require("../icons/still");
|
||||
const video_1 = require("../icons/video");
|
||||
const modals_1 = require("../state/modals");
|
||||
const CompositionContextButton_1 = require("./CompositionContextButton");
|
||||
const ContextMenu_1 = require("./ContextMenu");
|
||||
const layout_1 = require("./layout");
|
||||
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
|
||||
const SidebarRenderButton_1 = require("./SidebarRenderButton");
|
||||
const COMPOSITION_ITEM_HEIGHT = 32;
|
||||
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: COMPOSITION_ITEM_HEIGHT,
|
||||
};
|
||||
const labelStyle = {
|
||||
textAlign: 'left',
|
||||
textDecoration: 'none',
|
||||
fontSize: 13,
|
||||
flex: 1,
|
||||
whiteSpace: 'nowrap',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
};
|
||||
const iconStyle = {
|
||||
width: 18,
|
||||
height: 18,
|
||||
flexShrink: 0,
|
||||
};
|
||||
const CompositionSelectorItem = ({ item, level, currentComposition, tabIndex, selectComposition, toggleFolder, }) => {
|
||||
const selected = (0, react_1.useMemo)(() => {
|
||||
if (item.type === 'composition') {
|
||||
return currentComposition === item.composition.id;
|
||||
}
|
||||
return false;
|
||||
}, [item, currentComposition]);
|
||||
const [hovered, setHovered] = (0, react_1.useState)(false);
|
||||
const onPointerEnter = (0, react_1.useCallback)(() => {
|
||||
setHovered(true);
|
||||
}, []);
|
||||
const onPointerLeave = (0, react_1.useCallback)(() => {
|
||||
setHovered(false);
|
||||
}, []);
|
||||
const style = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
...itemStyle,
|
||||
backgroundColor: (0, colors_1.getBackgroundFromHoverState)({ hovered, selected }),
|
||||
paddingLeft: 12 + level * 8,
|
||||
};
|
||||
}, [hovered, level, selected]);
|
||||
const label = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
...labelStyle,
|
||||
color: selected || hovered ? 'white' : colors_1.LIGHT_TEXT,
|
||||
};
|
||||
}, [hovered, selected]);
|
||||
const onClick = (0, react_1.useCallback)((evt) => {
|
||||
evt.preventDefault();
|
||||
if (item.type === 'composition') {
|
||||
selectComposition(item.composition, true);
|
||||
}
|
||||
else {
|
||||
toggleFolder(item.folderName, item.parentName);
|
||||
}
|
||||
}, [item, selectComposition, toggleFolder]);
|
||||
const onKeyPress = (0, react_1.useCallback)((evt) => {
|
||||
if (evt.key === 'Enter') {
|
||||
onClick(evt);
|
||||
}
|
||||
}, [onClick]);
|
||||
const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
|
||||
const contextMenu = (0, react_1.useMemo)(() => {
|
||||
if (item.type === 'composition') {
|
||||
return [
|
||||
{
|
||||
id: 'duplicate',
|
||||
keyHint: null,
|
||||
label: `Duplicate...`,
|
||||
leftItem: null,
|
||||
onClick: () => {
|
||||
setSelectedModal({
|
||||
type: 'duplicate-comp',
|
||||
compositionId: item.composition.id,
|
||||
compositionType: item.composition.durationInFrames === 1
|
||||
? 'still'
|
||||
: 'composition',
|
||||
});
|
||||
},
|
||||
quickSwitcherLabel: null,
|
||||
subMenu: null,
|
||||
type: 'item',
|
||||
value: 'duplicate',
|
||||
},
|
||||
{
|
||||
id: 'rename',
|
||||
keyHint: null,
|
||||
label: `Rename...`,
|
||||
leftItem: null,
|
||||
onClick: () => {
|
||||
setSelectedModal({
|
||||
type: 'rename-comp',
|
||||
compositionId: item.composition.id,
|
||||
});
|
||||
},
|
||||
quickSwitcherLabel: null,
|
||||
subMenu: null,
|
||||
type: 'item',
|
||||
value: 'rename',
|
||||
},
|
||||
{
|
||||
id: 'delete',
|
||||
keyHint: null,
|
||||
label: `Delete...`,
|
||||
leftItem: null,
|
||||
onClick: () => {
|
||||
setSelectedModal({
|
||||
type: 'delete-comp',
|
||||
compositionId: item.composition.id,
|
||||
});
|
||||
},
|
||||
quickSwitcherLabel: null,
|
||||
subMenu: null,
|
||||
type: 'item',
|
||||
value: 'delete',
|
||||
},
|
||||
{
|
||||
type: 'divider',
|
||||
id: 'copy-id-divider',
|
||||
},
|
||||
{
|
||||
id: 'copy-id',
|
||||
keyHint: null,
|
||||
label: `Copy ID`,
|
||||
leftItem: null,
|
||||
onClick: () => {
|
||||
navigator.clipboard
|
||||
.writeText(item.composition.id)
|
||||
.catch((err) => {
|
||||
(0, NotificationCenter_1.showNotification)(`Could not copy to clipboard: ${err.message}`, 1000);
|
||||
})
|
||||
.then(() => {
|
||||
(0, NotificationCenter_1.showNotification)('Copied to clipboard', 1000);
|
||||
});
|
||||
},
|
||||
quickSwitcherLabel: null,
|
||||
subMenu: null,
|
||||
type: 'item',
|
||||
value: 'remove',
|
||||
},
|
||||
];
|
||||
}
|
||||
return [];
|
||||
}, [item, setSelectedModal]);
|
||||
if (item.type === 'folder') {
|
||||
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("button", { style: style, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, tabIndex: tabIndex, onClick: onClick, type: "button", title: item.folderName, children: [item.expanded ? ((0, jsx_runtime_1.jsx)(folder_1.ExpandedFolderIcon, { style: iconStyle, color: hovered || selected ? 'white' : colors_1.LIGHT_TEXT })) : ((0, jsx_runtime_1.jsx)(folder_1.CollapsedFolderIcon, { color: hovered || selected ? 'white' : colors_1.LIGHT_TEXT, style: iconStyle })), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, jsx_runtime_1.jsx)("div", { style: label, children: item.folderName })] }), item.expanded
|
||||
? item.items.map((childItem) => {
|
||||
return ((0, jsx_runtime_1.jsx)(exports.CompositionSelectorItem, { currentComposition: currentComposition, selectComposition: selectComposition, item: childItem, tabIndex: tabIndex, level: level + 1, toggleFolder: toggleFolder }, childItem.key + childItem.type));
|
||||
})
|
||||
: null] }));
|
||||
}
|
||||
return ((0, jsx_runtime_1.jsx)(ContextMenu_1.ContextMenu, { values: contextMenu, children: (0, jsx_runtime_1.jsx)(layout_1.Row, { align: "center", children: (0, jsx_runtime_1.jsxs)("a", { style: style, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, tabIndex: tabIndex, onClick: onClick, onKeyPress: onKeyPress, type: "button", title: item.composition.id, className: "__remotion-composition", "data-compname": item.composition.id, children: [(0, is_composition_still_1.isCompositionStill)(item.composition) ? ((0, jsx_runtime_1.jsx)(still_1.StillIcon, { color: hovered || selected ? 'white' : colors_1.LIGHT_TEXT, style: iconStyle })) : ((0, jsx_runtime_1.jsx)(video_1.FilmIcon, { color: hovered || selected ? 'white' : colors_1.LIGHT_TEXT, style: iconStyle })), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, jsx_runtime_1.jsx)("div", { style: label, children: item.composition.id }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.5 }), (0, jsx_runtime_1.jsx)(CompositionContextButton_1.CompositionContextButton, { values: contextMenu, visible: hovered }), (0, jsx_runtime_1.jsx)(SidebarRenderButton_1.SidebarRenderButton, { visible: hovered, composition: item.composition })] }) }) }));
|
||||
};
|
||||
exports.CompositionSelectorItem = CompositionSelectorItem;
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
import React from 'react';
|
||||
import type { ComboboxValue } from './NewComposition/ComboBox';
|
||||
export declare const ContextMenu: React.FC<{
|
||||
readonly children: React.ReactNode;
|
||||
readonly values: ComboboxValue[];
|
||||
}>;
|
||||
Generated
Vendored
+98
@@ -0,0 +1,98 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ContextMenu = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const player_1 = require("@remotion/player");
|
||||
const react_1 = require("react");
|
||||
const react_dom_1 = __importDefault(require("react-dom"));
|
||||
const mobile_layout_1 = require("../helpers/mobile-layout");
|
||||
const noop_1 = require("../helpers/noop");
|
||||
const z_index_1 = require("../state/z-index");
|
||||
const portals_1 = require("./Menu/portals");
|
||||
const styles_1 = require("./Menu/styles");
|
||||
const MenuContent_1 = require("./NewComposition/MenuContent");
|
||||
const ContextMenu = ({ children, values }) => {
|
||||
const ref = (0, react_1.useRef)(null);
|
||||
const [opened, setOpened] = (0, react_1.useState)({ type: 'not-open' });
|
||||
const { currentZIndex } = (0, z_index_1.useZIndex)();
|
||||
const style = (0, react_1.useMemo)(() => {
|
||||
return {};
|
||||
}, []);
|
||||
const size = player_1.PlayerInternals.useElementSize(ref, {
|
||||
triggerOnWindowResize: true,
|
||||
shouldApplyCssTransforms: true,
|
||||
});
|
||||
const isMobileLayout = (0, mobile_layout_1.useMobileLayout)();
|
||||
(0, react_1.useEffect)(() => {
|
||||
const { current } = ref;
|
||||
if (!current) {
|
||||
return;
|
||||
}
|
||||
const onClick = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setOpened({ type: 'open', left: e.clientX, top: e.clientY });
|
||||
return false;
|
||||
};
|
||||
current.addEventListener('contextmenu', onClick);
|
||||
return () => {
|
||||
current.removeEventListener('contextmenu', onClick);
|
||||
};
|
||||
}, [size]);
|
||||
const spaceToBottom = (0, react_1.useMemo)(() => {
|
||||
if (size && opened.type === 'open') {
|
||||
return size.windowSize.height - opened.top;
|
||||
}
|
||||
return 0;
|
||||
}, [opened, size]);
|
||||
const spaceToTop = (0, react_1.useMemo)(() => {
|
||||
if (size && opened.type === 'open') {
|
||||
return opened.top;
|
||||
}
|
||||
return 0;
|
||||
}, [opened, size]);
|
||||
const portalStyle = (0, react_1.useMemo)(() => {
|
||||
if (opened.type === 'not-open') {
|
||||
return;
|
||||
}
|
||||
if (!size) {
|
||||
return;
|
||||
}
|
||||
const spaceToRight = size.windowSize.width - size.left;
|
||||
const spaceToLeft = size.left + size.width;
|
||||
const minSpaceRequired = isMobileLayout
|
||||
? styles_1.MAX_MOBILE_MENU_WIDTH
|
||||
: styles_1.MAX_MENU_WIDTH;
|
||||
const verticalLayout = spaceToTop > spaceToBottom ? 'bottom' : 'top';
|
||||
const canOpenOnLeft = spaceToLeft >= minSpaceRequired;
|
||||
const canOpenOnRight = spaceToRight >= minSpaceRequired;
|
||||
const horizontalLayout = canOpenOnRight ? 'left' : 'right';
|
||||
return {
|
||||
...styles_1.menuContainerTowardsTop,
|
||||
...(verticalLayout === 'top'
|
||||
? {
|
||||
top: opened.top,
|
||||
}
|
||||
: {
|
||||
bottom: size.windowSize.height - opened.top,
|
||||
}),
|
||||
...(horizontalLayout === 'left'
|
||||
? {
|
||||
left: opened.left,
|
||||
}
|
||||
: {
|
||||
right: canOpenOnLeft ? size.windowSize.width - opened.left : 0,
|
||||
}),
|
||||
};
|
||||
}, [opened, size, isMobileLayout, spaceToTop, spaceToBottom]);
|
||||
const onHide = (0, react_1.useCallback)(() => {
|
||||
setOpened({ type: 'not-open' });
|
||||
}, []);
|
||||
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { ref: ref, onContextMenu: () => false, style: style, children: children }), portalStyle
|
||||
? react_dom_1.default.createPortal((0, jsx_runtime_1.jsx)("div", { style: styles_1.fullScreenOverlay, children: (0, jsx_runtime_1.jsx)("div", { style: styles_1.outerPortal, className: "css-reset", children: (0, jsx_runtime_1.jsx)(z_index_1.HigherZIndex, { onOutsideClick: onHide, onEscape: onHide, children: (0, jsx_runtime_1.jsx)("div", { style: portalStyle, children: (0, jsx_runtime_1.jsx)(MenuContent_1.MenuContent, { onNextMenu: noop_1.noop, onPreviousMenu: noop_1.noop, values: values, onHide: onHide, leaveLeftSpace: true, preselectIndex: false, topItemCanBeUnselected: false, fixedHeight: null }) }) }) }) }), (0, portals_1.getPortal)(currentZIndex))
|
||||
: null] }));
|
||||
};
|
||||
exports.ContextMenu = ContextMenu;
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
import React from 'react';
|
||||
export declare const CONTROL_BUTTON_PADDING = 6;
|
||||
export declare const ControlButton: (props: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement> & {
|
||||
readonly title: string;
|
||||
}) => import("react/jsx-runtime").JSX.Element;
|
||||
Generated
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ControlButton = exports.CONTROL_BUTTON_PADDING = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const z_index_1 = require("../state/z-index");
|
||||
exports.CONTROL_BUTTON_PADDING = 6;
|
||||
const ControlButton = (props) => {
|
||||
const style = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
opacity: props.disabled ? 0.5 : 1,
|
||||
display: 'inline-flex',
|
||||
background: 'none',
|
||||
border: 'none',
|
||||
padding: exports.CONTROL_BUTTON_PADDING,
|
||||
};
|
||||
}, [props.disabled]);
|
||||
const { tabIndex } = (0, z_index_1.useZIndex)();
|
||||
return ((0, jsx_runtime_1.jsx)("button", { type: 'button', tabIndex: tabIndex, ...props, style: style }));
|
||||
};
|
||||
exports.ControlButton = ControlButton;
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
import React from 'react';
|
||||
export declare const CopyButton: React.FC<{
|
||||
readonly textToCopy: string;
|
||||
readonly label: string;
|
||||
readonly labelWhenCopied: string;
|
||||
}>;
|
||||
Generated
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CopyButton = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const copy_text_1 = require("../helpers/copy-text");
|
||||
const Button_1 = require("./Button");
|
||||
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
|
||||
const layout_1 = require("./layout");
|
||||
const iconStyle = {
|
||||
width: 16,
|
||||
height: 16,
|
||||
color: 'white',
|
||||
};
|
||||
const buttonContainerStyle = {
|
||||
display: 'flex',
|
||||
minWidth: '114px',
|
||||
};
|
||||
const copyIcon = ((0, jsx_runtime_1.jsx)("svg", { "aria-hidden": "true", focusable: "false", "data-prefix": "far", "data-icon": "clipboard", className: "svg-inline--fa fa-clipboard fa-w-12", role: "img", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 384 512", style: iconStyle, children: (0, jsx_runtime_1.jsx)("path", { fill: "currentColor", d: "M336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 40c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm144 418c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V118c0-3.3 2.7-6 6-6h42v36c0 6.6 5.4 12 12 12h168c6.6 0 12-5.4 12-12v-36h42c3.3 0 6 2.7 6 6z" }) }));
|
||||
const labelStyle = {
|
||||
fontSize: 14,
|
||||
};
|
||||
const CopyButton = ({ textToCopy, label, labelWhenCopied }) => {
|
||||
const [copied, setCopied] = (0, react_1.useState)(false);
|
||||
const onClick = (0, react_1.useCallback)(() => {
|
||||
(0, copy_text_1.copyText)(textToCopy)
|
||||
.then(() => {
|
||||
setCopied(Date.now());
|
||||
})
|
||||
.catch((err) => {
|
||||
(0, NotificationCenter_1.showNotification)(`Could not copy: ${err.message}`, 2000);
|
||||
});
|
||||
}, [textToCopy]);
|
||||
(0, react_1.useEffect)(() => {
|
||||
if (!copied) {
|
||||
return;
|
||||
}
|
||||
const to = setTimeout(() => setCopied(false), 2000);
|
||||
return () => clearTimeout(to);
|
||||
}, [copied]);
|
||||
return ((0, jsx_runtime_1.jsxs)(Button_1.Button, { onClick: onClick, buttonContainerStyle: buttonContainerStyle, children: [copyIcon, (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1.5 }), ' ', (0, jsx_runtime_1.jsx)("span", { style: labelStyle, children: copied ? labelWhenCopied : label })] }));
|
||||
};
|
||||
exports.CopyButton = CopyButton;
|
||||
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
export declare const CURRENT_COMPOSITION_HEIGHT = 80;
|
||||
export declare const CurrentComposition: () => import("react/jsx-runtime").JSX.Element;
|
||||
Generated
Vendored
+45
@@ -0,0 +1,45 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CurrentComposition = exports.CURRENT_COMPOSITION_HEIGHT = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const remotion_1 = require("remotion");
|
||||
const colors_1 = require("../helpers/colors");
|
||||
const is_composition_still_1 = require("../helpers/is-composition-still");
|
||||
const render_frame_1 = require("../state/render-frame");
|
||||
exports.CURRENT_COMPOSITION_HEIGHT = 80;
|
||||
const container = {
|
||||
height: exports.CURRENT_COMPOSITION_HEIGHT,
|
||||
display: 'block',
|
||||
borderBottom: `1px solid ${colors_1.BORDER_COLOR}`,
|
||||
padding: 12,
|
||||
color: 'white',
|
||||
backgroundColor: colors_1.BACKGROUND,
|
||||
};
|
||||
const title = {
|
||||
fontWeight: 'bold',
|
||||
fontSize: 12,
|
||||
whiteSpace: 'nowrap',
|
||||
lineHeight: '18px',
|
||||
backgroundColor: colors_1.BACKGROUND,
|
||||
};
|
||||
const subtitle = {
|
||||
fontSize: 12,
|
||||
opacity: 0.8,
|
||||
whiteSpace: 'nowrap',
|
||||
lineHeight: '18px',
|
||||
backgroundColor: colors_1.BACKGROUND,
|
||||
};
|
||||
const row = {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
lineHeight: '18px',
|
||||
backgroundColor: colors_1.BACKGROUND,
|
||||
};
|
||||
const CurrentComposition = () => {
|
||||
const video = remotion_1.Internals.useVideo();
|
||||
if (!video) {
|
||||
return (0, jsx_runtime_1.jsx)("div", { style: container });
|
||||
}
|
||||
return ((0, jsx_runtime_1.jsx)("div", { style: container, children: (0, jsx_runtime_1.jsx)("div", { style: row, children: (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { style: title, children: video.id }), (0, jsx_runtime_1.jsxs)("div", { style: subtitle, children: [video.width, "x", video.height, (0, is_composition_still_1.isCompositionStill)(video) ? null : `, ${video.fps} FPS`] }), (0, is_composition_still_1.isCompositionStill)(video) ? ((0, jsx_runtime_1.jsx)("div", { style: subtitle, children: "Still" })) : ((0, jsx_runtime_1.jsxs)("div", { style: subtitle, children: ["Duration ", (0, render_frame_1.renderFrame)(video.durationInFrames, video.fps)] }))] }) }) }));
|
||||
};
|
||||
exports.CurrentComposition = CurrentComposition;
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
import type React from 'react';
|
||||
export declare const TitleUpdater: React.FC;
|
||||
export declare const CurrentCompositionKeybindings: React.FC<{
|
||||
readonly readOnlyStudio: boolean;
|
||||
}>;
|
||||
Generated
Vendored
+74
@@ -0,0 +1,74 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CurrentCompositionKeybindings = exports.TitleUpdater = void 0;
|
||||
const react_1 = require("react");
|
||||
const remotion_1 = require("remotion");
|
||||
const client_id_1 = require("../helpers/client-id");
|
||||
const document_title_1 = require("../helpers/document-title");
|
||||
const use_keybinding_1 = require("../helpers/use-keybinding");
|
||||
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
|
||||
const context_1 = require("./RenderQueue/context");
|
||||
const TitleUpdater = () => {
|
||||
const renderQueue = (0, react_1.useContext)(context_1.RenderQueueContext);
|
||||
const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
||||
const { jobs } = renderQueue;
|
||||
(0, react_1.useEffect)(() => {
|
||||
if (!canvasContent) {
|
||||
(0, document_title_1.setCurrentCanvasContentId)(null);
|
||||
return;
|
||||
}
|
||||
if (canvasContent.type === 'composition') {
|
||||
(0, document_title_1.setCurrentCanvasContentId)(canvasContent.compositionId);
|
||||
return;
|
||||
}
|
||||
if (canvasContent.type === 'output') {
|
||||
(0, document_title_1.setCurrentCanvasContentId)(canvasContent.path);
|
||||
return;
|
||||
}
|
||||
if (canvasContent.type === 'output-blob') {
|
||||
(0, document_title_1.setCurrentCanvasContentId)(canvasContent.displayName);
|
||||
return;
|
||||
}
|
||||
(0, document_title_1.setCurrentCanvasContentId)(canvasContent.asset);
|
||||
}, [canvasContent]);
|
||||
(0, react_1.useEffect)(() => {
|
||||
(0, document_title_1.setRenderJobs)(jobs);
|
||||
}, [jobs]);
|
||||
return null;
|
||||
};
|
||||
exports.TitleUpdater = TitleUpdater;
|
||||
const CurrentCompositionKeybindings = ({ readOnlyStudio }) => {
|
||||
const keybindings = (0, use_keybinding_1.useKeybinding)();
|
||||
const video = remotion_1.Internals.useVideo();
|
||||
const { type } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx).previewServerState;
|
||||
const openRenderModal = (0, react_1.useCallback)(() => {
|
||||
if (!video) {
|
||||
return;
|
||||
}
|
||||
if (readOnlyStudio) {
|
||||
return (0, NotificationCenter_1.showNotification)('Studio is read-only', 2000);
|
||||
}
|
||||
if (type !== 'connected') {
|
||||
(0, NotificationCenter_1.showNotification)('Studio server is offline', 2000);
|
||||
return;
|
||||
}
|
||||
const renderButton = document.getElementById('render-modal-button');
|
||||
renderButton.click();
|
||||
}, [readOnlyStudio, type, video]);
|
||||
(0, react_1.useEffect)(() => {
|
||||
const binding = keybindings.registerKeybinding({
|
||||
event: 'keydown',
|
||||
key: 'r',
|
||||
commandCtrlKey: false,
|
||||
callback: openRenderModal,
|
||||
preventDefault: true,
|
||||
triggerIfInputFieldFocused: false,
|
||||
keepRegisteredWhenNotHighestContext: false,
|
||||
});
|
||||
return () => {
|
||||
binding.unregister();
|
||||
};
|
||||
}, [keybindings, openRenderModal]);
|
||||
return null;
|
||||
};
|
||||
exports.CurrentCompositionKeybindings = CurrentCompositionKeybindings;
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
import React from 'react';
|
||||
export declare const BUFFER_STATE_DELAY_IN_MILLISECONDS: number;
|
||||
export declare const Editor: React.FC<{
|
||||
readonly Root: React.FC;
|
||||
readonly readOnlyStudio: boolean;
|
||||
}>;
|
||||
Generated
Vendored
+101
@@ -0,0 +1,101 @@
|
||||
"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;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Editor = exports.BUFFER_STATE_DELAY_IN_MILLISECONDS = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const player_1 = require("@remotion/player");
|
||||
const react_1 = __importStar(require("react"));
|
||||
const remotion_1 = require("remotion");
|
||||
const colors_1 = require("../helpers/colors");
|
||||
const noop_1 = require("../helpers/noop");
|
||||
const canvas_ref_1 = require("../state/canvas-ref");
|
||||
const timeline_zoom_1 = require("../state/timeline-zoom");
|
||||
const z_index_1 = require("../state/z-index");
|
||||
const EditorContent_1 = require("./EditorContent");
|
||||
const GlobalKeybindings_1 = require("./GlobalKeybindings");
|
||||
const Modals_1 = require("./Modals");
|
||||
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
|
||||
const TopPanel_1 = require("./TopPanel");
|
||||
const background = {
|
||||
backgroundColor: colors_1.BACKGROUND,
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
flexDirection: 'column',
|
||||
position: 'absolute',
|
||||
};
|
||||
const DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS = 300;
|
||||
exports.BUFFER_STATE_DELAY_IN_MILLISECONDS = typeof process.env.BUFFER_STATE_DELAY_IN_MILLISECONDS === 'undefined' ||
|
||||
process.env.BUFFER_STATE_DELAY_IN_MILLISECONDS === null
|
||||
? DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS
|
||||
: Number(process.env.BUFFER_STATE_DELAY_IN_MILLISECONDS);
|
||||
const Editor = ({ Root, readOnlyStudio }) => {
|
||||
const size = player_1.PlayerInternals.useElementSize(canvas_ref_1.drawRef, {
|
||||
triggerOnWindowResize: false,
|
||||
shouldApplyCssTransforms: true,
|
||||
});
|
||||
(0, react_1.useEffect)(() => {
|
||||
if (readOnlyStudio) {
|
||||
return;
|
||||
}
|
||||
const listenToChanges = (e) => {
|
||||
if (window.remotion_unsavedProps) {
|
||||
e.returnValue = 'Are you sure you want to leave?';
|
||||
}
|
||||
};
|
||||
window.addEventListener('beforeunload', listenToChanges);
|
||||
return () => {
|
||||
window.removeEventListener('beforeunload', listenToChanges);
|
||||
};
|
||||
}, [readOnlyStudio]);
|
||||
const [canvasMounted, setCanvasMounted] = react_1.default.useState(false);
|
||||
const onMounted = (0, react_1.useCallback)(() => {
|
||||
setCanvasMounted(true);
|
||||
}, []);
|
||||
const value = (0, react_1.useMemo)(() => {
|
||||
if (!size) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
type: 'canvas-size',
|
||||
canvasSize: size,
|
||||
};
|
||||
}, [size]);
|
||||
const MemoRoot = (0, react_1.useMemo)(() => {
|
||||
return react_1.default.memo(Root);
|
||||
}, [Root]);
|
||||
return ((0, jsx_runtime_1.jsx)(z_index_1.HigherZIndex, { onEscape: noop_1.noop, onOutsideClick: noop_1.noop, children: (0, jsx_runtime_1.jsxs)(timeline_zoom_1.TimelineZoomContext, { children: [(0, jsx_runtime_1.jsx)(remotion_1.Internals.CurrentScaleContext.Provider, { value: value, children: (0, jsx_runtime_1.jsxs)("div", { style: background, children: [canvasMounted ? (0, jsx_runtime_1.jsx)(MemoRoot, {}) : null, (0, jsx_runtime_1.jsxs)(remotion_1.Internals.CanUseRemotionHooksProvider, { children: [(0, jsx_runtime_1.jsx)(EditorContent_1.EditorContent, { readOnlyStudio: readOnlyStudio, children: (0, jsx_runtime_1.jsx)(TopPanel_1.TopPanel, { drawRef: canvas_ref_1.drawRef, bufferStateDelayInMilliseconds: exports.BUFFER_STATE_DELAY_IN_MILLISECONDS, onMounted: onMounted, readOnlyStudio: readOnlyStudio }) }), (0, jsx_runtime_1.jsx)(GlobalKeybindings_1.GlobalKeybindings, {})] })] }) }), (0, jsx_runtime_1.jsx)(Modals_1.Modals, { readOnlyStudio: readOnlyStudio }), (0, jsx_runtime_1.jsx)(NotificationCenter_1.NotificationCenter, {})] }) }));
|
||||
};
|
||||
exports.Editor = Editor;
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
import React from 'react';
|
||||
export declare const EditorContent: React.FC<{
|
||||
readonly readOnlyStudio: boolean;
|
||||
readonly children: React.ReactNode;
|
||||
}>;
|
||||
Generated
Vendored
+28
@@ -0,0 +1,28 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.EditorContent = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const remotion_1 = require("remotion");
|
||||
const is_current_selected_still_1 = require("../helpers/is-current-selected-still");
|
||||
const InitialCompositionLoader_1 = require("./InitialCompositionLoader");
|
||||
const MenuToolbar_1 = require("./MenuToolbar");
|
||||
const SplitterContainer_1 = require("./Splitter/SplitterContainer");
|
||||
const SplitterElement_1 = require("./Splitter/SplitterElement");
|
||||
const SplitterHandle_1 = require("./Splitter/SplitterHandle");
|
||||
const Timeline_1 = require("./Timeline/Timeline");
|
||||
const noop = () => undefined;
|
||||
const container = {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flex: 1,
|
||||
height: 0,
|
||||
};
|
||||
const EditorContent = ({ readOnlyStudio, children }) => {
|
||||
const isStill = (0, is_current_selected_still_1.useIsStill)();
|
||||
const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
||||
// Preventing multiple renders so the update check doesn't get rendered twice and needs to be aborted
|
||||
const onlyTopPanel = canvasContent === null || isStill || canvasContent.type !== 'composition';
|
||||
return ((0, jsx_runtime_1.jsxs)("div", { style: container, children: [(0, jsx_runtime_1.jsx)(InitialCompositionLoader_1.InitialCompositionLoader, {}), (0, jsx_runtime_1.jsx)(MenuToolbar_1.MenuToolbar, { readOnlyStudio: readOnlyStudio }), (0, jsx_runtime_1.jsxs)(SplitterContainer_1.SplitterContainer, { orientation: "horizontal", id: "top-to-bottom", maxFlex: 0.9, minFlex: 0.2, defaultFlex: 0.75, children: [(0, jsx_runtime_1.jsx)(SplitterElement_1.SplitterElement, { sticky: null, type: "flexer", children: children }), onlyTopPanel ? null : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(SplitterHandle_1.SplitterHandle, { allowToCollapse: "none", onCollapse: noop }), (0, jsx_runtime_1.jsx)(SplitterElement_1.SplitterElement, { sticky: null, type: "anti-flexer", children: (0, jsx_runtime_1.jsx)(Timeline_1.Timeline, {}) })] }))] })] }));
|
||||
};
|
||||
exports.EditorContent = EditorContent;
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
import React from 'react';
|
||||
export declare const EditorContexts: React.FC<{
|
||||
readonly children: React.ReactNode;
|
||||
readonly readOnlyStudio: boolean;
|
||||
}>;
|
||||
Generated
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.EditorContexts = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const player_1 = require("@remotion/player");
|
||||
const client_id_1 = require("../helpers/client-id");
|
||||
const folders_1 = require("../state/folders");
|
||||
const highest_z_index_1 = require("../state/highest-z-index");
|
||||
const keybindings_1 = require("../state/keybindings");
|
||||
const preview_size_1 = require("../state/preview-size");
|
||||
const sidebar_1 = require("../state/sidebar");
|
||||
const VisualControls_1 = require("../visual-controls/VisualControls");
|
||||
const CheckerboardProvider_1 = require("./CheckerboardProvider");
|
||||
const get_zod_if_possible_1 = require("./get-zod-if-possible");
|
||||
const MediaVolumeProvider_1 = require("./MediaVolumeProvider");
|
||||
const ModalsProvider_1 = require("./ModalsProvider");
|
||||
const ClientRenderQueueProcessor_1 = require("./RenderQueue/ClientRenderQueueProcessor");
|
||||
const context_1 = require("./RenderQueue/context");
|
||||
const SetTimelineInOutProvider_1 = require("./SetTimelineInOutProvider");
|
||||
const ShowGuidesProvider_1 = require("./ShowGuidesProvider");
|
||||
const ShowRulersProvider_1 = require("./ShowRulersProvider");
|
||||
const ZoomGesturesProvider_1 = require("./ZoomGesturesProvider");
|
||||
const EditorContexts = ({ children, readOnlyStudio }) => {
|
||||
return ((0, jsx_runtime_1.jsx)(get_zod_if_possible_1.ZodProvider, { children: (0, jsx_runtime_1.jsx)(VisualControls_1.VisualControlsProvider, { children: (0, jsx_runtime_1.jsx)(client_id_1.PreviewServerConnection, { readOnlyStudio: readOnlyStudio, children: (0, jsx_runtime_1.jsxs)(context_1.RenderQueueContextProvider, { children: [(0, jsx_runtime_1.jsx)(ClientRenderQueueProcessor_1.ClientRenderQueueProcessor, {}), (0, jsx_runtime_1.jsx)(keybindings_1.KeybindingContextProvider, { children: (0, jsx_runtime_1.jsx)(CheckerboardProvider_1.CheckerboardProvider, { children: (0, jsx_runtime_1.jsx)(ZoomGesturesProvider_1.ZoomGesturesProvider, { children: (0, jsx_runtime_1.jsx)(ShowRulersProvider_1.ShowRulersProvider, { children: (0, jsx_runtime_1.jsx)(ShowGuidesProvider_1.ShowGuidesProvider, { children: (0, jsx_runtime_1.jsx)(preview_size_1.PreviewSizeProvider, { children: (0, jsx_runtime_1.jsx)(ModalsProvider_1.ModalsProvider, { children: (0, jsx_runtime_1.jsx)(MediaVolumeProvider_1.MediaVolumeProvider, { children: (0, jsx_runtime_1.jsx)(player_1.PlayerInternals.PlayerEmitterProvider, { currentPlaybackRate: null, children: (0, jsx_runtime_1.jsx)(sidebar_1.SidebarContextProvider, { children: (0, jsx_runtime_1.jsx)(folders_1.FolderContextProvider, { children: (0, jsx_runtime_1.jsx)(highest_z_index_1.HighestZIndexProvider, { children: (0, jsx_runtime_1.jsx)(SetTimelineInOutProvider_1.SetTimelineInOutProvider, { children: children }) }) }) }) }) }) }) }) }) }) }) }) })] }) }) }) }));
|
||||
};
|
||||
exports.EditorContexts = EditorContexts;
|
||||
Generated
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
import type { Guide } from '../../state/editor-guides';
|
||||
declare const _default: import("react").NamedExoticComponent<{
|
||||
guide: Guide;
|
||||
canvasDimensions: {
|
||||
left: number;
|
||||
top: number;
|
||||
width: number;
|
||||
height: number;
|
||||
};
|
||||
scale: number;
|
||||
}>;
|
||||
export default _default;
|
||||
Generated
Vendored
+91
@@ -0,0 +1,91 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const no_react_1 = require("remotion/no-react");
|
||||
const colors_1 = require("../../helpers/colors");
|
||||
const editor_guides_1 = require("../../state/editor-guides");
|
||||
const editor_rulers_1 = require("../../state/editor-rulers");
|
||||
const ContextMenu_1 = require("../ContextMenu");
|
||||
const PADDING_FOR_EASY_DRAG = 4;
|
||||
const GuideComp = ({ guide, canvasDimensions, scale }) => {
|
||||
const { shouldCreateGuideRef, setGuidesList, setSelectedGuideId, selectedGuideId, setHoveredGuideId, hoveredGuideId, } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
|
||||
const onPointerEnter = (0, react_1.useCallback)(() => {
|
||||
setHoveredGuideId(() => guide.id);
|
||||
}, [guide.id, setHoveredGuideId]);
|
||||
const onPointerLeave = (0, react_1.useCallback)(() => {
|
||||
setHoveredGuideId(() => null);
|
||||
}, [setHoveredGuideId]);
|
||||
const isVerticalGuide = guide.orientation === 'vertical';
|
||||
const guideStyle = (0, react_1.useMemo)(() => {
|
||||
const canvasPosition = isVerticalGuide
|
||||
? canvasDimensions.left
|
||||
: canvasDimensions.top;
|
||||
const guidePosition = guide.position * scale + canvasPosition;
|
||||
return {
|
||||
position: 'absolute',
|
||||
width: `${isVerticalGuide ? '1px' : '100%'}`,
|
||||
height: `${isVerticalGuide ? '100%' : '1px'}`,
|
||||
left: `${isVerticalGuide ? guidePosition - PADDING_FOR_EASY_DRAG : 0}px`,
|
||||
top: `${isVerticalGuide ? 0 : guidePosition - PADDING_FOR_EASY_DRAG}px`,
|
||||
cursor: `${isVerticalGuide ? 'ew-resize' : 'ns-resize'}`,
|
||||
padding: isVerticalGuide
|
||||
? `0 ${PADDING_FOR_EASY_DRAG}px`
|
||||
: `${PADDING_FOR_EASY_DRAG}px 0`,
|
||||
};
|
||||
}, [guide, scale, canvasDimensions, isVerticalGuide]);
|
||||
const guideContentStyle = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
position: 'relative',
|
||||
minWidth: `${isVerticalGuide ? '1px' : `calc(100% + ${editor_rulers_1.RULER_WIDTH}px`}`,
|
||||
minHeight: `${isVerticalGuide ? `calc(100% + ${editor_rulers_1.RULER_WIDTH}px` : '1px'}`,
|
||||
top: `${isVerticalGuide ? `-${editor_rulers_1.RULER_WIDTH}px` : '0px'}`,
|
||||
left: `${isVerticalGuide ? '0px' : `-${editor_rulers_1.RULER_WIDTH}px`}`,
|
||||
display: guide.show ? 'block' : 'none',
|
||||
backgroundColor: selectedGuideId === guide.id || hoveredGuideId === guide.id
|
||||
? colors_1.SELECTED_GUIDE
|
||||
: colors_1.UNSELECTED_GUIDE,
|
||||
};
|
||||
}, [isVerticalGuide, guide.show, guide.id, selectedGuideId, hoveredGuideId]);
|
||||
const onMouseDown = (0, react_1.useCallback)((e) => {
|
||||
e.preventDefault();
|
||||
if (e.button !== 0) {
|
||||
return;
|
||||
}
|
||||
shouldCreateGuideRef.current = true;
|
||||
document.body.style.cursor = 'no-drop';
|
||||
setSelectedGuideId(() => guide.id);
|
||||
}, [shouldCreateGuideRef, setSelectedGuideId, guide.id]);
|
||||
const values = (0, react_1.useMemo)(() => {
|
||||
return [
|
||||
{
|
||||
id: '1',
|
||||
keyHint: null,
|
||||
label: 'Remove guide',
|
||||
leftItem: null,
|
||||
onClick: () => {
|
||||
setGuidesList((prevState) => {
|
||||
const newGuides = prevState.filter((selected) => {
|
||||
return selected.id !== guide.id;
|
||||
});
|
||||
(0, editor_guides_1.persistGuidesList)(newGuides);
|
||||
return newGuides;
|
||||
});
|
||||
},
|
||||
quickSwitcherLabel: null,
|
||||
subMenu: null,
|
||||
type: 'item',
|
||||
value: 'remove',
|
||||
},
|
||||
];
|
||||
}, [guide.id, setGuidesList]);
|
||||
return ((0, jsx_runtime_1.jsx)(ContextMenu_1.ContextMenu, { values: values, children: (0, jsx_runtime_1.jsx)("div", { style: guideStyle, onMouseDown: onMouseDown, className: "__remotion_editor_guide", onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, children: (0, jsx_runtime_1.jsx)("div", { style: guideContentStyle, className: [
|
||||
'__remotion_editor_guide_content',
|
||||
selectedGuideId === guide.id || hoveredGuideId === guide.id
|
||||
? '__remotion_editor_guide_selected'
|
||||
: null,
|
||||
]
|
||||
.filter(no_react_1.NoReactInternals.truthy)
|
||||
.join(' ') }) }) }));
|
||||
};
|
||||
exports.default = (0, react_1.memo)(GuideComp);
|
||||
Generated
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
import { type Size } from '@remotion/player';
|
||||
import type { AssetMetadata } from '../../helpers/get-asset-metadata';
|
||||
import type { Dimensions } from '../../helpers/is-current-selected-still';
|
||||
declare const EditorGuides: React.FC<{
|
||||
canvasSize: Size | null;
|
||||
contentDimensions: Dimensions | 'none' | null;
|
||||
assetMetadata: AssetMetadata | null;
|
||||
}>;
|
||||
export default EditorGuides;
|
||||
Generated
Vendored
+32
@@ -0,0 +1,32 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const remotion_1 = require("remotion");
|
||||
const use_studio_canvas_dimensions_1 = require("../../helpers/use-studio-canvas-dimensions");
|
||||
const editor_guides_1 = require("../../state/editor-guides");
|
||||
const Guide_1 = __importDefault(require("./Guide"));
|
||||
const EditorGuides = ({ canvasSize, contentDimensions, assetMetadata }) => {
|
||||
const { canvasPosition: canvasDimensions, scale } = (0, use_studio_canvas_dimensions_1.useStudioCanvasDimensions)({
|
||||
canvasSize,
|
||||
contentDimensions,
|
||||
assetMetadata,
|
||||
});
|
||||
const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
||||
if (canvasContent === null || canvasContent.type !== 'composition') {
|
||||
throw new Error('Expected to be in a composition');
|
||||
}
|
||||
const { guidesList } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
|
||||
const guidesForThisComposition = (0, react_1.useMemo)(() => {
|
||||
return guidesList.filter((guide) => {
|
||||
return guide.compositionId === canvasContent.compositionId;
|
||||
});
|
||||
}, [canvasContent.compositionId, guidesList]);
|
||||
return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: guidesForThisComposition.map((guide) => {
|
||||
return ((0, jsx_runtime_1.jsx)(Guide_1.default, { guide: guide, canvasDimensions: canvasDimensions, scale: scale }, guide.id));
|
||||
}) }));
|
||||
};
|
||||
exports.default = EditorGuides;
|
||||
Generated
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
import type { Size } from '@remotion/player';
|
||||
import React from 'react';
|
||||
interface Point {
|
||||
value: number;
|
||||
position: number;
|
||||
}
|
||||
interface RulerProps {
|
||||
readonly scale: number;
|
||||
readonly points: Point[];
|
||||
readonly originOffset: number;
|
||||
readonly startMarking: number;
|
||||
readonly markingGaps: number;
|
||||
readonly orientation: 'horizontal' | 'vertical';
|
||||
readonly size: Size;
|
||||
}
|
||||
declare const Ruler: React.FC<RulerProps>;
|
||||
export default Ruler;
|
||||
Generated
Vendored
+108
@@ -0,0 +1,108 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const remotion_1 = require("remotion");
|
||||
const colors_1 = require("../../helpers/colors");
|
||||
const editor_ruler_1 = require("../../helpers/editor-ruler");
|
||||
const editor_guides_1 = require("../../state/editor-guides");
|
||||
const editor_rulers_1 = require("../../state/editor-rulers");
|
||||
const makeGuideId = () => {
|
||||
return Math.random().toString(36).substring(7);
|
||||
};
|
||||
const Ruler = ({ scale, points, originOffset, startMarking, size, markingGaps, orientation, }) => {
|
||||
const rulerCanvasRef = (0, react_1.useRef)(null);
|
||||
const isVerticalRuler = orientation === 'vertical';
|
||||
const { shouldCreateGuideRef, setGuidesList, selectedGuideId, hoveredGuideId, setSelectedGuideId, guidesList, setEditorShowGuides, } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
|
||||
const unsafeVideoConfig = remotion_1.Internals.useUnsafeVideoConfig();
|
||||
if (!unsafeVideoConfig) {
|
||||
throw new Error('Video config not set');
|
||||
}
|
||||
const [cursor, setCursor] = (0, react_1.useState)(isVerticalRuler ? 'ew-resize' : 'ns-resize');
|
||||
const selectedOrHoveredGuide = (0, react_1.useMemo)(() => {
|
||||
var _a, _b;
|
||||
return ((_b = (_a = guidesList.find((guide) => guide.id === selectedGuideId)) !== null && _a !== void 0 ? _a : guidesList.find((guide) => guide.id === hoveredGuideId)) !== null && _b !== void 0 ? _b : null);
|
||||
}, [guidesList, hoveredGuideId, selectedGuideId]);
|
||||
const rulerWidth = isVerticalRuler ? editor_rulers_1.RULER_WIDTH : size.width - editor_rulers_1.RULER_WIDTH;
|
||||
const rulerHeight = isVerticalRuler ? size.height - editor_rulers_1.RULER_WIDTH : editor_rulers_1.RULER_WIDTH;
|
||||
(0, react_1.useEffect)(() => {
|
||||
(0, editor_ruler_1.drawMarkingOnRulerCanvas)({
|
||||
scale,
|
||||
points,
|
||||
startMarking,
|
||||
originOffset,
|
||||
markingGaps,
|
||||
orientation,
|
||||
rulerCanvasRef,
|
||||
selectedGuide: selectedOrHoveredGuide,
|
||||
canvasHeight: rulerHeight * window.devicePixelRatio,
|
||||
canvasWidth: rulerWidth * window.devicePixelRatio,
|
||||
});
|
||||
}, [
|
||||
scale,
|
||||
points,
|
||||
startMarking,
|
||||
originOffset,
|
||||
markingGaps,
|
||||
orientation,
|
||||
selectedOrHoveredGuide,
|
||||
size,
|
||||
rulerHeight,
|
||||
rulerWidth,
|
||||
]);
|
||||
const rulerStyle = (0, react_1.useMemo)(() => ({
|
||||
position: 'absolute',
|
||||
background: colors_1.BACKGROUND,
|
||||
width: rulerWidth,
|
||||
height: rulerHeight,
|
||||
left: isVerticalRuler ? 0 : 'unset',
|
||||
top: isVerticalRuler ? 'unset' : 0,
|
||||
borderBottom: isVerticalRuler ? undefined : '1px solid ' + colors_1.RULER_COLOR,
|
||||
borderRight: isVerticalRuler ? '1px solid ' + colors_1.RULER_COLOR : undefined,
|
||||
cursor,
|
||||
}), [rulerWidth, rulerHeight, cursor, isVerticalRuler]);
|
||||
const onMouseDown = (0, react_1.useCallback)((e) => {
|
||||
if (e.button !== 0) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
shouldCreateGuideRef.current = true;
|
||||
document.body.style.cursor = 'no-drop';
|
||||
const guideId = makeGuideId();
|
||||
setEditorShowGuides(() => true);
|
||||
setSelectedGuideId(() => guideId);
|
||||
setGuidesList((prevState) => {
|
||||
return [
|
||||
...prevState,
|
||||
{
|
||||
orientation,
|
||||
position: -originOffset,
|
||||
show: false,
|
||||
id: guideId,
|
||||
compositionId: unsafeVideoConfig.id,
|
||||
},
|
||||
];
|
||||
});
|
||||
}, [
|
||||
shouldCreateGuideRef,
|
||||
setEditorShowGuides,
|
||||
setSelectedGuideId,
|
||||
setGuidesList,
|
||||
orientation,
|
||||
originOffset,
|
||||
unsafeVideoConfig.id,
|
||||
]);
|
||||
const changeCursor = (0, react_1.useCallback)((e) => {
|
||||
e.preventDefault();
|
||||
if (selectedGuideId !== null) {
|
||||
setCursor('no-drop');
|
||||
}
|
||||
}, [setCursor, selectedGuideId]);
|
||||
(0, react_1.useEffect)(() => {
|
||||
if (selectedGuideId === null) {
|
||||
setCursor(isVerticalRuler ? 'ew-resize' : 'ns-resize');
|
||||
}
|
||||
}, [selectedGuideId, isVerticalRuler]);
|
||||
return ((0, jsx_runtime_1.jsx)("canvas", { ref: rulerCanvasRef, width: rulerWidth * window.devicePixelRatio, height: rulerHeight * window.devicePixelRatio, style: rulerStyle, onPointerDown: onMouseDown, onPointerEnter: changeCursor, onPointerLeave: changeCursor }));
|
||||
};
|
||||
exports.default = Ruler;
|
||||
Generated
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
import { type Size } from '@remotion/player';
|
||||
import React from 'react';
|
||||
import type { AssetMetadata } from '../../helpers/get-asset-metadata';
|
||||
import type { Dimensions } from '../../helpers/is-current-selected-still';
|
||||
export declare const EditorRulers: React.FC<{
|
||||
readonly canvasSize: Size;
|
||||
readonly contentDimensions: Dimensions | 'none' | null;
|
||||
readonly assetMetadata: AssetMetadata | null;
|
||||
readonly containerRef: React.RefObject<HTMLDivElement | null>;
|
||||
}>;
|
||||
Generated
Vendored
+167
@@ -0,0 +1,167 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.EditorRulers = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const colors_1 = require("../../helpers/colors");
|
||||
const editor_ruler_1 = require("../../helpers/editor-ruler");
|
||||
const use_studio_canvas_dimensions_1 = require("../../helpers/use-studio-canvas-dimensions");
|
||||
const editor_guides_1 = require("../../state/editor-guides");
|
||||
const editor_rulers_1 = require("../../state/editor-rulers");
|
||||
const Ruler_1 = __importDefault(require("./Ruler"));
|
||||
const originBlockStyles = {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
borderBottom: '1px solid ' + colors_1.RULER_COLOR,
|
||||
borderRight: '1px solid ' + colors_1.RULER_COLOR,
|
||||
width: `${editor_rulers_1.RULER_WIDTH}px`,
|
||||
height: `${editor_rulers_1.RULER_WIDTH}px`,
|
||||
background: colors_1.BACKGROUND,
|
||||
};
|
||||
const EditorRulers = ({ contentDimensions, canvasSize, assetMetadata, containerRef }) => {
|
||||
const { scale, canvasPosition } = (0, use_studio_canvas_dimensions_1.useStudioCanvasDimensions)({
|
||||
canvasSize,
|
||||
contentDimensions,
|
||||
assetMetadata,
|
||||
});
|
||||
const { shouldCreateGuideRef, shouldDeleteGuideRef, setGuidesList, selectedGuideId, setSelectedGuideId, } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
|
||||
const rulerMarkingGaps = (0, react_1.useMemo)(() => {
|
||||
const minimumGap = editor_rulers_1.MINIMUM_RULER_MARKING_GAP_PX;
|
||||
const predefinedGap = editor_rulers_1.PREDEFINED_RULER_SCALE_GAPS.find((gap) => gap * scale > minimumGap);
|
||||
return predefinedGap || editor_rulers_1.MAXIMUM_PREDEFINED_RULER_SCALE_GAP;
|
||||
}, [scale]);
|
||||
const horizontalRulerScaleRange = (0, react_1.useMemo)(() => (0, editor_ruler_1.getRulerScaleRange)({
|
||||
canvasLength: canvasPosition.width,
|
||||
scale,
|
||||
canvasSize,
|
||||
}), [canvasPosition.width, canvasSize, scale]);
|
||||
const verticalRulerScaleRange = (0, react_1.useMemo)(() => (0, editor_ruler_1.getRulerScaleRange)({
|
||||
canvasLength: canvasPosition.height,
|
||||
scale,
|
||||
canvasSize,
|
||||
}), [canvasPosition.height, canvasSize, scale]);
|
||||
const { points: horizontalRulerPoints, startMarking: horizontalRulerStartMarking, } = (0, react_1.useMemo)(() => (0, editor_ruler_1.getRulerPoints)({
|
||||
rulerScaleRange: horizontalRulerScaleRange,
|
||||
rulerMarkingGaps,
|
||||
scale,
|
||||
}), [horizontalRulerScaleRange, rulerMarkingGaps, scale]);
|
||||
const { points: verticalRulerPoints, startMarking: verticalRulerStartMarking } = (0, react_1.useMemo)(() => (0, editor_ruler_1.getRulerPoints)({
|
||||
rulerScaleRange: verticalRulerScaleRange,
|
||||
rulerMarkingGaps,
|
||||
scale,
|
||||
}), [verticalRulerScaleRange, rulerMarkingGaps, scale]);
|
||||
const requestAnimationFrameRef = (0, react_1.useRef)(null);
|
||||
const onMouseMove = (0, react_1.useCallback)((e) => {
|
||||
if (requestAnimationFrameRef.current) {
|
||||
cancelAnimationFrame(requestAnimationFrameRef.current);
|
||||
}
|
||||
requestAnimationFrameRef.current = requestAnimationFrame(() => {
|
||||
var _a;
|
||||
const { clientX: mouseX, clientY: mouseY } = e;
|
||||
const { left: containerLeft = 0, top: containerTop = 0, right: containerRight = 0, bottom: containerBottom = 0, } = ((_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect()) || {};
|
||||
if (mouseX < containerLeft ||
|
||||
mouseX > containerRight ||
|
||||
mouseY < containerTop ||
|
||||
mouseY > containerBottom) {
|
||||
if (!shouldDeleteGuideRef.current) {
|
||||
shouldDeleteGuideRef.current = true;
|
||||
}
|
||||
if (document.body.style.cursor !== 'no-drop') {
|
||||
document.body.style.cursor = 'no-drop';
|
||||
}
|
||||
setGuidesList((prevState) => {
|
||||
const newGuides = prevState.map((guide) => {
|
||||
if (guide.id !== selectedGuideId) {
|
||||
return guide;
|
||||
}
|
||||
return {
|
||||
...guide,
|
||||
show: false,
|
||||
};
|
||||
});
|
||||
(0, editor_guides_1.persistGuidesList)(newGuides);
|
||||
return newGuides;
|
||||
});
|
||||
}
|
||||
else {
|
||||
if (shouldDeleteGuideRef.current) {
|
||||
shouldDeleteGuideRef.current = false;
|
||||
}
|
||||
setGuidesList((prevState) => {
|
||||
// Intentionally no persist, only persist on mouse up
|
||||
return prevState.map((guide) => {
|
||||
if (guide.id !== selectedGuideId) {
|
||||
return guide;
|
||||
}
|
||||
const position = guide.orientation === 'vertical'
|
||||
? (mouseX - containerLeft) / scale -
|
||||
canvasPosition.left / scale
|
||||
: (mouseY - containerTop) / scale -
|
||||
canvasPosition.top / scale;
|
||||
const desiredCursor = guide.orientation === 'vertical' ? 'ew-resize' : 'ns-resize';
|
||||
if (document.body.style.cursor !== desiredCursor) {
|
||||
document.body.style.cursor = desiredCursor;
|
||||
}
|
||||
return {
|
||||
...guide,
|
||||
position: Math.floor(position / 1.0),
|
||||
show: true,
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}, [
|
||||
containerRef,
|
||||
shouldDeleteGuideRef,
|
||||
setGuidesList,
|
||||
selectedGuideId,
|
||||
scale,
|
||||
canvasPosition.left,
|
||||
canvasPosition.top,
|
||||
]);
|
||||
const onMouseUp = (0, react_1.useCallback)(() => {
|
||||
setGuidesList((prevState) => {
|
||||
const newGuides = prevState.filter((selected) => {
|
||||
if (!shouldDeleteGuideRef.current) {
|
||||
return true;
|
||||
}
|
||||
return selected.id !== selectedGuideId;
|
||||
});
|
||||
(0, editor_guides_1.persistGuidesList)(newGuides);
|
||||
return newGuides;
|
||||
});
|
||||
shouldDeleteGuideRef.current = false;
|
||||
document.body.style.cursor = 'auto';
|
||||
shouldCreateGuideRef.current = false;
|
||||
setSelectedGuideId(() => null);
|
||||
document.removeEventListener('pointerup', onMouseUp);
|
||||
document.removeEventListener('pointermove', onMouseMove);
|
||||
}, [
|
||||
selectedGuideId,
|
||||
shouldCreateGuideRef,
|
||||
shouldDeleteGuideRef,
|
||||
setSelectedGuideId,
|
||||
setGuidesList,
|
||||
onMouseMove,
|
||||
]);
|
||||
(0, react_1.useEffect)(() => {
|
||||
if (selectedGuideId !== null) {
|
||||
document.addEventListener('pointermove', onMouseMove);
|
||||
document.addEventListener('pointerup', onMouseUp);
|
||||
}
|
||||
return () => {
|
||||
document.removeEventListener('pointermove', onMouseMove);
|
||||
document.removeEventListener('pointerup', onMouseUp);
|
||||
if (requestAnimationFrameRef.current) {
|
||||
cancelAnimationFrame(requestAnimationFrameRef.current);
|
||||
}
|
||||
};
|
||||
}, [selectedGuideId, onMouseMove, onMouseUp]);
|
||||
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { style: originBlockStyles }), (0, jsx_runtime_1.jsx)(Ruler_1.default, { orientation: "horizontal", scale: scale, points: horizontalRulerPoints, startMarking: horizontalRulerStartMarking, markingGaps: rulerMarkingGaps, originOffset: canvasPosition.left, size: canvasSize }), (0, jsx_runtime_1.jsx)(Ruler_1.default, { orientation: "vertical", scale: scale, points: verticalRulerPoints, startMarking: verticalRulerStartMarking, markingGaps: rulerMarkingGaps, originOffset: canvasPosition.top, size: canvasSize })] }));
|
||||
};
|
||||
exports.EditorRulers = EditorRulers;
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
export declare const useIsRulerVisible: () => boolean | null;
|
||||
Generated
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.useIsRulerVisible = void 0;
|
||||
const react_1 = require("react");
|
||||
const remotion_1 = require("remotion");
|
||||
const editor_rulers_1 = require("../../state/editor-rulers");
|
||||
const useIsRulerVisible = () => {
|
||||
const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
||||
const { editorShowRulers } = (0, react_1.useContext)(editor_rulers_1.EditorShowRulersContext);
|
||||
return (editorShowRulers && canvasContent && canvasContent.type === 'composition');
|
||||
};
|
||||
exports.useIsRulerVisible = useIsRulerVisible;
|
||||
Generated
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
export declare const explorerSidebarTabs: import("react").RefObject<{
|
||||
selectAssetsPanel: () => void;
|
||||
selectCompositionPanel: () => void;
|
||||
} | null>;
|
||||
export declare const ExplorerPanel: React.FC<{
|
||||
readOnlyStudio: boolean;
|
||||
}>;
|
||||
Generated
Vendored
+58
@@ -0,0 +1,58 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ExplorerPanel = exports.explorerSidebarTabs = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const colors_1 = require("../helpers/colors");
|
||||
const AssetSelector_1 = require("./AssetSelector");
|
||||
const CompositionSelector_1 = require("./CompositionSelector");
|
||||
const CompSelectorRef_1 = require("./CompSelectorRef");
|
||||
const Tabs_1 = require("./Tabs");
|
||||
const container = {
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
maxWidth: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flex: 1,
|
||||
};
|
||||
const localStorageKey = 'remotion.sidebarPanel';
|
||||
const getSelectedPanel = () => {
|
||||
const panel = localStorage.getItem(localStorageKey);
|
||||
if (panel === 'assets') {
|
||||
return 'assets';
|
||||
}
|
||||
return 'compositions';
|
||||
};
|
||||
const tabsContainer = {
|
||||
backgroundColor: colors_1.BACKGROUND,
|
||||
};
|
||||
const persistSelectedOptionsSidebarPanel = (panel) => {
|
||||
localStorage.setItem(localStorageKey, panel);
|
||||
};
|
||||
exports.explorerSidebarTabs = (0, react_1.createRef)();
|
||||
const ExplorerPanel = ({ readOnlyStudio }) => {
|
||||
const [panel, setPanel] = (0, react_1.useState)(() => getSelectedPanel());
|
||||
const onCompositionsSelected = (0, react_1.useCallback)(() => {
|
||||
setPanel('compositions');
|
||||
persistSelectedOptionsSidebarPanel('compositions');
|
||||
}, []);
|
||||
const onAssetsSelected = (0, react_1.useCallback)(() => {
|
||||
setPanel('assets');
|
||||
persistSelectedOptionsSidebarPanel('assets');
|
||||
}, []);
|
||||
(0, react_1.useImperativeHandle)(exports.explorerSidebarTabs, () => {
|
||||
return {
|
||||
selectAssetsPanel: () => {
|
||||
setPanel('assets');
|
||||
persistSelectedOptionsSidebarPanel('assets');
|
||||
},
|
||||
selectCompositionPanel: () => {
|
||||
setPanel('compositions');
|
||||
persistSelectedOptionsSidebarPanel('compositions');
|
||||
},
|
||||
};
|
||||
}, []);
|
||||
return ((0, jsx_runtime_1.jsx)(CompSelectorRef_1.CompSelectorRef, { children: (0, jsx_runtime_1.jsxs)("div", { style: container, className: "css-reset", children: [(0, jsx_runtime_1.jsx)("div", { style: tabsContainer, children: (0, jsx_runtime_1.jsxs)(Tabs_1.Tabs, { children: [(0, jsx_runtime_1.jsx)(Tabs_1.Tab, { selected: panel === 'compositions', onClick: onCompositionsSelected, children: "Compositions" }), (0, jsx_runtime_1.jsx)(Tabs_1.Tab, { selected: panel === 'assets', onClick: onAssetsSelected, children: "Assets" })] }) }), panel === 'compositions' ? ((0, jsx_runtime_1.jsx)(CompositionSelector_1.CompositionSelector, {})) : ((0, jsx_runtime_1.jsx)(AssetSelector_1.AssetSelector, { readOnlyStudio: readOnlyStudio }))] }) }));
|
||||
};
|
||||
exports.ExplorerPanel = ExplorerPanel;
|
||||
Generated
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
import React from 'react';
|
||||
import type { AssetMetadata } from '../helpers/get-asset-metadata';
|
||||
import type { AssetFileType } from './Preview';
|
||||
export declare const FilePreview: React.FC<{
|
||||
readonly src: string;
|
||||
readonly fileType: AssetFileType;
|
||||
readonly currentAsset: string;
|
||||
readonly assetMetadata: AssetMetadata | null;
|
||||
}>;
|
||||
Generated
Vendored
+40
@@ -0,0 +1,40 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.FilePreview = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const studio_shared_1 = require("@remotion/studio-shared");
|
||||
const JSONViewer_1 = require("./JSONViewer");
|
||||
const TextViewer_1 = require("./TextViewer");
|
||||
const layout_1 = require("./layout");
|
||||
const msgStyle = {
|
||||
fontSize: 13,
|
||||
color: 'white',
|
||||
fontFamily: 'sans-serif',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
};
|
||||
const FilePreview = ({ fileType, src, currentAsset, assetMetadata }) => {
|
||||
if (!assetMetadata) {
|
||||
throw new Error('expected to have assetMetadata');
|
||||
}
|
||||
if (assetMetadata.type === 'not-found') {
|
||||
throw new Error('expected to have assetMetadata, got "not-found"');
|
||||
}
|
||||
if (fileType === 'audio') {
|
||||
return (0, jsx_runtime_1.jsx)("audio", { src: src, controls: true });
|
||||
}
|
||||
if (fileType === 'video') {
|
||||
return (0, jsx_runtime_1.jsx)("video", { src: src, controls: true });
|
||||
}
|
||||
if (fileType === 'image') {
|
||||
return (0, jsx_runtime_1.jsx)("img", { src: src });
|
||||
}
|
||||
if (fileType === 'json') {
|
||||
return (0, jsx_runtime_1.jsx)(JSONViewer_1.JSONViewer, { src: src });
|
||||
}
|
||||
if (fileType === 'txt') {
|
||||
return (0, jsx_runtime_1.jsx)(TextViewer_1.TextViewer, { src: src });
|
||||
}
|
||||
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { style: msgStyle, children: currentAsset }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { y: 0.5 }), (0, jsx_runtime_1.jsxs)("div", { style: msgStyle, children: ["Size: ", (0, studio_shared_1.formatBytes)(assetMetadata.size), " "] })] }));
|
||||
};
|
||||
exports.FilePreview = FilePreview;
|
||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
import React from 'react';
|
||||
export declare const FpsCounter: React.FC<{
|
||||
readonly playbackSpeed: number;
|
||||
}>;
|
||||
Generated
Vendored
+75
@@ -0,0 +1,75 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.FpsCounter = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const remotion_1 = require("remotion");
|
||||
const label = {
|
||||
color: 'white',
|
||||
fontSize: 15,
|
||||
fontFamily: 'Arial, Helvetica, sans-serif',
|
||||
whiteSpace: 'nowrap',
|
||||
};
|
||||
const pushWithMaxSize = (arr, value, maxSize) => {
|
||||
arr.push(value);
|
||||
return arr.slice(-maxSize);
|
||||
};
|
||||
const FpsCounter = ({ playbackSpeed }) => {
|
||||
const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
|
||||
const [playing] = remotion_1.Internals.Timeline.usePlayingState();
|
||||
const frame = remotion_1.Internals.Timeline.useTimelinePosition();
|
||||
const [marker, rerender] = (0, react_1.useState)({});
|
||||
const [fps, setFps] = (0, react_1.useState)(0);
|
||||
const previousUpdates = (0, react_1.useRef)([]);
|
||||
const fpsRef = (0, react_1.useRef)(0);
|
||||
const playingRef = (0, react_1.useRef)(playing);
|
||||
(0, react_1.useLayoutEffect)(() => {
|
||||
fpsRef.current = 0;
|
||||
previousUpdates.current = [];
|
||||
playingRef.current = playing;
|
||||
}, [playing]);
|
||||
(0, react_1.useLayoutEffect)(() => {
|
||||
if (playingRef.current === false)
|
||||
return;
|
||||
previousUpdates.current = pushWithMaxSize(previousUpdates.current, performance.now(), 15);
|
||||
if (previousUpdates.current.length < 2)
|
||||
return;
|
||||
const diff = Math.max(...previousUpdates.current) -
|
||||
Math.min(...previousUpdates.current);
|
||||
const averageDistanceBetween = diff / (previousUpdates.current.length - 1);
|
||||
fpsRef.current = 1000 / averageDistanceBetween;
|
||||
if (previousUpdates.current.length === 2)
|
||||
setFps(fpsRef.current);
|
||||
/* This effect should depends only on frame, otherwise it will push extra updates to ref and fps will be wrong */
|
||||
}, [frame]);
|
||||
(0, react_1.useEffect)(() => {
|
||||
if (playing) {
|
||||
const t = setTimeout(() => {
|
||||
rerender({});
|
||||
setFps(fpsRef.current);
|
||||
}, 1000);
|
||||
return () => clearTimeout(t);
|
||||
}
|
||||
}, [marker, playing]);
|
||||
const style = (0, react_1.useMemo)(() => {
|
||||
if (!videoConfig) {
|
||||
return {};
|
||||
}
|
||||
const expectedFps = Math.abs(playbackSpeed) * videoConfig.fps;
|
||||
return {
|
||||
...label,
|
||||
color: fps < expectedFps * 0.9 ? 'red' : 'white',
|
||||
};
|
||||
}, [fps, playbackSpeed, videoConfig]);
|
||||
if (fps === 0) {
|
||||
return null;
|
||||
}
|
||||
if (playing === false) {
|
||||
return null;
|
||||
}
|
||||
if (videoConfig === null) {
|
||||
return null;
|
||||
}
|
||||
return (0, jsx_runtime_1.jsxs)("div", { style: style, children: [fps.toFixed(1), " FPS"] });
|
||||
};
|
||||
exports.FpsCounter = FpsCounter;
|
||||
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
import type React from 'react';
|
||||
export declare const FramePersistor: React.FC;
|
||||
Generated
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.FramePersistor = void 0;
|
||||
const react_1 = require("react");
|
||||
const remotion_1 = require("remotion");
|
||||
const FramePersistor = () => {
|
||||
const [playing] = remotion_1.Internals.Timeline.usePlayingState();
|
||||
const config = (0, remotion_1.useVideoConfig)();
|
||||
const frame = remotion_1.Internals.Timeline.useTimelinePosition();
|
||||
const setFrame = remotion_1.Internals.useTimelineSetFrame();
|
||||
(0, react_1.useEffect)(() => {
|
||||
if (!playing) {
|
||||
setFrame((f) => {
|
||||
const newObj = { ...f, [config.id]: frame };
|
||||
remotion_1.Internals.persistCurrentFrame(newObj);
|
||||
return newObj;
|
||||
});
|
||||
}
|
||||
}, [config.id, frame, playing, setFrame]);
|
||||
return null;
|
||||
};
|
||||
exports.FramePersistor = FramePersistor;
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
export declare const FullScreenToggle: React.FC<{}>;
|
||||
Generated
Vendored
+48
@@ -0,0 +1,48 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.FullScreenToggle = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const remotion_1 = require("remotion");
|
||||
const no_react_1 = require("remotion/no-react");
|
||||
const use_keybinding_1 = require("../helpers/use-keybinding");
|
||||
const canvas_ref_1 = require("../state/canvas-ref");
|
||||
const ControlButton_1 = require("./ControlButton");
|
||||
const accessibilityLabel = [
|
||||
'Enter fullscreen preview',
|
||||
(0, use_keybinding_1.areKeyboardShortcutsDisabled)() ? null : '(F)',
|
||||
]
|
||||
.filter(no_react_1.NoReactInternals.truthy)
|
||||
.join(' ');
|
||||
const FullScreenToggle = () => {
|
||||
const keybindings = (0, use_keybinding_1.useKeybinding)();
|
||||
const { setSize } = (0, react_1.useContext)(remotion_1.Internals.PreviewSizeContext);
|
||||
const onClick = (0, react_1.useCallback)(() => {
|
||||
var _a;
|
||||
(_a = canvas_ref_1.drawRef.current) === null || _a === void 0 ? void 0 : _a.requestFullscreen();
|
||||
if (document.fullscreenElement)
|
||||
setSize(() => ({
|
||||
size: 'auto',
|
||||
translation: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
}));
|
||||
}, [setSize]);
|
||||
(0, react_1.useEffect)(() => {
|
||||
const f = keybindings.registerKeybinding({
|
||||
event: 'keydown',
|
||||
key: 'f',
|
||||
callback: onClick,
|
||||
commandCtrlKey: false,
|
||||
preventDefault: true,
|
||||
triggerIfInputFieldFocused: false,
|
||||
keepRegisteredWhenNotHighestContext: false,
|
||||
});
|
||||
return () => {
|
||||
f.unregister();
|
||||
};
|
||||
}, [keybindings, onClick]);
|
||||
return ((0, jsx_runtime_1.jsx)(ControlButton_1.ControlButton, { title: accessibilityLabel, "aria-label": accessibilityLabel, onClick: onClick, children: (0, jsx_runtime_1.jsx)("svg", { style: { width: 18, height: 18 }, viewBox: "0 0 448 512", fill: "#fff", children: (0, jsx_runtime_1.jsx)("path", { d: "M0 180V56c0-13.3 10.7-24 24-24h124c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H64v84c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12zM288 44v40c0 6.6 5.4 12 12 12h84v84c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12V56c0-13.3-10.7-24-24-24H300c-6.6 0-12 5.4-12 12zm148 276h-40c-6.6 0-12 5.4-12 12v84h-84c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h124c13.3 0 24-10.7 24-24V332c0-6.6-5.4-12-12-12zM160 468v-40c0-6.6-5.4-12-12-12H64v-84c0-6.6-5.4-12-12-12H12c-6.6 0-12 5.4-12 12v124c0 13.3 10.7 24 24 24h124c6.6 0 12-5.4 12-12z" }) }) }));
|
||||
};
|
||||
exports.FullScreenToggle = FullScreenToggle;
|
||||
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
import type React from 'react';
|
||||
export declare const GlobalKeybindings: React.FC;
|
||||
Generated
Vendored
+119
@@ -0,0 +1,119 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.GlobalKeybindings = void 0;
|
||||
const react_1 = require("react");
|
||||
const use_keybinding_1 = require("../helpers/use-keybinding");
|
||||
const checkerboard_1 = require("../state/checkerboard");
|
||||
const modals_1 = require("../state/modals");
|
||||
const AskAiModal_1 = require("./AskAiModal");
|
||||
const CompositionSelector_1 = require("./CompositionSelector");
|
||||
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
|
||||
const GlobalKeybindings = () => {
|
||||
const keybindings = (0, use_keybinding_1.useKeybinding)();
|
||||
const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
|
||||
const { setCheckerboard } = (0, react_1.useContext)(checkerboard_1.CheckerboardContext);
|
||||
const { navigateToNextComposition, navigateToPreviousComposition } = (0, CompositionSelector_1.useCompositionNavigation)();
|
||||
(0, react_1.useEffect)(() => {
|
||||
const nKey = keybindings.registerKeybinding({
|
||||
event: 'keypress',
|
||||
key: 'n',
|
||||
callback: () => {
|
||||
(0, NotificationCenter_1.showNotification)(`To make a new composition, right-click an existing one and select "Duplicate"`, 5000);
|
||||
},
|
||||
commandCtrlKey: false,
|
||||
preventDefault: true,
|
||||
triggerIfInputFieldFocused: false,
|
||||
keepRegisteredWhenNotHighestContext: false,
|
||||
});
|
||||
const cmdKKey = keybindings.registerKeybinding({
|
||||
event: 'keydown',
|
||||
key: 'k',
|
||||
callback: () => {
|
||||
setSelectedModal({
|
||||
type: 'quick-switcher',
|
||||
mode: 'compositions',
|
||||
invocationTimestamp: Date.now(),
|
||||
});
|
||||
},
|
||||
triggerIfInputFieldFocused: true,
|
||||
keepRegisteredWhenNotHighestContext: false,
|
||||
commandCtrlKey: true,
|
||||
preventDefault: true,
|
||||
});
|
||||
const cmdIKey = process.env.ASK_AI_ENABLED
|
||||
? keybindings.registerKeybinding({
|
||||
event: 'keydown',
|
||||
key: 'i',
|
||||
callback: () => {
|
||||
var _a;
|
||||
(_a = AskAiModal_1.askAiModalRef.current) === null || _a === void 0 ? void 0 : _a.toggle();
|
||||
},
|
||||
triggerIfInputFieldFocused: true,
|
||||
keepRegisteredWhenNotHighestContext: true,
|
||||
commandCtrlKey: true,
|
||||
preventDefault: true,
|
||||
})
|
||||
: null;
|
||||
const cKey = keybindings.registerKeybinding({
|
||||
event: 'keypress',
|
||||
key: 't',
|
||||
callback: () => {
|
||||
setCheckerboard((c) => !c);
|
||||
},
|
||||
commandCtrlKey: false,
|
||||
preventDefault: true,
|
||||
triggerIfInputFieldFocused: false,
|
||||
keepRegisteredWhenNotHighestContext: false,
|
||||
});
|
||||
const questionMark = keybindings.registerKeybinding({
|
||||
event: 'keypress',
|
||||
key: '?',
|
||||
callback: () => {
|
||||
setSelectedModal({
|
||||
type: 'quick-switcher',
|
||||
mode: 'docs',
|
||||
invocationTimestamp: Date.now(),
|
||||
});
|
||||
},
|
||||
commandCtrlKey: false,
|
||||
preventDefault: true,
|
||||
triggerIfInputFieldFocused: false,
|
||||
keepRegisteredWhenNotHighestContext: false,
|
||||
});
|
||||
const pageDown = keybindings.registerKeybinding({
|
||||
event: 'keydown',
|
||||
key: 'PageDown',
|
||||
callback: navigateToNextComposition,
|
||||
commandCtrlKey: false,
|
||||
preventDefault: true,
|
||||
triggerIfInputFieldFocused: false,
|
||||
keepRegisteredWhenNotHighestContext: false,
|
||||
});
|
||||
const pageUp = keybindings.registerKeybinding({
|
||||
event: 'keydown',
|
||||
key: 'PageUp',
|
||||
callback: navigateToPreviousComposition,
|
||||
commandCtrlKey: false,
|
||||
preventDefault: true,
|
||||
triggerIfInputFieldFocused: false,
|
||||
keepRegisteredWhenNotHighestContext: false,
|
||||
});
|
||||
return () => {
|
||||
nKey.unregister();
|
||||
cKey.unregister();
|
||||
questionMark.unregister();
|
||||
cmdKKey.unregister();
|
||||
cmdIKey === null || cmdIKey === void 0 ? void 0 : cmdIKey.unregister();
|
||||
pageDown.unregister();
|
||||
pageUp.unregister();
|
||||
};
|
||||
}, [
|
||||
keybindings,
|
||||
setCheckerboard,
|
||||
setSelectedModal,
|
||||
navigateToNextComposition,
|
||||
navigateToPreviousComposition,
|
||||
]);
|
||||
return null;
|
||||
};
|
||||
exports.GlobalKeybindings = GlobalKeybindings;
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
import React from 'react';
|
||||
export declare const GlobalPropsEditorUpdateButton: React.FC<{
|
||||
readonly compositionId: string;
|
||||
readonly currentDefaultProps: Record<string, unknown>;
|
||||
}>;
|
||||
Generated
Vendored
+76
@@ -0,0 +1,76 @@
|
||||
"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;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.GlobalPropsEditorUpdateButton = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = __importStar(require("react"));
|
||||
const remotion_1 = require("remotion");
|
||||
const save_default_props_1 = require("../api/save-default-props");
|
||||
const fast_refresh_context_1 = require("../fast-refresh-context");
|
||||
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
|
||||
const SchemaResetButton_1 = require("./RenderModal/SchemaEditor/SchemaResetButton");
|
||||
const SchemaSaveButton_1 = require("./RenderModal/SchemaEditor/SchemaSaveButton");
|
||||
const container = {
|
||||
display: 'inline-block',
|
||||
flexDirection: 'row',
|
||||
};
|
||||
const GlobalPropsEditorUpdateButton = ({ compositionId, currentDefaultProps }) => {
|
||||
const { fastRefreshes } = (0, react_1.useContext)(fast_refresh_context_1.FastRefreshContext);
|
||||
const [disabled, setDisabled] = react_1.default.useState(false);
|
||||
const onClicked = (0, react_1.useCallback)(() => {
|
||||
setDisabled(true);
|
||||
window.remotion_ignoreFastRefreshUpdate = fastRefreshes + 1;
|
||||
(0, save_default_props_1.saveDefaultProps)({
|
||||
compositionId,
|
||||
defaultProps: () => currentDefaultProps,
|
||||
})
|
||||
.catch((err) => {
|
||||
(0, NotificationCenter_1.showNotification)(`Cannot update default props: ${err.stack}`, 2000);
|
||||
})
|
||||
.finally(() => {
|
||||
setDisabled(true);
|
||||
});
|
||||
}, [compositionId, currentDefaultProps, fastRefreshes]);
|
||||
const onReset = (0, react_1.useCallback)(() => {
|
||||
window.remotion_ignoreFastRefreshUpdate = null;
|
||||
window.dispatchEvent(new CustomEvent(remotion_1.Internals.PROPS_UPDATED_EXTERNALLY, {
|
||||
detail: {
|
||||
resetUnsaved: compositionId,
|
||||
},
|
||||
}));
|
||||
}, [compositionId]);
|
||||
return ((0, jsx_runtime_1.jsxs)("div", { style: container, children: [(0, jsx_runtime_1.jsx)(SchemaResetButton_1.SchemaResetButton, { onClick: onReset }), (0, jsx_runtime_1.jsx)(SchemaSaveButton_1.SchemaSaveButton, { disabled: disabled, onClick: onClicked })] }));
|
||||
};
|
||||
exports.GlobalPropsEditorUpdateButton = GlobalPropsEditorUpdateButton;
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
import type React from 'react';
|
||||
import type { _InternalTypes } from 'remotion';
|
||||
export declare const useSelectAsset: () => (asset: string) => void;
|
||||
export declare const useSelectComposition: () => (c: _InternalTypes["AnyComposition"], push: boolean) => void;
|
||||
export declare const InitialCompositionLoader: React.FC;
|
||||
Generated
Vendored
+136
@@ -0,0 +1,136 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.InitialCompositionLoader = exports.useSelectComposition = exports.useSelectAsset = void 0;
|
||||
const react_1 = require("react");
|
||||
const remotion_1 = require("remotion");
|
||||
const get_static_files_1 = require("../api/get-static-files");
|
||||
const mobile_layout_1 = require("../helpers/mobile-layout");
|
||||
const url_state_1 = require("../helpers/url-state");
|
||||
const folders_1 = require("../state/folders");
|
||||
const sidebar_1 = require("../state/sidebar");
|
||||
const CompositionSelector_1 = require("./CompositionSelector");
|
||||
const ExplorerPanel_1 = require("./ExplorerPanel");
|
||||
const load_canvas_content_from_url_1 = require("./load-canvas-content-from-url");
|
||||
const useSelectAsset = () => {
|
||||
const { setCanvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionSetters);
|
||||
const { setAssetFoldersExpanded } = (0, react_1.useContext)(folders_1.FolderContext);
|
||||
return (asset) => {
|
||||
var _a;
|
||||
setCanvasContent({ type: 'asset', asset });
|
||||
(_a = ExplorerPanel_1.explorerSidebarTabs.current) === null || _a === void 0 ? void 0 : _a.selectAssetsPanel();
|
||||
setAssetFoldersExpanded((ex) => {
|
||||
const split = asset.split('/');
|
||||
const keysToExpand = split.map((_, i) => {
|
||||
return split.slice(0, i).join('/');
|
||||
});
|
||||
const newState = {
|
||||
...ex,
|
||||
};
|
||||
for (const key of keysToExpand) {
|
||||
newState[key] = true;
|
||||
}
|
||||
return newState;
|
||||
});
|
||||
};
|
||||
};
|
||||
exports.useSelectAsset = useSelectAsset;
|
||||
const useSelectComposition = () => {
|
||||
const { setCompositionFoldersExpanded } = (0, react_1.useContext)(folders_1.FolderContext);
|
||||
const { setCanvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionSetters);
|
||||
const isMobileLayout = (0, mobile_layout_1.useMobileLayout)();
|
||||
const { setSidebarCollapsedState } = (0, react_1.useContext)(sidebar_1.SidebarContext);
|
||||
return (0, react_1.useCallback)((c, push) => {
|
||||
var _a;
|
||||
if (push) {
|
||||
(0, url_state_1.pushUrl)(`/${c.id}`);
|
||||
}
|
||||
(_a = ExplorerPanel_1.explorerSidebarTabs.current) === null || _a === void 0 ? void 0 : _a.selectCompositionPanel();
|
||||
setCanvasContent({ type: 'composition', compositionId: c.id });
|
||||
const { folderName, parentFolderName } = c;
|
||||
if (folderName !== null) {
|
||||
setCompositionFoldersExpanded((ex) => {
|
||||
const keysToExpand = (0, CompositionSelector_1.getKeysToExpand)(folderName, parentFolderName);
|
||||
const newState = {
|
||||
...ex,
|
||||
};
|
||||
for (const key of keysToExpand) {
|
||||
newState[key] = true;
|
||||
}
|
||||
return newState;
|
||||
});
|
||||
if (isMobileLayout) {
|
||||
setSidebarCollapsedState({ left: 'collapsed', right: 'collapsed' });
|
||||
}
|
||||
}
|
||||
}, [
|
||||
isMobileLayout,
|
||||
setCanvasContent,
|
||||
setCompositionFoldersExpanded,
|
||||
setSidebarCollapsedState,
|
||||
]);
|
||||
};
|
||||
exports.useSelectComposition = useSelectComposition;
|
||||
const InitialCompositionLoader = () => {
|
||||
const { compositions, canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
||||
const { setCanvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionSetters);
|
||||
const selectComposition = (0, exports.useSelectComposition)();
|
||||
const selectAsset = (0, exports.useSelectAsset)();
|
||||
(0, react_1.useEffect)(() => {
|
||||
if (canvasContent) {
|
||||
return;
|
||||
}
|
||||
const canvasContentFromUrl = (0, load_canvas_content_from_url_1.deriveCanvasContentFromUrl)();
|
||||
if (canvasContentFromUrl && canvasContentFromUrl.type === 'composition') {
|
||||
const exists = compositions.find((c) => c.id === canvasContentFromUrl.compositionId);
|
||||
if (exists) {
|
||||
selectComposition(exists, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (canvasContentFromUrl && canvasContentFromUrl.type === 'asset') {
|
||||
selectAsset(canvasContentFromUrl.asset);
|
||||
return;
|
||||
}
|
||||
if (canvasContentFromUrl && canvasContentFromUrl.type === 'output') {
|
||||
setCanvasContent(canvasContentFromUrl);
|
||||
return;
|
||||
}
|
||||
if (compositions.length > 0) {
|
||||
selectComposition(compositions[0], true);
|
||||
}
|
||||
}, [
|
||||
compositions,
|
||||
canvasContent,
|
||||
selectComposition,
|
||||
setCanvasContent,
|
||||
selectAsset,
|
||||
]);
|
||||
(0, react_1.useEffect)(() => {
|
||||
const onchange = () => {
|
||||
const newCanvas = (0, load_canvas_content_from_url_1.deriveCanvasContentFromUrl)();
|
||||
if (newCanvas && newCanvas.type === 'composition') {
|
||||
const newComp = (0, url_state_1.getRoute)().substring(1);
|
||||
const exists = compositions.find((c) => c.id === newComp);
|
||||
if (exists) {
|
||||
selectComposition(exists, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (newCanvas && newCanvas.type === 'asset') {
|
||||
const staticFiles = (0, get_static_files_1.getStaticFiles)();
|
||||
const exists = staticFiles.find((file) => {
|
||||
return file.name === newCanvas.asset;
|
||||
});
|
||||
if (exists) {
|
||||
setCanvasContent(newCanvas);
|
||||
}
|
||||
return;
|
||||
}
|
||||
setCanvasContent(newCanvas);
|
||||
};
|
||||
window.addEventListener('popstate', onchange);
|
||||
return () => window.removeEventListener('popstate', onchange);
|
||||
}, [compositions, selectComposition, setCanvasContent]);
|
||||
return null;
|
||||
};
|
||||
exports.InitialCompositionLoader = InitialCompositionLoader;
|
||||
Generated
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
import React from 'react';
|
||||
export type RenderInlineAction = (color: string) => React.ReactNode;
|
||||
export type InlineActionProps = {
|
||||
readonly onClick: React.MouseEventHandler<HTMLButtonElement>;
|
||||
readonly disabled?: boolean;
|
||||
readonly renderAction: RenderInlineAction;
|
||||
readonly title?: string;
|
||||
};
|
||||
export declare const InlineAction: ({ renderAction, onClick, disabled, title, }: InlineActionProps) => import("react/jsx-runtime").JSX.Element;
|
||||
Generated
Vendored
+34
@@ -0,0 +1,34 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.InlineAction = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const colors_1 = require("../helpers/colors");
|
||||
const z_index_1 = require("../state/z-index");
|
||||
const InlineAction = ({ renderAction, onClick, disabled, title, }) => {
|
||||
const { tabIndex } = (0, z_index_1.useZIndex)();
|
||||
const [hovered, setHovered] = (0, react_1.useState)(false);
|
||||
const onPointerEnter = (0, react_1.useCallback)(() => {
|
||||
setHovered(true);
|
||||
}, []);
|
||||
const onPointerLeave = (0, react_1.useCallback)(() => {
|
||||
setHovered(false);
|
||||
}, []);
|
||||
const style = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
border: 'none',
|
||||
background: disabled
|
||||
? 'transparent'
|
||||
: (0, colors_1.getBackgroundFromHoverState)({ hovered, selected: false }),
|
||||
height: 24,
|
||||
width: 24,
|
||||
display: 'inline-flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
borderRadius: 3,
|
||||
pointerEvents: disabled ? 'none' : 'auto',
|
||||
};
|
||||
}, [disabled, hovered]);
|
||||
return ((0, jsx_runtime_1.jsx)("button", { type: "button", onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, onClick: onClick, style: style, tabIndex: tabIndex, title: title, children: renderAction(hovered ? 'white' : colors_1.LIGHT_TEXT) }));
|
||||
};
|
||||
exports.InlineAction = InlineAction;
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
import { type InlineActionProps } from './InlineAction';
|
||||
import type { ComboboxValue } from './NewComposition/ComboBox';
|
||||
export declare const InlineDropdown: ({ values, ...props }: Omit<InlineActionProps, "onClick"> & {
|
||||
readonly values: ComboboxValue[];
|
||||
}) => import("react/jsx-runtime").JSX.Element;
|
||||
Generated
Vendored
+85
@@ -0,0 +1,85 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.InlineDropdown = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const player_1 = require("@remotion/player");
|
||||
const react_1 = require("react");
|
||||
const react_dom_1 = __importDefault(require("react-dom"));
|
||||
const mobile_layout_1 = require("../helpers/mobile-layout");
|
||||
const noop_1 = require("../helpers/noop");
|
||||
const z_index_1 = require("../state/z-index");
|
||||
const InlineAction_1 = require("./InlineAction");
|
||||
const portals_1 = require("./Menu/portals");
|
||||
const styles_1 = require("./Menu/styles");
|
||||
const MenuContent_1 = require("./NewComposition/MenuContent");
|
||||
const InlineDropdown = ({ values, ...props }) => {
|
||||
const ref = (0, react_1.useRef)(null);
|
||||
const [opened, setOpened] = (0, react_1.useState)({ type: 'not-open' });
|
||||
const { currentZIndex } = (0, z_index_1.useZIndex)();
|
||||
const size = player_1.PlayerInternals.useElementSize(ref, {
|
||||
triggerOnWindowResize: true,
|
||||
shouldApplyCssTransforms: true,
|
||||
});
|
||||
const isMobileLayout = (0, mobile_layout_1.useMobileLayout)();
|
||||
const onClick = (0, react_1.useCallback)((e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setOpened({ type: 'open', left: e.clientX, top: e.clientY });
|
||||
}, []);
|
||||
const spaceToBottom = (0, react_1.useMemo)(() => {
|
||||
if (size && opened.type === 'open') {
|
||||
return size.windowSize.height - opened.top;
|
||||
}
|
||||
return 0;
|
||||
}, [opened, size]);
|
||||
const spaceToTop = (0, react_1.useMemo)(() => {
|
||||
if (size && opened.type === 'open') {
|
||||
return opened.top;
|
||||
}
|
||||
return 0;
|
||||
}, [opened, size]);
|
||||
const portalStyle = (0, react_1.useMemo)(() => {
|
||||
if (opened.type === 'not-open') {
|
||||
return;
|
||||
}
|
||||
if (!size) {
|
||||
return;
|
||||
}
|
||||
const spaceToRight = size.windowSize.width - size.left;
|
||||
const spaceToLeft = size.left + size.width;
|
||||
const minSpaceRequired = isMobileLayout
|
||||
? styles_1.MAX_MOBILE_MENU_WIDTH
|
||||
: styles_1.MAX_MENU_WIDTH;
|
||||
const verticalLayout = spaceToTop > spaceToBottom ? 'bottom' : 'top';
|
||||
const canOpenOnLeft = spaceToLeft >= minSpaceRequired;
|
||||
const canOpenOnRight = spaceToRight >= minSpaceRequired;
|
||||
const horizontalLayout = canOpenOnRight ? 'left' : 'right';
|
||||
return {
|
||||
...styles_1.menuContainerTowardsTop,
|
||||
...(verticalLayout === 'top'
|
||||
? {
|
||||
top: opened.top,
|
||||
}
|
||||
: {
|
||||
bottom: size.windowSize.height - opened.top,
|
||||
}),
|
||||
...(horizontalLayout === 'left'
|
||||
? {
|
||||
left: opened.left,
|
||||
}
|
||||
: {
|
||||
right: canOpenOnLeft ? size.windowSize.width - opened.left : 0,
|
||||
}),
|
||||
};
|
||||
}, [opened, size, isMobileLayout, spaceToTop, spaceToBottom]);
|
||||
const onHide = (0, react_1.useCallback)(() => {
|
||||
setOpened({ type: 'not-open' });
|
||||
}, []);
|
||||
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { ref: ref, children: (0, jsx_runtime_1.jsx)(InlineAction_1.InlineAction, { onClick: onClick, ...props }) }), portalStyle
|
||||
? react_dom_1.default.createPortal((0, jsx_runtime_1.jsx)("div", { style: styles_1.fullScreenOverlay, children: (0, jsx_runtime_1.jsx)("div", { style: styles_1.outerPortal, className: "css-reset", children: (0, jsx_runtime_1.jsx)(z_index_1.HigherZIndex, { onOutsideClick: onHide, onEscape: onHide, children: (0, jsx_runtime_1.jsx)("div", { style: portalStyle, children: (0, jsx_runtime_1.jsx)(MenuContent_1.MenuContent, { onNextMenu: noop_1.noop, onPreviousMenu: noop_1.noop, values: values, onHide: onHide, leaveLeftSpace: true, preselectIndex: false, topItemCanBeUnselected: false, fixedHeight: null }) }) }) }) }), (0, portals_1.getPortal)(currentZIndex))
|
||||
: null] }));
|
||||
};
|
||||
exports.InlineDropdown = InlineDropdown;
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
import type { PackageManager } from '@remotion/studio-shared';
|
||||
import React from 'react';
|
||||
export declare const InstallPackageModal: React.FC<{
|
||||
readonly packageManager: PackageManager;
|
||||
}>;
|
||||
Generated
Vendored
+140
@@ -0,0 +1,140 @@
|
||||
"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;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.InstallPackageModal = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const studio_shared_1 = require("@remotion/studio-shared");
|
||||
const react_1 = __importStar(require("react"));
|
||||
const remotion_1 = require("remotion");
|
||||
const install_package_1 = require("../api/install-package");
|
||||
const restart_studio_1 = require("../api/restart-studio");
|
||||
const ShortcutHint_1 = require("../error-overlay/remotion-overlay/ShortcutHint");
|
||||
const client_id_1 = require("../helpers/client-id");
|
||||
const colors_1 = require("../helpers/colors");
|
||||
const use_keybinding_1 = require("../helpers/use-keybinding");
|
||||
const Checkbox_1 = require("./Checkbox");
|
||||
const InstallablePackage_1 = require("./InstallablePackage");
|
||||
const is_menu_item_1 = require("./Menu/is-menu-item");
|
||||
const ModalButton_1 = require("./ModalButton");
|
||||
const ModalFooter_1 = require("./ModalFooter");
|
||||
const ModalHeader_1 = require("./ModalHeader");
|
||||
const DismissableModal_1 = require("./NewComposition/DismissableModal");
|
||||
const layout_1 = require("./layout");
|
||||
const container = {
|
||||
padding: 20,
|
||||
maxHeight: 400,
|
||||
overflowY: 'auto',
|
||||
};
|
||||
const text = {
|
||||
fontSize: 14,
|
||||
};
|
||||
const InstallPackageModal = ({ packageManager }) => {
|
||||
const [state, setState] = react_1.default.useState({ type: 'idle' });
|
||||
const [map, setMap] = react_1.default.useState({});
|
||||
const { previewServerState: ctx } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
|
||||
const selectedPackages = Object.keys(map).filter((pkg) => map[pkg]);
|
||||
const onClick = (0, react_1.useCallback)(async () => {
|
||||
if (state.type === 'done') {
|
||||
setState({ type: 'restarting' });
|
||||
(0, restart_studio_1.restartStudio)();
|
||||
return;
|
||||
}
|
||||
setState({ type: 'installing' });
|
||||
try {
|
||||
await (0, install_package_1.installPackages)(selectedPackages);
|
||||
setState({ type: 'done' });
|
||||
}
|
||||
catch (err) {
|
||||
setState({ type: 'error', error: err });
|
||||
}
|
||||
}, [selectedPackages, state.type]);
|
||||
const canSelectPackages = state.type === 'idle' && ctx.type === 'connected';
|
||||
const disabled = !(canSelectPackages || state.type === 'done') ||
|
||||
selectedPackages.length === 0;
|
||||
const { registerKeybinding } = (0, use_keybinding_1.useKeybinding)();
|
||||
(0, react_1.useEffect)(() => {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
const enter = registerKeybinding({
|
||||
callback() {
|
||||
onClick();
|
||||
},
|
||||
commandCtrlKey: true,
|
||||
key: 'Enter',
|
||||
event: 'keydown',
|
||||
preventDefault: true,
|
||||
triggerIfInputFieldFocused: true,
|
||||
keepRegisteredWhenNotHighestContext: true,
|
||||
});
|
||||
return () => {
|
||||
enter.unregister();
|
||||
};
|
||||
}, [disabled, onClick, registerKeybinding]);
|
||||
return ((0, jsx_runtime_1.jsxs)(DismissableModal_1.DismissableModal, { children: [(0, jsx_runtime_1.jsx)(ModalHeader_1.ModalHeader, { title: "Install packages" }), (0, jsx_runtime_1.jsx)("div", { style: container, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: state.type === 'done' ? ((0, jsx_runtime_1.jsxs)("div", { style: text, children: ["Installed package", selectedPackages.length === 1 ? '' : 's', ' ', "successfully. Restart the server to complete."] })) : state.type === 'restarting' ? ((0, jsx_runtime_1.jsx)("div", { style: text, children: "Restarting the Studio server..." })) : state.type === 'installing' ? ((0, jsx_runtime_1.jsxs)("div", { style: text, children: ["Installing package", selectedPackages.length === 1 ? '' : 's', ". Check your terminal for progress."] })) : ((0, jsx_runtime_1.jsxs)("div", { style: text, children: [Object.entries(studio_shared_1.installableMap)
|
||||
.filter(([, install]) => install)
|
||||
.map(([pkgShort]) => {
|
||||
var _a, _b;
|
||||
const pkg = pkgShort === 'core' ? 'remotion' : `@remotion/${pkgShort}`;
|
||||
const isInstalled = (_b = (_a = window.remotion_installedPackages) === null || _a === void 0 ? void 0 : _a.includes(pkg)) !== null && _b !== void 0 ? _b : false;
|
||||
const link = studio_shared_1.apiDocs[pkgShort];
|
||||
const description = studio_shared_1.descriptions[pkgShort];
|
||||
if (!link) {
|
||||
throw new Error('No link for ' + pkg);
|
||||
}
|
||||
if (!description) {
|
||||
throw new Error('No description for ' + pkg);
|
||||
}
|
||||
return ((0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)(Checkbox_1.Checkbox, { checked: map[pkg], name: pkg, onChange: () => {
|
||||
setMap((prev) => ({ ...prev, [pkg]: !prev[pkg] }));
|
||||
}, disabled: !canSelectPackages || isInstalled }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1.5 }), (0, jsx_runtime_1.jsx)(InstallablePackage_1.InstallablePackageComp, { description: description, isInstalled: isInstalled, link: link, pkg: pkg })] }, pkg));
|
||||
}), studio_shared_1.extraPackages.map((extraPkg) => {
|
||||
var _a, _b;
|
||||
const isInstalled = (_b = (_a = window.remotion_installedPackages) === null || _a === void 0 ? void 0 : _a.includes(extraPkg.name)) !== null && _b !== void 0 ? _b : false;
|
||||
return ((0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)(Checkbox_1.Checkbox, { checked: map[extraPkg.name], name: extraPkg.name, onChange: () => {
|
||||
setMap((prev) => ({
|
||||
...prev,
|
||||
[extraPkg.name]: !prev[extraPkg.name],
|
||||
}));
|
||||
}, disabled: !canSelectPackages || isInstalled }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1.5 }), (0, jsx_runtime_1.jsx)(InstallablePackage_1.InstallablePackageComp, { description: extraPkg.description, isInstalled: isInstalled, link: extraPkg.docsUrl, pkg: `${extraPkg.name}@${extraPkg.version}` })] }, extraPkg.name));
|
||||
})] })) }), (0, jsx_runtime_1.jsx)(ModalFooter_1.ModalFooterContainer, { children: (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [state.type === 'idle' ? ((0, jsx_runtime_1.jsxs)("span", { style: { color: colors_1.LIGHT_TEXT, fontSize: 13, lineHeight: 1.2 }, children: ["This will install ", selectedPackages.length, " package", selectedPackages.length === 1 ? '' : 's', (0, jsx_runtime_1.jsx)("br", {}), "using ", packageManager, ", Remotion v", remotion_1.VERSION] })) : null, (0, jsx_runtime_1.jsx)(layout_1.Flex, {}), (0, jsx_runtime_1.jsxs)(ModalButton_1.ModalButton, { onClick: onClick, disabled: disabled, children: [state.type === 'restarting'
|
||||
? 'Restarting...'
|
||||
: state.type === 'installing'
|
||||
? 'Installing...'
|
||||
: state.type === 'done'
|
||||
? 'Restart Server'
|
||||
: 'Install', disabled ? null : (0, jsx_runtime_1.jsx)(ShortcutHint_1.ShortcutHint, { keyToPress: "\u21B5", cmdOrCtrl: true })] })] }) })] }));
|
||||
};
|
||||
exports.InstallPackageModal = InstallPackageModal;
|
||||
Generated
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
import React from 'react';
|
||||
export declare const InstallablePackageComp: React.FC<{
|
||||
readonly isInstalled: boolean;
|
||||
readonly pkg: string;
|
||||
readonly link: string;
|
||||
readonly description: string;
|
||||
}>;
|
||||
Generated
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.InstallablePackageComp = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const colors_1 = require("../helpers/colors");
|
||||
const FONT_SIZE = 13;
|
||||
const InstallablePackageComp = ({ isInstalled, pkg, link, description }) => {
|
||||
return ((0, jsx_runtime_1.jsxs)("div", { style: {
|
||||
fontSize: FONT_SIZE,
|
||||
lineHeight: 1.2,
|
||||
paddingBottom: 4,
|
||||
paddingTop: 4,
|
||||
}, children: [(0, jsx_runtime_1.jsx)("a", { href: link, style: {
|
||||
fontSize: FONT_SIZE,
|
||||
color: colors_1.TEXT_COLOR,
|
||||
textDecoration: 'none',
|
||||
}, target: "_blank", children: pkg }), ' ', isInstalled ? ((0, jsx_runtime_1.jsx)("span", { style: { opacity: 0.3, fontSize: 'inherit' }, children: "(installed)" })) : null, (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)("span", { style: { color: colors_1.LIGHT_TEXT, fontSize: FONT_SIZE }, children: description })] }));
|
||||
};
|
||||
exports.InstallablePackageComp = InstallablePackageComp;
|
||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
import React from 'react';
|
||||
export declare const JSONViewer: React.FC<{
|
||||
readonly src: string;
|
||||
}>;
|
||||
Generated
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.JSONViewer = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const RemTextarea_1 = require("./NewComposition/RemTextarea");
|
||||
const jsonStyle = {
|
||||
marginTop: 14,
|
||||
marginBottom: 14,
|
||||
fontFamily: 'monospace',
|
||||
flex: 1,
|
||||
};
|
||||
const JSONViewer = ({ src }) => {
|
||||
const [json, setJson] = (0, react_1.useState)(null);
|
||||
(0, react_1.useEffect)(() => {
|
||||
fetch(src)
|
||||
.then((res) => res.json())
|
||||
.then((jsonRes) => {
|
||||
setJson(JSON.stringify(jsonRes, null, 2));
|
||||
});
|
||||
}, [src]);
|
||||
return ((0, jsx_runtime_1.jsx)(RemTextarea_1.RemTextarea, { value: json !== null && json !== void 0 ? json : undefined, status: "ok", onChange: () => {
|
||||
return null;
|
||||
}, style: jsonStyle }));
|
||||
};
|
||||
exports.JSONViewer = JSONViewer;
|
||||
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
import React from 'react';
|
||||
export declare const KeyboardShortcutsExplainer: React.FC;
|
||||
Generated
Vendored
+57
File diff suppressed because one or more lines are too long
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
import type { Bug } from './UpdateCheck';
|
||||
export declare const KnownBugs: React.FC<{
|
||||
bugs: Bug[];
|
||||
}>;
|
||||
Generated
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.KnownBugs = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const OpenIssueButton_1 = require("./UpdateModal/OpenIssueButton");
|
||||
const container = {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
};
|
||||
const text = {
|
||||
fontSize: 14,
|
||||
flex: 1,
|
||||
};
|
||||
const KnownBugs = ({ bugs }) => {
|
||||
const bugElements = bugs.map((bug) => {
|
||||
return ((0, jsx_runtime_1.jsxs)("div", { style: container, children: [(0, jsx_runtime_1.jsxs)("div", { style: text, children: ["\uD83E\uDEB2 ", bug.title] }), (0, jsx_runtime_1.jsx)(OpenIssueButton_1.OpenIssueButton, { link: bug.link })] }, bug.description + bug.link));
|
||||
});
|
||||
return (0, jsx_runtime_1.jsx)("div", { children: bugElements });
|
||||
};
|
||||
exports.KnownBugs = KnownBugs;
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
import React from 'react';
|
||||
export declare const LoopToggle: React.FC<{
|
||||
readonly loop: boolean;
|
||||
readonly setLoop: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
}>;
|
||||
Generated
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.LoopToggle = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const colors_1 = require("../helpers/colors");
|
||||
const loop_1 = require("../state/loop");
|
||||
const ControlButton_1 = require("./ControlButton");
|
||||
const accessibilityLabel = 'Loop video';
|
||||
const LoopToggle = ({ loop, setLoop }) => {
|
||||
const onClick = (0, react_1.useCallback)(() => {
|
||||
setLoop((c) => {
|
||||
(0, loop_1.persistLoopOption)(!c);
|
||||
return !c;
|
||||
});
|
||||
}, [setLoop]);
|
||||
return ((0, jsx_runtime_1.jsx)(ControlButton_1.ControlButton, { title: accessibilityLabel, "aria-label": accessibilityLabel, onClick: onClick, children: (0, jsx_runtime_1.jsx)("svg", { viewBox: "0 0 512 512", style: { width: 18, height: 18 }, children: (0, jsx_runtime_1.jsx)("path", { fill: loop ? colors_1.BLUE : 'white', d: "M493.544 181.463c11.956 22.605 18.655 48.4 18.452 75.75C511.339 345.365 438.56 416 350.404 416H192v47.495c0 22.475-26.177 32.268-40.971 17.475l-80-80c-9.372-9.373-9.372-24.569 0-33.941l80-80C166.138 271.92 192 282.686 192 304v48h158.875c52.812 0 96.575-42.182 97.12-94.992.155-15.045-3.17-29.312-9.218-42.046-4.362-9.185-2.421-20.124 4.8-27.284 4.745-4.706 8.641-8.555 11.876-11.786 11.368-11.352 30.579-8.631 38.091 5.571zM64.005 254.992c.545-52.81 44.308-94.992 97.12-94.992H320v47.505c0 22.374 26.121 32.312 40.971 17.465l80-80c9.372-9.373 9.372-24.569 0-33.941l-80-80C346.014 16.077 320 26.256 320 48.545V96H161.596C73.44 96 .661 166.635.005 254.788c-.204 27.35 6.495 53.145 18.452 75.75 7.512 14.202 26.723 16.923 38.091 5.57 3.235-3.231 7.13-7.08 11.876-11.786 7.22-7.16 9.162-18.098 4.8-27.284-6.049-12.735-9.374-27.001-9.219-42.046z" }) }) }));
|
||||
};
|
||||
exports.LoopToggle = LoopToggle;
|
||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
import React from 'react';
|
||||
export declare const MediaVolumeProvider: React.FC<{
|
||||
readonly children: React.ReactNode;
|
||||
}>;
|
||||
Generated
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.MediaVolumeProvider = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const remotion_1 = require("remotion");
|
||||
const mute_1 = require("../state/mute");
|
||||
const MediaVolumeProvider = ({ children }) => {
|
||||
const [mediaMuted, setMediaMuted] = (0, react_1.useState)(() => (0, mute_1.loadMuteOption)());
|
||||
const [mediaVolume, setMediaVolume] = (0, react_1.useState)(1);
|
||||
const mediaVolumeContextValue = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
mediaMuted,
|
||||
mediaVolume,
|
||||
};
|
||||
}, [mediaMuted, mediaVolume]);
|
||||
const setMediaVolumeContextValue = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
setMediaMuted,
|
||||
setMediaVolume,
|
||||
};
|
||||
}, []);
|
||||
return ((0, jsx_runtime_1.jsx)(remotion_1.Internals.MediaVolumeContext.Provider, { value: mediaVolumeContextValue, children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.SetMediaVolumeContext.Provider, { value: setMediaVolumeContextValue, children: children }) }));
|
||||
};
|
||||
exports.MediaVolumeProvider = MediaVolumeProvider;
|
||||
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
import React from 'react';
|
||||
export declare const MenuDivider: React.FC;
|
||||
Generated
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.MenuDivider = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const colors_1 = require("../../helpers/colors");
|
||||
const menuDivider = {
|
||||
marginTop: 4,
|
||||
marginBottom: 4,
|
||||
height: 1,
|
||||
backgroundColor: colors_1.INPUT_BORDER_COLOR_HOVERED,
|
||||
};
|
||||
const MenuDivider = () => {
|
||||
return (0, jsx_runtime_1.jsx)("div", { style: menuDivider });
|
||||
};
|
||||
exports.MenuDivider = MenuDivider;
|
||||
Generated
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
import type { SetStateAction } from 'react';
|
||||
import React from 'react';
|
||||
import type { ComboboxValue } from '../NewComposition/ComboBox';
|
||||
export type MenuId = 'remotion' | 'file' | 'view' | 'install' | 'tools' | 'help';
|
||||
export type Menu = {
|
||||
id: MenuId;
|
||||
label: React.ReactNode;
|
||||
items: ComboboxValue[];
|
||||
leaveLeftPadding: boolean;
|
||||
};
|
||||
export declare const MenuItem: React.FC<{
|
||||
readonly label: React.ReactNode;
|
||||
readonly id: MenuId;
|
||||
readonly selected: boolean;
|
||||
readonly onItemSelected: (s: SetStateAction<string | null>) => void;
|
||||
readonly onItemHovered: (id: MenuId) => void;
|
||||
readonly onItemQuit: () => void;
|
||||
readonly onPreviousMenu: () => void;
|
||||
readonly onNextMenu: () => void;
|
||||
readonly menu: Menu;
|
||||
readonly leaveLeftPadding: boolean;
|
||||
}>;
|
||||
Generated
Vendored
+97
@@ -0,0 +1,97 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.MenuItem = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const player_1 = require("@remotion/player");
|
||||
const react_1 = require("react");
|
||||
const react_dom_1 = __importDefault(require("react-dom"));
|
||||
const colors_1 = require("../../helpers/colors");
|
||||
const z_index_1 = require("../../state/z-index");
|
||||
const MenuContent_1 = require("../NewComposition/MenuContent");
|
||||
const is_menu_item_1 = require("./is-menu-item");
|
||||
const portals_1 = require("./portals");
|
||||
const styles_1 = require("./styles");
|
||||
const container = {
|
||||
fontSize: 13,
|
||||
color: 'white',
|
||||
paddingLeft: 10,
|
||||
paddingRight: 10,
|
||||
cursor: 'default',
|
||||
paddingTop: 8,
|
||||
paddingBottom: 8,
|
||||
userSelect: 'none',
|
||||
WebkitUserSelect: 'none',
|
||||
border: 'none',
|
||||
};
|
||||
const MenuItem = ({ label: itemName, selected, id, onItemSelected, onItemHovered, onItemQuit, onPreviousMenu, onNextMenu, menu, }) => {
|
||||
const [hovered, setHovered] = (0, react_1.useState)(false);
|
||||
const ref = (0, react_1.useRef)(null);
|
||||
const size = player_1.PlayerInternals.useElementSize(ref, {
|
||||
triggerOnWindowResize: true,
|
||||
shouldApplyCssTransforms: true,
|
||||
});
|
||||
const { tabIndex, currentZIndex } = (0, z_index_1.useZIndex)();
|
||||
const containerStyle = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
...container,
|
||||
backgroundColor: (0, colors_1.getBackgroundFromHoverState)({
|
||||
hovered,
|
||||
selected,
|
||||
}),
|
||||
};
|
||||
}, [hovered, selected]);
|
||||
const portalStyle = (0, react_1.useMemo)(() => {
|
||||
if (!selected || !size) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
...styles_1.menuContainerTowardsBottom,
|
||||
left: size.left,
|
||||
top: size.top + size.height,
|
||||
};
|
||||
}, [selected, size]);
|
||||
const onPointerEnter = (0, react_1.useCallback)(() => {
|
||||
onItemHovered(id);
|
||||
setHovered(true);
|
||||
}, [id, onItemHovered]);
|
||||
const onPointerLeave = (0, react_1.useCallback)(() => {
|
||||
setHovered(false);
|
||||
}, []);
|
||||
const onPointerDown = (0, react_1.useCallback)((e) => {
|
||||
if (e.button !== 0) {
|
||||
return;
|
||||
}
|
||||
onItemSelected(id);
|
||||
window.addEventListener('pointerup', (evt) => {
|
||||
if (!(0, is_menu_item_1.isMenuItem)(evt.target)) {
|
||||
onItemQuit();
|
||||
}
|
||||
}, {
|
||||
once: true,
|
||||
});
|
||||
}, [id, onItemQuit, onItemSelected]);
|
||||
const onClick = (0, react_1.useCallback)((e) => {
|
||||
e.stopPropagation();
|
||||
const isKeyboardInitiated = e.detail === 0;
|
||||
if (!isKeyboardInitiated) {
|
||||
return;
|
||||
}
|
||||
onItemSelected((p) => {
|
||||
return p === null ? id : null;
|
||||
});
|
||||
}, [id, onItemSelected]);
|
||||
const outerStyle = (0, react_1.useMemo)(() => {
|
||||
var _a, _b;
|
||||
return {
|
||||
...styles_1.outerPortal,
|
||||
top: ((_a = size === null || size === void 0 ? void 0 : size.top) !== null && _a !== void 0 ? _a : 0) + ((_b = size === null || size === void 0 ? void 0 : size.height) !== null && _b !== void 0 ? _b : 0),
|
||||
};
|
||||
}, [size]);
|
||||
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("button", { ref: ref, role: "button", tabIndex: tabIndex, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, onPointerDown: onPointerDown, onClick: onClick, style: containerStyle, type: "button", className: is_menu_item_1.MENU_INITIATOR_CLASSNAME, children: itemName }), portalStyle
|
||||
? react_dom_1.default.createPortal((0, jsx_runtime_1.jsx)("div", { className: "css-reset", style: outerStyle, children: (0, jsx_runtime_1.jsx)(z_index_1.HigherZIndex, { onEscape: onItemQuit, onOutsideClick: onItemQuit, children: (0, jsx_runtime_1.jsx)("div", { style: portalStyle, children: (0, jsx_runtime_1.jsx)(MenuContent_1.MenuContent, { onNextMenu: onPreviousMenu, onPreviousMenu: onNextMenu, values: menu.items, onHide: onItemQuit, leaveLeftSpace: menu.leaveLeftPadding, preselectIndex: false, topItemCanBeUnselected: true, fixedHeight: null }) }) }) }), (0, portals_1.getPortal)(currentZIndex))
|
||||
: null] }));
|
||||
};
|
||||
exports.MenuItem = MenuItem;
|
||||
Generated
Vendored
+20
@@ -0,0 +1,20 @@
|
||||
import type { PointerEvent } from 'react';
|
||||
import React from 'react';
|
||||
import type { SubMenu } from '../NewComposition/ComboBox';
|
||||
export type SubMenuActivated = false | 'with-mouse' | 'without-mouse';
|
||||
export declare const MenuSubItem: React.FC<{
|
||||
readonly label: React.ReactNode;
|
||||
readonly id: string;
|
||||
readonly onActionChosen: (id: string, e: PointerEvent<HTMLDivElement>) => void;
|
||||
readonly selected: boolean;
|
||||
readonly onItemSelected: (id: string) => void;
|
||||
readonly keyHint: string | null;
|
||||
readonly leaveLeftSpace: boolean;
|
||||
readonly leftItem: React.ReactNode;
|
||||
readonly subMenu: SubMenu | null;
|
||||
readonly onQuitMenu: () => void;
|
||||
readonly onNextMenu: () => void;
|
||||
readonly subMenuActivated: SubMenuActivated;
|
||||
readonly setSubMenuActivated: React.Dispatch<React.SetStateAction<SubMenuActivated>>;
|
||||
readonly disabled?: boolean;
|
||||
}>;
|
||||
Generated
Vendored
+121
@@ -0,0 +1,121 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.MenuSubItem = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const player_1 = require("@remotion/player");
|
||||
const react_1 = require("react");
|
||||
const react_dom_1 = __importDefault(require("react-dom"));
|
||||
const colors_1 = require("../../helpers/colors");
|
||||
const mobile_layout_1 = require("../../helpers/mobile-layout");
|
||||
const use_keybinding_1 = require("../../helpers/use-keybinding");
|
||||
const caret_1 = require("../../icons/caret");
|
||||
const z_index_1 = require("../../state/z-index");
|
||||
const layout_1 = require("../layout");
|
||||
const SubMenu_1 = require("./SubMenu");
|
||||
const is_menu_item_1 = require("./is-menu-item");
|
||||
const portals_1 = require("./portals");
|
||||
const styles_1 = require("./styles");
|
||||
const container = {
|
||||
paddingTop: 8,
|
||||
paddingBottom: 8,
|
||||
paddingLeft: 12,
|
||||
paddingRight: 8,
|
||||
cursor: 'default',
|
||||
};
|
||||
const labelStyle = {
|
||||
fontSize: 13,
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
whiteSpace: 'nowrap',
|
||||
flex: 1,
|
||||
};
|
||||
const keyHintCss = {
|
||||
flexDirection: 'row',
|
||||
color: colors_1.LIGHT_TEXT,
|
||||
fontSize: 13,
|
||||
};
|
||||
const leftSpace = {
|
||||
width: 24,
|
||||
marginLeft: -6,
|
||||
display: 'inline-flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
};
|
||||
const MenuSubItem = ({ label, leaveLeftSpace, leftItem, onActionChosen, id, selected, onItemSelected, keyHint, subMenu, onQuitMenu, subMenuActivated, setSubMenuActivated, disabled, }) => {
|
||||
const [hovered, setHovered] = (0, react_1.useState)(false);
|
||||
const ref = (0, react_1.useRef)(null);
|
||||
const size = player_1.PlayerInternals.useElementSize(ref, {
|
||||
triggerOnWindowResize: true,
|
||||
shouldApplyCssTransforms: true,
|
||||
});
|
||||
const mobileLayout = (0, mobile_layout_1.useMobileLayout)();
|
||||
const { currentZIndex } = (0, z_index_1.useZIndex)();
|
||||
const style = (0, react_1.useMemo)(() => {
|
||||
return {
|
||||
...container,
|
||||
backgroundColor: selected && !disabled ? colors_1.CLEAR_HOVER : 'transparent',
|
||||
opacity: disabled ? 0.5 : 1,
|
||||
cursor: disabled ? 'not-allowed' : 'default',
|
||||
};
|
||||
}, [selected, disabled]);
|
||||
const onPointerUp = (0, react_1.useCallback)((e) => {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
if (subMenu) {
|
||||
setSubMenuActivated('with-mouse');
|
||||
setHovered(true);
|
||||
return;
|
||||
}
|
||||
onActionChosen(id, e);
|
||||
}, [disabled, id, onActionChosen, setSubMenuActivated, subMenu]);
|
||||
const onPointerEnter = (0, react_1.useCallback)(() => {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
onItemSelected(id);
|
||||
setHovered(true);
|
||||
}, [disabled, id, onItemSelected]);
|
||||
const onPointerLeave = (0, react_1.useCallback)(() => {
|
||||
setHovered(false);
|
||||
}, []);
|
||||
const onQuitSubmenu = (0, react_1.useCallback)(() => {
|
||||
setSubMenuActivated(false);
|
||||
}, [setSubMenuActivated]);
|
||||
const portalStyle = (0, react_1.useMemo)(() => {
|
||||
if (!selected || !size || !subMenu || !subMenuActivated) {
|
||||
return null;
|
||||
}
|
||||
const left = size.left + size.width + styles_1.SUBMENU_LEFT_INSET;
|
||||
return {
|
||||
...styles_1.menuContainerTowardsBottom,
|
||||
left: mobileLayout ? left * 0.7 : left,
|
||||
top: size.top - styles_1.MENU_VERTICAL_PADDING,
|
||||
};
|
||||
}, [mobileLayout, selected, size, subMenu, subMenuActivated]);
|
||||
(0, react_1.useEffect)(() => {
|
||||
if (!hovered || !subMenu) {
|
||||
return;
|
||||
}
|
||||
const hi = setTimeout(() => {
|
||||
setSubMenuActivated('with-mouse');
|
||||
}, 100);
|
||||
return () => clearTimeout(hi);
|
||||
}, [hovered, selected, setSubMenuActivated, subMenu]);
|
||||
(0, react_1.useEffect)(() => {
|
||||
var _a;
|
||||
if (selected) {
|
||||
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({
|
||||
// block is vertical alignment, inline is horizontal alignment. So we use "block"
|
||||
block: 'nearest',
|
||||
});
|
||||
}
|
||||
}, [selected]);
|
||||
return ((0, jsx_runtime_1.jsx)("div", { ref: ref, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, style: style, onPointerUp: onPointerUp, role: "button", className: is_menu_item_1.MENU_ITEM_CLASSNAME, children: (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [leaveLeftSpace ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { style: leftSpace, children: leftItem }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 })] })) : null, (0, jsx_runtime_1.jsx)("div", { style: labelStyle, title: typeof label === 'string' ? label : undefined, children: label }), ' ', (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 2 }), subMenu ? (0, jsx_runtime_1.jsx)(caret_1.CaretRight, {}) : null, keyHint && !(0, use_keybinding_1.areKeyboardShortcutsDisabled)() ? ((0, jsx_runtime_1.jsx)("span", { style: keyHintCss, children: keyHint })) : null, portalStyle && subMenu
|
||||
? react_dom_1.default.createPortal((0, jsx_runtime_1.jsx)(SubMenu_1.SubMenuComponent, { onQuitFullMenu: onQuitMenu, subMenu: subMenu, onQuitSubMenu: onQuitSubmenu, portalStyle: portalStyle, subMenuActivated: subMenuActivated }), (0, portals_1.getPortal)(currentZIndex))
|
||||
: null] }) }));
|
||||
};
|
||||
exports.MenuSubItem = MenuSubItem;
|
||||
Generated
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
import type { SubMenu } from '../NewComposition/ComboBox';
|
||||
import type { SubMenuActivated } from './MenuSubItem';
|
||||
export declare const SubMenuComponent: React.FC<{
|
||||
readonly portalStyle: React.CSSProperties;
|
||||
readonly subMenu: SubMenu;
|
||||
readonly onQuitFullMenu: () => void;
|
||||
readonly onQuitSubMenu: () => void;
|
||||
readonly subMenuActivated: SubMenuActivated;
|
||||
}>;
|
||||
Generated
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.SubMenuComponent = void 0;
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const mobile_layout_1 = require("../../helpers/mobile-layout");
|
||||
const noop_1 = require("../../helpers/noop");
|
||||
const z_index_1 = require("../../state/z-index");
|
||||
const MenuContent_1 = require("../NewComposition/MenuContent");
|
||||
const portals_1 = require("./portals");
|
||||
const SubMenuComponent = ({ portalStyle, subMenuActivated, subMenu, onQuitFullMenu, onQuitSubMenu, }) => {
|
||||
const mobileLayout = (0, mobile_layout_1.useMobileLayout)();
|
||||
const onOutsideClick = (0, react_1.useCallback)((e) => {
|
||||
if (portals_1.portals.find((p) => p.contains(e)) || mobileLayout) {
|
||||
onQuitSubMenu();
|
||||
}
|
||||
else {
|
||||
onQuitFullMenu();
|
||||
}
|
||||
}, [mobileLayout, onQuitFullMenu, onQuitSubMenu]);
|
||||
return ((0, jsx_runtime_1.jsx)(z_index_1.HigherZIndex, { onEscape: onQuitFullMenu, onOutsideClick: onOutsideClick, children: (0, jsx_runtime_1.jsx)("div", { style: portalStyle, className: "css-reset", children: (0, jsx_runtime_1.jsx)(MenuContent_1.MenuContent, { onNextMenu: noop_1.noop, onPreviousMenu: onQuitSubMenu, values: subMenu.items, onHide: onQuitFullMenu, leaveLeftSpace: subMenu.leaveLeftSpace, preselectIndex: subMenuActivated === 'without-mouse' &&
|
||||
typeof subMenu.preselectIndex === 'number'
|
||||
? subMenu.preselectIndex
|
||||
: false, topItemCanBeUnselected: false, fixedHeight: null }) }) }));
|
||||
};
|
||||
exports.SubMenuComponent = SubMenuComponent;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user