UNPKG

@remotion/studio

Version:

APIs for interacting with the Remotion Studio

181 lines (180 loc) 11.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DuplicateComposition = void 0; const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const remotion_1 = require("remotion"); const validate_new_comp_data_1 = require("../../helpers/validate-new-comp-data"); const ModalFooter_1 = require("../ModalFooter"); const ModalHeader_1 = require("../ModalHeader"); const ResolveCompositionBeforeModal_1 = require("../RenderModal/ResolveCompositionBeforeModal"); const layout_1 = require("../RenderModal/layout"); const layout_2 = require("../layout"); const CodemodFooter_1 = require("./CodemodFooter"); const ComboBox_1 = require("./ComboBox"); const DismissableModal_1 = require("./DismissableModal"); const InputDragger_1 = require("./InputDragger"); const NewCompDuration_1 = require("./NewCompDuration"); const RemInput_1 = require("./RemInput"); const ValidationMessage_1 = require("./ValidationMessage"); const content = { padding: 12, paddingRight: 12, flex: 1, fontSize: 13, minWidth: 500, }; const comboBoxStyle = { width: 190, }; const DuplicateCompositionLoaded = ({ initialType }) => { const context = (0, react_1.useContext)(ResolveCompositionBeforeModal_1.ResolvedCompositionContext); if (!context) { throw new Error('Resolved composition context'); } const { resolved, unresolved } = context; const [initialCompType] = (0, react_1.useState)(initialType); const hadDimensionsDefined = unresolved.width && unresolved.height; const hadFpsDefined = unresolved.fps !== undefined; const hadDurationDefined = unresolved.durationInFrames !== undefined; const [selectedFrameRate, setFrameRate] = (0, react_1.useState)(resolved.result.fps); const { compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager); const [type, setType] = (0, react_1.useState)(initialCompType); const [newId, setName] = (0, react_1.useState)(() => { var _a; const numberAtEnd = (_a = resolved.result.id.match(/([0-9]+)$/)) === null || _a === void 0 ? void 0 : _a[0]; let prefix = numberAtEnd ? Number(numberAtEnd) : 1; const initialName = resolved.result.id.replace(/([0-9]+)$/, ''); let currentName = initialName; while (true) { currentName = initialName + prefix; const err = (0, validate_new_comp_data_1.validateCompositionName)(currentName, compositions); if (!err) { break; } prefix++; } return currentName; }); const [size, setSize] = (0, react_1.useState)(() => ({ width: resolved.result.width, height: resolved.result.height, })); const [durationInFrames, setDurationInFrames] = (0, react_1.useState)(resolved.result.durationInFrames); const onTypeChanged = (0, react_1.useCallback)((newType) => { setType(newType); }, []); const onWidthChanged = (0, react_1.useCallback)((newValue) => { setSize((s) => { const { height } = s; const newWidth = Number(newValue); return { height, width: newWidth, }; }); }, []); const onWidthDirectlyChanged = (0, react_1.useCallback)((newWidth) => { setSize((s) => { const { height } = s; return { height, width: newWidth, }; }); }, []); const onHeightDirectlyChanged = (0, react_1.useCallback)((newHeight) => { setSize((s) => { const { width } = s; return { width, height: newHeight, }; }); }, []); const onHeightChanged = (0, react_1.useCallback)((newValue) => { setSize((s) => { const { width } = s; const newHeight = Number(newValue); return { width, height: newHeight, }; }); }, []); const onNameChange = (0, react_1.useCallback)((e) => { setName(e.target.value); }, []); const onTextFpsChange = (0, react_1.useCallback)((newFps) => { setFrameRate(Number(newFps)); }, []); const onFpsChange = (0, react_1.useCallback)((newFps) => { setFrameRate(newFps); }, []); const compNameErrMessage = (0, validate_new_comp_data_1.validateCompositionName)(newId, compositions); const compWidthErrMessage = (0, validate_new_comp_data_1.validateCompositionDimension)('Width', size.width); const compHeightErrMessage = (0, validate_new_comp_data_1.validateCompositionDimension)('Height', size.height); const typeValues = (0, react_1.useMemo)(() => { return [ { id: 'composition', keyHint: null, label: '<Composition />', leftItem: null, onClick: () => onTypeChanged('composition'), subMenu: null, type: 'item', value: 'composition', quickSwitcherLabel: null, }, { id: 'still', keyHint: null, label: '<Still />', leftItem: null, onClick: () => onTypeChanged('still'), subMenu: null, type: 'item', value: 'still', quickSwitcherLabel: null, }, ]; }, [onTypeChanged]); const valid = compNameErrMessage === null && compWidthErrMessage === null && compHeightErrMessage === null; const codemod = (0, react_1.useMemo)(() => { return { type: 'duplicate-composition', idToDuplicate: resolved.result.id, newDurationInFrames: hadDurationDefined ? Number(durationInFrames) : null, newFps: hadFpsDefined ? Number(selectedFrameRate) : null, newHeight: hadDimensionsDefined ? Number(size.height) : null, newWidth: hadDimensionsDefined ? Number(size.width) : null, newId, tag: type === 'still' ? 'Still' : 'Composition', }; }, [ durationInFrames, hadDimensionsDefined, hadDurationDefined, hadFpsDefined, newId, resolved.result.id, selectedFrameRate, size.height, size.width, type, ]); const onSubmit = (0, react_1.useCallback)((e) => { e.preventDefault(); }, []); return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ModalHeader_1.ModalHeader, { title: `Duplicate ${resolved.result.id}` }), (0, jsx_runtime_1.jsxs)("form", { onSubmit: onSubmit, children: [(0, jsx_runtime_1.jsxs)("div", { style: content, children: [initialCompType === 'composition' ? ( // We allow converting from a composition to a still, but // not the other way around (0, jsx_runtime_1.jsxs)("div", { style: layout_1.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_1.label, children: "Type" }), (0, jsx_runtime_1.jsx)("div", { style: layout_1.rightRow, children: (0, jsx_runtime_1.jsx)(ComboBox_1.Combobox, { title: "Type of composition", style: comboBoxStyle, values: typeValues, selectedId: type }) })] })) : null, (0, jsx_runtime_1.jsxs)("div", { style: layout_1.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_1.label, children: "ID" }), (0, jsx_runtime_1.jsx)("div", { style: layout_1.rightRow, children: (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(RemInput_1.RemotionInput, { value: newId, onChange: onNameChange, type: "text", autoFocus: true, placeholder: "Composition ID", status: "ok", rightAlign: true }), compNameErrMessage ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(layout_2.Spacing, { y: 1, block: true }), (0, jsx_runtime_1.jsx)(ValidationMessage_1.ValidationMessage, { align: "flex-start", message: compNameErrMessage, type: "error" })] })) : null] }) })] }), hadDimensionsDefined ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { style: layout_1.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_1.label, children: "Width" }), (0, jsx_runtime_1.jsxs)("div", { style: layout_1.rightRow, children: [(0, jsx_runtime_1.jsx)(InputDragger_1.InputDragger, { type: "number", value: size.width, placeholder: "Width", onTextChange: onWidthChanged, name: "width", step: 2, min: 2, required: true, status: "ok", formatter: (w) => `${w}px`, max: 100000000, onValueChange: onWidthDirectlyChanged, rightAlign: false }), compWidthErrMessage ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(layout_2.Spacing, { y: 1, block: true }), (0, jsx_runtime_1.jsx)(ValidationMessage_1.ValidationMessage, { align: "flex-start", message: compWidthErrMessage, type: "error" })] })) : null] })] }), (0, jsx_runtime_1.jsxs)("div", { style: layout_1.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_1.label, children: "Height" }), (0, jsx_runtime_1.jsxs)("div", { style: layout_1.rightRow, children: [(0, jsx_runtime_1.jsx)(InputDragger_1.InputDragger, { type: "number", value: size.height, onTextChange: onHeightChanged, placeholder: "Height", name: "height", step: 2, required: true, formatter: (h) => `${h}px`, min: 2, status: "ok", max: 100000000, onValueChange: onHeightDirectlyChanged, rightAlign: false }), compHeightErrMessage ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(layout_2.Spacing, { y: 1, block: true }), (0, jsx_runtime_1.jsx)(ValidationMessage_1.ValidationMessage, { align: "flex-start", message: compHeightErrMessage, type: "error" })] })) : null] })] })] })) : null, type === 'composition' && hadDurationDefined ? ((0, jsx_runtime_1.jsx)(NewCompDuration_1.NewCompDuration, { durationInFrames: durationInFrames, setDurationInFrames: setDurationInFrames })) : null, type === 'composition' && hadFpsDefined ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_1.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_1.label, children: "FPS" }), (0, jsx_runtime_1.jsx)("div", { style: layout_1.rightRow, children: (0, jsx_runtime_1.jsx)(InputDragger_1.InputDragger, { type: "number", value: selectedFrameRate, onTextChange: onTextFpsChange, placeholder: "Frame rate (fps)", name: "fps", min: 1, required: true, status: "ok", max: 240, step: 0.01, onValueChange: onFpsChange, rightAlign: false }) })] })) : null] }), (0, jsx_runtime_1.jsx)(ModalFooter_1.ModalFooterContainer, { children: (0, jsx_runtime_1.jsx)(CodemodFooter_1.CodemodFooter, { loadingNotification: 'Duplicating...', errorNotification: 'Could not duplicate composition', successNotification: `Duplicated ${unresolved.id} as ${newId}`, genericSubmitLabel: 'Duplicate', submitLabel: ({ relativeRootPath }) => `Add to ${relativeRootPath}`, codemod: codemod, valid: valid }) })] })] })); }; const DuplicateComposition = ({ compositionId, compositionType }) => { return ((0, jsx_runtime_1.jsx)(DismissableModal_1.DismissableModal, { children: (0, jsx_runtime_1.jsx)(ResolveCompositionBeforeModal_1.ResolveCompositionBeforeModal, { compositionId: compositionId, children: (0, jsx_runtime_1.jsx)(DuplicateCompositionLoaded, { initialType: compositionType }) }) })); }; exports.DuplicateComposition = DuplicateComposition;