UNPKG

@remotion/studio

Version:

APIs for interacting with the Remotion Studio

159 lines (158 loc) 8.02 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TimelineListItem = exports.SPACING = void 0; const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const remotion_1 = require("remotion"); const client_id_1 = require("../../helpers/client-id"); const colors_1 = require("../../helpers/colors"); const timeline_layout_1 = require("../../helpers/timeline-layout"); const call_api_1 = require("../call-api"); const ContextMenu_1 = require("../ContextMenu"); const ExpandedTracksProvider_1 = require("../ExpandedTracksProvider"); const NotificationCenter_1 = require("../Notifications/NotificationCenter"); const TimelineExpandedSection_1 = require("./TimelineExpandedSection"); const TimelineLayerEye_1 = require("./TimelineLayerEye"); const TimelineStack_1 = require("./TimelineStack"); const use_resolved_stack_1 = require("./use-resolved-stack"); const use_sequence_props_subscription_1 = require("./use-sequence-props-subscription"); exports.SPACING = 5; const space = { width: exports.SPACING, flexShrink: 0, }; const arrowButton = { background: 'none', border: 'none', color: 'white', cursor: 'pointer', padding: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', width: 12, height: 12, flexShrink: 0, fontSize: 8, marginRight: 4, userSelect: 'none', outline: 'none', lineHeight: 1, }; const TimelineListItem = ({ nestedDepth, sequence, isCompact }) => { var _a, _b; const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx); const visualModeEnvEnabled = Boolean(process.env.EXPERIMENTAL_VISUAL_MODE_ENABLED); const previewConnected = previewServerState.type === 'connected'; const visualModeActive = visualModeEnvEnabled && previewConnected; const { hidden, setHidden } = (0, react_1.useContext)(remotion_1.Internals.SequenceVisibilityToggleContext); const { expandedTracks, toggleTrack } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksContext); const originalLocation = (0, use_resolved_stack_1.useResolvedStack)((_a = sequence.stack) !== null && _a !== void 0 ? _a : null); const nodePath = (0, use_sequence_props_subscription_1.useSequencePropsSubscription)(sequence, originalLocation, visualModeActive); const validatedLocation = (0, react_1.useMemo)(() => { var _a; if (!originalLocation || !originalLocation.source || !originalLocation.line) { return null; } return { source: originalLocation.source, line: originalLocation.line, column: (_a = originalLocation.column) !== null && _a !== void 0 ? _a : 0, }; }, [originalLocation]); const canDeleteFromSource = Boolean(nodePath && (validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source)); const deleteDisabled = (0, react_1.useMemo)(() => !previewConnected || !sequence.controls || !canDeleteFromSource, [previewConnected, sequence.controls, canDeleteFromSource]); const onDeleteSequenceFromSource = (0, react_1.useCallback)(async () => { if (!(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source) || !nodePath) { return; } try { const result = await (0, call_api_1.callApi)('/api/delete-jsx-node', { fileName: validatedLocation.source, nodePath, }); if (result.success) { (0, NotificationCenter_1.showNotification)('Removed sequence from source file', 2000); } else { (0, NotificationCenter_1.showNotification)(result.reason, 4000); } } catch (err) { (0, NotificationCenter_1.showNotification)(err.message, 4000); } }, [nodePath, validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source]); const contextMenuValues = (0, react_1.useMemo)(() => { if (!visualModeEnvEnabled) { return []; } return [ { type: 'item', id: 'delete-sequence', keyHint: null, label: 'Delete', leftItem: null, disabled: deleteDisabled, onClick: () => { if (deleteDisabled) { return; } onDeleteSequenceFromSource(); }, quickSwitcherLabel: null, subMenu: null, value: 'delete-sequence', }, ]; }, [deleteDisabled, onDeleteSequenceFromSource, visualModeEnvEnabled]); const isExpanded = visualModeActive && ((_b = expandedTracks[sequence.id]) !== null && _b !== void 0 ? _b : false); const onToggleExpand = (0, react_1.useCallback)(() => { toggleTrack(sequence.id); }, [sequence.id, toggleTrack]); const padder = (0, react_1.useMemo)(() => { return { width: Number(exports.SPACING * 3) * nestedDepth, flexShrink: 0, }; }, [nestedDepth]); const isItemHidden = (0, react_1.useMemo)(() => { var _a; return (_a = hidden[sequence.id]) !== null && _a !== void 0 ? _a : false; }, [hidden, sequence.id]); const onToggleVisibility = (0, react_1.useCallback)((type) => { setHidden((prev) => { return { ...prev, [sequence.id]: type !== 'enable', }; }); }, [sequence.id, setHidden]); const outer = (0, react_1.useMemo)(() => { return { height: (0, timeline_layout_1.getTimelineLayerHeight)(sequence.type) + timeline_layout_1.TIMELINE_ITEM_BORDER_BOTTOM, color: 'white', fontFamily: 'Arial, Helvetica, sans-serif', display: 'flex', flexDirection: 'row', alignItems: 'center', wordBreak: 'break-all', textAlign: 'left', paddingLeft: exports.SPACING, borderBottom: `1px solid ${colors_1.TIMELINE_TRACK_SEPARATOR}`, }; }, [sequence.type]); const arrowStyle = (0, react_1.useMemo)(() => { return { ...arrowButton, transform: isExpanded ? 'rotate(90deg)' : 'rotate(0deg)', }; }, [isExpanded]); const trackRow = (jsx_runtime_1.jsxs("div", { style: outer, children: [ jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: sequence.type === 'audio' ? 'speaker' : 'eye', hidden: isItemHidden, onInvoked: onToggleVisibility }), jsx_runtime_1.jsx("div", { style: padder }), sequence.parent && nestedDepth > 0 ? jsx_runtime_1.jsx("div", { style: space }) : null, visualModeActive ? (sequence.controls ? (jsx_runtime_1.jsx("button", { type: "button", style: arrowStyle, onClick: onToggleExpand, "aria-expanded": isExpanded, "aria-label": `${isExpanded ? 'Collapse' : 'Expand'} track`, children: jsx_runtime_1.jsx("svg", { width: "12", height: "12", viewBox: "0 0 8 8", style: { display: 'block' }, children: jsx_runtime_1.jsx("path", { d: "M2 1L6 4L2 7Z", fill: "white" }) }) })) : (jsx_runtime_1.jsx("div", { style: arrowButton }))) : null, jsx_runtime_1.jsx(TimelineStack_1.TimelineStack, { sequence: sequence, isCompact: isCompact, originalLocation: originalLocation }) ] })); return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [visualModeEnvEnabled ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, children: trackRow })) : (trackRow), visualModeActive && isExpanded && sequence.controls ? (jsx_runtime_1.jsx(TimelineExpandedSection_1.TimelineExpandedSection, { sequence: sequence, originalLocation: originalLocation, nestedDepth: nestedDepth, nodePath: nodePath })) : null] })); }; exports.TimelineListItem = TimelineListItem;