@remotion/studio 4.0.487 → 4.0.489

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.
@@ -123,6 +123,42 @@ var noop = () => {
123
123
  return;
124
124
  };
125
125
 
126
+ // src/helpers/studio-runtime-config.ts
127
+ import { DEFAULT_TIMELINE_TRACKS } from "@remotion/studio-shared";
128
+ var DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS = 300;
129
+ var defaultStudioRuntimeConfig = {
130
+ askAIEnabled: false,
131
+ bufferStateDelayInMilliseconds: null,
132
+ experimentalClientSideRenderingEnabled: false,
133
+ interactivityEnabled: true,
134
+ keyboardShortcutsEnabled: true,
135
+ maxTimelineTracks: null
136
+ };
137
+ var getStudioRuntimeConfig = () => {
138
+ if (typeof window === "undefined") {
139
+ return defaultStudioRuntimeConfig;
140
+ }
141
+ return window.remotion_studioConfig ?? defaultStudioRuntimeConfig;
142
+ };
143
+ var getStudioAskAIEnabled = () => {
144
+ return getStudioRuntimeConfig().askAIEnabled;
145
+ };
146
+ var getStudioInteractivityEnabled = () => {
147
+ return getStudioRuntimeConfig().interactivityEnabled;
148
+ };
149
+ var getStudioKeyboardShortcutsEnabled = () => {
150
+ return getStudioRuntimeConfig().keyboardShortcutsEnabled;
151
+ };
152
+ var getStudioExperimentalClientSideRenderingEnabled = () => {
153
+ return getStudioRuntimeConfig().experimentalClientSideRenderingEnabled;
154
+ };
155
+ var getStudioMaxTimelineTracks = () => {
156
+ return getStudioRuntimeConfig().maxTimelineTracks ?? DEFAULT_TIMELINE_TRACKS;
157
+ };
158
+ var getStudioBufferStateDelayInMilliseconds = () => {
159
+ return getStudioRuntimeConfig().bufferStateDelayInMilliseconds ?? DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS;
160
+ };
161
+
126
162
  // src/state/canvas-ref.ts
127
163
  import { createRef } from "react";
128
164
  var canvasRef = createRef();
@@ -942,18 +978,18 @@ var KeybindingContextProvider = ({ children }) => {
942
978
  };
943
979
 
944
980
  // src/helpers/use-keybinding.ts
