@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.
@@ -7676,12 +7676,12 @@ var TimelineZoomContext = ({ children }) => {
7676
7676
  // src/components/Canvas.tsx
7677
7677
  import {
7678
7678
  ASSET_DRAG_MIME_TYPE as ASSET_DRAG_MIME_TYPE2,
7679
- COMPOSITION_DRAG_MIME_TYPE as COMPOSITION_DRAG_MIME_TYPE2,
7680
7679
  COMPONENT_DRAG_MIME_TYPE as COMPONENT_DRAG_MIME_TYPE2,
7680
+ COMPOSITION_DRAG_MIME_TYPE as COMPOSITION_DRAG_MIME_TYPE2,
7681
7681
  ELEMENT_DRAG_MIME_TYPE as ELEMENT_DRAG_MIME_TYPE3,
7682
7682
  parseAssetDragData,
7683
- parseCompositionDragData,
7684
7683
  parseComponentDragData,
7684
+ parseCompositionDragData,
7685
7685
  parseSfxDragData,
7686
7686
  SFX_DRAG_MIME_TYPE as SFX_DRAG_MIME_TYPE2
7687
7687
  } from "@remotion/studio-shared";
@@ -7963,21 +7963,191 @@ var getRemoteAssetUrlFromDataTransfer = (dataTransfer) => {
7963
7963
  return isHttpUrl(plainText) ? plainText : null;
7964
7964
  };
7965
7965
 
7966
+ // src/components/ConfirmationDialog.tsx
7967
+ import {
7968
+ useCallback as useCallback28,
7969
+ useContext as useContext13,
7970
+ useEffect as useEffect25,
7971
+ useMemo as useMemo32,
7972
+ useRef as useRef15
7973
+ } from "react";
7974
+
7975
+ // src/components/ModalButton.tsx
7976
+ import { useMemo as useMemo31 } from "react";
7977
+ import { jsx as jsx57 } from "react/jsx-runtime";
7978
+ var buttonStyle2 = {
7979
+ backgroundColor: BLUE,
7980
+ color: WHITE
7981
+ };
7982
+ var ModalButton = (props) => {
7983
+ const style5 = useMemo31(() => {
7984
+ return {
7985
+ ...buttonStyle2,
7986
+ backgroundColor: props.disabled ? BLUE_DISABLED : BLUE
7987
+ };
7988
+ }, [props.disabled]);
7989
+ return /* @__PURE__ */ jsx57(Button, {
7990
+ ...props,
7991
+ style: style5
7992
+ });
7993
+ };
7994
+
7995
+ // src/components/ModalFooter.tsx
7996
+ import { jsx as jsx58 } from "react/jsx-runtime";
7997
+ var content = {
7998
+ padding: 12,
7999
+ paddingRight: 12,
8000
+ flex: 1,
8001
+ fontSize: 13,
8002
+ minWidth: 500
8003
+ };
8004
+ var ModalFooterContainer = ({ children }) => {
8005
+ return /* @__PURE__ */ jsx58("div", {
8006
+ style: { ...content, borderTop: BORDER_BLACK },
8007
+ children
8008
+ });
8009
+ };
8010
+
8011
+ // src/components/ConfirmationDialog.tsx
8012
+ import { jsx as jsx59, jsxs as jsxs28 } from "react/jsx-runtime";
8013
+ var content2 = {
8014
+ padding: 16,
8015
+ fontSize: 14,
8016
+ flex: 1,
8017
+ minWidth: 420,
8018
+ maxWidth: 560,
8019
+ lineHeight: 1.4
8020
+ };
8021
+ var useConfirmationDialog = () => {
8022
+ const { setSelectedModal } = useContext13(ModalsContext);
8023
+ return useCallback28((options) => {
8024
+ return new Promise((resolve) => {
8025
+ let settled = false;
8026
+ const settle = (result) => {
8027
+ if (settled) {
8028
+ return;
8029
+ }
8030
+ settled = true;
8031
+ resolve(result);
8032
+ };
8033
+ setSelectedModal({
8034
+ type: "confirmation-dialog",
8035
+ id: String(Math.random()),
8036
+ title: options.title,
8037
+ message: options.message,
8038
+ confirmLabel: options.confirmLabel ?? "Continue",
8039
+ cancelLabel: options.cancelLabel ?? "Cancel",
8040
+ onConfirm: () => settle(true),
8041
+ onCancel: () => settle(false)
8042
+ });
8043
+ });
8044
+ }, [setSelectedModal]);
8045
+ };
8046
+ var ConfirmationDialog = ({ state }) => {
8047
+ const { setSelectedModal } = useContext13(ModalsContext);
8048
+ const settledRef = useRef15(false);
8049
+ const closeCurrentModal = useCallback28(() => {
8050
+ setSelectedModal((modal) => modal?.type === "confirmation-dialog" && modal.id === state.id ? null : modal);
8051
+ }, [setSelectedModal, state.id]);
8052
+ const settle = useCallback28((confirmed) => {
8053
+ if (settledRef.current) {
8054
+ return;
8055
+ }
8056
+ settledRef.current = true;
8057
+ closeCurrentModal();
8058
+ if (confirmed) {
8059
+ state.onConfirm();
8060
+ } else {
8061
+ state.onCancel();
8062
+ }
8063
+ }, [closeCurrentModal, state]);
8064
+ useEffect25(() => {
8065
+ return () => {
8066
+ if (settledRef.current) {
8067
+ return;
8068
+ }
8069
+ settledRef.current = true;
8070
+ state.onCancel();
8071
+ };
8072
+ }, [state]);
8073
+ const onCancel = useCallback28(() => {
8074
+ settle(false);
8075
+ }, [settle]);
8076
+ const onConfirm = useCallback28(() => {
8077
+ settle(true);
8078
+ }, [settle]);
8079
+ const onSubmit = useCallback28((e) => {
8080
+ e.preventDefault();
8081
+ onConfirm();
8082
+ }, [onConfirm]);
8083
+ const cancelStyle = useMemo32(() => {
8084
+ return {
8085
+ minWidth: 90
8086
+ };
8087
+ }, []);
8088
+ return /* @__PURE__ */ jsxs28(ModalContainer, {
8089
+ onOutsideClick: onCancel,
8090
+ onEscape: onCancel,
8091
+ children: [
8092
+ /* @__PURE__ */ jsx59(ModalHeader, {
8093
+ title: state.title,
8094
+ onClose: onCancel
8095
+ }),
8096
+ /* @__PURE__ */ jsxs28("form", {
8097
+ onSubmit,
8098
+ children: [
8099
+ /* @__PURE__ */ jsx59("div", {
8100
+ style: content2,
8101
+ children: state.message
8102
+ }),
8103
+ /* @__PURE__ */ jsx59(ModalFooterContainer, {
8104
+ children: /* @__PURE__ */ jsxs28(Row, {
8105
+ align: "center",
8106
+ children: [
8107
+ /* @__PURE__ */ jsx59(Flex, {}),
8108
+ /* @__PURE__ */ jsx59(Button, {
8109
+ onClick: onCancel,
8110
+ style: cancelStyle,
8111
+ children: state.cancelLabel
8112
+ }),
8113
+ /* @__PURE__ */ jsx59(Spacing, {
8114
+ x: 1
8115
+ }),
8116
+ /* @__PURE__ */ jsxs28(ModalButton, {
8117
+ onClick: onConfirm,
8118
+ autoFocus: true,
8119
+ children: [
8120
+ state.confirmLabel,
8121
+ /* @__PURE__ */ jsx59(ShortcutHint, {
8122
+ keyToPress: "↵",
8123
+ cmdOrCtrl: false
8124
+ })
8125
+ ]
8126
+ })
8127
+ ]
8128
+ })
8129
+ })
8130
+ ]
8131
+ })
8132
+ ]
8133
+ });
8134
+ };
8135
+
7966
8136
  // src/components/EditorGuides/index.tsx
7967
8137
  import { useContext as useContext19, useMemo as useMemo39 } from "react";
7968
8138
  import { Internals as Internals22 } from "remotion";
7969
8139
 
7970
8140
  // src/helpers/use-studio-canvas-dimensions.ts
7971
8141
  import { PlayerInternals as PlayerInternals7 } from "@remotion/player";
7972
- import { useContext as useContext13, useMemo as useMemo31 } from "react";
8142
+ import { useContext as useContext14, useMemo as useMemo33 } from "react";
7973
8143
  import { Internals as Internals12 } from "remotion";
7974
8144
  var useStudioCanvasDimensions = ({
7975
8145
  canvasSize,
7976
8146
  contentDimensions,
7977
8147
  assetMetadata
7978
8148
  }) => {
7979
- const { size: previewSize } = useContext13(Internals12.PreviewSizeContext);
7980
- const { centerX, centerY, scale } = useMemo31(() => {
8149
+ const { size: previewSize } = useContext14(Internals12.PreviewSizeContext);
8150
+ const { centerX, centerY, scale } = useMemo33(() => {
7981
8151
  if (contentDimensions === "none" || contentDimensions === null || assetMetadata && (assetMetadata.type === "not-found" || assetMetadata.type === "metadata-error") || !canvasSize) {
7982
8152
  return {
7983
8153
  centerX: previewSize.translation.x,
@@ -7999,7 +8169,7 @@ var useStudioCanvasDimensions = ({
7999
8169
  previewSize.translation.x,
8000
8170
  assetMetadata
8001
8171
  ]);
8002
- const canvasPosition = useMemo31(() => {
8172
+ const canvasPosition = useMemo33(() => {
8003
8173
  return {
8004
8174
  left: centerX - previewSize.translation.x,
8005
8175
  top: centerY - previewSize.translation.y,
@@ -8086,9 +8256,9 @@ var getRulerGuideHighlight = ({
8086
8256
 
8087
8257
  // src/components/ContextMenu.tsx
8088
8258
  import { PlayerInternals as PlayerInternals8 } from "@remotion/player";
8089
- import React44, { useCallback as useCallback28, useEffect as useEffect25, useMemo as useMemo32, useRef as useRef15, useState as useState24 } from "react";
8259
+ import React46, { useCallback as useCallback29, useEffect as useEffect26, useMemo as useMemo34, useRef as useRef16, useState as useState24 } from "react";
8090
8260
  import ReactDOM4 from "react-dom";
8091
- import { jsx as jsx57, jsxs as jsxs28, Fragment as Fragment11 } from "react/jsx-runtime";
8261
+ import { jsx as jsx60, jsxs as jsxs29, Fragment as Fragment11 } from "react/jsx-runtime";
8092
8262
  var CONTEXT_MENU_Z_INDEX = 1001;
8093
8263
  var contextMenuFullScreenOverlay = {
8094
8264
  ...fullScreenOverlay,
@@ -8107,25 +8277,25 @@ var notifyContextMenuOpened = (id) => {
8107
8277
  }));
8108
8278
  };
8109
8279
  var ContextMenuPortal = ({ sizeSource, currentZIndex, onHide, opened, values }) => {
8110
- const menuRef = useRef15(null);
8280
+ const menuRef = useRef16(null);
8111
8281
  const size2 = PlayerInternals8.useElementSize(sizeSource, {
8112
8282
  triggerOnWindowResize: true,
8113
8283
  shouldApplyCssTransforms: true
8114
8284
  });
8115
8285
  const isMobileLayout = useMobileLayout();
8116
- const spaceToBottom = useMemo32(() => {
8286
+ const spaceToBottom = useMemo34(() => {
8117
8287
  if (size2) {
8118
8288
  return size2.windowSize.height - opened.top;
8119
8289
  }
8120
8290
  return 0;
8121
8291
  }, [opened.top, size2]);
8122
- const spaceToTop = useMemo32(() => {
8292
+ const spaceToTop = useMemo34(() => {
8123
8293
  if (size2) {
8124
8294
  return opened.top;
8125
8295
  }
8126
8296
  return 0;
8127
8297
  }, [opened.top, size2]);
8128
- const portalStyle = useMemo32(() => {
8298
+ const portalStyle = useMemo34(() => {
8129
8299
  if (!size2) {
8130
8300
  return;
8131
8301
  }
@@ -8157,7 +8327,7 @@ var ContextMenuPortal = ({ sizeSource, currentZIndex, onHide, opened, values })
8157
8327
  spaceToTop,
8158
8328
  spaceToBottom
8159
8329
  ]);
8160
- useEffect25(() => {
8330
+ useEffect26(() => {
8161
8331
  const preventNativeContextMenu = (event) => {
8162
8332
  event.preventDefault();
8163
8333
  };
@@ -8166,7 +8336,7 @@ var ContextMenuPortal = ({ sizeSource, currentZIndex, onHide, opened, values })
8166
8336
  window.removeEventListener("contextmenu", preventNativeContextMenu, true);
8167
8337
  };
8168
8338
  }, []);
8169
- useEffect25(() => {
8339
+ useEffect26(() => {
8170
8340
  const dismissWithoutClickThrough = (event) => {
8171
8341
  if (event.button !== 0) {
8172
8342
  return;
@@ -8184,26 +8354,26 @@ var ContextMenuPortal = ({ sizeSource, currentZIndex, onHide, opened, values })
8184
8354
  window.removeEventListener("pointerdown", dismissWithoutClickThrough, true);
8185
8355
  };
8186
8356
  }, [onHide]);
8187
- const onMenuPointerDown = useCallback28((e) => {
8357
+ const onMenuPointerDown = useCallback29((e) => {
8188
8358
  e.stopPropagation();
8189
8359
  }, []);
8190
8360
  if (!portalStyle) {
8191
8361
  return null;
8192
8362
  }
8193
- return ReactDOM4.createPortal(/* @__PURE__ */ jsx57("div", {
8363
+ return ReactDOM4.createPortal(/* @__PURE__ */ jsx60("div", {
8194
8364
  style: contextMenuFullScreenOverlay,
8195
- children: /* @__PURE__ */ jsx57("div", {
8365
+ children: /* @__PURE__ */ jsx60("div", {
8196
8366
  style: contextMenuOuterPortal,
8197
8367
  className: "css-reset",
8198
- children: /* @__PURE__ */ jsx57(HigherZIndex, {
8368
+ children: /* @__PURE__ */ jsx60(HigherZIndex, {
8199
8369
  onOutsideClick: onHide,
8200
8370
  onEscape: onHide,
8201
8371
  outsideClickButton: "primary",
8202
- children: /* @__PURE__ */ jsx57("div", {
8372
+ children: /* @__PURE__ */ jsx60("div", {
8203
8373
  ref: menuRef,
8204
8374
  style: portalStyle,
8205
8375
  onPointerDown: onMenuPointerDown,
8206
- children: /* @__PURE__ */ jsx57(MenuContent, {
8376
+ children: /* @__PURE__ */ jsx60(MenuContent, {
8207
8377
  onNextMenu: noop,
8208
8378
  onPreviousMenu: noop,
8209
8379
  values,
@@ -8218,7 +8388,7 @@ var ContextMenuPortal = ({ sizeSource, currentZIndex, onHide, opened, values })
8218
8388
  })
8219
8389
  }), getPortal(currentZIndex));
8220
8390
  };
8221
- var ContextMenu = React44.forwardRef(({
8391
+ var ContextMenu = React46.forwardRef(({
8222
8392
  children,
8223
8393
  values,
8224
8394
  onOpen,
@@ -8226,11 +8396,11 @@ var ContextMenu = React44.forwardRef(({
8226
8396
  className: className2 = undefined,
8227
8397
  onPointerDown = undefined
8228
8398
  }, forwardedRef) => {
8229
- const ref = useRef15(null);
8230
- const idRef = useRef15(nextContextMenuId++);
8399
+ const ref = useRef16(null);
8400
+ const idRef = useRef16(nextContextMenuId++);
8231
8401
  const [opened, setOpened] = useState24({ type: "not-open" });
8232
8402
  const { currentZIndex } = useZIndex();
8233
- const setRef = useCallback28((node) => {
8403
+ const setRef = useCallback29((node) => {
8234
8404
  ref.current = node;
8235
8405
  if (typeof forwardedRef === "function") {
8236
8406
  forwardedRef(node);
@@ -8240,7 +8410,7 @@ var ContextMenu = React44.forwardRef(({
8240
8410
  forwardedRef.current = node;
8241
8411
  }
8242
8412
  }, [forwardedRef]);
8243
- useEffect25(() => {
8413
+ useEffect26(() => {
8244
8414
  const { current } = ref;
8245
8415
  if (!current) {
8246
8416
  return;
@@ -8260,10 +8430,10 @@ var ContextMenu = React44.forwardRef(({
8260
8430
  current.removeEventListener("contextmenu", onClick);
8261
8431
  };
8262
8432
  }, [onOpen]);
8263
- const onHide = useCallback28(() => {
8433
+ const onHide = useCallback29(() => {
8264
8434
  setOpened({ type: "not-open" });
8265
8435
  }, []);
8266
- useEffect25(() => {
8436
+ useEffect26(() => {
8267
8437
  const onOtherContextMenuOpened = (event) => {
8268
8438
  if (event.detail === idRef.current) {
8269
8439
  return;
@@ -8275,9 +8445,9 @@ var ContextMenu = React44.forwardRef(({
8275
8445
  window.removeEventListener(contextMenuOpenedEvent, onOtherContextMenuOpened);
8276
8446
  };
8277
8447
  }, [onHide]);
8278
- return /* @__PURE__ */ jsxs28(Fragment11, {
8448
+ return /* @__PURE__ */ jsxs29(Fragment11, {
8279
8449
  children: [
8280
- /* @__PURE__ */ jsx57("div", {
8450
+ /* @__PURE__ */ jsx60("div", {
8281
8451
  ref: setRef,
8282
8452
  onContextMenu: () => false,
8283
8453
  style: style5,
@@ -8285,7 +8455,7 @@ var ContextMenu = React44.forwardRef(({
8285
8455
  onPointerDown,
8286
8456
  children
8287
8457
  }),
8288
- opened.type === "open" ? /* @__PURE__ */ jsx57(ContextMenuPortal, {
8458
+ opened.type === "open" ? /* @__PURE__ */ jsx60(ContextMenuPortal, {
8289
8459
  sizeSource: ref,
8290
8460
  currentZIndex,
8291
8461
  onHide,
@@ -8297,15 +8467,15 @@ var ContextMenu = React44.forwardRef(({
8297
8467
  });
8298
8468
  ContextMenu.displayName = "ContextMenu";
8299
8469
  var ContextMenuForTarget = ({ triggerRef, values, onOpen }) => {
8300
- const idRef = useRef15(nextContextMenuId++);
8470
+ const idRef = useRef16(nextContextMenuId++);
8301
8471
  const [opened, setOpened] = useState24({ type: "not-open" });
8302
8472
  const [openedValues, setOpenedValues] = useState24(values);
8303
8473
  const [body, setBody] = useState24(null);
8304
8474
  const { currentZIndex } = useZIndex();
8305
- useEffect25(() => {
8475
+ useEffect26(() => {
8306
8476
  setBody(document.body);
8307
8477
  }, []);
8308
- useEffect25(() => {
8478
+ useEffect26(() => {
8309
8479
  const { current } = triggerRef;
8310
8480
  if (!current) {
8311
8481
  return;
@@ -8332,10 +8502,10 @@ var ContextMenuForTarget = ({ triggerRef, values, onOpen }) => {
8332
8502
  current.removeEventListener("contextmenu", onClick);
8333
8503
  };
8334
8504
  }, [onOpen, triggerRef, values]);
8335
- const onHide = useCallback28(() => {
8505
+ const onHide = useCallback29(() => {
8336
8506
  setOpened({ type: "not-open" });
8337
8507
  }, []);
8338
- useEffect25(() => {
8508
+ useEffect26(() => {
8339
8509
  const onOtherContextMenuOpened = (event) => {
8340
8510
  if (event.detail === idRef.current) {
8341
8511
  return;
@@ -8347,7 +8517,7 @@ var ContextMenuForTarget = ({ triggerRef, values, onOpen }) => {
8347
8517
  window.removeEventListener(contextMenuOpenedEvent, onOtherContextMenuOpened);
8348
8518
  };
8349
8519
  }, [onHide]);
8350
- return opened.type === "open" ? /* @__PURE__ */ jsx57(ContextMenuPortal, {
8520
+ return opened.type === "open" ? /* @__PURE__ */ jsx60(ContextMenuPortal, {
8351
8521
  sizeSource: body,
8352
8522
  currentZIndex,
8353
8523
  onHide,
@@ -8357,9 +8527,9 @@ var ContextMenuForTarget = ({ triggerRef, values, onOpen }) => {
8357
8527
  };
8358
8528
 
8359
8529
  // src/components/ForceSpecificCursor.tsx
8360
- import React45, { useMemo as useMemo33 } from "react";
8361
- import { jsx as jsx58 } from "react/jsx-runtime";
8362
- var ref = React45.createRef();
8530
+ import React47, { useMemo as useMemo35 } from "react";
8531
+ import { jsx as jsx61 } from "react/jsx-runtime";
8532
+ var ref = React47.createRef();
8363
8533
  var forceSpecificCursor = (cursor) => {
8364
8534
  if (!ref.current) {
8365
8535
  throw new Error("ForceSpecificCursor is not mounted");
@@ -8376,7 +8546,7 @@ var stopForcingSpecificCursor = () => {
8376
8546
  };
8377
8547
  var Z_INDEX_FORCE_SPECIFIC_CURSOR = 100;
8378
8548
  var ForceSpecificCursor = () => {
8379
- const style5 = useMemo33(() => {
8549
+ const style5 = useMemo35(() => {
8380
8550
  return {
8381
8551
  position: "fixed",
8382
8552
  inset: 0,
@@ -8384,7 +8554,7 @@ var ForceSpecificCursor = () => {
8384
8554
  pointerEvents: "none"
8385
8555
  };
8386
8556
  }, []);
8387
- return /* @__PURE__ */ jsx58("div", {
8557
+ return /* @__PURE__ */ jsx61("div", {
8388
8558
  ref,
8389
8559
  style: style5
8390
8560
  });
@@ -8420,6 +8590,10 @@ import {
8420
8590
  Internals as Internals21
8421
8591
  } from "remotion";
8422
8592
 
8593
+ // src/helpers/interactivity-enabled.ts
8594
+ var interactivityEnabled = process.env.INTERACTIVITY_ENABLED;
8595
+ var studioInteractivityEnabled = interactivityEnabled === undefined || interactivityEnabled === null ? true : interactivityEnabled !== false && interactivityEnabled !== "false";
8596
+
8423
8597
  // src/helpers/timeline-node-path-key.ts
8424
8598
  import { stringifySequenceExpandedRowKey } from "@remotion/studio-shared";
8425
8599
  var timelineNodePathInfoToKey = (info) => [
@@ -8429,7 +8603,7 @@ var timelineNodePathInfoToKey = (info) => [
8429
8603
  ].join(".");
8430
8604
 
8431
8605
  // src/components/ExpandedTracksProvider.tsx
8432
- import { createContext as createContext14, useCallback as useCallback29, useMemo as useMemo34, useState as useState25 } from "react";
8606
+ import { createContext as createContext14, useCallback as useCallback30, useMemo as useMemo36, useState as useState25 } from "react";
8433
8607
 
8434
8608
  // src/helpers/migrate-expanded-tracks-for-subscription-key.ts
8435
8609
  import { stringifySequenceExpandedRowKey as stringifySequenceExpandedRowKey2 } from "@remotion/studio-shared";
@@ -8456,7 +8630,7 @@ var migrateExpandedTracksForSubscriptionKey = (prev, oldKey, newKey) => {
8456
8630
  };
8457
8631
 
8458
8632
  // src/components/ExpandedTracksProvider.tsx
8459
- import { jsx as jsx59 } from "react/jsx-runtime";
8633
+ import { jsx as jsx62 } from "react/jsx-runtime";
8460
8634
  var SESSION_STORAGE_KEY = "remotion.editor.expandedTracks";
8461
8635
  var onlyCollapsedTrackValues = (state) => {
8462
8636
  const result = {};
@@ -8511,7 +8685,7 @@ var ExpandedTracksSetterContext = createContext14({
8511
8685
  });
8512
8686
  var ExpandedTracksProvider = ({ children }) => {
8513
8687
  const [expandedTracks, setExpandedTracks] = useState25(loadExpandedTracks);
8514
- const expandParentTracks = useCallback29((nodePathInfo) => {
8688
+ const expandParentTracks = useCallback30((nodePathInfo) => {
8515
8689
  const keysToExpand = [];
8516
8690
  for (let i = 0;i < nodePathInfo.auxiliaryKeys.length; i++) {
8517
8691
  keysToExpand.push(timelineNodePathInfoToKey({
@@ -8538,7 +8712,7 @@ var ExpandedTracksProvider = ({ children }) => {
8538
8712
  return next;
8539
8713
  });
8540
8714
  }, []);
8541
- const toggleTrack = useCallback29((nodePathInfo) => {
8715
+ const toggleTrack = useCallback30((nodePathInfo) => {
8542
8716
  setExpandedTracks((prev) => {
8543
8717
  const key2 = timelineNodePathInfoToKey(nodePathInfo);
8544
8718
  const next = { ...prev };
@@ -8552,7 +8726,7 @@ var ExpandedTracksProvider = ({ children }) => {
8552
8726
  return next;
8553
8727
  });
8554
8728
  }, []);
8555
- const migrateExpandedTracks = useCallback29((oldKey, newKey) => {
8729
+ const migrateExpandedTracks = useCallback30((oldKey, newKey) => {
8556
8730
  setExpandedTracks((prev) => {
8557
8731
  const next = migrateExpandedTracksForSubscriptionKey(prev, oldKey, newKey);
8558
8732
  if (!next) {
@@ -8562,17 +8736,17 @@ var ExpandedTracksProvider = ({ children }) => {
8562
8736
  return next;
8563
8737
  });
8564
8738
  }, []);
8565
- const getterValue = useMemo34(() => ({
8739
+ const getterValue = useMemo36(() => ({
8566
8740
  getIsExpanded: (nodePathInfo) => expandedTracks[timelineNodePathInfoToKey(nodePathInfo)] ?? true
8567
8741
  }), [expandedTracks]);
8568
- const setterValue = useMemo34(() => ({
8742
+ const setterValue = useMemo36(() => ({
8569
8743
  expandParentTracks,
8570
8744
  toggleTrack,
8571
8745
  migrateExpandedTracksForSubscriptionKey: migrateExpandedTracks
8572
8746
  }), [expandParentTracks, toggleTrack, migrateExpandedTracks]);
8573
- return /* @__PURE__ */ jsx59(ExpandedTracksSetterContext.Provider, {
8747
+ return /* @__PURE__ */ jsx62(ExpandedTracksSetterContext.Provider, {
8574
8748
  value: setterValue,
8575
- children: /* @__PURE__ */ jsx59(ExpandedTracksGetterContext.Provider, {
8749
+ children: /* @__PURE__ */ jsx62(ExpandedTracksGetterContext.Provider, {
8576
8750
  value: getterValue,
8577
8751
  children
8578
8752
  })
@@ -8769,7 +8943,7 @@ import {
8769
8943
  parseEffectClipboardDataResult,
8770
8944
  parseEffectPropClipboardDataResult
8771
8945
  } from "@remotion/studio-shared";
8772
- import { useContext as useContext14, useEffect as useEffect26 } from "react";
8946
+ import { useContext as useContext15, useEffect as useEffect27 } from "react";
8773
8947
  import {
8774
8948
  Internals as Internals16
8775
8949
  } from "remotion";
@@ -9713,14 +9887,14 @@ var getPasteEffectPropTarget = ({
9713
9887
  };
9714
9888
  var TimelineClipboardKeybindings = () => {
9715
9889
  const keybindings = useKeybinding();
9716
- const { previewServerState } = useContext14(StudioServerConnectionCtx);
9890
+ const { previewServerState } = useContext15(StudioServerConnectionCtx);
9717
9891
  const { canSelect } = useTimelineSelection();
9718
9892
  const currentSelection = useCurrentTimelineSelectionStateAsRef();
9719
- const propStatusesRef = useContext14(Internals16.VisualModePropStatusesRefContext);
9720
- const { setPropStatuses } = useContext14(Internals16.VisualModeSettersContext);
9721
- const sequencesRef = useContext14(Internals16.SequenceManagerRefContext);
9722
- const { overrideIdToNodePathMappings } = useContext14(Internals16.OverrideIdsToNodePathsGettersContext);
9723
- useEffect26(() => {
9893
+ const propStatusesRef = useContext15(Internals16.VisualModePropStatusesRefContext);
9894
+ const { setPropStatuses } = useContext15(Internals16.VisualModeSettersContext);
9895
+ const sequencesRef = useContext15(Internals16.SequenceManagerRefContext);
9896
+ const { overrideIdToNodePathMappings } = useContext15(Internals16.OverrideIdsToNodePathsGettersContext);
9897
+ useEffect27(() => {
9724
9898
  if (!canSelect || previewServerState.type !== "connected") {
9725
9899
  return;
9726
9900
  }
@@ -9987,176 +10161,6 @@ import { LINEAR_KEYFRAME_EASING as LINEAR_KEYFRAME_EASING2 } from "@remotion/stu
9987
10161
  import { useContext as useContext16, useEffect as useEffect28, useRef as useRef17 } from "react";
9988
10162
  import { Internals as Internals20 } from "remotion";
9989
10163
 
9990
- // src/components/ConfirmationDialog.tsx
9991
- import {
9992
- useCallback as useCallback30,
9993
- useContext as useContext15,
9994
- useEffect as useEffect27,
9995
- useMemo as useMemo36,
9996
- useRef as useRef16
9997
- } from "react";
9998
-
9999
- // src/components/ModalButton.tsx
10000
- import { useMemo as useMemo35 } from "react";
10001
- import { jsx as jsx60 } from "react/jsx-runtime";
10002
- var buttonStyle2 = {
10003
- backgroundColor: BLUE,
10004
- color: WHITE
10005
- };
10006
- var ModalButton = (props) => {
10007
- const style5 = useMemo35(() => {
10008
- return {
10009
- ...buttonStyle2,
10010
- backgroundColor: props.disabled ? BLUE_DISABLED : BLUE
10011
- };
10012
- }, [props.disabled]);
10013
- return /* @__PURE__ */ jsx60(Button, {
10014
- ...props,
10015
- style: style5
10016
- });
10017
- };
10018
-
10019
- // src/components/ModalFooter.tsx
10020
- import { jsx as jsx61 } from "react/jsx-runtime";
10021
- var content = {
10022
- padding: 12,
10023
- paddingRight: 12,
10024
- flex: 1,
10025
- fontSize: 13,
10026
- minWidth: 500
10027
- };
10028
- var ModalFooterContainer = ({ children }) => {
10029
- return /* @__PURE__ */ jsx61("div", {
10030
- style: { ...content, borderTop: BORDER_BLACK },
10031
- children
10032
- });
10033
- };
10034
-
10035
- // src/components/ConfirmationDialog.tsx
10036
- import { jsx as jsx62, jsxs as jsxs29 } from "react/jsx-runtime";
10037
- var content2 = {
10038
- padding: 16,
10039
- fontSize: 14,
10040
- flex: 1,
10041
- minWidth: 420,
10042
- maxWidth: 560,
10043
- lineHeight: 1.4
10044
- };
10045
- var useConfirmationDialog = () => {
10046
- const { setSelectedModal } = useContext15(ModalsContext);
10047
- return useCallback30((options) => {
10048
- return new Promise((resolve) => {
10049
- let settled = false;
10050
- const settle = (result) => {
10051
- if (settled) {
10052
- return;
10053
- }
10054
- settled = true;
10055
- resolve(result);
10056
- };
10057
- setSelectedModal({
10058
- type: "confirmation-dialog",
10059
- id: String(Math.random()),
10060
- title: options.title,
10061
- message: options.message,
10062
- confirmLabel: options.confirmLabel ?? "Continue",
10063
- cancelLabel: options.cancelLabel ?? "Cancel",
10064
- onConfirm: () => settle(true),
10065
- onCancel: () => settle(false)
10066
- });
10067
- });
10068
- }, [setSelectedModal]);
10069
- };
10070
- var ConfirmationDialog = ({ state }) => {
10071
- const { setSelectedModal } = useContext15(ModalsContext);
10072
- const settledRef = useRef16(false);
10073
- const closeCurrentModal = useCallback30(() => {
10074
- setSelectedModal((modal) => modal?.type === "confirmation-dialog" && modal.id === state.id ? null : modal);
10075
- }, [setSelectedModal, state.id]);
10076
- const settle = useCallback30((confirmed) => {
10077
- if (settledRef.current) {
10078
- return;
10079
- }
10080
- settledRef.current = true;
10081
- closeCurrentModal();
10082
- if (confirmed) {
10083
- state.onConfirm();
10084
- } else {
10085
- state.onCancel();
10086
- }
10087
- }, [closeCurrentModal, state]);
10088
- useEffect27(() => {
10089
- return () => {
10090
- if (settledRef.current) {
10091
- return;
10092
- }
10093
- settledRef.current = true;
10094
- state.onCancel();
10095
- };
10096
- }, [state]);
10097
- const onCancel = useCallback30(() => {
10098
- settle(false);
10099
- }, [settle]);
10100
- const onConfirm = useCallback30(() => {
10101
- settle(true);
10102
- }, [settle]);
10103
- const onSubmit = useCallback30((e) => {
10104
- e.preventDefault();
10105
- onConfirm();
10106
- }, [onConfirm]);
10107
- const cancelStyle = useMemo36(() => {
10108
- return {
10109
- minWidth: 90
10110
- };
10111
- }, []);
10112
- return /* @__PURE__ */ jsxs29(ModalContainer, {
10113
- onOutsideClick: onCancel,
10114
- onEscape: onCancel,
10115
- children: [
10116
- /* @__PURE__ */ jsx62(ModalHeader, {
10117
- title: state.title,
10118
- onClose: onCancel
10119
- }),
10120
- /* @__PURE__ */ jsxs29("form", {
10121
- onSubmit,
10122
- children: [
10123
- /* @__PURE__ */ jsx62("div", {
10124
- style: content2,
10125
- children: state.message
10126
- }),
10127
- /* @__PURE__ */ jsx62(ModalFooterContainer, {
10128
- children: /* @__PURE__ */ jsxs29(Row, {
10129
- align: "center",
10130
- children: [
10131
- /* @__PURE__ */ jsx62(Flex, {}),
10132
- /* @__PURE__ */ jsx62(Button, {
10133
- onClick: onCancel,
10134
- style: cancelStyle,
10135
- children: state.cancelLabel
10136
- }),
10137
- /* @__PURE__ */ jsx62(Spacing, {
10138
- x: 1
10139
- }),
10140
- /* @__PURE__ */ jsxs29(ModalButton, {
10141
- onClick: onConfirm,
10142
- autoFocus: true,
10143
- children: [
10144
- state.confirmLabel,
10145
- /* @__PURE__ */ jsx62(ShortcutHint, {
10146
- keyToPress: "↵",
10147
- cmdOrCtrl: false
10148
- })
10149
- ]
10150
- })
10151
- ]
10152
- })
10153
- })
10154
- ]
10155
- })
10156
- ]
10157
- });
10158
- };
10159
-
10160
10164
  // src/components/Timeline/delete-selected-timeline-item.ts
10161
10165
  import { Internals as Internals17 } from "remotion";
10162
10166
 
@@ -12004,7 +12008,7 @@ var TimelineSelectionProvider = ({ children }) => {
12004
12008
  const { canvasContent } = useContext17(Internals21.CompositionManager);
12005
12009
  const timelineSelectionScope = canvasContent?.type === "composition" ? canvasContent.compositionId : null;
12006
12010
  const { expandParentTracks } = useContext17(ExpandedTracksSetterContext);
12007
- const canSelect = previewServerState.type === "connected" && !window.remotion_isReadOnlyStudio;
12011
+ const canSelect = studioInteractivityEnabled && previewServerState.type === "connected" && !window.remotion_isReadOnlyStudio;
12008
12012
  const [selectedItems, setSelectedItems] = useState26([]);
12009
12013
  const selectionAnchor = useRef18(null);
12010
12014
  const selectionScope = useRef18(null);
@@ -21709,7 +21713,7 @@ var SelectedOutlineOverlay = ({
21709
21713
  selectItem(item, interaction, undefined, { reveal: true });
21710
21714
  }, [selectItem]);
21711
21715
  const outlineTargets = useMemo50(() => {
21712
- if (!editorShowOutlines) {
21716
+ if (!studioInteractivityEnabled || !editorShowOutlines) {
21713
21717
  return [];
21714
21718
  }
21715
21719
  const selectedSequenceKeys = getSelectedSequenceKeys(selectedItems);
@@ -22571,6 +22575,31 @@ var ResetZoomButton = ({ onClick }) => {
22571
22575
 
22572
22576
  // src/components/Canvas.tsx
22573
22577
  import { jsx as jsx84, jsxs as jsxs41, Fragment as Fragment17 } from "react/jsx-runtime";
22578
+ var elementInstallCompositionIdStyle = {
22579
+ fontFamily: "monospace",
22580
+ fontSize: 13
22581
+ };
22582
+ var elementInstallCodeDetailsStyle = {
22583
+ marginTop: 12,
22584
+ fontSize: 13
22585
+ };
22586
+ var elementInstallCodeSummaryStyle = {
22587
+ cursor: "pointer",
22588
+ fontSize: 13,
22589
+ fontWeight: 500
22590
+ };
22591
+ var elementInstallCodeBlockStyle = {
22592
+ marginTop: 8,
22593
+ marginBottom: 0,
22594
+ maxHeight: 240,
22595
+ overflow: "auto",
22596
+ padding: 12,
22597
+ borderRadius: 6,
22598
+ backgroundColor: "rgba(255, 255, 255, 0.06)",
22599
+ fontSize: 12,
22600
+ lineHeight: 1.5,
22601
+ whiteSpace: "pre"
22602
+ };
22574
22603
  var getContainerStyle = (editorZoomGestures) => ({
22575
22604
  flex: 1,
22576
22605
  display: "flex",
@@ -22705,12 +22734,18 @@ var Canvas = ({ canvasContent, size: size2 }) => {
22705
22734
  const suppressWheelFromWebKitPinchRef = useRef29(false);
22706
22735
  const touchPinchRef = useRef29(null);
22707
22736
  const keybindings = useKeybinding();
22737
+ const confirm = useConfirmationDialog();
22708
22738
  const config = Internals34.useUnsafeVideoConfig();
22709
22739
  const areRulersVisible = useIsRulerVisible();
22710
22740
  const { editorShowGuides } = useContext32(EditorShowGuidesContext);
22711
22741
  const { compositions } = useContext32(Internals34.CompositionManager);
22712
- const { previewServerState } = useContext32(StudioServerConnectionCtx);
22742
+ const { previewServerState, subscribeToEvent } = useContext32(StudioServerConnectionCtx);
22743
+ const previewServerClientId = previewServerState.type === "connected" ? previewServerState.clientId : null;
22713
22744
  const [isAddingAsset, setIsAddingAsset] = useState39(false);
22745
+ const [installingElementName, setInstallingElementName] = useState39(null);
22746
+ const [pendingElementInstallRequests, setPendingElementInstallRequests] = useState39([]);
22747
+ const [activeElementInstallRequest, setActiveElementInstallRequest] = useState39(null);
22748
+ const lastFocusedAtRef = useRef29(typeof document === "undefined" || document.hasFocus() ? Date.now() : null);
22714
22749
  const [assetResolution, setAssetResolution] = useState39(null);
22715
22750
  const currentCompositionId = canvasContent.type === "composition" ? canvasContent.compositionId : null;
22716
22751
  const currentComposition = useMemo52(() => {
@@ -22725,7 +22760,8 @@ var Canvas = ({ canvasContent, size: size2 }) => {
22725
22760
  compositionFile,
22726
22761
  compositionId: currentCompositionId
22727
22762
  });
22728
- const canDropAssets = previewServerState.type === "connected" && !window.remotion_isReadOnlyStudio && compositionComponentInfo?.canAddSequence === true && currentCompositionId !== null && compositionFile !== null && !isAddingAsset;
22763
+ const canInstallElements = previewServerClientId !== null && !window.remotion_isReadOnlyStudio && compositionComponentInfo?.canAddSequence === true && currentCompositionId !== null && compositionFile !== null;
22764
+ const canDropAssets = canInstallElements && !isAddingAsset;
22729
22765
  const contentDimensions = useMemo52(() => {
22730
22766
  if ((canvasContent.type === "asset" || canvasContent.type === "output" || canvasContent.type === "output-blob") && assetResolution && assetResolution.type === "found") {
22731
22767
  return assetResolution.dimensions;
@@ -23081,6 +23117,145 @@ var Canvas = ({ canvasContent, size: size2 }) => {
23081
23117
  useEffect40(() => {
23082
23118
  fetchMetadata();
23083
23119
  }, [fetchMetadata]);
23120
+ const updateElementInstallTarget = useCallback43(() => {
23121
+ if (previewServerClientId === null) {
23122
+ return;
23123
+ }
23124
+ callApi("/api/update-element-install-target", {
23125
+ clientId: previewServerClientId,
23126
+ compositionFile: canInstallElements ? compositionFile : null,
23127
+ compositionId: canInstallElements ? currentCompositionId : null,
23128
+ canInstall: canInstallElements,
23129
+ lastFocusedAt: lastFocusedAtRef.current,
23130
+ readOnly: window.remotion_isReadOnlyStudio
23131
+ }).catch(() => {
23132
+ return;
23133
+ });
23134
+ }, [
23135
+ canInstallElements,
23136
+ compositionFile,
23137
+ currentCompositionId,
23138
+ previewServerClientId
23139
+ ]);
23140
+ useEffect40(() => {
23141
+ updateElementInstallTarget();
23142
+ const interval = window.setInterval(updateElementInstallTarget, 2000);
23143
+ return () => {
23144
+ window.clearInterval(interval);
23145
+ };
23146
+ }, [updateElementInstallTarget]);
23147
+ useEffect40(() => {
23148
+ const markFocused = () => {
23149
+ lastFocusedAtRef.current = Date.now();
23150
+ updateElementInstallTarget();
23151
+ };
23152
+ window.addEventListener("focus", markFocused);
23153
+ document.addEventListener("pointerdown", markFocused, { capture: true });
23154
+ return () => {
23155
+ window.removeEventListener("focus", markFocused);
23156
+ document.removeEventListener("pointerdown", markFocused, { capture: true });
23157
+ };
23158
+ }, [updateElementInstallTarget]);
23159
+ useEffect40(() => {
23160
+ if (installingElementName === null) {
23161
+ return;
23162
+ }
23163
+ const previousTitle = document.title;
23164
+ document.title = `\uD83D\uDCE6 Install ${installingElementName} - Remotion Studio`;
23165
+ return () => {
23166
+ document.title = previousTitle;
23167
+ };
23168
+ }, [installingElementName]);
23169
+ useEffect40(() => {
23170
+ if (previewServerClientId === null) {
23171
+ return;
23172
+ }
23173
+ return subscribeToEvent("element-install-request", (event) => {
23174
+ if (event.type !== "element-install-request" || event.request.clientId !== previewServerClientId) {
23175
+ return;
23176
+ }
23177
+ setPendingElementInstallRequests((requests) => [
23178
+ ...requests,
23179
+ event.request
23180
+ ]);
23181
+ });
23182
+ }, [previewServerClientId, subscribeToEvent]);
23183
+ useEffect40(() => {
23184
+ if (activeElementInstallRequest !== null || pendingElementInstallRequests.length === 0) {
23185
+ return;
23186
+ }
23187
+ const [nextRequest, ...remainingRequests] = pendingElementInstallRequests;
23188
+ if (!nextRequest) {
23189
+ throw new Error("Expected pending Element install request");
23190
+ }
23191
+ setActiveElementInstallRequest(nextRequest);
23192
+ setPendingElementInstallRequests(remainingRequests);
23193
+ }, [activeElementInstallRequest, pendingElementInstallRequests]);
23194
+ useEffect40(() => {
23195
+ if (activeElementInstallRequest === null) {
23196
+ return;
23197
+ }
23198
+ let canceled = false;
23199
+ const handleInstallRequest = async () => {
23200
+ setInstallingElementName(activeElementInstallRequest.element.displayName);
23201
+ const accepted = await confirm({
23202
+ title: "Install Element",
23203
+ message: /* @__PURE__ */ jsxs41(Fragment17, {
23204
+ children: [
23205
+ "Install “",
23206
+ activeElementInstallRequest.element.displayName,
23207
+ "” into",
23208
+ " ",
23209
+ /* @__PURE__ */ jsx84("code", {
23210
+ style: elementInstallCompositionIdStyle,
23211
+ children: activeElementInstallRequest.compositionId
23212
+ }),
23213
+ " ",
23214
+ "composition? This will create an Element source file and update the composition source.",
23215
+ /* @__PURE__ */ jsxs41("details", {
23216
+ style: elementInstallCodeDetailsStyle,
23217
+ children: [
23218
+ /* @__PURE__ */ jsx84("summary", {
23219
+ style: elementInstallCodeSummaryStyle,
23220
+ children: "Preview Element source"
23221
+ }),
23222
+ /* @__PURE__ */ jsx84("pre", {
23223
+ style: elementInstallCodeBlockStyle,
23224
+ children: /* @__PURE__ */ jsx84("code", {
23225
+ children: activeElementInstallRequest.element.sourceCode
23226
+ })
23227
+ })
23228
+ ]
23229
+ })
23230
+ ]
23231
+ }),
23232
+ confirmLabel: "Install",
23233
+ cancelLabel: "Cancel"
23234
+ });
23235
+ if (accepted && !canceled) {
23236
+ await insertElement({
23237
+ element: activeElementInstallRequest.element,
23238
+ compositionFile: activeElementInstallRequest.compositionFile,
23239
+ compositionId: activeElementInstallRequest.compositionId,
23240
+ dropPosition: null
23241
+ });
23242
+ }
23243
+ };
23244
+ handleInstallRequest().finally(() => {
23245
+ if (canceled) {
23246
+ return;
23247
+ }
23248
+ setInstallingElementName(null);
23249
+ setActiveElementInstallRequest(null);
23250
+ }).catch((err) => {
23251
+ setTimeout(() => {
23252
+ throw err;
23253
+ }, 0);
23254
+ });
23255
+ return () => {
23256
+ canceled = true;
23257
+ };
23258
+ }, [activeElementInstallRequest, confirm]);
23084
23259
  const onDragOver = useCallback43((event) => {
23085
23260
  if (!canDropAssets || !isFileDragEvent(event) && !isAssetDragEvent(event) && !isCompositionDragEvent(event) && !isComponentDragEvent(event) && !isElementDragEvent(event) && !isSfxDragEvent(event) && !isRemoteAssetDragEvent(event) || !isDragEventInsideCanvas(event)) {
23086
23261
  return;
@@ -26733,6 +26908,9 @@ var VisualControlsProvider = ({ children }) => {
26733
26908
  if (!env.isStudio) {
26734
26909
  return value;
26735
26910
  }
26911
+ if (!studioInteractivityEnabled) {
26912
+ return value;
26913
+ }
26736
26914
  if (!z) {
26737
26915
  return value;
26738
26916
  }
@@ -33123,7 +33301,7 @@ var DefaultInspector = ({ composition, currentDefaultProps, readOnlyStudio, setD
33123
33301
  const { handles: visualControlHandles } = useContext55(VisualControlsContext);
33124
33302
  const [defaultPropsMode, setDefaultPropsMode] = useState68("schema");
33125
33303
  const compositionId = composition?.id ?? null;
33126
- const hasVisualControls = Object.keys(visualControlHandles).length > 0;
33304
+ const hasVisualControls = studioInteractivityEnabled && Object.keys(visualControlHandles).length > 0;
33127
33305
  useEffect60(() => {
33128
33306
  setDefaultPropsMode("schema");
33129
33307
  }, [compositionId]);
@@ -48804,7 +48982,7 @@ var TimelineDragHandler = () => {
48804
48982
  ref: sliderAreaRef,
48805
48983
  style: containerStyle9,
48806
48984
  ...{ [TIMELINE_SCRUBBER_ATTR]: true },
48807
- children: video ? /* @__PURE__ */ jsx260(TimelineDragHandlerInnerMemo, {}) : null
48985
+ children: video && studioInteractivityEnabled ? /* @__PURE__ */ jsx260(TimelineDragHandlerInnerMemo, {}) : null
48808
48986
  });
48809
48987
  };
48810
48988
  var TimelineDragHandlerInner = () => {
@@ -49871,6 +50049,7 @@ var TimelineSequenceItem = ({
49871
50049
  const nodePath = nodePathInfo?.sequenceSubscriptionKey ?? null;
49872
50050
  const { previewServerState } = useContext111(StudioServerConnectionCtx);
49873
50051
  const previewConnected = previewServerState.type === "connected";
50052
+ const previewInteractive = previewConnected && studioInteractivityEnabled;
49874
50053
  const { getIsExpanded } = useContext111(ExpandedTracksGetterContext);
49875
50054
  const { toggleTrack } = useContext111(ExpandedTracksSetterContext);
49876
50055
  const { setPropStatuses } = useContext111(Internals91.VisualModeSettersContext);
@@ -49907,7 +50086,7 @@ var TimelineSequenceItem = ({
49907
50086
  propStatusesForOverride,
49908
50087
  saveName
49909
50088
  } = useRenameSequence({
49910
- clientId: previewServerState.type === "connected" ? previewServerState.clientId : null,
50089
+ clientId: previewInteractive && previewServerState.type === "connected" ? previewServerState.clientId : null,
49911
50090
  nodePathInfo,
49912
50091
  sequence,
49913
50092
  validatedLocation
@@ -49915,22 +50094,22 @@ var TimelineSequenceItem = ({
49915
50094
  const canDeleteFromSource = Boolean(nodePath && validatedLocation?.source);
49916
50095
  const nodePathKey = useMemo170(() => nodePath ? Internals91.makeSequencePropsSubscriptionKey(nodePath) : null, [nodePath]);
49917
50096
  const parentId = sequence.parent ?? null;
49918
- const canReorderSequence = previewConnected && Boolean(nodePath && nodePathKey && validatedLocation?.source) && nodePathInfo?.numberOfSequencesWithThisNodePath === 1;
49919
- const canHandleSequenceDrag = previewConnected;
50097
+ const canReorderSequence = previewInteractive && Boolean(nodePath && nodePathKey && validatedLocation?.source) && nodePathInfo?.numberOfSequencesWithThisNodePath === 1;
50098
+ const canHandleSequenceDrag = previewInteractive;
49920
50099
  const confirm = useConfirmationDialog();
49921
- const deleteDisabled = useMemo170(() => !previewConnected || !sequence.controls || !canDeleteFromSource, [previewConnected, sequence.controls, canDeleteFromSource]);
50100
+ const deleteDisabled = useMemo170(() => !previewInteractive || !sequence.controls || !canDeleteFromSource, [previewInteractive, sequence.controls, canDeleteFromSource]);
49922
50101
  const duplicateDisabled = deleteDisabled;
49923
- const disableInteractivityDisabled = !previewConnected || !sequence.showInTimeline || !nodePath || !validatedLocation?.source;
50102
+ const disableInteractivityDisabled = !previewInteractive || !sequence.showInTimeline || !nodePath || !validatedLocation?.source;
49924
50103
  const onDuplicateSequenceFromSource = useCallback162(() => {
49925
- if (!validatedLocation?.source || !nodePathInfo) {
50104
+ if (duplicateDisabled || !validatedLocation?.source || !nodePathInfo) {
49926
50105
  return;
49927
50106
  }
49928
50107
  duplicateSequencesFromSource([nodePathInfo], confirm).catch(() => {
49929
50108
  return;
49930
50109
  });
49931
- }, [confirm, nodePathInfo, validatedLocation?.source]);
50110
+ }, [confirm, duplicateDisabled, nodePathInfo, validatedLocation?.source]);
49932
50111
  const onDeleteSequenceFromSource = useCallback162(async () => {
49933
- if (!validatedLocation?.source || !nodePath) {
50112
+ if (deleteDisabled || !validatedLocation?.source || !nodePath) {
49934
50113
  return;
49935
50114
  }
49936
50115
  if (nodePathInfo && nodePathInfo.numberOfSequencesWithThisNodePath > 1) {
@@ -49960,7 +50139,13 @@ var TimelineSequenceItem = ({
49960
50139
  } catch (err) {
49961
50140
  showNotification(err.message, 4000);
49962
50141
  }
49963
- }, [confirm, nodePath, validatedLocation?.source, nodePathInfo]);
50142
+ }, [
50143
+ confirm,
50144
+ deleteDisabled,
50145
+ nodePath,
50146
+ validatedLocation?.source,
50147
+ nodePathInfo
50148
+ ]);
49964
50149
  const onDisableSequenceInteractivity = useCallback162(() => {
49965
50150
  if (disableInteractivityDisabled || !nodePath || !validatedLocation?.source || previewServerState.type !== "connected") {
49966
50151
  return;
@@ -50195,8 +50380,8 @@ var TimelineSequenceItem = ({
50195
50380
  ...effectDropHighlight
50196
50381
  } : inner2;
50197
50382
  }, [effectDropHovered, inner2]);
50198
- const hasExpandableContent = Boolean(sequence.controls) || sequence.effects.length > 0;
50199
- const canToggleVisibility = previewConnected && Boolean(sequence.controls) && nodePath !== null && validatedLocation !== null && codeHiddenStatus !== undefined && codeHiddenStatus !== null && codeHiddenStatus.status === "static";
50383
+ const hasExpandableContent = studioInteractivityEnabled && (Boolean(sequence.controls) || sequence.effects.length > 0);
50384
+ const canToggleVisibility = previewInteractive && Boolean(sequence.controls) && nodePath !== null && validatedLocation !== null && codeHiddenStatus !== undefined && codeHiddenStatus !== null && codeHiddenStatus.status === "static";
50200
50385
  const onSequenceDoubleClick = useCallback162((e) => {
50201
50386
  if (isTimelineSelectionModifierEvent(e)) {
50202
50387
  e.stopPropagation();
@@ -50249,7 +50434,7 @@ var TimelineSequenceItem = ({
50249
50434
  setIsRenaming(true);
50250
50435
  }, [canRenameThisSequence]);
50251
50436
  const freezeFrameMenuItem = useSequenceFreezeFrameMenuItem({
50252
- clientId: previewServerState.type === "connected" ? previewServerState.clientId : null,
50437
+ clientId: previewInteractive && previewServerState.type === "connected" ? previewServerState.clientId : null,
50253
50438
  nodePath,
50254
50439
  propStatusesForOverride,
50255
50440
  sequence,
@@ -50258,7 +50443,7 @@ var TimelineSequenceItem = ({
50258
50443
  timelinePosition,
50259
50444
  validatedSource: validatedLocation?.source ?? null
50260
50445
  });
50261
- const canAddEffect = nodePathInfo?.supportsEffects === true && previewServerState.type === "connected" && Boolean(validatedLocation?.source);
50446
+ const canAddEffect = nodePathInfo?.supportsEffects === true && previewInteractive && Boolean(validatedLocation?.source);
50262
50447
  const onAddEffect = useCallback162(() => {
50263
50448
  if (!canAddEffect || previewServerState.type !== "connected" || !nodePath || !validatedLocation?.source) {
50264
50449
  return;
@@ -50287,7 +50472,7 @@ var TimelineSequenceItem = ({
50287
50472
  disableInteractivityDisabled,
50288
50473
  duplicateDisabled,
50289
50474
  fileLocation,
50290
- includeSourceEditItems: true,
50475
+ includeSourceEditItems: studioInteractivityEnabled,
50291
50476
  onDeleteSequenceFromSource,
50292
50477
  onDisableSequenceInteractivity,
50293
50478
  onDuplicateSequenceFromSource,
@@ -50295,7 +50480,7 @@ var TimelineSequenceItem = ({
50295
50480
  originalLocation,
50296
50481
  selectAsset,
50297
50482
  sequence,
50298
- sourceActions: [
50483
+ sourceActions: studioInteractivityEnabled ? [
50299
50484
  ...nodePathInfo?.supportsEffects ? [
50300
50485
  {
50301
50486
  type: "item",
@@ -50329,7 +50514,7 @@ var TimelineSequenceItem = ({
50329
50514
  value: "rename-sequence"
50330
50515
  },
50331
50516
  ...freezeFrameMenuItem ? [freezeFrameMenuItem] : []
50332
- ]
50517
+ ] : []
50333
50518
  });
50334
50519
  }, [
50335
50520
  assetLinkInfo,
@@ -50353,7 +50538,7 @@ var TimelineSequenceItem = ({
50353
50538
  selectAsset,
50354
50539
  sequence
50355
50540
  ]);
50356
- const canDropEffect = previewServerState.type === "connected" && nodePath !== null && validatedLocation !== null && sequence.controls?.supportsEffects === true;
50541
+ const canDropEffect = previewInteractive && nodePath !== null && validatedLocation !== null && sequence.controls?.supportsEffects === true;
50357
50542
  const sequenceReorderLineStyle = useMemo170(() => {
50358
50543
  if (!sequenceDropIndicator) {
50359
50544
  return null;
@@ -50409,7 +50594,7 @@ var TimelineSequenceItem = ({
50409
50594
  onInvoked: onToggleVisibility
50410
50595
  }) : /* @__PURE__ */ jsx268(TimelineLayerEyeSpacer, {}),
50411
50596
  arrow: hasExpandableContent && nodePathInfo !== null ? /* @__PURE__ */ jsx268(TimelineSequenceExpandArrow, {
50412
- disabled: !previewConnected,
50597
+ disabled: !previewInteractive,
50413
50598
  isExpanded,
50414
50599
  nodePathInfo,
50415
50600
  onToggleExpand,
@@ -50479,7 +50664,7 @@ var TimelineSequenceItem = ({
50479
50664
  onOpen: selectable ? onSelect : null,
50480
50665
  children: draggableTrackRow
50481
50666
  }) : draggableTrackRow,
50482
- previewConnected && isExpanded && hasExpandableContent && nodePathInfo && validatedLocation ? /* @__PURE__ */ jsx268(TimelineExpandedSection, {
50667
+ previewConnected && studioInteractivityEnabled && isExpanded && hasExpandableContent && nodePathInfo && validatedLocation ? /* @__PURE__ */ jsx268(TimelineExpandedSection, {
50483
50668
  sequence,
50484
50669
  validatedLocation,
50485
50670
  nodePathInfo,
@@ -53228,11 +53413,12 @@ var TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffset
53228
53413
  const propStatusesForOverride = useMemo176(() => {
53229
53414
  return nodePath ? Internals97.getPropStatusesCtx(propStatuses, nodePath) : undefined;
53230
53415
  }, [propStatuses, nodePath]);
53231
- const durationCanUpdate = Boolean(propStatusesForOverride?.durationInFrames?.status === "static");
53232
- const fromCanUpdate = Boolean(propStatusesForOverride?.from?.status === "static");
53233
- const trimBeforeCanUpdate = Boolean(propStatusesForOverride?.trimBefore?.status === "static");
53416
+ const durationCanUpdate = Boolean(studioInteractivityEnabled && propStatusesForOverride?.durationInFrames?.status === "static");
53417
+ const fromCanUpdate = Boolean(studioInteractivityEnabled && propStatusesForOverride?.from?.status === "static");
53418
+ const trimBeforeCanUpdate = Boolean(studioInteractivityEnabled && propStatusesForOverride?.trimBefore?.status === "static");
53234
53419
  const { previewServerState } = useContext118(StudioServerConnectionCtx);
53235
53420
  const previewConnected = previewServerState.type === "connected";
53421
+ const previewInteractive = previewConnected && studioInteractivityEnabled;
53236
53422
  const { setPropStatuses } = useContext118(Internals97.VisualModeSettersContext);
53237
53423
  const timelinePosition = Internals97.Timeline.useTimelinePosition();
53238
53424
  const selectAsset = useSelectAsset();
@@ -53252,9 +53438,9 @@ var TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffset
53252
53438
  });
53253
53439
  }, [canOpenInEditor, originalLocation]);
53254
53440
  const canDeleteFromSource = Boolean(nodePath && validatedLocation?.source);
53255
- const deleteDisabled = !previewConnected || !s.controls || !canDeleteFromSource;
53441
+ const deleteDisabled = !previewInteractive || !s.controls || !canDeleteFromSource;
53256
53442
  const duplicateDisabled = deleteDisabled;
53257
- const disableInteractivityDisabled = !previewConnected || !s.showInTimeline || !nodePath || !validatedLocation?.source;
53443
+ const disableInteractivityDisabled = !previewInteractive || !s.showInTimeline || !nodePath || !validatedLocation?.source;
53258
53444
  const mediaSrc = s.type === "audio" || s.type === "video" || s.type === "image" ? s.src : null;
53259
53445
  const assetLinkInfo = useMemo176(() => mediaSrc ? getTimelineAssetLinkInfo(mediaSrc) : null, [mediaSrc]);
53260
53446
  const onDuplicateSequenceFromSource = useCallback165(() => {
@@ -53321,7 +53507,7 @@ var TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffset
53321
53507
  validatedLocation?.source
53322
53508
  ]);
53323
53509
  const freezeFrameMenuItem = useSequenceFreezeFrameMenuItem({
53324
- clientId: previewServerState.type === "connected" ? previewServerState.clientId : null,
53510
+ clientId: previewInteractive && previewServerState.type === "connected" ? previewServerState.clientId : null,
53325
53511
  nodePath,
53326
53512
  propStatusesForOverride,
53327
53513
  sequence: s,
@@ -53341,7 +53527,7 @@ var TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffset
53341
53527
  disableInteractivityDisabled,
53342
53528
  duplicateDisabled,
53343
53529
  fileLocation,
53344
- includeSourceEditItems: true,
53530
+ includeSourceEditItems: studioInteractivityEnabled,
53345
53531
  onDeleteSequenceFromSource,
53346
53532
  onDisableSequenceInteractivity,
53347
53533
  onDuplicateSequenceFromSource,
@@ -53349,7 +53535,7 @@ var TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffset
53349
53535
  originalLocation,
53350
53536
  selectAsset,
53351
53537
  sequence: s,
53352
- sourceActions: freezeFrameMenuItem ? [freezeFrameMenuItem] : []
53538
+ sourceActions: studioInteractivityEnabled && freezeFrameMenuItem ? [freezeFrameMenuItem] : []
53353
53539
  });
53354
53540
  }, [
53355
53541
  assetLinkInfo,
@@ -53576,6 +53762,7 @@ var TimelineContextMenuArea = ({ children }) => {
53576
53762
  const [isAddingAsset, setIsAddingAsset] = useState100(false);
53577
53763
  const { previewServerState } = useContext120(StudioServerConnectionCtx);
53578
53764
  const previewConnected = previewServerState.type === "connected";
53765
+ const previewInteractive = previewConnected && studioInteractivityEnabled;
53579
53766
  const currentCompositionId = canvasContent?.type === "composition" ? canvasContent.compositionId : null;
53580
53767
  const currentComposition = useMemo179(() => {
53581
53768
  if (currentCompositionId === null) {
@@ -53589,8 +53776,8 @@ var TimelineContextMenuArea = ({ children }) => {
53589
53776
  compositionFile,
53590
53777
  compositionId: currentCompositionId
53591
53778
  });
53592
- const canInsertSolid = previewConnected && compositionComponentInfo?.canAddSequence === true && currentCompositionId !== null && compositionFile !== null && videoConfig !== null && !isAddingSolid;
53593
- const canInsertAsset = previewConnected && !window.remotion_isReadOnlyStudio && compositionComponentInfo?.canAddSequence === true && currentCompositionId !== null && compositionFile !== null && !isAddingAsset;
53779
+ const canInsertSolid = previewInteractive && compositionComponentInfo?.canAddSequence === true && currentCompositionId !== null && compositionFile !== null && videoConfig !== null && !isAddingSolid;
53780
+ const canInsertAsset = previewInteractive && !window.remotion_isReadOnlyStudio && compositionComponentInfo?.canAddSequence === true && currentCompositionId !== null && compositionFile !== null && !isAddingAsset;
53594
53781
  const insertSolid = useCallback166(async () => {
53595
53782
  if (!canInsertSolid || currentCompositionId === null || compositionFile === null || videoConfig === null) {
53596
53783
  return;
@@ -53682,6 +53869,7 @@ var TimelineInner = () => {
53682
53869
  const { overrideIdToNodePathMappings } = useContext120(Internals98.OverrideIdsToNodePathsGettersContext);
53683
53870
  const { previewServerState } = useContext120(StudioServerConnectionCtx);
53684
53871
  const previewConnected = previewServerState.type === "connected";
53872
+ const previewInteractive = previewConnected && studioInteractivityEnabled;
53685
53873
  const videoConfigIsNull = videoConfig === null;
53686
53874
  const timeline = useMemo179(() => {
53687
53875
  if (videoConfigIsNull) {
@@ -53703,7 +53891,7 @@ var TimelineInner = () => {
53703
53891
  return /* @__PURE__ */ jsxs147(TimelineContextMenuArea, {
53704
53892
  children: [
53705
53893
  sequences.map((sequence) => {
53706
- if (!shouldSubscribeToSequenceProps(sequence, previewConnected)) {
53894
+ if (!shouldSubscribeToSequenceProps(sequence, previewInteractive)) {
53707
53895
  return null;
53708
53896
  }
53709
53897
  return /* @__PURE__ */ jsx284(SubscribeToNodePaths, {
@@ -53714,15 +53902,15 @@ var TimelineInner = () => {
53714
53902
  effects: sequence.effects
53715
53903
  }, sequence.id);
53716
53904
  }),
53717
- /* @__PURE__ */ jsx284(SequencePropsObserver, {}),
53905
+ studioInteractivityEnabled ? /* @__PURE__ */ jsx284(SequencePropsObserver, {}) : null,
53718
53906
  /* @__PURE__ */ jsx284(TimelineKeyframeTracksProvider, {
53719
53907
  tracks: filtered,
53720
53908
  children: /* @__PURE__ */ jsxs147(TimelineSelectableItemsProvider, {
53721
53909
  timeline: shown,
53722
53910
  children: [
53723
- /* @__PURE__ */ jsx284(TimelineSelectAllKeybindings, {
53911
+ studioInteractivityEnabled ? /* @__PURE__ */ jsx284(TimelineSelectAllKeybindings, {
53724
53912
  timeline: shown
53725
- }),
53913
+ }) : null,
53726
53914
  /* @__PURE__ */ jsx284(TimelineHeightContainer, {
53727
53915
  shown,
53728
53916
  hasBeenCut,
@@ -53762,7 +53950,7 @@ var TimelineInner = () => {
53762
53950
  /* @__PURE__ */ jsx284(TimelineInOutPointer, {}),
53763
53951
  /* @__PURE__ */ jsx284(TimelineTimeIndicators, {}),
53764
53952
  /* @__PURE__ */ jsx284(TimelineDragHandler, {}),
53765
- /* @__PURE__ */ jsx284(TimelineInOutDragHandler, {}),
53953
+ studioInteractivityEnabled ? /* @__PURE__ */ jsx284(TimelineInOutDragHandler, {}) : null,
53766
53954
  /* @__PURE__ */ jsx284(TimelineSlider, {})
53767
53955
  ]
53768
53956
  })