@remotion/studio 4.0.487 → 4.0.488

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,6 +19,8 @@ const use_keybinding_1 = require("../helpers/use-keybinding");
19
19
  const canvas_ref_1 = require("../state/canvas-ref");
20
20
  const editor_guides_1 = require("../state/editor-guides");
21
21
  const editor_zoom_gestures_1 = require("../state/editor-zoom-gestures");
22
+ const call_api_1 = require("./call-api");
23
+ const ConfirmationDialog_1 = require("./ConfirmationDialog");
22
24
  const EditorGuides_1 = __importDefault(require("./EditorGuides"));
23
25
  const EditorRuler_1 = require("./EditorRuler");
24
26
  const use_is_ruler_visible_1 = require("./EditorRuler/use-is-ruler-visible");
@@ -29,6 +31,31 @@ const layout_1 = require("./layout");
29
31
  const Preview_1 = require("./Preview");
30
32
  const ResetZoomButton_1 = require("./ResetZoomButton");
31
33
  const use_resolved_stack_1 = require("./Timeline/use-resolved-stack");
34
+ const elementInstallCompositionIdStyle = {
35
+ fontFamily: 'monospace',
36
+ fontSize: 13,
37
+ };
38
+ const elementInstallCodeDetailsStyle = {
39
+ marginTop: 12,
40
+ fontSize: 13,
41
+ };
42
+ const elementInstallCodeSummaryStyle = {
43
+ cursor: 'pointer',
44
+ fontSize: 13,
45
+ fontWeight: 500,
46
+ };
47
+ const elementInstallCodeBlockStyle = {
48
+ marginTop: 8,
49
+ marginBottom: 0,
50
+ maxHeight: 240,
51
+ overflow: 'auto',
52
+ padding: 12,
53
+ borderRadius: 6,
54
+ backgroundColor: 'rgba(255, 255, 255, 0.06)',
55
+ fontSize: 12,
56
+ lineHeight: 1.5,
57
+ whiteSpace: 'pre',
58
+ };
32
59
  const getContainerStyle = (editorZoomGestures) => ({
33
60
  flex: 1,
34
61
  display: 'flex',
@@ -183,12 +210,20 @@ const Canvas = ({ canvasContent, size }) => {
183
210
  const suppressWheelFromWebKitPinchRef = (0, react_1.useRef)(false);
184
211
  const touchPinchRef = (0, react_1.useRef)(null);
185
212
  const keybindings = (0, use_keybinding_1.useKeybinding)();
213
+ const confirm = (0, ConfirmationDialog_1.useConfirmationDialog)();
186
214
  const config = remotion_1.Internals.useUnsafeVideoConfig();
187
215
  const areRulersVisible = (0, use_is_ruler_visible_1.useIsRulerVisible)();
188
216
  const { editorShowGuides } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
189
217
  const { compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
190
- const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
218
+ const { previewServerState, subscribeToEvent } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
219
+ const previewServerClientId = previewServerState.type === 'connected'
220
+ ? previewServerState.clientId
221
+ : null;
191
222
  const [isAddingAsset, setIsAddingAsset] = (0, react_1.useState)(false);
223
+ const [installingElementName, setInstallingElementName] = (0, react_1.useState)(null);
224
+ const [pendingElementInstallRequests, setPendingElementInstallRequests] = (0, react_1.useState)([]);
225
+ const [activeElementInstallRequest, setActiveElementInstallRequest] = (0, react_1.useState)(null);
226
+ const lastFocusedAtRef = (0, react_1.useRef)(typeof document === 'undefined' || document.hasFocus() ? Date.now() : null);
192
227
  const [assetResolution, setAssetResolution] = (0, react_1.useState)(null);
193
228
  const currentCompositionId = canvasContent.type === 'composition' ? canvasContent.compositionId : null;
194
229
  const currentComposition = (0, react_1.useMemo)(() => {
@@ -204,12 +239,12 @@ const Canvas = ({ canvasContent, size }) => {
204
239
  compositionFile,
205
240
  compositionId: currentCompositionId,
206
241
  });
207
- const canDropAssets = previewServerState.type === 'connected' &&
242
+ const canInstallElements = previewServerClientId !== null &&
208
243
  !window.remotion_isReadOnlyStudio &&
209
244
  (compositionComponentInfo === null || compositionComponentInfo === void 0 ? void 0 : compositionComponentInfo.canAddSequence) === true &&
210
245
  currentCompositionId !== null &&
211
- compositionFile !== null &&
212
- !isAddingAsset;
246
+ compositionFile !== null;
247
+ const canDropAssets = canInstallElements && !isAddingAsset;
213
248
  const contentDimensions = (0, react_1.useMemo)(() => {
214
249
  if ((canvasContent.type === 'asset' ||
215
250
  canvasContent.type === 'output' ||
@@ -576,6 +611,123 @@ const Canvas = ({ canvasContent, size }) => {
576
611
  (0, react_1.useEffect)(() => {
577
612
  fetchMetadata();
578
613
  }, [fetchMetadata]);
614
+ const updateElementInstallTarget = (0, react_1.useCallback)(() => {
615
+ if (previewServerClientId === null) {
616
+ return;
617
+ }
618
+ (0, call_api_1.callApi)('/api/update-element-install-target', {
619
+ clientId: previewServerClientId,
620
+ compositionFile: canInstallElements ? compositionFile : null,
621
+ compositionId: canInstallElements ? currentCompositionId : null,
622
+ canInstall: canInstallElements,
623
+ lastFocusedAt: lastFocusedAtRef.current,
624
+ readOnly: window.remotion_isReadOnlyStudio,
625
+ }).catch(() => undefined);
626
+ }, [
627
+ canInstallElements,
628
+ compositionFile,
629
+ currentCompositionId,
630
+ previewServerClientId,
631
+ ]);
632
+ (0, react_1.useEffect)(() => {
633
+ updateElementInstallTarget();
634
+ const interval = window.setInterval(updateElementInstallTarget, 2000);
635
+ return () => {
636
+ window.clearInterval(interval);
637
+ };
638
+ }, [updateElementInstallTarget]);
639
+ (0, react_1.useEffect)(() => {
640
+ const markFocused = () => {
641
+ lastFocusedAtRef.current = Date.now();
642
+ updateElementInstallTarget();
643
+ };
644
+ window.addEventListener('focus', markFocused);
645
+ document.addEventListener('pointerdown', markFocused, { capture: true });
646
+ return () => {
647
+ window.removeEventListener('focus', markFocused);
648
+ document.removeEventListener('pointerdown', markFocused, { capture: true });
649
+ };
650
+ }, [updateElementInstallTarget]);
651
+ (0, react_1.useEffect)(() => {
652
+ if (installingElementName === null) {
653
+ return;
654
+ }
655
+ const previousTitle = document.title;
656
+ document.title = `📦 Install ${installingElementName} - Remotion Studio`;
657
+ return () => {
658
+ document.title = previousTitle;
659
+ };
660
+ }, [installingElementName]);
661
+ (0, react_1.useEffect)(() => {
662
+ if (previewServerClientId === null) {
663
+ return;
664
+ }
665
+ return subscribeToEvent('element-install-request', (event) => {
666
+ if (event.type !== 'element-install-request' ||
667
+ event.request.clientId !== previewServerClientId) {
668
+ return;
669
+ }
670
+ setPendingElementInstallRequests((requests) => [
671
+ ...requests,
672
+ event.request,
673
+ ]);
674
+ });
675
+ }, [previewServerClientId, subscribeToEvent]);
676
+ (0, react_1.useEffect)(() => {
677
+ if (activeElementInstallRequest !== null ||
678
+ pendingElementInstallRequests.length === 0) {
679
+ return;
680
+ }
681
+ const [nextRequest, ...remainingRequests] = pendingElementInstallRequests;
682
+ if (!nextRequest) {
683
+ throw new Error('Expected pending Element install request');
684
+ }
685
+ setActiveElementInstallRequest(nextRequest);
686
+ setPendingElementInstallRequests(remainingRequests);
687
+ }, [activeElementInstallRequest, pendingElementInstallRequests]);
688
+ (0, react_1.useEffect)(() => {
689
+ if (activeElementInstallRequest === null) {
690
+ return;
691
+ }
692
+ let canceled = false;
693
+ const handleInstallRequest = async () => {
694
+ setInstallingElementName(activeElementInstallRequest.element.displayName);
695
+ const accepted = await confirm({
696
+ title: 'Install Element',
697
+ message: (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: ["Install \u201C", activeElementInstallRequest.element.displayName, "\u201D into", ' ', jsx_runtime_1.jsx("code", { style: elementInstallCompositionIdStyle, children: activeElementInstallRequest.compositionId }), ' ', "composition? This will create an Element source file and update the composition source.",
698
+ jsx_runtime_1.jsxs("details", { style: elementInstallCodeDetailsStyle, children: [
699
+ jsx_runtime_1.jsx("summary", { style: elementInstallCodeSummaryStyle, children: "Preview Element source" }), jsx_runtime_1.jsx("pre", { style: elementInstallCodeBlockStyle, children: jsx_runtime_1.jsx("code", { children: activeElementInstallRequest.element.sourceCode }) })
700
+ ] })
701
+ ] })),
702
+ confirmLabel: 'Install',
703
+ cancelLabel: 'Cancel',
704
+ });
705
+ if (accepted && !canceled) {
706
+ await (0, import_assets_1.insertElement)({
707
+ element: activeElementInstallRequest.element,
708
+ compositionFile: activeElementInstallRequest.compositionFile,
709
+ compositionId: activeElementInstallRequest.compositionId,
710
+ dropPosition: null,
711
+ });
712
+ }
713
+ };
714
+ handleInstallRequest()
715
+ .finally(() => {
716
+ if (canceled) {
717
+ return;
718
+ }
719
+ setInstallingElementName(null);
720
+ setActiveElementInstallRequest(null);
721
+ })
722
+ .catch((err) => {
723
+ setTimeout(() => {
724
+ throw err;
725
+ }, 0);
726
+ });
727
+ return () => {
728
+ canceled = true;
729
+ };
730
+ }, [activeElementInstallRequest, confirm]);
579
731
  const onDragOver = (0, react_1.useCallback)((event) => {
580
732
  if (!canDropAssets ||
581
733
  (!isFileDragEvent(event) &&
@@ -4,6 +4,7 @@ exports.DefaultInspector = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
+ const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
7
8
  const VisualControls_1 = require("../../visual-controls/VisualControls");
8
9
  const CurrentAsset_1 = require("../CurrentAsset");
9
10
  const CurrentComposition_1 = require("../CurrentComposition");
@@ -27,7 +28,7 @@ const DefaultInspector = ({ composition, currentDefaultProps, readOnlyStudio, se
27
28
  const { handles: visualControlHandles } = (0, react_1.useContext)(VisualControls_1.VisualControlsContext);
28
29
  const [defaultPropsMode, setDefaultPropsMode] = (0, react_1.useState)('schema');
29
30
  const compositionId = (_a = composition === null || composition === void 0 ? void 0 : composition.id) !== null && _a !== void 0 ? _a : null;
30
- const hasVisualControls = Object.keys(visualControlHandles).length > 0;
31
+ const hasVisualControls = interactivity_enabled_1.studioInteractivityEnabled && Object.keys(visualControlHandles).length > 0;
31
32
  (0, react_1.useEffect)(() => {
32
33
  setDefaultPropsMode('schema');
33
34
  }, [compositionId]);
@@ -40,6 +40,7 @@ const react_1 = __importStar(require("react"));
40
40
  const remotion_1 = require("remotion");
41
41
  const no_react_1 = require("remotion/no-react");
42
42
  const client_id_1 = require("../helpers/client-id");
43
+ const interactivity_enabled_1 = require("../helpers/interactivity-enabled");
43
44
  const use_keybinding_1 = require("../helpers/use-keybinding");
44
45
  const editor_guides_1 = require("../state/editor-guides");
45
46
  const editor_outlines_1 = require("../state/editor-outlines");
@@ -158,7 +159,7 @@ const SelectedOutlineOverlay = ({ compositionHeight, compositionWidth, scale, tr
158
159
  selectItem(item, interaction, undefined, { reveal: true });
159
160
  }, [selectItem]);
160
161
  const outlineTargets = (0, react_1.useMemo)(() => {
161
- if (!editorShowOutlines) {
162
+ if (!interactivity_enabled_1.studioInteractivityEnabled || !editorShowOutlines) {
162
163
  return [];
163
164
  }
164
165
  const selectedSequenceKeys = (0, selected_outline_measurement_1.getSelectedSequenceKeys)(selectedItems);
@@ -40,6 +40,7 @@ const remotion_1 = require("remotion");
40
40
  const calculate_timeline_1 = require("../../helpers/calculate-timeline");
41
41
  const client_id_1 = require("../../helpers/client-id");
42
42
  const colors_1 = require("../../helpers/colors");
43
+ const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
43
44
  const is_current_selected_still_1 = require("../../helpers/is-current-selected-still");
44
45
  const open_in_editor_1 = require("../../helpers/open-in-editor");
45
46
  const call_api_1 = require("../call-api");
@@ -88,6 +89,7 @@ const TimelineContextMenuArea = ({ children }) => {
88
89
  const [isAddingAsset, setIsAddingAsset] = (0, react_1.useState)(false);
89
90
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
90
91
  const previewConnected = previewServerState.type === 'connected';
92
+ const previewInteractive = previewConnected && interactivity_enabled_1.studioInteractivityEnabled;
91
93
  const currentCompositionId = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition' ? canvasContent.compositionId : null;
92
94
  const currentComposition = (0, react_1.useMemo)(() => {
93
95
  var _a;
@@ -102,13 +104,13 @@ const TimelineContextMenuArea = ({ children }) => {
102
104
  compositionFile,
103
105
  compositionId: currentCompositionId,
104
106
  });
105
- const canInsertSolid = previewConnected &&
107
+ const canInsertSolid = previewInteractive &&
106
108
  (compositionComponentInfo === null || compositionComponentInfo === void 0 ? void 0 : compositionComponentInfo.canAddSequence) === true &&
107
109
  currentCompositionId !== null &&
108
110
  compositionFile !== null &&
109
111
  videoConfig !== null &&
110
112
  !isAddingSolid;
111
- const canInsertAsset = previewConnected &&
113
+ const canInsertAsset = previewInteractive &&
112
114
  !window.remotion_isReadOnlyStudio &&
113
115
  (compositionComponentInfo === null || compositionComponentInfo === void 0 ? void 0 : compositionComponentInfo.canAddSequence) === true &&
114
116
  currentCompositionId !== null &&
@@ -207,6 +209,7 @@ const TimelineInner = () => {
207
209
  const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
208
210
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
209
211
  const previewConnected = previewServerState.type === 'connected';
212
+ const previewInteractive = previewConnected && interactivity_enabled_1.studioInteractivityEnabled;
210
213
  const videoConfigIsNull = videoConfig === null;
211
214
  const timeline = (0, react_1.useMemo)(() => {
212
215
  if (videoConfigIsNull) {
@@ -228,15 +231,14 @@ const TimelineInner = () => {
228
231
  }, [filtered]);
229
232
  const hasBeenCut = filtered.length > shown.length;
230
233
  return (jsx_runtime_1.jsxs(TimelineContextMenuArea, { children: [sequences.map((sequence) => {
231
- if (!(0, should_subscribe_to_sequence_props_1.shouldSubscribeToSequenceProps)(sequence, previewConnected)) {
234
+ if (!(0, should_subscribe_to_sequence_props_1.shouldSubscribeToSequenceProps)(sequence, previewInteractive)) {
232
235
  return null;
233
236
  }
234
237
  return (jsx_runtime_1.jsx(SubscribeToNodePaths_1.SubscribeToNodePaths, { overrideId: sequence.controls.overrideId, componentIdentity: sequence.controls.componentIdentity, schema: sequence.controls.schema, getStack: sequence.getStack, effects: sequence.effects }, sequence.id));
235
- }), jsx_runtime_1.jsx(SequencePropsObserver_1.SequencePropsObserver, {}), jsx_runtime_1.jsx(TimelineKeyframeTracksContext_1.TimelineKeyframeTracksProvider, { tracks: filtered, children: jsx_runtime_1.jsxs(TimelineSelection_1.TimelineSelectableItemsProvider, { timeline: shown, children: [
236
- jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectAllKeybindings, { timeline: shown }), jsx_runtime_1.jsx(TimelineHeightContainer_1.TimelineHeightContainer, { shown: shown, hasBeenCut: hasBeenCut, children: isStill ? (jsx_runtime_1.jsx(TimelineList_1.TimelineList, { timeline: shown })) : (jsx_runtime_1.jsxs(TimelineWidthProvider_1.TimelineWidthProvider, { children: [
238
+ }), interactivity_enabled_1.studioInteractivityEnabled ? jsx_runtime_1.jsx(SequencePropsObserver_1.SequencePropsObserver, {}) : null, jsx_runtime_1.jsx(TimelineKeyframeTracksContext_1.TimelineKeyframeTracksProvider, { tracks: filtered, children: jsx_runtime_1.jsxs(TimelineSelection_1.TimelineSelectableItemsProvider, { timeline: shown, children: [interactivity_enabled_1.studioInteractivityEnabled ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectAllKeybindings, { timeline: shown })) : null, jsx_runtime_1.jsx(TimelineHeightContainer_1.TimelineHeightContainer, { shown: shown, hasBeenCut: hasBeenCut, children: isStill ? (jsx_runtime_1.jsx(TimelineList_1.TimelineList, { timeline: shown })) : (jsx_runtime_1.jsxs(TimelineWidthProvider_1.TimelineWidthProvider, { children: [
237
239
  jsx_runtime_1.jsx(TimelinePinchZoom_1.TimelinePinchZoom, {}), jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { orientation: "vertical", defaultFlex: 0.2, id: "names-to-timeline", maxFlex: 0.5, minFlex: 0.15, children: [
238
240
  jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "flexer", sticky: jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePlaceholders, {}), children: jsx_runtime_1.jsx(TimelineList_1.TimelineList, { timeline: shown }) }), jsx_runtime_1.jsx(SplitterHandle_1.SplitterHandle, { onCollapse: noop, allowToCollapse: "none" }), jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "anti-flexer", sticky: null, children: jsx_runtime_1.jsxs(TimelineScrollable_1.TimelineScrollable, { children: [
239
- jsx_runtime_1.jsx(TimelineTracks_1.TimelineTracks, { timeline: shown, hasBeenCut: hasBeenCut }), jsx_runtime_1.jsx(TimelinePlayCursorSyncer_1.TimelinePlayCursorSyncer, {}), jsx_runtime_1.jsx(TimelineInOutPointer_1.TimelineInOutPointer, {}), jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimeIndicators, {}), jsx_runtime_1.jsx(TimelineDragHandler_1.TimelineDragHandler, {}), jsx_runtime_1.jsx(TimelineInOutDragHandler_1.TimelineInOutDragHandler, {}), jsx_runtime_1.jsx(TimelineSlider_1.TimelineSlider, {})
241
+ jsx_runtime_1.jsx(TimelineTracks_1.TimelineTracks, { timeline: shown, hasBeenCut: hasBeenCut }), jsx_runtime_1.jsx(TimelinePlayCursorSyncer_1.TimelinePlayCursorSyncer, {}), jsx_runtime_1.jsx(TimelineInOutPointer_1.TimelineInOutPointer, {}), jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimeIndicators, {}), jsx_runtime_1.jsx(TimelineDragHandler_1.TimelineDragHandler, {}), interactivity_enabled_1.studioInteractivityEnabled ? (jsx_runtime_1.jsx(TimelineInOutDragHandler_1.TimelineInOutDragHandler, {})) : null, jsx_runtime_1.jsx(TimelineSlider_1.TimelineSlider, {})
240
242
  ] }) })
241
243
  ] })
242
244
  ] })) })
@@ -38,6 +38,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
38
38
  const player_1 = require("@remotion/player");
39
39
  const react_1 = __importStar(require("react"));
40
40
  const remotion_1 = require("remotion");
41
+ const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
41
42
  const timeline_layout_1 = require("../../helpers/timeline-layout");
42
43
  const timeline_zoom_1 = require("../../state/timeline-zoom");
43
44
  const z_index_1 = require("../../state/z-index");
@@ -88,7 +89,7 @@ const TimelineDragHandler = () => {
88
89
  if (!canvasContent || canvasContent.type !== 'composition') {
89
90
  return null;
90
91
  }
91
- return (jsx_runtime_1.jsx("div", { ref: timeline_refs_1.sliderAreaRef, style: containerStyle, [TimelineSelection_1.TIMELINE_SCRUBBER_ATTR]: true, children: video ? jsx_runtime_1.jsx(TimelineDragHandlerInnerMemo, {}) : null }));
92
+ return (jsx_runtime_1.jsx("div", { ref: timeline_refs_1.sliderAreaRef, style: containerStyle, [TimelineSelection_1.TIMELINE_SCRUBBER_ATTR]: true, children: video && interactivity_enabled_1.studioInteractivityEnabled ? (jsx_runtime_1.jsx(TimelineDragHandlerInnerMemo, {})) : null }));
92
93
  };
93
94
  exports.TimelineDragHandler = TimelineDragHandler;
94
95
  const TimelineDragHandlerInner = () => {
@@ -7,6 +7,7 @@ const react_1 = require("react");
7
7
  const remotion_1 = require("remotion");
8
8
  const client_id_1 = require("../../helpers/client-id");
9
9
  const colors_1 = require("../../helpers/colors");
10
+ const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
10
11
  const timeline_layout_1 = require("../../helpers/timeline-layout");
11
12
  const timeline_node_path_key_1 = require("../../helpers/timeline-node-path-key");
12
13
  const use_keybinding_1 = require("../../helpers/use-keybinding");
@@ -557,7 +558,8 @@ const TimelineSelectionProvider = ({ children }) => {
557
558
  const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
558
559
  const timelineSelectionScope = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition' ? canvasContent.compositionId : null;
559
560
  const { expandParentTracks } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksSetterContext);
560
- const canSelect = previewServerState.type === 'connected' &&
561
+ const canSelect = interactivity_enabled_1.studioInteractivityEnabled &&
562
+ previewServerState.type === 'connected' &&
561
563
  !window.remotion_isReadOnlyStudio;
562
564
  const [selectedItems, setSelectedItems] = (0, react_1.useState)([]);
563
565
  const selectionAnchor = (0, react_1.useRef)(null);
@@ -41,6 +41,7 @@ const client_id_1 = require("../../helpers/client-id");
41
41
  const colors_1 = require("../../helpers/colors");
42
42
  const format_file_location_1 = require("../../helpers/format-file-location");
43
43
  const get_timeline_sequence_layout_1 = require("../../helpers/get-timeline-sequence-layout");
44
+ const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
44
45
  const open_in_editor_1 = require("../../helpers/open-in-editor");
45
46
  const timeline_layout_1 = require("../../helpers/timeline-layout");
46
47
  const use_max_media_duration_1 = require("../../helpers/use-max-media-duration");
@@ -177,11 +178,15 @@ const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffs
177
178
  ? remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePath)
178
179
  : undefined;
179
180
  }, [propStatuses, nodePath]);
180
- const durationCanUpdate = Boolean(((_a = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.durationInFrames) === null || _a === void 0 ? void 0 : _a.status) === 'static');
181
- const fromCanUpdate = Boolean(((_b = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.from) === null || _b === void 0 ? void 0 : _b.status) === 'static');
182
- const trimBeforeCanUpdate = Boolean(((_c = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.trimBefore) === null || _c === void 0 ? void 0 : _c.status) === 'static');
181
+ const durationCanUpdate = Boolean(interactivity_enabled_1.studioInteractivityEnabled &&
182
+ ((_a = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.durationInFrames) === null || _a === void 0 ? void 0 : _a.status) === 'static');
183
+ const fromCanUpdate = Boolean(interactivity_enabled_1.studioInteractivityEnabled &&
184
+ ((_b = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.from) === null || _b === void 0 ? void 0 : _b.status) === 'static');
185
+ const trimBeforeCanUpdate = Boolean(interactivity_enabled_1.studioInteractivityEnabled &&
186
+ ((_c = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.trimBefore) === null || _c === void 0 ? void 0 : _c.status) === 'static');
183
187
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
184
188
  const previewConnected = previewServerState.type === 'connected';
189
+ const previewInteractive = previewConnected && interactivity_enabled_1.studioInteractivityEnabled;
185
190
  const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
186
191
  const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
187
192
  const selectAsset = (0, use_select_asset_1.useSelectAsset)();
@@ -201,9 +206,9 @@ const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffs
201
206
  });
202
207
  }, [canOpenInEditor, originalLocation]);
203
208
  const canDeleteFromSource = Boolean(nodePath && (validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source));
204
- const deleteDisabled = !previewConnected || !s.controls || !canDeleteFromSource;
209
+ const deleteDisabled = !previewInteractive || !s.controls || !canDeleteFromSource;
205
210
  const duplicateDisabled = deleteDisabled;
206
- const disableInteractivityDisabled = !previewConnected ||
211
+ const disableInteractivityDisabled = !previewInteractive ||
207
212
  !s.showInTimeline ||
208
213
  !nodePath ||
209
214
  !(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source);
@@ -280,7 +285,7 @@ const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffs
280
285
  validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source,
281
286
  ]);
282
287
  const freezeFrameMenuItem = (0, use_sequence_freeze_frame_menu_item_1.useSequenceFreezeFrameMenuItem)({
283
- clientId: previewServerState.type === 'connected'
288
+ clientId: previewInteractive && previewServerState.type === 'connected'
284
289
  ? previewServerState.clientId
285
290
  : null,
286
291
  nodePath,
@@ -302,7 +307,7 @@ const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffs
302
307
  disableInteractivityDisabled,
303
308
  duplicateDisabled,
304
309
  fileLocation,
305
- includeSourceEditItems: true,
310
+ includeSourceEditItems: interactivity_enabled_1.studioInteractivityEnabled,
306
311
  onDeleteSequenceFromSource,
307
312
  onDisableSequenceInteractivity,
308
313
  onDuplicateSequenceFromSource,
@@ -310,7 +315,9 @@ const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffs
310
315
  originalLocation,
311
316
  selectAsset,
312
317
  sequence: s,
313
- sourceActions: freezeFrameMenuItem ? [freezeFrameMenuItem] : [],
318
+ sourceActions: interactivity_enabled_1.studioInteractivityEnabled && freezeFrameMenuItem
319
+ ? [freezeFrameMenuItem]
320
+ : [],
314
321
  });
315
322
  }, [
316
323
  assetLinkInfo,
@@ -40,6 +40,7 @@ const remotion_1 = require("remotion");
40
40
  const client_id_1 = require("../../helpers/client-id");
41
41
  const colors_1 = require("../../helpers/colors");
42
42
  const format_file_location_1 = require("../../helpers/format-file-location");
43
+ const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
43
44
  const timeline_layout_1 = require("../../helpers/timeline-layout");
44
45
  const use_keybinding_1 = require("../../helpers/use-keybinding");
45
46
  const modals_1 = require("../../state/modals");
@@ -158,6 +159,7 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
158
159
  const nodePath = (_d = nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.sequenceSubscriptionKey) !== null && _d !== void 0 ? _d : null;
159
160
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
160
161
  const previewConnected = previewServerState.type === 'connected';
162
+ const previewInteractive = previewConnected && interactivity_enabled_1.studioInteractivityEnabled;
161
163
  const { getIsExpanded } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksGetterContext);
162
164
  const { toggleTrack } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksSetterContext);
163
165
  const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
@@ -191,7 +193,7 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
191
193
  };
192
194
  }, [originalLocation]);
193
195
  const { canRename: canRenameThisSequence, displayName, fallbackDisplayName, propStatusesForOverride, saveName, } = (0, use_rename_sequence_1.useRenameSequence)({
194
- clientId: previewServerState.type === 'connected'
196
+ clientId: previewInteractive && previewServerState.type === 'connected'
195
197
  ? previewServerState.clientId
196
198
  : null,
197
199
  nodePathInfo,
@@ -201,25 +203,25 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
201
203
  const canDeleteFromSource = Boolean(nodePath && (validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source));
202
204
  const nodePathKey = (0, react_1.useMemo)(() => nodePath ? remotion_1.Internals.makeSequencePropsSubscriptionKey(nodePath) : null, [nodePath]);
203
205
  const parentId = (_e = sequence.parent) !== null && _e !== void 0 ? _e : null;
204
- const canReorderSequence = previewConnected &&
206
+ const canReorderSequence = previewInteractive &&
205
207
  Boolean(nodePath && nodePathKey && (validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source)) &&
206
208
  (nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.numberOfSequencesWithThisNodePath) === 1;
207
- const canHandleSequenceDrag = previewConnected;
209
+ const canHandleSequenceDrag = previewInteractive;
208
210
  const confirm = (0, ConfirmationDialog_1.useConfirmationDialog)();
209
- const deleteDisabled = (0, react_1.useMemo)(() => !previewConnected || !sequence.controls || !canDeleteFromSource, [previewConnected, sequence.controls, canDeleteFromSource]);
211
+ const deleteDisabled = (0, react_1.useMemo)(() => !previewInteractive || !sequence.controls || !canDeleteFromSource, [previewInteractive, sequence.controls, canDeleteFromSource]);
210
212
  const duplicateDisabled = deleteDisabled;
211
- const disableInteractivityDisabled = !previewConnected ||
213
+ const disableInteractivityDisabled = !previewInteractive ||
212
214
  !sequence.showInTimeline ||
213
215
  !nodePath ||
214
216
  !(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source);
215
217
  const onDuplicateSequenceFromSource = (0, react_1.useCallback)(() => {
216
- if (!(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source) || !nodePathInfo) {
218
+ if (duplicateDisabled || !(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source) || !nodePathInfo) {
217
219
  return;
218
220
  }
219
221
  (0, duplicate_selected_timeline_item_1.duplicateSequencesFromSource)([nodePathInfo], confirm).catch(() => undefined);
220
- }, [confirm, nodePathInfo, validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source]);
222
+ }, [confirm, duplicateDisabled, nodePathInfo, validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source]);
221
223
  const onDeleteSequenceFromSource = (0, react_1.useCallback)(async () => {
222
- if (!(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source) || !nodePath) {
224
+ if (deleteDisabled || !(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source) || !nodePath) {
223
225
  return;
224
226
  }
225
227
  if (nodePathInfo && nodePathInfo.numberOfSequencesWithThisNodePath > 1) {
@@ -253,7 +255,13 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
253
255
  catch (err) {
254
256
  (0, NotificationCenter_1.showNotification)(err.message, 4000);
255
257
  }
256
- }, [confirm, nodePath, validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source, nodePathInfo]);
258
+ }, [
259
+ confirm,
260
+ deleteDisabled,
261
+ nodePath,
262
+ validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source,
263
+ nodePathInfo,
264
+ ]);
257
265
  const onDisableSequenceInteractivity = (0, react_1.useCallback)(() => {
258
266
  if (disableInteractivityDisabled ||
259
267
  !nodePath ||
@@ -517,8 +525,9 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
517
525
  }
518
526
  : inner;
519
527
  }, [effectDropHovered, inner]);
520
- const hasExpandableContent = Boolean(sequence.controls) || sequence.effects.length > 0;
521
- const canToggleVisibility = previewConnected &&
528
+ const hasExpandableContent = interactivity_enabled_1.studioInteractivityEnabled &&
529
+ (Boolean(sequence.controls) || sequence.effects.length > 0);
530
+ const canToggleVisibility = previewInteractive &&
522
531
  Boolean(sequence.controls) &&
523
532
  nodePath !== null &&
524
533
  validatedLocation !== null &&
@@ -583,7 +592,7 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
583
592
  setIsRenaming(true);
584
593
  }, [canRenameThisSequence]);
585
594
  const freezeFrameMenuItem = (0, use_sequence_freeze_frame_menu_item_1.useSequenceFreezeFrameMenuItem)({
586
- clientId: previewServerState.type === 'connected'
595
+ clientId: previewInteractive && previewServerState.type === 'connected'
587
596
  ? previewServerState.clientId
588
597
  : null,
589
598
  nodePath,
@@ -595,7 +604,7 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
595
604
  validatedSource: (_f = validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source) !== null && _f !== void 0 ? _f : null,
596
605
  });
597
606
  const canAddEffect = (nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.supportsEffects) === true &&
598
- previewServerState.type === 'connected' &&
607
+ previewInteractive &&
599
608
  Boolean(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source);
600
609
  const onAddEffect = (0, react_1.useCallback)(() => {
601
610
  if (!canAddEffect ||
@@ -628,7 +637,7 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
628
637
  disableInteractivityDisabled,
629
638
  duplicateDisabled,
630
639
  fileLocation,
631
- includeSourceEditItems: true,
640
+ includeSourceEditItems: interactivity_enabled_1.studioInteractivityEnabled,
632
641
  onDeleteSequenceFromSource,
633
642
  onDisableSequenceInteractivity,
634
643
  onDuplicateSequenceFromSource,
@@ -636,43 +645,45 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
636
645
  originalLocation,
637
646
  selectAsset,
638
647
  sequence,
639
- sourceActions: [
640
- ...((nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.supportsEffects)
641
- ? [
642
- {
643
- type: 'item',
644
- id: 'add-effect',
645
- keyHint: null,
646
- label: 'Add effect...',
647
- leftItem: null,
648
- disabled: !canAddEffect,
649
- onClick: onAddEffect,
650
- quickSwitcherLabel: null,
651
- subMenu: null,
652
- value: 'add-effect',
653
- },
654
- {
655
- type: 'divider',
656
- id: 'add-effect-divider',
648
+ sourceActions: interactivity_enabled_1.studioInteractivityEnabled
649
+ ? [
650
+ ...((nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.supportsEffects)
651
+ ? [
652
+ {
653
+ type: 'item',
654
+ id: 'add-effect',
655
+ keyHint: null,
656
+ label: 'Add effect...',
657
+ leftItem: null,
658
+ disabled: !canAddEffect,
659
+ onClick: onAddEffect,
660
+ quickSwitcherLabel: null,
661
+ subMenu: null,
662
+ value: 'add-effect',
663
+ },
664
+ {
665
+ type: 'divider',
666
+ id: 'add-effect-divider',
667
+ },
668
+ ]
669
+ : []),
670
+ {
671
+ type: 'item',
672
+ id: 'rename-sequence',
673
+ keyHint: null,
674
+ label: 'Rename...',
675
+ leftItem: null,
676
+ disabled: !canRenameThisSequence,
677
+ onClick: () => {
678
+ onRenameSequence();
657
679
  },
658
- ]
659
- : []),
660
- {
661
- type: 'item',
662
- id: 'rename-sequence',
663
- keyHint: null,
664
- label: 'Rename...',
665
- leftItem: null,
666
- disabled: !canRenameThisSequence,
667
- onClick: () => {
668
- onRenameSequence();
680
+ quickSwitcherLabel: null,
681
+ subMenu: null,
682
+ value: 'rename-sequence',
669
683
  },
670
- quickSwitcherLabel: null,
671
- subMenu: null,
672
- value: 'rename-sequence',
673
- },
674
- ...(freezeFrameMenuItem ? [freezeFrameMenuItem] : []),
675
- ],
684
+ ...(freezeFrameMenuItem ? [freezeFrameMenuItem] : []),
685
+ ]
686
+ : [],
676
687
  });
677
688
  }, [
678
689
  assetLinkInfo,
@@ -696,7 +707,7 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
696
707
  selectAsset,
697
708
  sequence,
698
709
  ]);
699
- const canDropEffect = previewServerState.type === 'connected' &&
710
+ const canDropEffect = previewInteractive &&
700
711
  nodePath !== null &&
701
712
  validatedLocation !== null &&
702
713
  ((_c = sequence.controls) === null || _c === void 0 ? void 0 : _c.supportsEffects) === true;
@@ -754,7 +765,7 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
754
765
  clientId: previewServerState.clientId,
755
766
  });
756
767
  }, [canDropEffect, nodePath, previewServerState, validatedLocation]);
757
- const trackRow = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: nestedDepth, eye: canToggleVisibility ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: sequence.type === 'audio' ? 'speaker' : 'eye', hidden: isItemHidden, onInvoked: onToggleVisibility })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: hasExpandableContent && nodePathInfo !== null ? (jsx_runtime_1.jsx(TimelineSequenceExpandArrow, { disabled: !previewConnected, isExpanded: isExpanded, nodePathInfo: nodePathInfo, onToggleExpand: onToggleExpand, sequence: sequence })) : (jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {})), style: rowStyle, selected: selected, selectable: selectable, selectionItem: selectionItem, onSelect: onSelect, showSelectedBackground: true, containsSelection: containsSelection, outerHeight: outerHeight, onDragLeave: canDropEffect ? onEffectDragLeave : undefined, onDragOver: canDropEffect ? onEffectDragOver : undefined, onDrop: canDropEffect ? onEffectDrop : undefined, onDoubleClick: canRenameThisSequence || canOpenInEditor
768
+ const trackRow = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: nestedDepth, eye: canToggleVisibility ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: sequence.type === 'audio' ? 'speaker' : 'eye', hidden: isItemHidden, onInvoked: onToggleVisibility })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: hasExpandableContent && nodePathInfo !== null ? (jsx_runtime_1.jsx(TimelineSequenceExpandArrow, { disabled: !previewInteractive, isExpanded: isExpanded, nodePathInfo: nodePathInfo, onToggleExpand: onToggleExpand, sequence: sequence })) : (jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {})), style: rowStyle, selected: selected, selectable: selectable, selectionItem: selectionItem, onSelect: onSelect, showSelectedBackground: true, containsSelection: containsSelection, outerHeight: outerHeight, onDragLeave: canDropEffect ? onEffectDragLeave : undefined, onDragOver: canDropEffect ? onEffectDragOver : undefined, onDrop: canDropEffect ? onEffectDrop : undefined, onDoubleClick: canRenameThisSequence || canOpenInEditor
758
769
  ? onSequenceDoubleClick
759
770
  : undefined, children: jsx_runtime_1.jsxs("div", { style: labelContainerStyle, children: [
760
771
  jsx_runtime_1.jsx(TimelineSequenceName_1.TimelineSequenceName, { displayName: displayName, fallbackDisplayName: fallbackDisplayName, selected: selected, containsSelection: containsSelection, editing: isRenaming, onCancelEditing: onCancelRenaming, onSaveName: onSaveName }), mediaSrc ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
@@ -764,6 +775,7 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
764
775
  ] })) : null] }) }));
765
776
  const draggableTrackRow = canHandleSequenceDrag ? (jsx_runtime_1.jsxs("div", { draggable: canReorderSequence, onDragStart: onSequenceDragStart, onDragEnd: onSequenceDragEnd, onDragOver: onSequenceDragOver, onDragLeave: onSequenceDragLeave, onDrop: onSequenceDrop, style: sequenceReorderWrapper, children: [sequenceReorderLineStyle ? (jsx_runtime_1.jsx("div", { style: sequenceReorderLineStyle })) : null, sequenceDropRejection ? (jsx_runtime_1.jsx("div", { style: sequenceReorderRejectionStyle, children: sequenceDropRejection })) : null, trackRow] })) : (trackRow);
766
777
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [previewConnected ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, onOpen: selectable ? onSelect : null, children: draggableTrackRow })) : (draggableTrackRow), previewConnected &&
778
+ interactivity_enabled_1.studioInteractivityEnabled &&
767
779
  isExpanded &&
768
780
  hasExpandableContent &&
769
781
  nodePathInfo &&