360 lines
16 KiB
JavaScript
360 lines
16 KiB
JavaScript
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.RenderButton = 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 remotion_1 = require("remotion");
|
|
const client_id_1 = require("../helpers/client-id");
|
|
const colors_1 = require("../helpers/colors");
|
|
const show_browser_rendering_1 = require("../helpers/show-browser-rendering");
|
|
const use_keybinding_1 = require("../helpers/use-keybinding");
|
|
const caret_1 = require("../icons/caret");
|
|
const render_1 = require("../icons/render");
|
|
const in_out_1 = require("../state/in-out");
|
|
const modals_1 = require("../state/modals");
|
|
const z_index_1 = require("../state/z-index");
|
|
const is_menu_item_1 = require("./Menu/is-menu-item");
|
|
const portals_1 = require("./Menu/portals");
|
|
const styles_1 = require("./Menu/styles");
|
|
const MenuContent_1 = require("./NewComposition/MenuContent");
|
|
const layout_1 = require("./layout");
|
|
const splitButtonContainer = {
|
|
display: 'inline-flex',
|
|
flexDirection: 'row',
|
|
alignItems: 'stretch',
|
|
borderRadius: 4,
|
|
border: `1px solid ${colors_1.INPUT_BORDER_COLOR_UNHOVERED}`,
|
|
backgroundColor: colors_1.INPUT_BACKGROUND,
|
|
overflow: 'hidden',
|
|
};
|
|
const mainButtonStyle = {
|
|
paddingLeft: 7,
|
|
paddingRight: 7,
|
|
paddingTop: 7,
|
|
paddingBottom: 7,
|
|
background: 'transparent',
|
|
border: 'none',
|
|
color: 'white',
|
|
cursor: 'pointer',
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
fontSize: 14,
|
|
fontFamily: 'inherit',
|
|
};
|
|
const dividerStyle = {
|
|
width: 1,
|
|
backgroundColor: colors_1.INPUT_BORDER_COLOR_UNHOVERED,
|
|
alignSelf: 'stretch',
|
|
};
|
|
const dropdownTriggerStyle = {
|
|
paddingLeft: 6,
|
|
paddingRight: 6,
|
|
paddingTop: 7,
|
|
paddingBottom: 7,
|
|
background: 'transparent',
|
|
border: 'none',
|
|
color: 'white',
|
|
cursor: 'pointer',
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
};
|
|
const mainButtonContent = {
|
|
paddingLeft: 4,
|
|
paddingRight: 6,
|
|
};
|
|
const label = {
|
|
fontSize: 14,
|
|
};
|
|
const RENDER_TYPE_STORAGE_KEY = 'remotion.renderType';
|
|
const getInitialRenderType = (readOnlyStudio) => {
|
|
if (!show_browser_rendering_1.SHOW_BROWSER_RENDERING) {
|
|
return 'server-render';
|
|
}
|
|
if (readOnlyStudio) {
|
|
return 'client-render';
|
|
}
|
|
try {
|
|
const stored = localStorage.getItem(RENDER_TYPE_STORAGE_KEY);
|
|
if (stored === 'server-render' || stored === 'client-render') {
|
|
return stored;
|
|
}
|
|
}
|
|
catch (_a) {
|
|
// localStorage might not be available
|
|
}
|
|
return 'server-render';
|
|
};
|
|
const RenderButton = ({ readOnlyStudio, }) => {
|
|
const { inFrame, outFrame } = (0, in_out_1.useTimelineInOutFramePosition)();
|
|
const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
|
|
const [renderType, setRenderType] = (0, react_1.useState)(() => getInitialRenderType(readOnlyStudio));
|
|
const [dropdownOpened, setDropdownOpened] = (0, react_1.useState)(false);
|
|
const dropdownRef = (0, react_1.useRef)(null);
|
|
const containerRef = (0, react_1.useRef)(null);
|
|
const { currentZIndex } = (0, z_index_1.useZIndex)();
|
|
const size = player_1.PlayerInternals.useElementSize(dropdownRef, {
|
|
triggerOnWindowResize: true,
|
|
shouldApplyCssTransforms: true,
|
|
});
|
|
const refresh = size === null || size === void 0 ? void 0 : size.refresh;
|
|
const onPointerDown = (0, react_1.useCallback)(() => {
|
|
setDropdownOpened((o) => {
|
|
if (!o) {
|
|
refresh === null || refresh === void 0 ? void 0 : refresh();
|
|
}
|
|
return !o;
|
|
});
|
|
}, [refresh]);
|
|
const onClickDropdown = (0, react_1.useCallback)((e) => {
|
|
e.stopPropagation();
|
|
const isKeyboardInitiated = e.detail === 0;
|
|
if (!isKeyboardInitiated) {
|
|
return;
|
|
}
|
|
setDropdownOpened((o) => {
|
|
if (!o) {
|
|
refresh === null || refresh === void 0 ? void 0 : refresh();
|
|
window.addEventListener('pointerup', (evt) => {
|
|
if (!(0, is_menu_item_1.isMenuItem)(evt.target)) {
|
|
setDropdownOpened(false);
|
|
}
|
|
}, {
|
|
once: true,
|
|
});
|
|
}
|
|
return !o;
|
|
});
|
|
}, [refresh]);
|
|
const connectionStatus = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx)
|
|
.previewServerState.type;
|
|
const shortcut = (0, use_keybinding_1.areKeyboardShortcutsDisabled)() ? '' : '(R)';
|
|
const tooltip = connectionStatus === 'connected'
|
|
? 'Export the current composition ' + shortcut
|
|
: 'Connect to the Studio server to render';
|
|
const iconStyle = (0, react_1.useMemo)(() => {
|
|
return {
|
|
style: {
|
|
height: 16,
|
|
color: 'currentColor',
|
|
},
|
|
};
|
|
}, []);
|
|
const video = remotion_1.Internals.useVideo();
|
|
const getCurrentFrame = player_1.PlayerInternals.useFrameImperative();
|
|
const { props } = (0, react_1.useContext)(remotion_1.Internals.EditorPropsContext);
|
|
const openServerRenderModal = (0, react_1.useCallback)(() => {
|
|
var _a, _b, _c;
|
|
if (!video) {
|
|
return null;
|
|
}
|
|
const defaults = window.remotion_renderDefaults;
|
|
if (!defaults) {
|
|
throw new TypeError('Expected defaults');
|
|
}
|
|
setSelectedModal({
|
|
type: 'server-render',
|
|
compositionId: video.id,
|
|
initialFrame: getCurrentFrame(),
|
|
initialStillImageFormat: defaults.stillImageFormat,
|
|
initialVideoImageFormat: null,
|
|
initialJpegQuality: defaults.jpegQuality,
|
|
initialScale: (_b = (_a = window.remotion_renderDefaults) === null || _a === void 0 ? void 0 : _a.scale) !== null && _b !== void 0 ? _b : 1,
|
|
initialLogLevel: defaults.logLevel,
|
|
initialConcurrency: defaults.concurrency,
|
|
maxConcurrency: defaults.maxConcurrency,
|
|
minConcurrency: defaults.minConcurrency,
|
|
initialMuted: defaults.muted,
|
|
initialEnforceAudioTrack: defaults.enforceAudioTrack,
|
|
initialProResProfile: defaults.proResProfile,
|
|
initialx264Preset: defaults.x264Preset,
|
|
initialPixelFormat: null,
|
|
initialAudioBitrate: defaults.audioBitrate,
|
|
initialVideoBitrate: defaults.videoBitrate,
|
|
initialEveryNthFrame: defaults.everyNthFrame,
|
|
initialNumberOfGifLoops: defaults.numberOfGifLoops,
|
|
initialDelayRenderTimeout: defaults.delayRenderTimeout,
|
|
defaultConfigurationAudioCodec: defaults.audioCodec,
|
|
initialEnvVariables: window.process.env,
|
|
initialDisableWebSecurity: defaults.disableWebSecurity,
|
|
initialDarkMode: defaults.darkMode,
|
|
initialOpenGlRenderer: defaults.openGlRenderer,
|
|
initialHeadless: defaults.headless,
|
|
initialIgnoreCertificateErrors: defaults.ignoreCertificateErrors,
|
|
initialOffthreadVideoCacheSizeInBytes: defaults.offthreadVideoCacheSizeInBytes,
|
|
initialOffthreadVideoThreads: defaults.offthreadVideoThreads,
|
|
defaultProps: (_c = props[video.id]) !== null && _c !== void 0 ? _c : video.defaultProps,
|
|
inFrameMark: inFrame,
|
|
outFrameMark: outFrame,
|
|
initialColorSpace: defaults.colorSpace,
|
|
initialMultiProcessOnLinux: defaults.multiProcessOnLinux,
|
|
defaultConfigurationVideoCodec: defaults.codec,
|
|
initialEncodingBufferSize: defaults.encodingBufferSize,
|
|
initialEncodingMaxRate: defaults.encodingMaxRate,
|
|
initialUserAgent: defaults.userAgent,
|
|
initialBeep: defaults.beepOnFinish,
|
|
initialRepro: defaults.repro,
|
|
initialForSeamlessAacConcatenation: defaults.forSeamlessAacConcatenation,
|
|
renderTypeOfLastRender: null,
|
|
defaulMetadata: defaults.metadata,
|
|
initialHardwareAcceleration: defaults.hardwareAcceleration,
|
|
initialChromeMode: defaults.chromeMode,
|
|
initialMediaCacheSizeInBytes: defaults.mediaCacheSizeInBytes,
|
|
renderDefaults: defaults,
|
|
});
|
|
}, [video, setSelectedModal, getCurrentFrame, props, inFrame, outFrame]);
|
|
const openClientRenderModal = (0, react_1.useCallback)(() => {
|
|
var _a;
|
|
if (!video) {
|
|
return null;
|
|
}
|
|
const defaults = window.remotion_renderDefaults;
|
|
if (!defaults) {
|
|
throw new TypeError('Expected defaults');
|
|
}
|
|
setSelectedModal({
|
|
type: 'web-render',
|
|
compositionId: video.id,
|
|
initialFrame: getCurrentFrame(),
|
|
defaultProps: (_a = props[video.id]) !== null && _a !== void 0 ? _a : video.defaultProps,
|
|
inFrameMark: inFrame,
|
|
outFrameMark: outFrame,
|
|
initialLogLevel: defaults.logLevel,
|
|
initialLicenseKey: defaults.publicLicenseKey,
|
|
initialStillImageFormat: defaults.stillImageFormat,
|
|
initialScale: defaults.scale,
|
|
initialDelayRenderTimeout: defaults.delayRenderTimeout,
|
|
initialDefaultOutName: null,
|
|
initialContainer: null,
|
|
initialVideoCodec: null,
|
|
initialAudioCodec: null,
|
|
initialAudioBitrate: null,
|
|
initialVideoBitrate: null,
|
|
initialHardwareAcceleration: null,
|
|
initialKeyframeIntervalInSeconds: null,
|
|
initialTransparent: null,
|
|
initialMuted: null,
|
|
initialMediaCacheSizeInBytes: defaults.mediaCacheSizeInBytes,
|
|
});
|
|
}, [video, setSelectedModal, getCurrentFrame, props, inFrame, outFrame]);
|
|
const onClick = (0, react_1.useCallback)(() => {
|
|
if (!show_browser_rendering_1.SHOW_BROWSER_RENDERING || renderType === 'server-render') {
|
|
openServerRenderModal();
|
|
}
|
|
else {
|
|
openClientRenderModal();
|
|
}
|
|
}, [renderType, openServerRenderModal, openClientRenderModal]);
|
|
const onHideDropdown = (0, react_1.useCallback)(() => {
|
|
setDropdownOpened(false);
|
|
}, []);
|
|
const handleRenderTypeChange = (0, react_1.useCallback)((newType) => {
|
|
setRenderType(newType);
|
|
try {
|
|
localStorage.setItem(RENDER_TYPE_STORAGE_KEY, newType);
|
|
}
|
|
catch (_a) {
|
|
// localStorage might not be available
|
|
}
|
|
setDropdownOpened(false);
|
|
if (newType === 'server-render') {
|
|
openServerRenderModal();
|
|
}
|
|
else {
|
|
openClientRenderModal();
|
|
}
|
|
}, [openServerRenderModal, openClientRenderModal]);
|
|
const dropdownValues = (0, react_1.useMemo)(() => {
|
|
return [
|
|
{
|
|
type: 'item',
|
|
id: 'server-render',
|
|
label: 'Server-side render',
|
|
value: 'server-render',
|
|
onClick: () => handleRenderTypeChange('server-render'),
|
|
keyHint: null,
|
|
leftItem: null,
|
|
subMenu: null,
|
|
quickSwitcherLabel: null,
|
|
},
|
|
{
|
|
type: 'item',
|
|
id: 'client-render',
|
|
label: 'Client-side render',
|
|
value: 'client-render',
|
|
onClick: () => handleRenderTypeChange('client-render'),
|
|
keyHint: null,
|
|
leftItem: null,
|
|
subMenu: null,
|
|
quickSwitcherLabel: null,
|
|
},
|
|
];
|
|
}, [handleRenderTypeChange]);
|
|
const spaceToBottom = (0, react_1.useMemo)(() => {
|
|
const margin = 10;
|
|
if (size && dropdownOpened) {
|
|
return size.windowSize.height - (size.top + size.height) - margin;
|
|
}
|
|
return 0;
|
|
}, [dropdownOpened, size]);
|
|
const spaceToTop = (0, react_1.useMemo)(() => {
|
|
const margin = 10;
|
|
if (size && dropdownOpened) {
|
|
return size.top - margin;
|
|
}
|
|
return 0;
|
|
}, [dropdownOpened, size]);
|
|
const derivedMaxHeight = (0, react_1.useMemo)(() => {
|
|
return spaceToTop > spaceToBottom ? spaceToTop : spaceToBottom;
|
|
}, [spaceToBottom, spaceToTop]);
|
|
const portalStyle = (0, react_1.useMemo)(() => {
|
|
if (!dropdownOpened || !size) {
|
|
return null;
|
|
}
|
|
const verticalLayout = spaceToTop > spaceToBottom ? 'bottom' : 'top';
|
|
return {
|
|
...(verticalLayout === 'top'
|
|
? {
|
|
...styles_1.menuContainerTowardsBottom,
|
|
top: size.top + size.height,
|
|
}
|
|
: {
|
|
...styles_1.menuContainerTowardsTop,
|
|
bottom: size.windowSize.height - size.top,
|
|
}),
|
|
right: size.windowSize.width - size.left - size.width,
|
|
};
|
|
}, [dropdownOpened, size, spaceToBottom, spaceToTop]);
|
|
const containerStyle = (0, react_1.useMemo)(() => {
|
|
return {
|
|
...splitButtonContainer,
|
|
borderColor: colors_1.INPUT_BORDER_COLOR_UNHOVERED,
|
|
opacity: connectionStatus !== 'connected' ? 0.7 : 1,
|
|
cursor: connectionStatus !== 'connected' ? 'inherit' : 'pointer',
|
|
};
|
|
}, [connectionStatus]);
|
|
const renderLabel = renderType === 'server-render' ? 'Render' : 'Render on web';
|
|
const shouldShowDropdown = (0, react_1.useMemo)(() => {
|
|
// Server render is not available
|
|
if (readOnlyStudio) {
|
|
return false;
|
|
}
|
|
// client render is not available
|
|
if (!show_browser_rendering_1.SHOW_BROWSER_RENDERING) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}, [readOnlyStudio]);
|
|
if (!video) {
|
|
return null;
|
|
}
|
|
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("button", { style: { display: 'none' }, id: "render-modal-button-server", disabled: connectionStatus !== 'connected' && renderType === 'server-render', onClick: openServerRenderModal, type: "button" }), ' ', (0, jsx_runtime_1.jsx)("button", { style: { display: 'none' }, id: "render-modal-button-client", onClick: openClientRenderModal, type: "button" }), (0, jsx_runtime_1.jsxs)("div", { ref: containerRef, style: containerStyle, title: tooltip, children: [(0, jsx_runtime_1.jsx)("button", { type: "button", style: mainButtonStyle, onClick: onClick, id: "render-modal-button", disabled: connectionStatus !== 'connected' && renderType === 'server-render', children: (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", style: mainButtonContent, children: [(0, jsx_runtime_1.jsx)(render_1.ThinRenderIcon, { fill: "currentcolor", svgProps: iconStyle }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, jsx_runtime_1.jsx)("span", { style: label, children: renderLabel })] }) }), shouldShowDropdown ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { style: dividerStyle }), (0, jsx_runtime_1.jsx)("button", { ref: dropdownRef, type: "button", style: dropdownTriggerStyle, disabled: connectionStatus !== 'connected', className: is_menu_item_1.MENU_INITIATOR_CLASSNAME, onPointerDown: onPointerDown, onClick: onClickDropdown, children: (0, jsx_runtime_1.jsx)(caret_1.CaretDown, {}) })] })) : null] }), 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: onHideDropdown, onEscape: onHideDropdown, children: (0, jsx_runtime_1.jsx)("div", { style: portalStyle, children: (0, jsx_runtime_1.jsx)(MenuContent_1.MenuContent, { onNextMenu: () => { }, onPreviousMenu: () => { }, values: dropdownValues, onHide: onHideDropdown, leaveLeftSpace: false, preselectIndex: dropdownValues.findIndex((v) => v.id === renderType), topItemCanBeUnselected: false, fixedHeight: derivedMaxHeight }) }) }) }) }), (0, portals_1.getPortal)(currentZIndex))
|
|
: null] }));
|
|
};
|
|
exports.RenderButton = RenderButton;
|