945
- if (!process.env.KEYBOARD_SHORTCUTS_ENABLED) {
981
+ if (!getStudioKeyboardShortcutsEnabled()) {
946
982
  console.warn("Keyboard shortcuts disabled either due to: a) --disable-keyboard-shortcuts being passed b) Config.setKeyboardShortcutsEnabled(false) being set or c) a Remotion version mismatch.");
947
983
  }
948
984
  var areKeyboardShortcutsDisabled = () => {
949
- return !process.env.KEYBOARD_SHORTCUTS_ENABLED;
985
+ return !getStudioKeyboardShortcutsEnabled();
950
986
  };
951
987
  var useKeybinding = () => {
952
988
  const [paneId] = useState3(() => String(Math.random()));
953
989
  const context = useContext4(KeybindingContext);
954
990
  const { isHighestContext } = useZIndex();
955
991
  const registerKeybinding = useCallback4((options) => {
956
- if (!process.env.KEYBOARD_SHORTCUTS_ENABLED) {
992
+ if (!getStudioKeyboardShortcutsEnabled()) {
957
993
  return {
958
994
  unregister: () => {
959
995
  return;
@@ -1989,7 +2025,7 @@ var PreviewServerConnection = ({ children, readOnlyStudio }) => {
1989
2025
  };
1990
2026
 
1991
2027
  // src/helpers/show-browser-rendering.ts
1992
- var SHOW_BROWSER_RENDERING = Boolean(process.env.EXPERIMENTAL_CLIENT_SIDE_RENDERING_ENABLED);
2028
+ var SHOW_BROWSER_RENDERING = getStudioExperimentalClientSideRenderingEnabled();
1993
2029
 
1994
2030
  // src/helpers/timeline-node-path-key.ts
1995
2031
  import { stringifySequenceExpandedRowKey } from "@remotion/studio-shared";
@@ -3734,7 +3770,7 @@ var MenuContent = ({
3734
3770
  return containerStyles;
3735
3771
  }, [fixedHeight, isMobileLayout]);
3736
3772
  useEffect11(() => {
3737
- if (!keybindings.isHighestContext || !process.env.KEYBOARD_SHORTCUTS_ENABLED) {
3773
+ if (!keybindings.isHighestContext || !getStudioKeyboardShortcutsEnabled()) {
3738
3774
  return;
3739
3775
  }
3740
3776
  const onKeyDown = (event) => {
@@ -6089,6 +6125,9 @@ import {
6089
6125
  Internals as Internals19
6090
6126
  } from "remotion";
6091
6127
 
6128
+ // src/helpers/interactivity-enabled.ts
6129
+ var studioInteractivityEnabled = getStudioInteractivityEnabled();
6130
+
6092
6131
  // src/components/ExpandedTracksProvider.tsx
6093
6132
  import { createContext as createContext13, useCallback as useCallback24, useMemo as useMemo24, useState as useState20 } from "react";
6094
6133
 
@@ -9486,7 +9525,7 @@ var TimelineSelectionProvider = ({ children }) => {
9486
9525
  const { canvasContent } = useContext18(Internals19.CompositionManager);
9487
9526
  const timelineSelectionScope = canvasContent?.type === "composition" ? canvasContent.compositionId : null;
9488
9527
  const { expandParentTracks } = useContext18(ExpandedTracksSetterContext);
9489
- const canSelect = previewServerState.type === "connected" && !window.remotion_isReadOnlyStudio;
9528
+ const canSelect = studioInteractivityEnabled && previewServerState.type === "connected" && !window.remotion_isReadOnlyStudio;
9490
9529
  const [selectedItems, setSelectedItems] = useState21([]);
9491
9530
  const selectionAnchor = useRef16(null);
9492
9531
  const selectionScope = useRef16(null);
@@ -10088,7 +10127,7 @@ var GlobalKeybindings = ({ readOnlyStudio }) => {
10088
10127
  commandCtrlKey: true,
10089
10128
  preventDefault: true
10090
10129
  });
10091
- const cmdIKey = process.env.ASK_AI_ENABLED ? keybindings.registerKeybinding({
10130
+ const cmdIKey = getStudioAskAIEnabled() ? keybindings.registerKeybinding({
10092
10131
  event: "keydown",
10093
10132
  key: "i",
10094
10133
  callback: () => {
@@ -11713,7 +11752,7 @@ var useMenuStructure = (closeMenu, readOnlyStudio) => {
11713
11752
  label: "Tools",
11714
11753
  leaveLeftPadding: false,
11715
11754
  items: [
11716
- process.env.ASK_AI_ENABLED ? {
11755
+ getStudioAskAIEnabled() ? {
11717
11756
  id: "ask-ai",
11718
11757
  value: "ask-ai",
11719
11758
  label: "Ask AI",
@@ -13898,12 +13937,12 @@ var ErrorLoader = ({
13898
13937
  // src/components/Canvas.tsx
13899
13938
  import {
13900
13939
  ASSET_DRAG_MIME_TYPE as ASSET_DRAG_MIME_TYPE2,
13901
- COMPOSITION_DRAG_MIME_TYPE as COMPOSITION_DRAG_MIME_TYPE4,
13902
13940
  COMPONENT_DRAG_MIME_TYPE as COMPONENT_DRAG_MIME_TYPE2,
13941
+ COMPOSITION_DRAG_MIME_TYPE as COMPOSITION_DRAG_MIME_TYPE4,
13903
13942
  ELEMENT_DRAG_MIME_TYPE as ELEMENT_DRAG_MIME_TYPE3,
13904
13943
  parseAssetDragData,
13905
- parseCompositionDragData as parseCompositionDragData3,
13906
13944
  parseComponentDragData,
13945
+ parseCompositionDragData as parseCompositionDragData3,
13907
13946
  parseSfxDragData,
13908
13947
  SFX_DRAG_MIME_TYPE as SFX_DRAG_MIME_TYPE2
13909
13948
  } from "@remotion/studio-shared";
@@ -23383,7 +23422,7 @@ var SelectedOutlineOverlay = ({
23383
23422
  selectItem(item, interaction, undefined, { reveal: true });
23384
23423
  }, [selectItem]);
23385
23424
  const outlineTargets = useMemo56(() => {
23386
- if (!editorShowOutlines) {
23425
+ if (!studioInteractivityEnabled || !editorShowOutlines) {
23387
23426
  return [];
23388
23427
  }
23389
23428
  const selectedSequenceKeys = getSelectedSequenceKeys(selectedItems);
@@ -24193,6 +24232,31 @@ var ResetZoomButton = ({ onClick }) => {
24193
24232
 
24194
24233
  // src/components/Canvas.tsx
24195
24234
  import { jsx as jsx94, jsxs as jsxs43, Fragment as Fragment19 } from "react/jsx-runtime";
24235
+ var elementInstallCompositionIdStyle = {
24236
+ fontFamily: "monospace",
24237
+ fontSize: 13
24238
+ };
24239
+ var elementInstallCodeDetailsStyle = {
24240
+ marginTop: 12,
24241
+ fontSize: 13
24242
+ };
24243
+ var elementInstallCodeSummaryStyle = {
24244
+ cursor: "pointer",
24245
+ fontSize: 13,
24246
+ fontWeight: 500
24247
+ };
24248
+ var elementInstallCodeBlockStyle = {
24249
+ marginTop: 8,
24250
+ marginBottom: 0,
24251
+ maxHeight: 240,
24252
+ overflow: "auto",
24253
+ padding: 12,
24254
+ borderRadius: 6,
24255
+ backgroundColor: "rgba(255, 255, 255, 0.06)",
24256
+ fontSize: 12,
24257
+ lineHeight: 1.5,
24258
+ whiteSpace: "pre"
24259
+ };
24196
24260
  var getContainerStyle = (editorZoomGestures) => ({
24197
24261
  flex: 1,
24198
24262
  display: "flex",
@@ -24327,12 +24391,18 @@ var Canvas = ({ canvasContent, size: size2 }) => {
24327
24391
  const suppressWheelFromWebKitPinchRef = useRef32(false);
24328
24392
  const touchPinchRef = useRef32(null);
24329
24393
  const keybindings = useKeybinding();
24394
+ const confirm = useConfirmationDialog();
24330
24395
  const config = Internals40.useUnsafeVideoConfig();
24331
24396
  const areRulersVisible = useIsRulerVisible();
24332
24397
  const { editorShowGuides } = useContext38(EditorShowGuidesContext);
24333
24398
  const { compositions } = useContext38(Internals40.CompositionManager);
24334
- const { previewServerState } = useContext38(StudioServerConnectionCtx);
24399
+ const { previewServerState, subscribeToEvent } = useContext38(StudioServerConnectionCtx);
24400
+ const previewServerClientId = previewServerState.type === "connected" ? previewServerState.clientId : null;
24335
24401
  const [isAddingAsset, setIsAddingAsset] = useState42(false);
24402
+ const [installingElementName, setInstallingElementName] = useState42(null);
24403
+ const [pendingElementInstallRequests, setPendingElementInstallRequests] = useState42([]);
24404
+ const [activeElementInstallRequest, setActiveElementInstallRequest] = useState42(null);
24405
+ const lastFocusedAtRef = useRef32(typeof document === "undefined" || document.hasFocus() ? Date.now() : null);
24336
24406
  const [assetResolution, setAssetResolution] = useState42(null);
24337
24407
  const currentCompositionId = canvasContent.type === "composition" ? canvasContent.compositionId : null;
24338
24408
  const currentComposition = useMemo58(() => {
@@ -24347,7 +24417,8 @@ var Canvas = ({ canvasContent, size: size2 }) => {
24347
24417
  compositionFile,
24348
24418
  compositionId: currentCompositionId
24349
24419
  });
24350
- const canDropAssets = previewServerState.type === "connected" && !window.remotion_isReadOnlyStudio && compositionComponentInfo?.canAddSequence === true && currentCompositionId !== null && compositionFile !== null && !isAddingAsset;
24420
+ const canInstallElements = previewServerClientId !== null && !window.remotion_isReadOnlyStudio && compositionComponentInfo?.canAddSequence === true && currentCompositionId !== null && compositionFile !== null;
24421
+ const canDropAssets = canInstallElements && !isAddingAsset;
24351
24422
  const contentDimensions = useMemo58(() => {
24352
24423
  if ((canvasContent.type === "asset" || canvasContent.type === "output" || canvasContent.type === "output-blob") && assetResolution && assetResolution.type === "found") {
24353
24424
  return assetResolution.dimensions;
@@ -24703,6 +24774,146 @@ var Canvas = ({ canvasContent, size: size2 }) => {
24703
24774
  useEffect42(() => {
24704
24775
  fetchMetadata();
24705
24776
  }, [fetchMetadata]);
24777
+ const updateElementInstallTarget = useCallback51((requestId) => {
24778
+ if (previewServerClientId === null) {
24779
+ return;
24780
+ }
24781
+ callApi("/api/update-element-install-target", {
24782
+ requestId,
24783
+ clientId: previewServerClientId,
24784
+ compositionFile: canInstallElements ? compositionFile : null,
24785
+ compositionId: canInstallElements ? currentCompositionId : null,
24786
+ canInstall: canInstallElements,
24787
+ lastFocusedAt: lastFocusedAtRef.current,
24788
+ readOnly: window.remotion_isReadOnlyStudio
24789
+ }).catch(() => {
24790
+ return;
24791
+ });
24792
+ }, [
24793
+ canInstallElements,
24794
+ compositionFile,
24795
+ currentCompositionId,
24796
+ previewServerClientId
24797
+ ]);
24798
+ useEffect42(() => {
24799
+ const markFocused = () => {
24800
+ lastFocusedAtRef.current = Date.now();
24801
+ };
24802
+ window.addEventListener("focus", markFocused);
24803
+ document.addEventListener("pointerdown", markFocused, { capture: true });
24804
+ return () => {
24805
+ window.removeEventListener("focus", markFocused);
24806
+ document.removeEventListener("pointerdown", markFocused, { capture: true });
24807
+ };
24808
+ }, []);
24809
+ useEffect42(() => {
24810
+ return subscribeToEvent("request-element-install-target", (event) => {
24811
+ if (event.type !== "request-element-install-target") {
24812
+ return;
24813
+ }
24814
+ updateElementInstallTarget(event.requestId);
24815
+ });
24816
+ }, [subscribeToEvent, updateElementInstallTarget]);
24817
+ useEffect42(() => {
24818
+ if (installingElementName === null) {
24819
+ return;
24820
+ }
24821
+ const previousTitle = document.title;
24822
+ document.title = `\uD83D\uDCE6 Install ${installingElementName} - Remotion Studio`;
24823
+ return () => {
24824
+ document.title = previousTitle;
24825
+ };
24826
+ }, [installingElementName]);
24827
+ useEffect42(() => {
24828
+ if (previewServerClientId === null) {
24829
+ return;
24830
+ }
24831
+ return subscribeToEvent("element-install-request", (event) => {
24832
+ if (event.type !== "element-install-request" || event.request.clientId !== previewServerClientId) {
24833
+ return;
24834
+ }
24835
+ setPendingElementInstallRequests((requests) => [
24836
+ ...requests,
24837
+ event.request
24838
+ ]);
24839
+ });
24840
+ }, [previewServerClientId, subscribeToEvent]);
24841
+ useEffect42(() => {
24842
+ if (activeElementInstallRequest !== null || pendingElementInstallRequests.length === 0) {
24843
+ return;
24844
+ }
24845
+ const [nextRequest, ...remainingRequests] = pendingElementInstallRequests;
24846
+ if (!nextRequest) {
24847
+ throw new Error("Expected pending Element install request");
24848
+ }
24849
+ setActiveElementInstallRequest(nextRequest);
24850
+ setPendingElementInstallRequests(remainingRequests);
24851
+ }, [activeElementInstallRequest, pendingElementInstallRequests]);
24852
+ useEffect42(() => {
24853
+ if (activeElementInstallRequest === null) {
24854
+ return;
24855
+ }
24856
+ let canceled = false;
24857
+ const handleInstallRequest = async () => {
24858
+ setInstallingElementName(activeElementInstallRequest.element.displayName);
24859
+ const accepted = await confirm({
24860
+ title: "Install Element",
24861
+ message: /* @__PURE__ */ jsxs43(Fragment19, {
24862
+ children: [
24863
+ "Install “",
24864
+ activeElementInstallRequest.element.displayName,
24865
+ "” into",
24866
+ " ",
24867
+ /* @__PURE__ */ jsx94("code", {
24868
+ style: elementInstallCompositionIdStyle,
24869
+ children: activeElementInstallRequest.compositionId
24870
+ }),
24871
+ " ",
24872
+ "composition? This will create an Element source file and update the composition source.",
24873
+ /* @__PURE__ */ jsxs43("details", {
24874
+ style: elementInstallCodeDetailsStyle,
24875
+ children: [
24876
+ /* @__PURE__ */ jsx94("summary", {
24877
+ style: elementInstallCodeSummaryStyle,
24878
+ children: "Preview Element source"
24879
+ }),
24880
+ /* @__PURE__ */ jsx94("pre", {
24881
+ style: elementInstallCodeBlockStyle,
24882
+ children: /* @__PURE__ */ jsx94("code", {
24883
+ children: activeElementInstallRequest.element.sourceCode
24884
+ })
24885
+ })
24886
+ ]
24887
+ })
24888
+ ]
24889
+ }),
24890
+ confirmLabel: "Install",
24891
+ cancelLabel: "Cancel"
24892
+ });
24893
+ if (accepted && !canceled) {
24894
+ await insertElement({
24895
+ element: activeElementInstallRequest.element,
24896
+ compositionFile: activeElementInstallRequest.compositionFile,
24897
+ compositionId: activeElementInstallRequest.compositionId,
24898
+ dropPosition: null
24899
+ });
24900
+ }
24901
+ };
24902
+ handleInstallRequest().finally(() => {
24903
+ if (canceled) {
24904
+ return;
24905
+ }
24906
+ setInstallingElementName(null);
24907
+ setActiveElementInstallRequest(null);
24908
+ }).catch((err) => {
24909
+ setTimeout(() => {
24910
+ throw err;
24911
+ }, 0);
24912
+ });
24913
+ return () => {
24914
+ canceled = true;
24915
+ };
24916
+ }, [activeElementInstallRequest, confirm]);
24706
24917
  const onDragOver = useCallback51((event) => {
24707
24918
  if (!canDropAssets || !isFileDragEvent(event) && !isAssetDragEvent(event) && !isCompositionDragEvent(event) && !isComponentDragEvent(event) && !isElementDragEvent(event) && !isSfxDragEvent(event) && !isRemoteAssetDragEvent(event) || !isDragEventInsideCanvas(event)) {
24708
24919
  return;
@@ -26907,6 +27118,9 @@ var VisualControlsProvider = ({ children }) => {
26907
27118
  if (!env.isStudio) {
26908
27119
  return value;
26909
27120
  }
27121
+ if (!studioInteractivityEnabled) {
27122
+ return value;
27123
+ }
26910
27124
  if (!z) {
26911
27125
  return value;
26912
27126
  }
@@ -33297,7 +33511,7 @@ var DefaultInspector = ({ composition, currentDefaultProps, readOnlyStudio, setD
33297
33511
  const { handles: visualControlHandles } = useContext56(VisualControlsContext);
33298
33512
  const [defaultPropsMode, setDefaultPropsMode] = useState68("schema");
33299
33513
  const compositionId = composition?.id ?? null;
33300
- const hasVisualControls = Object.keys(visualControlHandles).length > 0;
33514
+ const hasVisualControls = studioInteractivityEnabled && Object.keys(visualControlHandles).length > 0;
33301
33515
  useEffect60(() => {
33302
33516
  setDefaultPropsMode("schema");
33303
33517
  }, [compositionId]);
@@ -47537,9 +47751,8 @@ import React207, { useCallback as useCallback166, useContext as useContext120, u
47537
47751
  import { Internals as Internals98 } from "remotion";
47538
47752
 
47539
47753
  // src/components/Timeline/MaxTimelineTracks.tsx
47540
- import { DEFAULT_TIMELINE_TRACKS } from "@remotion/studio-shared";
47541
47754
  import { jsxs as jsxs128 } from "react/jsx-runtime";
47542
- var MAX_TIMELINE_TRACKS = typeof process.env.MAX_TIMELINE_TRACKS === "undefined" || process.env.MAX_TIMELINE_TRACKS === null ? DEFAULT_TIMELINE_TRACKS : Number(process.env.MAX_TIMELINE_TRACKS);
47755
+ var MAX_TIMELINE_TRACKS = getStudioMaxTimelineTracks();
47543
47756
  var MAX_TIMELINE_TRACKS_NOTICE_HEIGHT = 24;
47544
47757
  var container39 = {
47545
47758
  height: MAX_TIMELINE_TRACKS_NOTICE_HEIGHT,
@@ -48135,7 +48348,7 @@ var TimelineDragHandler = () => {
48135
48348
  ref: sliderAreaRef,
48136
48349
  style: containerStyle9,
48137
48350
  ...{ [TIMELINE_SCRUBBER_ATTR]: true },
48138
- children: video ? /* @__PURE__ */ jsx258(TimelineDragHandlerInnerMemo, {}) : null
48351
+ children: video && studioInteractivityEnabled ? /* @__PURE__ */ jsx258(TimelineDragHandlerInnerMemo, {}) : null
48139
48352
  });
48140
48353
  };
48141
48354
  var TimelineDragHandlerInner = () => {
@@ -49202,6 +49415,7 @@ var TimelineSequenceItem = ({
49202
49415
  const nodePath = nodePathInfo?.sequenceSubscriptionKey ?? null;
49203
49416
  const { previewServerState } = useContext111(StudioServerConnectionCtx);
49204
49417
  const previewConnected = previewServerState.type === "connected";
49418
+ const previewInteractive = previewConnected && studioInteractivityEnabled;
49205
49419
  const { getIsExpanded } = useContext111(ExpandedTracksGetterContext);
49206
49420
  const { toggleTrack } = useContext111(ExpandedTracksSetterContext);
49207
49421
  const { setPropStatuses } = useContext111(Internals91.VisualModeSettersContext);
@@ -49238,7 +49452,7 @@ var TimelineSequenceItem = ({
49238
49452
  propStatusesForOverride,
49239
49453
  saveName
49240
49454
  } = useRenameSequence({
49241
- clientId: previewServerState.type === "connected" ? previewServerState.clientId : null,
49455
+ clientId: previewInteractive && previewServerState.type === "connected" ? previewServerState.clientId : null,
49242
49456
  nodePathInfo,
49243
49457
  sequence,
49244
49458
  validatedLocation
@@ -49246,22 +49460,22 @@ var TimelineSequenceItem = ({
49246
49460
  const canDeleteFromSource = Boolean(nodePath && validatedLocation?.source);
49247
49461
  const nodePathKey = useMemo170(() => nodePath ? Internals91.makeSequencePropsSubscriptionKey(nodePath) : null, [nodePath]);
49248
49462
  const parentId = sequence.parent ?? null;
49249
- const canReorderSequence = previewConnected && Boolean(nodePath && nodePathKey && validatedLocation?.source) && nodePathInfo?.numberOfSequencesWithThisNodePath === 1;
49250
- const canHandleSequenceDrag = previewConnected;
49463
+ const canReorderSequence = previewInteractive && Boolean(nodePath && nodePathKey && validatedLocation?.source) && nodePathInfo?.numberOfSequencesWithThisNodePath === 1;
49464
+ const canHandleSequenceDrag = previewInteractive;
49251
49465
  const confirm = useConfirmationDialog();
49252
- const deleteDisabled = useMemo170(() => !previewConnected || !sequence.controls || !canDeleteFromSource, [previewConnected, sequence.controls, canDeleteFromSource]);
49466
+ const deleteDisabled = useMemo170(() => !previewInteractive || !sequence.controls || !canDeleteFromSource, [previewInteractive, sequence.controls, canDeleteFromSource]);
49253
49467
  const duplicateDisabled = deleteDisabled;
49254
- const disableInteractivityDisabled = !previewConnected || !sequence.showInTimeline || !nodePath || !validatedLocation?.source;
49468
+ const disableInteractivityDisabled = !previewInteractive || !sequence.showInTimeline || !nodePath || !validatedLocation?.source;
49255
49469
  const onDuplicateSequenceFromSource = useCallback162(() => {
49256
- if (!validatedLocation?.source || !nodePathInfo) {
49470
+ if (duplicateDisabled || !validatedLocation?.source || !nodePathInfo) {
49257
49471
  return;
49258
49472
  }
49259
49473
  duplicateSequencesFromSource([nodePathInfo], confirm).catch(() => {
49260
49474
  return;
49261
49475
  });
49262
- }, [confirm, nodePathInfo, validatedLocation?.source]);
49476
+ }, [confirm, duplicateDisabled, nodePathInfo, validatedLocation?.source]);
49263
49477
  const onDeleteSequenceFromSource = useCallback162(async () => {
49264
- if (!validatedLocation?.source || !nodePath) {
49478
+ if (deleteDisabled || !validatedLocation?.source || !nodePath) {
49265
49479
  return;
49266
49480
  }
49267
49481
  if (nodePathInfo && nodePathInfo.numberOfSequencesWithThisNodePath > 1) {
@@ -49291,7 +49505,13 @@ var TimelineSequenceItem = ({
49291
49505
  } catch (err) {
49292
49506
  showNotification(err.message, 4000);
49293
49507
  }
49294
- }, [confirm, nodePath, validatedLocation?.source, nodePathInfo]);
49508
+ }, [
49509
+ confirm,
49510
+ deleteDisabled,
49511
+ nodePath,
49512
+ validatedLocation?.source,
49513
+ nodePathInfo
49514
+ ]);
49295
49515
  const onDisableSequenceInteractivity = useCallback162(() => {
49296
49516
  if (disableInteractivityDisabled || !nodePath || !validatedLocation?.source || previewServerState.type !== "connected") {
49297
49517
  return;
@@ -49526,8 +49746,8 @@ var TimelineSequenceItem = ({
49526
49746
  ...effectDropHighlight
49527
49747
  } : inner2;
49528
49748
  }, [effectDropHovered, inner2]);
49529
- const hasExpandableContent = Boolean(sequence.controls) || sequence.effects.length > 0;
49530
- const canToggleVisibility = previewConnected && Boolean(sequence.controls) && nodePath !== null && validatedLocation !== null && codeHiddenStatus !== undefined && codeHiddenStatus !== null && codeHiddenStatus.status === "static";
49749
+ const hasExpandableContent = studioInteractivityEnabled && (Boolean(sequence.controls) || sequence.effects.length > 0);
49750
+ const canToggleVisibility = previewInteractive && Boolean(sequence.controls) && nodePath !== null && validatedLocation !== null && codeHiddenStatus !== undefined && codeHiddenStatus !== null && codeHiddenStatus.status === "static";
49531
49751
  const onSequenceDoubleClick = useCallback162((e) => {
49532
49752
  if (isTimelineSelectionModifierEvent(e)) {
49533
49753
  e.stopPropagation();
@@ -49549,7 +49769,7 @@ var TimelineSequenceItem = ({
49549
49769
  await saveName(name);
49550
49770
  }, [saveName]);
49551
49771
  React194.useEffect(() => {
49552
- if (!canRenameSelectedSequence || !process.env.KEYBOARD_SHORTCUTS_ENABLED) {
49772
+ if (!canRenameSelectedSequence || !getStudioKeyboardShortcutsEnabled()) {
49553
49773
  setIsRenaming(false);
49554
49774
  return;
49555
49775
  }
@@ -49580,7 +49800,7 @@ var TimelineSequenceItem = ({
49580
49800
  setIsRenaming(true);
49581
49801
  }, [canRenameThisSequence]);
49582
49802
  const freezeFrameMenuItem = useSequenceFreezeFrameMenuItem({
49583
- clientId: previewServerState.type === "connected" ? previewServerState.clientId : null,
49803
+ clientId: previewInteractive && previewServerState.type === "connected" ? previewServerState.clientId : null,
49584
49804
  nodePath,
49585
49805
  propStatusesForOverride,
49586
49806
  sequence,
@@ -49589,7 +49809,7 @@ var TimelineSequenceItem = ({
49589
49809
  timelinePosition,
49590
49810
  validatedSource: validatedLocation?.source ?? null
49591
49811
  });
49592
- const canAddEffect = nodePathInfo?.supportsEffects === true && previewServerState.type === "connected" && Boolean(validatedLocation?.source);
49812
+ const canAddEffect = nodePathInfo?.supportsEffects === true && previewInteractive && Boolean(validatedLocation?.source);
49593
49813
  const onAddEffect = useCallback162(() => {
49594
49814
  if (!canAddEffect || previewServerState.type !== "connected" || !nodePath || !validatedLocation?.source) {
49595
49815
  return;
@@ -49618,7 +49838,7 @@ var TimelineSequenceItem = ({
49618
49838
  disableInteractivityDisabled,
49619
49839
  duplicateDisabled,
49620
49840
  fileLocation,
49621
- includeSourceEditItems: true,
49841
+ includeSourceEditItems: studioInteractivityEnabled,
49622
49842
  onDeleteSequenceFromSource,
49623
49843
  onDisableSequenceInteractivity,
49624
49844
  onDuplicateSequenceFromSource,
@@ -49626,7 +49846,7 @@ var TimelineSequenceItem = ({
49626
49846
  originalLocation,
49627
49847
  selectAsset,
49628
49848
  sequence,
49629
- sourceActions: [
49849
+ sourceActions: studioInteractivityEnabled ? [
49630
49850
  ...nodePathInfo?.supportsEffects ? [
49631
49851
  {
49632
49852
  type: "item",
@@ -49660,7 +49880,7 @@ var TimelineSequenceItem = ({
49660
49880
  value: "rename-sequence"
49661
49881
  },
49662
49882
  ...freezeFrameMenuItem ? [freezeFrameMenuItem] : []
49663
- ]
49883
+ ] : []
49664
49884
  });
49665
49885
  }, [
49666
49886
  assetLinkInfo,
@@ -49684,7 +49904,7 @@ var TimelineSequenceItem = ({
49684
49904
  selectAsset,
49685
49905
  sequence
49686
49906
  ]);
49687
- const canDropEffect = previewServerState.type === "connected" && nodePath !== null && validatedLocation !== null && sequence.controls?.supportsEffects === true;
49907
+ const canDropEffect = previewInteractive && nodePath !== null && validatedLocation !== null && sequence.controls?.supportsEffects === true;
49688
49908
  const sequenceReorderLineStyle = useMemo170(() => {
49689
49909
  if (!sequenceDropIndicator) {
49690
49910
  return null;
@@ -49740,7 +49960,7 @@ var TimelineSequenceItem = ({
49740
49960
  onInvoked: onToggleVisibility
49741
49961
  }) : /* @__PURE__ */ jsx266(TimelineLayerEyeSpacer, {}),
49742
49962
  arrow: hasExpandableContent && nodePathInfo !== null ? /* @__PURE__ */ jsx266(TimelineSequenceExpandArrow, {
49743
- disabled: !previewConnected,
49963
+ disabled: !previewInteractive,
49744
49964
  isExpanded,
49745
49965
  nodePathInfo,
49746
49966
  onToggleExpand,
@@ -49810,7 +50030,7 @@ var TimelineSequenceItem = ({
49810
50030
  onOpen: selectable ? onSelect : null,
49811
50031
  children: draggableTrackRow
49812
50032
  }) : draggableTrackRow,
49813
- previewConnected && isExpanded && hasExpandableContent && nodePathInfo && validatedLocation ? /* @__PURE__ */ jsx266(TimelineExpandedSection, {
50033
+ previewConnected && studioInteractivityEnabled && isExpanded && hasExpandableContent && nodePathInfo && validatedLocation ? /* @__PURE__ */ jsx266(TimelineExpandedSection, {
49814
50034
  sequence,
49815
50035
  validatedLocation,
49816
50036
  nodePathInfo,
@@ -52559,11 +52779,12 @@ var TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffset
52559
52779
  const propStatusesForOverride = useMemo176(() => {
52560
52780
  return nodePath ? Internals97.getPropStatusesCtx(propStatuses, nodePath) : undefined;
52561
52781
  }, [propStatuses, nodePath]);
52562
- const durationCanUpdate = Boolean(propStatusesForOverride?.durationInFrames?.status === "static");
52563
- const fromCanUpdate = Boolean(propStatusesForOverride?.from?.status === "static");
52564
- const trimBeforeCanUpdate = Boolean(propStatusesForOverride?.trimBefore?.status === "static");
52782
+ const durationCanUpdate = Boolean(studioInteractivityEnabled && propStatusesForOverride?.durationInFrames?.status === "static");
52783
+ const fromCanUpdate = Boolean(studioInteractivityEnabled && propStatusesForOverride?.from?.status === "static");
52784
+ const trimBeforeCanUpdate = Boolean(studioInteractivityEnabled && propStatusesForOverride?.trimBefore?.status === "static");
52565
52785
  const { previewServerState } = useContext118(StudioServerConnectionCtx);
52566
52786
  const previewConnected = previewServerState.type === "connected";
52787
+ const previewInteractive = previewConnected && studioInteractivityEnabled;
52567
52788
  const { setPropStatuses } = useContext118(Internals97.VisualModeSettersContext);
52568
52789
  const timelinePosition = Internals97.Timeline.useTimelinePosition();
52569
52790
  const selectAsset = useSelectAsset();
@@ -52583,9 +52804,9 @@ var TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffset
52583
52804
  });
52584
52805
  }, [canOpenInEditor, originalLocation]);
52585
52806
  const canDeleteFromSource = Boolean(nodePath && validatedLocation?.source);
52586
- const deleteDisabled = !previewConnected || !s.controls || !canDeleteFromSource;
52807
+ const deleteDisabled = !previewInteractive || !s.controls || !canDeleteFromSource;
52587
52808
  const duplicateDisabled = deleteDisabled;
52588
- const disableInteractivityDisabled = !previewConnected || !s.showInTimeline || !nodePath || !validatedLocation?.source;
52809
+ const disableInteractivityDisabled = !previewInteractive || !s.showInTimeline || !nodePath || !validatedLocation?.source;
52589
52810
  const mediaSrc = s.type === "audio" || s.type === "video" || s.type === "image" ? s.src : null;
52590
52811
  const assetLinkInfo = useMemo176(() => mediaSrc ? getTimelineAssetLinkInfo(mediaSrc) : null, [mediaSrc]);
52591
52812
  const onDuplicateSequenceFromSource = useCallback165(() => {
@@ -52652,7 +52873,7 @@ var TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffset
52652
52873
  validatedLocation?.source
52653
52874
  ]);
52654
52875
  const freezeFrameMenuItem = useSequenceFreezeFrameMenuItem({
52655
- clientId: previewServerState.type === "connected" ? previewServerState.clientId : null,
52876
+ clientId: previewInteractive && previewServerState.type === "connected" ? previewServerState.clientId : null,
52656
52877
  nodePath,
52657
52878
  propStatusesForOverride,
52658
52879
  sequence: s,
@@ -52672,7 +52893,7 @@ var TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffset
52672
52893
  disableInteractivityDisabled,
52673
52894
  duplicateDisabled,
52674
52895
  fileLocation,
52675
- includeSourceEditItems: true,
52896
+ includeSourceEditItems: studioInteractivityEnabled,
52676
52897
  onDeleteSequenceFromSource,
52677
52898
  onDisableSequenceInteractivity,
52678
52899
  onDuplicateSequenceFromSource,
@@ -52680,7 +52901,7 @@ var TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffset
52680
52901
  originalLocation,
52681
52902
  selectAsset,
52682
52903
  sequence: s,
52683
- sourceActions: freezeFrameMenuItem ? [freezeFrameMenuItem] : []
52904
+ sourceActions: studioInteractivityEnabled && freezeFrameMenuItem ? [freezeFrameMenuItem] : []
52684
52905
  });
52685
52906
  }, [
52686
52907
  assetLinkInfo,
@@ -52907,6 +53128,7 @@ var TimelineContextMenuArea = ({ children }) => {
52907
53128
  const [isAddingAsset, setIsAddingAsset] = useState99(false);
52908
53129
  const { previewServerState } = useContext120(StudioServerConnectionCtx);
52909
53130
  const previewConnected = previewServerState.type === "connected";
53131
+ const previewInteractive = previewConnected && studioInteractivityEnabled;
52910
53132
  const currentCompositionId = canvasContent?.type === "composition" ? canvasContent.compositionId : null;
52911
53133
  const currentComposition = useMemo179(() => {
52912
53134
  if (currentCompositionId === null) {
@@ -52920,8 +53142,8 @@ var TimelineContextMenuArea = ({ children }) => {
52920
53142
  compositionFile,
52921
53143
  compositionId: currentCompositionId
52922
53144
  });
52923
- const canInsertSolid = previewConnected && compositionComponentInfo?.canAddSequence === true && currentCompositionId !== null && compositionFile !== null && videoConfig !== null && !isAddingSolid;
52924
- const canInsertAsset = previewConnected && !window.remotion_isReadOnlyStudio && compositionComponentInfo?.canAddSequence === true && currentCompositionId !== null && compositionFile !== null && !isAddingAsset;
53145
+ const canInsertSolid = previewInteractive && compositionComponentInfo?.canAddSequence === true && currentCompositionId !== null && compositionFile !== null && videoConfig !== null && !isAddingSolid;
53146
+ const canInsertAsset = previewInteractive && !window.remotion_isReadOnlyStudio && compositionComponentInfo?.canAddSequence === true && currentCompositionId !== null && compositionFile !== null && !isAddingAsset;
52925
53147
  const insertSolid = useCallback166(async () => {
52926
53148
  if (!canInsertSolid || currentCompositionId === null || compositionFile === null || videoConfig === null) {
52927
53149
  return;
@@ -53013,6 +53235,7 @@ var TimelineInner = () => {
53013
53235
  const { overrideIdToNodePathMappings } = useContext120(Internals98.OverrideIdsToNodePathsGettersContext);
53014
53236
  const { previewServerState } = useContext120(StudioServerConnectionCtx);
53015
53237
  const previewConnected = previewServerState.type === "connected";
53238
+ const previewInteractive = previewConnected && studioInteractivityEnabled;
53016
53239
  const videoConfigIsNull = videoConfig === null;
53017
53240
  const timeline = useMemo179(() => {
53018
53241
  if (videoConfigIsNull) {
@@ -53034,7 +53257,7 @@ var TimelineInner = () => {
53034
53257
  return /* @__PURE__ */ jsxs146(TimelineContextMenuArea, {
53035
53258
  children: [
53036
53259
  sequences.map((sequence) => {
53037
- if (!shouldSubscribeToSequenceProps(sequence, previewConnected)) {
53260
+ if (!shouldSubscribeToSequenceProps(sequence, previewInteractive)) {
53038
53261
  return null;
53039
53262
  }
53040
53263
  return /* @__PURE__ */ jsx282(SubscribeToNodePaths, {
@@ -53045,15 +53268,15 @@ var TimelineInner = () => {
53045
53268
  effects: sequence.effects
53046
53269
  }, sequence.id);
53047
53270
  }),
53048
- /* @__PURE__ */ jsx282(SequencePropsObserver, {}),
53271
+ studioInteractivityEnabled ? /* @__PURE__ */ jsx282(SequencePropsObserver, {}) : null,
53049
53272
  /* @__PURE__ */ jsx282(TimelineKeyframeTracksProvider, {
53050
53273
  tracks: filtered,
53051
53274
  children: /* @__PURE__ */ jsxs146(TimelineSelectableItemsProvider, {
53052
53275
  timeline: shown,
53053
53276
  children: [
53054
- /* @__PURE__ */ jsx282(TimelineSelectAllKeybindings, {
53277
+ studioInteractivityEnabled ? /* @__PURE__ */ jsx282(TimelineSelectAllKeybindings, {
53055
53278
  timeline: shown
53056
- }),
53279
+ }) : null,
53057
53280
  /* @__PURE__ */ jsx282(TimelineHeightContainer, {
53058
53281
  shown,
53059
53282
  hasBeenCut,
@@ -53093,7 +53316,7 @@ var TimelineInner = () => {
53093
53316
  /* @__PURE__ */ jsx282(TimelineInOutPointer, {}),
53094
53317
  /* @__PURE__ */ jsx282(TimelineTimeIndicators, {}),
53095
53318
  /* @__PURE__ */ jsx282(TimelineDragHandler, {}),
53096
- /* @__PURE__ */ jsx282(TimelineInOutDragHandler, {}),
53319
+ studioInteractivityEnabled ? /* @__PURE__ */ jsx282(TimelineInOutDragHandler, {}) : null,
53097
53320
  /* @__PURE__ */ jsx282(TimelineSlider, {})
53098
53321
  ]
53099
53322
  })
@@ -56819,7 +57042,7 @@ var KeyboardShortcutsExplainer = () => {
56819
57042
  })
56820
57043
  ]
56821
57044
  }),
56822
- process.env.ASK_AI_ENABLED && /* @__PURE__ */ jsxs164(Fragment57, {
57045
+ getStudioAskAIEnabled() && /* @__PURE__ */ jsxs164(Fragment57, {
56823
57046
  children: [
56824
57047
  /* @__PURE__ */ jsx304("br", {}),
56825
57048
  /* @__PURE__ */ jsx304("div", {
@@ -65398,7 +65621,7 @@ var Modals = ({ readOnlyStudio }) => {
65398
65621
  modalContextType && modalContextType.type === "confirmation-dialog" && /* @__PURE__ */ jsx360(ConfirmationDialog, {
65399
65622
  state: modalContextType
65400
65623
  }),
65401
- process.env.ASK_AI_ENABLED && /* @__PURE__ */ jsx360(AskAiModal, {})
65624
+ getStudioAskAIEnabled() && /* @__PURE__ */ jsx360(AskAiModal, {})
65402
65625
  ]
65403
65626
  });
65404
65627
  };
@@ -65486,8 +65709,7 @@ var background = {
65486
65709
  flexDirection: "column",
65487
65710
  position: "absolute"
65488
65711
  };
65489
- var DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS = 300;
65490
- var BUFFER_STATE_DELAY_IN_MILLISECONDS = typeof process.env.BUFFER_STATE_DELAY_IN_MILLISECONDS === "undefined" || process.env.BUFFER_STATE_DELAY_IN_MILLISECONDS === null ? DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS : Number(process.env.BUFFER_STATE_DELAY_IN_MILLISECONDS);
65712
+ var BUFFER_STATE_DELAY_IN_MILLISECONDS = getStudioBufferStateDelayInMilliseconds();
65491
65713
  var Editor = ({ Root, readOnlyStudio }) => {
65492
65714
  const [drawElement, setDrawElement] = useState125(null);
65493
65715
  const size3 = PlayerInternals23.useElementSize(drawElement, {