UNPKG

@remotion/studio

Version:

APIs for interacting with the Remotion Studio

170 lines (169 loc) 6.88 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useSequencePropsSubscription = void 0; const react_1 = require("react"); const remotion_1 = require("remotion"); const client_id_1 = require("../../helpers/client-id"); const timeline_layout_1 = require("../../helpers/timeline-layout"); const call_api_1 = require("../call-api"); const useSequencePropsSubscription = (sequence, originalLocation, visualModeEnabled) => { var _a; var _b, _c, _d, _e; const { setCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeOverridesContext); const overrideId = (_b = (_a = sequence.controls) === null || _a === void 0 ? void 0 : _a.overrideId) !== null && _b !== void 0 ? _b : null; const setPropStatusesForSequence = (0, react_1.useCallback)((statuses) => { if (!overrideId) { return; } setCodeValues(overrideId, statuses); }, [overrideId, setCodeValues]); const { previewServerState: state, subscribeToEvent } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx); const clientId = state.type === 'connected' ? state.clientId : undefined; const schemaFields = (0, react_1.useMemo)(() => (0, timeline_layout_1.getSchemaFields)(sequence.controls), [sequence.controls]); const schemaKeysString = (0, react_1.useMemo)(() => (schemaFields ? schemaFields.map((f) => f.key).join(',') : null), [schemaFields]); 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 locationSource = (_c = validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source) !== null && _c !== void 0 ? _c : null; const locationLine = (_d = validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.line) !== null && _d !== void 0 ? _d : null; const locationColumn = (_e = validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.column) !== null && _e !== void 0 ? _e : null; const currentLocationSource = (0, react_1.useRef)(locationSource); currentLocationSource.current = locationSource; const currentLocationLine = (0, react_1.useRef)(locationLine); currentLocationLine.current = locationLine; const currentLocationColumn = (0, react_1.useRef)(locationColumn); currentLocationColumn.current = locationColumn; const nodePathRef = (0, react_1.useRef)(null); const [nodePath, setNodePath] = (0, react_1.useState)(null); const isMountedRef = (0, react_1.useRef)(true); const setNodePathBoth = (0, react_1.useCallback)((next) => { nodePathRef.current = next; setNodePath(next); }, []); (0, react_1.useEffect)(() => { isMountedRef.current = true; return () => { isMountedRef.current = false; }; }, []); (0, react_1.useEffect)(() => { if (!visualModeEnabled) { setPropStatusesForSequence(null); setNodePathBoth(null); return; } if (!clientId || !locationSource || !locationLine || locationColumn === null || !schemaKeysString) { setPropStatusesForSequence(null); setNodePathBoth(null); return; } const keys = schemaKeysString.split(','); (0, call_api_1.callApi)('/api/subscribe-to-sequence-props', { fileName: locationSource, line: locationLine, column: locationColumn, keys, clientId, }) .then((result) => { if (currentLocationSource.current !== locationSource || currentLocationLine.current !== locationLine || currentLocationColumn.current !== locationColumn) { return; } if (result.canUpdate) { setNodePathBoth(result.nodePath); setPropStatusesForSequence(result.props); } else { setNodePathBoth(null); setPropStatusesForSequence(null); } }) .catch((err) => { setNodePathBoth(null); remotion_1.Internals.Log.error(err); setPropStatusesForSequence(null); }); return () => { const currentNodePath = nodePathRef.current; // Only clear props on true unmount, not on re-subscribe due to // line number changes — avoids flicker while re-subscribing. if (!isMountedRef.current) { setPropStatusesForSequence(null); } setNodePathBoth(null); if (currentNodePath) { (0, call_api_1.callApi)('/api/unsubscribe-from-sequence-props', { fileName: locationSource, nodePath: currentNodePath, clientId, }).catch(() => { // Ignore unsubscribe errors }); } }; }, [ visualModeEnabled, clientId, locationSource, locationLine, locationColumn, schemaKeysString, setPropStatusesForSequence, setNodePathBoth, ]); (0, react_1.useEffect)(() => { if (!visualModeEnabled) { return; } if (!locationSource || !locationLine || locationColumn === null) { return; } const listener = (event) => { if (event.type !== 'sequence-props-updated') { return; } if (event.fileName !== currentLocationSource.current || !nodePathRef.current || JSON.stringify(event.nodePath) !== JSON.stringify(nodePathRef.current)) { return; } if (event.result.canUpdate) { setPropStatusesForSequence(event.result.props); } else { setPropStatusesForSequence(null); setNodePathBoth(null); } }; const unsub = subscribeToEvent('sequence-props-updated', listener); return () => { unsub(); }; }, [ visualModeEnabled, locationSource, locationLine, locationColumn, subscribeToEvent, setPropStatusesForSequence, setNodePathBoth, ]); return nodePath; }; exports.useSequencePropsSubscription = useSequencePropsSubscription;