UNPKG

@remotion/studio

Version:

APIs for interacting with the Remotion Studio

188 lines (187 loc) 9.68 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.OptionsPanel = exports.optionsSidebarTabs = exports.persistSelectedOptionsSidebarPanel = 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 mobile_layout_1 = require("../helpers/mobile-layout"); const show_browser_rendering_1 = require("../helpers/show-browser-rendering"); const VisualControls_1 = require("../visual-controls/VisualControls"); const DefaultPropsEditor_1 = require("./DefaultPropsEditor"); const get_zod_if_possible_1 = require("./get-zod-if-possible"); const NotificationCenter_1 = require("./Notifications/NotificationCenter"); const deep_equal_1 = require("./RenderModal/SchemaEditor/deep-equal"); const extract_enum_json_paths_1 = require("./RenderModal/SchemaEditor/extract-enum-json-paths"); const SchemaResetButton_1 = require("./RenderModal/SchemaEditor/SchemaResetButton"); const RenderQueue_1 = require("./RenderQueue"); const actions_1 = require("./RenderQueue/actions"); const RendersTab_1 = require("./RendersTab"); const Tabs_1 = require("./Tabs"); const VisualControlsContent_1 = require("./VisualControls/VisualControlsContent"); const localStorageKey = 'remotion.sidebarPanel'; const getSelectedPanel = (renderingAvailable) => { if (!renderingAvailable) { return 'input-props'; } const panel = localStorage.getItem(localStorageKey); if (panel === 'renders') { return 'renders'; } if (panel === 'visual-controls') { return 'visual-controls'; } return 'input-props'; }; const tabsContainer = { backgroundColor: colors_1.BACKGROUND, }; const persistSelectedOptionsSidebarPanel = (panel) => { localStorage.setItem(localStorageKey, panel); }; exports.persistSelectedOptionsSidebarPanel = persistSelectedOptionsSidebarPanel; exports.optionsSidebarTabs = (0, react_1.createRef)(); const OptionsPanel = ({ readOnlyStudio }) => { const { props, updateProps } = (0, react_1.useContext)(remotion_1.Internals.EditorPropsContext); const renderingAvailable = !readOnlyStudio || show_browser_rendering_1.SHOW_BROWSER_RENDERING; const isMobileLayout = (0, mobile_layout_1.useMobileLayout)(); const visualControlsTabActivated = (0, react_1.useContext)(VisualControls_1.VisualControlsTabActivatedContext); const container = (0, react_1.useMemo)(() => ({ height: '100%', width: '100%', display: 'flex', position: isMobileLayout ? 'relative' : 'absolute', flexDirection: 'column', flex: 1, }), [isMobileLayout]); const [panel, setPanel] = (0, react_1.useState)(() => getSelectedPanel(renderingAvailable)); const onPropsSelected = (0, react_1.useCallback)(() => { setPanel('input-props'); (0, exports.persistSelectedOptionsSidebarPanel)('input-props'); }, []); const onRendersSelected = (0, react_1.useCallback)(() => { setPanel('renders'); (0, exports.persistSelectedOptionsSidebarPanel)('renders'); }, []); const onVisualControlsSelected = (0, react_1.useCallback)(() => { setPanel('visual-controls'); (0, exports.persistSelectedOptionsSidebarPanel)('visual-controls'); }, []); (0, react_1.useImperativeHandle)(exports.optionsSidebarTabs, () => { return { selectRendersPanel: () => { setPanel('renders'); (0, exports.persistSelectedOptionsSidebarPanel)('renders'); }, }; }, []); const { compositions, canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager); const composition = (0, react_1.useMemo)(() => { if (canvasContent === null || canvasContent.type !== 'composition') { return null; } for (const comp of compositions) { if (comp.id === canvasContent.compositionId) { return comp; } } return null; }, [canvasContent, compositions]); const z = (0, get_zod_if_possible_1.useZodIfPossible)(); const zodTypes = (0, get_zod_if_possible_1.useZodTypesIfPossible)(); const noComposition = !composition; const schema = (0, react_1.useMemo)(() => { if (!z) { return 'no-zod'; } if (noComposition) { return 'no-composition'; } if (!composition.schema) { return 'no-schema'; } if (!(typeof composition.schema.safeParse === 'function')) { throw new Error('A value which is not a Zod schema was passed to `schema`'); } return composition.schema; }, [composition === null || composition === void 0 ? void 0 : composition.schema, noComposition, z]); const currentDefaultProps = (0, react_1.useMemo)(() => { var _a, _b; if (composition === null) { return {}; } return (_b = (_a = props[composition.id]) !== null && _a !== void 0 ? _a : composition.defaultProps) !== null && _b !== void 0 ? _b : {}; }, [composition, props]); const saveToFile = (0, react_1.useCallback)((updater) => { if (readOnlyStudio) { return; } if (schema === 'no-zod' || schema === 'no-schema' || schema === 'no-composition' || z === null) { (0, NotificationCenter_1.showNotification)('Cannot update default props: No Zod schema', 2000); return; } if (!composition) { throw new Error('Composition is not found'); } const oldDefaultProps = currentDefaultProps; const newDefaultProps = updater(oldDefaultProps); (0, actions_1.callUpdateDefaultPropsApi)(composition.id, newDefaultProps, (0, extract_enum_json_paths_1.extractEnumJsonPaths)({ schema, zodRuntime: z, currentPath: [], zodTypes, })) .then((response) => { if (!response.success) { // eslint-disable-next-line no-console console.log(response.stack); (0, NotificationCenter_1.showNotification)(`Cannot update default props: ${response.reason}. See console for more information.`, 2000); } }) .catch((err) => { (0, NotificationCenter_1.showNotification)(`Cannot update default props: ${err.message}`, 2000); }); }, [composition, currentDefaultProps, readOnlyStudio, schema, z, zodTypes]); const compositionId = (0, react_1.useMemo)(() => { var _a; return (_a = composition === null || composition === void 0 ? void 0 : composition.id) !== null && _a !== void 0 ? _a : ''; }, [composition === null || composition === void 0 ? void 0 : composition.id]); const compositionDefaultProps = (0, react_1.useMemo)(() => { var _a; return (_a = composition === null || composition === void 0 ? void 0 : composition.defaultProps) !== null && _a !== void 0 ? _a : {}; }, [composition === null || composition === void 0 ? void 0 : composition.defaultProps]); const hasLocalModifications = (0, react_1.useMemo)(() => { if (!readOnlyStudio || !composition || !composition.defaultProps) { return false; } return !(0, deep_equal_1.deepEqual)(composition.defaultProps, currentDefaultProps); }, [readOnlyStudio, composition, currentDefaultProps]); const resetToOriginal = (0, react_1.useCallback)(() => { var _a, _b; if (!composition) { return; } updateProps({ id: composition.id, defaultProps: ((_a = composition.defaultProps) !== null && _a !== void 0 ? _a : {}), newProps: ((_b = composition.defaultProps) !== null && _b !== void 0 ? _b : {}), }); }, [composition, updateProps]); const setDefaultProps = (0, react_1.useCallback)((updater, { shouldSave }) => { updateProps({ id: compositionId, defaultProps: compositionDefaultProps, newProps: updater, }); if (shouldSave) { saveToFile(updater); } }, [compositionId, compositionDefaultProps, saveToFile, updateProps]); return (jsx_runtime_1.jsxs("div", { style: container, className: "css-reset", children: [ jsx_runtime_1.jsx("div", { style: tabsContainer, children: jsx_runtime_1.jsxs(Tabs_1.Tabs, { children: [visualControlsTabActivated ? (jsx_runtime_1.jsx(Tabs_1.Tab, { selected: panel === 'visual-controls', onClick: onVisualControlsSelected, children: "Controls" })) : null, jsx_runtime_1.jsxs(Tabs_1.Tab, { selected: panel === 'input-props', onClick: onPropsSelected, style: { justifyContent: 'space-between' }, children: ["Props", hasLocalModifications ? (jsx_runtime_1.jsx(SchemaResetButton_1.SchemaResetButton, { onClick: resetToOriginal })) : null] }), renderingAvailable ? (jsx_runtime_1.jsx(RendersTab_1.RendersTab, { onClick: onRendersSelected, selected: panel === 'renders' })) : null] }) }), panel === 'input-props' ? (composition ? (jsx_runtime_1.jsx(DefaultPropsEditor_1.DefaultPropsEditor, { unresolvedComposition: composition, defaultProps: currentDefaultProps, setDefaultProps: setDefaultProps, propsEditType: "default-props" }, composition.id)) : null) : panel === 'visual-controls' && visualControlsTabActivated ? (jsx_runtime_1.jsx(VisualControlsContent_1.VisualControlsContent, {})) : !renderingAvailable ? null : (jsx_runtime_1.jsx(RenderQueue_1.RenderQueue, {}))] })); }; exports.OptionsPanel = OptionsPanel;