@remotion/studio
Version:
APIs for interacting with the Remotion Studio
177 lines (176 loc) • 7.77 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TimelineStack = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const studio_shared_1 = require("@remotion/studio-shared");
const react_1 = require("react");
const source_map_1 = require("source-map");
const client_id_1 = require("../../../helpers/client-id");
const colors_1 = require("../../../helpers/colors");
const get_git_menu_item_1 = require("../../../helpers/get-git-menu-item");
const open_in_editor_1 = require("../../../helpers/open-in-editor");
const url_state_1 = require("../../../helpers/url-state");
const InitialCompositionLoader_1 = require("../../InitialCompositionLoader");
const NotificationCenter_1 = require("../../Notifications/NotificationCenter");
const Spinner_1 = require("../../Spinner");
const layout_1 = require("../../layout");
const get_stack_1 = require("./get-stack");
const source_attribution_1 = require("./source-attribution");
const publicPath = window.remotion_publicPath === '/' ? '' : window.remotion_publicPath;
const withoutSlashInTheEnd = publicPath.endsWith('/')
? publicPath.slice(0, -1)
: publicPath;
// @ts-expect-error
source_map_1.SourceMapConsumer.initialize({
'lib/mappings.wasm': withoutSlashInTheEnd + studio_shared_1.SOURCE_MAP_ENDPOINT,
});
const TimelineStack = ({ isCompact, sequence }) => {
const [originalLocation, setOriginalLocation] = (0, react_1.useState)(null);
const [stackHovered, setStackHovered] = (0, react_1.useState)(false);
const [titleHovered, setTitleHovered] = (0, react_1.useState)(false);
const [opening, setOpening] = (0, react_1.useState)(false);
const selectAsset = (0, InitialCompositionLoader_1.useSelectAsset)();
const connectionStatus = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx)
.previewServerState.type;
const assetPath = (0, react_1.useMemo)(() => {
if (sequence.type !== 'video' && sequence.type !== 'audio') {
return null;
}
const isStatic = sequence.src.startsWith(window.remotion_staticBase);
if (!isStatic) {
return null;
}
const relativePath = sequence.src.replace(window.remotion_staticBase + '/', '');
return relativePath;
}, [sequence]);
const navigateToAsset = (0, react_1.useCallback)((asset) => {
selectAsset(asset);
(0, url_state_1.pushUrl)(`/assets/${asset}`);
}, [selectAsset]);
const openEditor = (0, react_1.useCallback)(async (location) => {
if (!window.remotion_editorName) {
return;
}
setOpening(true);
try {
await (0, open_in_editor_1.openOriginalPositionInEditor)(location);
}
catch (err) {
(0, NotificationCenter_1.showNotification)(err.message, 2000);
}
finally {
setOpening(false);
}
}, []);
const canOpenInEditor = window.remotion_editorName &&
connectionStatus === 'connected' &&
originalLocation;
const canOpenInGitHub = window.remotion_gitSource && originalLocation;
const titleHoverable = (isCompact && (canOpenInEditor || canOpenInGitHub)) || assetPath;
const stackHoverable = !isCompact && (canOpenInEditor || canOpenInGitHub);
const onClickTitle = (0, react_1.useCallback)(() => {
if (!titleHoverable) {
return null;
}
if (assetPath) {
navigateToAsset(assetPath);
return;
}
if (!originalLocation) {
return;
}
if (canOpenInEditor) {
openEditor(originalLocation);
return;
}
if (canOpenInGitHub) {
window.open((0, get_git_menu_item_1.getGitRefUrl)(window.remotion_gitSource, originalLocation), '_blank');
}
}, [
assetPath,
canOpenInEditor,
canOpenInGitHub,
navigateToAsset,
openEditor,
originalLocation,
titleHoverable,
]);
const onClickStack = (0, react_1.useCallback)(() => {
if (!originalLocation) {
return;
}
if (canOpenInEditor) {
openEditor(originalLocation);
return;
}
if (canOpenInGitHub) {
window.open((0, get_git_menu_item_1.getGitRefUrl)(window.remotion_gitSource, originalLocation), '_blank');
}
}, [canOpenInEditor, canOpenInGitHub, openEditor, originalLocation]);
(0, react_1.useEffect)(() => {
if (!sequence.stack) {
return;
}
(0, get_stack_1.getOriginalLocationFromStack)(sequence.stack, 'sequence')
.then((frame) => {
setOriginalLocation(frame);
})
.catch((err) => {
// eslint-disable-next-line no-console
console.error('Could not get original location of Sequence', err);
});
}, [sequence.stack]);
const onStackPointerEnter = (0, react_1.useCallback)(() => {
setStackHovered(true);
}, []);
const onStackPointerLeave = (0, react_1.useCallback)(() => {
setStackHovered(false);
}, []);
const onTitlePointerEnter = (0, react_1.useCallback)(() => {
setTitleHovered(true);
}, []);
const onTitlePointerLeave = (0, react_1.useCallback)(() => {
setTitleHovered(false);
}, []);
const style = (0, react_1.useMemo)(() => {
return {
fontSize: 12,
color: opening
? colors_1.VERY_LIGHT_TEXT
: stackHovered && stackHoverable
? colors_1.LIGHT_TEXT
: colors_1.VERY_LIGHT_TEXT,
marginLeft: 10,
cursor: stackHoverable ? 'pointer' : undefined,
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
overflow: 'hidden',
flexShrink: 100000,
};
}, [opening, stackHovered, stackHoverable]);
const titleStyle = (0, react_1.useMemo)(() => {
const hoverEffect = titleHovered && titleHoverable;
return {
fontSize: 12,
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
overflow: 'hidden',
lineHeight: 1,
color: opening && isCompact ? colors_1.VERY_LIGHT_TEXT : colors_1.LIGHT_COLOR,
userSelect: 'none',
WebkitUserSelect: 'none',
borderBottom: hoverEffect ? '1px solid #fff' : 'none',
cursor: hoverEffect ? 'pointer' : undefined,
};
}, [titleHoverable, isCompact, opening, titleHovered]);
const text = sequence.displayName.length > 1000
? sequence.displayName.slice(0, 1000) + '...'
: sequence.displayName;
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { onPointerEnter: onTitlePointerEnter, onPointerLeave: onTitlePointerLeave, title: originalLocation
? (0, source_attribution_1.getOriginalSourceAttribution)(originalLocation)
: text || '<Sequence>', style: titleStyle, onClick: onClickTitle, children: text || '<Sequence>' }), isCompact || !originalLocation ? null : ((0, jsx_runtime_1.jsx)("div", { onPointerEnter: onStackPointerEnter, onPointerLeave: onStackPointerLeave, onClick: onClickStack, style: style, children: (0, source_attribution_1.getOriginalSourceAttribution)(originalLocation) })), opening ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.5 }), (0, jsx_runtime_1.jsx)(Spinner_1.Spinner, { duration: 0.5, size: 12 })] })) : null] }));
};
exports.TimelineStack = TimelineStack;