UNPKG

@remotion/studio

Version:

APIs for interacting with the Remotion Studio

210 lines (209 loc) 12.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 url_state_1 = require("../../helpers/url-state"); const validate_new_comp_data_1 = require("../../helpers/validate-new-comp-data"); const layout_1 = require("../layout"); const ModalFooter_1 = require("../ModalFooter"); const ModalHeader_1 = require("../ModalHeader"); const layout_2 = require("../RenderModal/layout"); const ResolveCompositionBeforeModal_1 = require("../RenderModal/ResolveCompositionBeforeModal"); 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 onDuplicateSuccess = (0, react_1.useCallback)(() => { (0, url_state_1.pushUrl)(`/${newId}`); }, [newId]); const onSubmit = (0, react_1.useCallback)((e) => { e.preventDefault(); }, []); return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [ jsx_runtime_1.jsx(ModalHeader_1.ModalHeader, { title: `Duplicate ${resolved.result.id}` }), jsx_runtime_1.jsxs("form", { onSubmit: onSubmit, children: [ 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 jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [ jsx_runtime_1.jsx("div", { style: layout_2.label, children: "Type" }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsx(ComboBox_1.Combobox, { title: "Type of composition", style: comboBoxStyle, values: typeValues, selectedId: type }) }) ] })) : null, jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [ jsx_runtime_1.jsx("div", { style: layout_2.label, children: "ID" }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsxs("div", { children: [ jsx_runtime_1.jsx(RemInput_1.RemotionInput, { value: newId, onChange: onNameChange, type: "text", autoFocus: true, placeholder: "Composition ID", status: "ok", rightAlign: true }), compNameErrMessage ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [ jsx_runtime_1.jsx(layout_1.Spacing, { y: 1, block: true }), jsx_runtime_1.jsx(ValidationMessage_1.ValidationMessage, { align: "flex-start", message: compNameErrMessage, type: "error" }) ] })) : null] }) }) ] }), hadDimensionsDefined ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [ jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [ jsx_runtime_1.jsx("div", { style: layout_2.label, children: "Width" }), jsx_runtime_1.jsxs("div", { style: layout_2.rightRow, children: [ 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 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [ jsx_runtime_1.jsx(layout_1.Spacing, { y: 1, block: true }), jsx_runtime_1.jsx(ValidationMessage_1.ValidationMessage, { align: "flex-start", message: compWidthErrMessage, type: "error" }) ] })) : null] }) ] }), jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [ jsx_runtime_1.jsx("div", { style: layout_2.label, children: "Height" }), jsx_runtime_1.jsxs("div", { style: layout_2.rightRow, children: [ 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 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [ jsx_runtime_1.jsx(layout_1.Spacing, { y: 1, block: true }), jsx_runtime_1.jsx(ValidationMessage_1.ValidationMessage, { align: "flex-start", message: compHeightErrMessage, type: "error" }) ] })) : null] }) ] }) ] })) : null, type === 'composition' && hadDurationDefined ? (jsx_runtime_1.jsx(NewCompDuration_1.NewCompDuration, { durationInFrames: durationInFrames, setDurationInFrames: setDurationInFrames })) : null, type === 'composition' && hadFpsDefined ? (jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [ jsx_runtime_1.jsx("div", { style: layout_2.label, children: "FPS" }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: 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] }), jsx_runtime_1.jsx(ModalFooter_1.ModalFooterContainer, { children: 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, onSuccess: onDuplicateSuccess }) }) ] }) ] })); }; const DuplicateComposition = ({ compositionId, compositionType }) => { return (jsx_runtime_1.jsx(DismissableModal_1.DismissableModal, { children: jsx_runtime_1.jsx(ResolveCompositionBeforeModal_1.ResolveCompositionBeforeModal, { compositionId: compositionId, children: jsx_runtime_1.jsx(DuplicateCompositionLoaded, { initialType: compositionType }) }) })); }; exports.DuplicateComposition = DuplicateComposition;