@remotion/studio
Version:
APIs for interacting with the Remotion Studio
188 lines (187 loc) • 9.68 kB
JavaScript
"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;