@remotion/studio 4.0.434 → 4.0.436

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.
@@ -3787,6 +3787,15 @@ var sortItemsByNonceHistory = (items) => {
3787
3787
  return result;
3788
3788
  };
3789
3789
 
3790
+ // src/state/modals.ts
3791
+ import { createContext as createContext9 } from "react";
3792
+ var ModalsContext = createContext9({
3793
+ selectedModal: null,
3794
+ setSelectedModal: () => {
3795
+ return;
3796
+ }
3797
+ });
3798
+
3790
3799
  // src/components/CompositionSelectorItem.tsx
3791
3800
  import { useCallback as useCallback23, useContext as useContext8, useMemo as useMemo26, useState as useState20 } from "react";
3792
3801
 
@@ -3850,15 +3859,6 @@ var FilmIcon = ({ color, ...props }) => {
3850
3859
  });
3851
3860
  };
3852
3861
 
3853
- // src/state/modals.ts
3854
- import { createContext as createContext9 } from "react";
3855
- var ModalsContext = createContext9({
3856
- selectedModal: null,
3857
- setSelectedModal: () => {
3858
- return;
3859
- }
3860
- });
3861
-
3862
3862
  // src/components/CompositionContextButton.tsx
3863
3863
  import { useCallback as useCallback20, useContext as useContext6, useMemo as useMemo23 } from "react";
3864
3864
 
@@ -3977,7 +3977,13 @@ var RenderQueueContextProvider = ({ children }) => {
3977
3977
  setClientJobs((prev) => prev.map((job) => job.id === nextJob.id ? {
3978
3978
  ...job,
3979
3979
  status: "running",
3980
- progress: { encodedFrames: 0, totalFrames: 0 }
3980
+ progress: {
3981
+ encodedFrames: 0,
3982
+ totalFrames: 0,
3983
+ doneIn: null,
3984
+ renderEstimatedTime: 0,
3985
+ progress: 0
3986
+ }
3981
3987
  } : job));
3982
3988
  processJobCallbackRef.current(nextJob);
3983
3989
  }, [clientJobs, currentlyProcessing]);
@@ -5197,7 +5203,8 @@ var itemStyle = {
5197
5203
  width: "100%",
5198
5204
  textAlign: "left",
5199
5205
  backgroundColor: BACKGROUND,
5200
- height: COMPOSITION_ITEM_HEIGHT
5206
+ height: COMPOSITION_ITEM_HEIGHT,
5207
+ userSelect: "none"
5201
5208
  };
5202
5209
  var labelStyle2 = {
5203
5210
  textAlign: "left",
@@ -5449,12 +5456,11 @@ var renderFrame = (frame2, fps) => {
5449
5456
 
5450
5457
  // src/components/CurrentComposition.tsx
5451
5458
  import { jsx as jsx53, jsxs as jsxs22 } from "react/jsx-runtime";
5452
- var CURRENT_COMPOSITION_HEIGHT = 80;
5459
+ var CURRENT_COMPOSITION_HEIGHT = 64;
5453
5460
  var container11 = {
5454
5461
  height: CURRENT_COMPOSITION_HEIGHT,
5455
5462
  display: "block",
5456
- borderBottom: `1px solid ${BORDER_COLOR}`,
5457
- padding: 12,
5463
+ padding: "6px 12px",
5458
5464
  color: "white",
5459
5465
  backgroundColor: BACKGROUND
5460
5466
  };
@@ -5556,6 +5562,29 @@ var container12 = {
5556
5562
  overflow: "hidden",
5557
5563
  backgroundColor: BACKGROUND
5558
5564
  };
5565
+ var QUICK_SWITCHER_TRIGGER_HEIGHT = 38;
5566
+ var quickSwitcherArea = {
5567
+ padding: "4px 12px",
5568
+ borderBottom: `1px solid ${BORDER_COLOR}`
5569
+ };
5570
+ var quickSwitcherTrigger = {
5571
+ backgroundColor: "rgba(255, 255, 255, 0.06)",
5572
+ borderRadius: 5,
5573
+ padding: "4px 10px",
5574
+ color: LIGHT_TEXT,
5575
+ fontSize: 12,
5576
+ cursor: "pointer",
5577
+ display: "flex",
5578
+ alignItems: "center",
5579
+ justifyContent: "space-between",
5580
+ border: "none",
5581
+ width: "100%",
5582
+ appearance: "none"
5583
+ };
5584
+ var shortcutLabel = {
5585
+ fontSize: 11,
5586
+ opacity: 0.6
5587
+ };
5559
5588
  var getKeysToExpand = (initialFolderName, parentFolderName, initial = []) => {
5560
5589
  initial.push(openFolderKey({
5561
5590
  folderName: initialFolderName,
@@ -5570,6 +5599,7 @@ var getKeysToExpand = (initialFolderName, parentFolderName, initial = []) => {
5570
5599
  var CompositionSelector = () => {
5571
5600
  const { compositions, canvasContent, folders } = useContext9(Internals9.CompositionManager);
5572
5601
  const { foldersExpanded } = useContext9(ExpandedFoldersContext);
5602
+ const { setSelectedModal } = useContext9(ModalsContext);
5573
5603
  const { tabIndex } = useZIndex();
5574
5604
  const selectComposition = useSelectComposition();
5575
5605
  const sortedCompositions = useMemo27(() => {
@@ -5583,17 +5613,43 @@ var CompositionSelector = () => {
5583
5613
  }, [sortedCompositions, sortedFolders, foldersExpanded]);
5584
5614
  const list = useMemo27(() => {
5585
5615
  return {
5586
- height: `calc(100% - ${CURRENT_COMPOSITION_HEIGHT}px)`,
5616
+ height: `calc(100% - ${CURRENT_COMPOSITION_HEIGHT}px - ${QUICK_SWITCHER_TRIGGER_HEIGHT}px)`,
5587
5617
  overflowY: "auto"
5588
5618
  };
5589
5619
  }, []);
5590
5620
  const toggleFolder = useCallback24((folderName, parentName) => {
5591
5621
  Internals9.compositionSelectorRef.current?.toggleFolder(folderName, parentName);
5592
5622
  }, []);
5623
+ const openQuickSwitcher = useCallback24(() => {
5624
+ setSelectedModal({
5625
+ type: "quick-switcher",
5626
+ mode: "compositions",
5627
+ invocationTimestamp: Date.now()
5628
+ });
5629
+ }, [setSelectedModal]);
5593
5630
  return /* @__PURE__ */ jsxs23("div", {
5594
5631
  style: container12,
5595
5632
  children: [
5596
5633
  /* @__PURE__ */ jsx54(CurrentComposition, {}),
5634
+ /* @__PURE__ */ jsx54("div", {
5635
+ style: quickSwitcherArea,
5636
+ children: /* @__PURE__ */ jsxs23("button", {
5637
+ type: "button",
5638
+ style: quickSwitcherTrigger,
5639
+ onClick: openQuickSwitcher,
5640
+ tabIndex,
5641
+ children: [
5642
+ "Search...",
5643
+ areKeyboardShortcutsDisabled() ? null : /* @__PURE__ */ jsxs23("span", {
5644
+ style: shortcutLabel,
5645
+ children: [
5646
+ cmdOrCtrlCharacter,
5647
+ "+K"
5648
+ ]
5649
+ })
5650
+ ]
5651
+ })
5652
+ }),
5597
5653
  /* @__PURE__ */ jsx54("div", {
5598
5654
  className: "__remotion-vertical-scrollbar",
5599
5655
  style: list,
@@ -17294,7 +17350,10 @@ var ClientRenderQueueProcessor = () => {
17294
17350
  onProgress: (progress) => {
17295
17351
  onProgress(job.id, {
17296
17352
  encodedFrames: progress.encodedFrames,
17297
- totalFrames
17353
+ totalFrames,
17354
+ doneIn: progress.doneIn,
17355
+ renderEstimatedTime: progress.renderEstimatedTime,
17356
+ progress: progress.progress
17298
17357
  });
17299
17358
  },
17300
17359
  outputTarget: "web-fs",
@@ -17585,8 +17644,7 @@ var RenderQueueItemStatus = ({ job }) => {
17585
17644
  if (job.status === "running") {
17586
17645
  let progressValue;
17587
17646
  if (isClientJob) {
17588
- const { encodedFrames, totalFrames } = job.progress;
17589
- progressValue = totalFrames > 0 ? encodedFrames / totalFrames : 0;
17647
+ progressValue = job.progress.progress;
17590
17648
  } else {
17591
17649
  progressValue = job.progress.value;
17592
17650
  }
@@ -17678,6 +17736,34 @@ var RenderQueueOutputName = ({ job }) => {
17678
17736
 
17679
17737
  // src/components/RenderQueue/RenderQueueProgressMessage.tsx
17680
17738
  import { useCallback as useCallback78, useContext as useContext43 } from "react";
17739
+
17740
+ // src/components/RenderQueue/client-render-progress.ts
17741
+ var formatEtaString = (timeRemainingInMilliseconds) => {
17742
+ const remainingTime = timeRemainingInMilliseconds / 1000;
17743
+ const remainingTimeHours = Math.floor(remainingTime / 3600);
17744
+ const remainingTimeMinutes = Math.floor(remainingTime % 3600 / 60);
17745
+ const remainingTimeSeconds = Math.floor(remainingTime % 60);
17746
+ return [
17747
+ remainingTimeHours ? `${remainingTimeHours}h` : null,
17748
+ remainingTimeMinutes ? `${remainingTimeMinutes}m` : null,
17749
+ `${remainingTimeSeconds}s`
17750
+ ].filter((value) => Boolean(value)).join(" ");
17751
+ };
17752
+ var getClientRenderProgressMessage = (progress) => {
17753
+ if (progress.totalFrames === 0) {
17754
+ return "Getting composition";
17755
+ }
17756
+ if (progress.doneIn !== null) {
17757
+ return `Encoded ${progress.totalFrames}/${progress.totalFrames}`;
17758
+ }
17759
+ if (progress.renderEstimatedTime > 0) {
17760
+ const etaString = `, time remaining: ${formatEtaString(progress.renderEstimatedTime)}`;
17761
+ return `Rendering ${progress.encodedFrames}/${progress.totalFrames}${etaString}`;
17762
+ }
17763
+ return `Encoded ${progress.encodedFrames}/${progress.totalFrames}`;
17764
+ };
17765
+
17766
+ // src/components/RenderQueue/RenderQueueProgressMessage.tsx
17681
17767
  import { jsx as jsx156 } from "react/jsx-runtime";
17682
17768
  var outputLocation2 = {
17683
17769
  ...renderQueueItemSubtitleStyle
@@ -17695,7 +17781,7 @@ var RenderQueueProgressMessage = ({ job }) => {
17695
17781
  jobId: job.id
17696
17782
  });
17697
17783
  }, [job.id, setSelectedModal]);
17698
- const message = isClientJob ? job.progress.totalFrames === 0 ? "Getting composition" : `Encoding frame ${job.progress.encodedFrames}/${job.progress.totalFrames}` : job.progress.message;
17784
+ const message = isClientJob ? getClientRenderProgressMessage(job.progress) : job.progress.message;
17699
17785
  return /* @__PURE__ */ jsx156("button", {
17700
17786
  onClick,
17701
17787
  type: "button",
@@ -27547,9 +27633,15 @@ var right3 = {
27547
27633
  textAlign: "right",
27548
27634
  flex: 1
27549
27635
  };
27550
- var EncodingProgress = ({ encodedFrames, totalFrames }) => {
27551
- const done = encodedFrames === totalFrames;
27552
- const progress = totalFrames > 0 ? encodedFrames / totalFrames : 0;
27636
+ var ProgressStatus = ({ encodedFrames, totalFrames, doneIn, renderEstimatedTime, progress }) => {
27637
+ const done = doneIn !== null;
27638
+ const message = getClientRenderProgressMessage({
27639
+ encodedFrames,
27640
+ totalFrames,
27641
+ doneIn,
27642
+ renderEstimatedTime,
27643
+ progress
27644
+ });
27553
27645
  return /* @__PURE__ */ jsxs121("div", {
27554
27646
  style: progressItem,
27555
27647
  children: [
@@ -27561,8 +27653,15 @@ var EncodingProgress = ({ encodedFrames, totalFrames }) => {
27561
27653
  }),
27562
27654
  /* @__PURE__ */ jsx240("div", {
27563
27655
  style: label11,
27564
- children: done ? `Encoded ${totalFrames} frames` : `Encoding ${encodedFrames} / ${totalFrames} frames`
27565
- })
27656
+ children: message
27657
+ }),
27658
+ doneIn !== null ? /* @__PURE__ */ jsxs121("div", {
27659
+ style: right3,
27660
+ children: [
27661
+ doneIn,
27662
+ "ms"
27663
+ ]
27664
+ }) : null
27566
27665
  ]
27567
27666
  });
27568
27667
  };
@@ -27620,15 +27719,18 @@ var ClientRenderProgress = ({ job }) => {
27620
27719
  ]
27621
27720
  });
27622
27721
  }
27623
- const { encodedFrames, totalFrames } = job.progress;
27722
+ const { encodedFrames, totalFrames, doneIn, renderEstimatedTime, progress } = job.progress;
27624
27723
  return /* @__PURE__ */ jsxs121("div", {
27625
27724
  children: [
27626
27725
  /* @__PURE__ */ jsx240(Spacing, {
27627
27726
  y: 0.5
27628
27727
  }),
27629
- job.type === "client-video" && /* @__PURE__ */ jsx240(EncodingProgress, {
27728
+ job.type === "client-video" && /* @__PURE__ */ jsx240(ProgressStatus, {
27630
27729
  encodedFrames,
27631
- totalFrames
27730
+ totalFrames,
27731
+ doneIn,
27732
+ renderEstimatedTime,
27733
+ progress
27632
27734
  }),
27633
27735
  /* @__PURE__ */ jsx240(Spacing, {
27634
27736
  y: 1
@@ -28049,7 +28151,7 @@ var addTrueBooleanFlagsIfChanged = (flags, mappings) => {
28049
28151
  }
28050
28152
  };
28051
28153
  var getNpmRemotionCommandPrefix = (version) => {
28052
- return version.trim() === "" ? "npx --yes --location=global -p @remotion/cli remotion" : `npx --yes --location=global -p @remotion/cli@${version} remotion`;
28154
+ return version.trim() === "" ? "bunx --yes --location=global -p @remotion/cli remotion" : `bunx --yes --location=global -p @remotion/cli@${version} remotion`;
28053
28155
  };
28054
28156
  var normalizeServeUrlForRenderCommand = ({
28055
28157
  locationHref,
@@ -208,7 +208,7 @@ var renderContent = (Root) => {
208
208
  renderToDOM(/* @__PURE__ */ jsx("div", {
209
209
  children: /* @__PURE__ */ jsx(DelayedSpinner, {})
210
210
  }));
211
- import("./chunk-t3wtt582.js").then(({ StudioInternals }) => {
211
+ import("./chunk-x88z6n54.js").then(({ StudioInternals }) => {
212
212
  window.remotion_isStudio = true;
213
213
  window.remotion_isReadOnlyStudio = true;
214
214
  window.remotion_inputProps = "{}";
@@ -38,8 +38,8 @@ const addTrueBooleanFlagsIfChanged = (flags, mappings) => {
38
38
  };
39
39
  const getNpmRemotionCommandPrefix = (version) => {
40
40
  return version.trim() === ''
41
- ? 'npx --yes --location=global -p @remotion/cli remotion'
42
- : `npx --yes --location=global -p @remotion/cli@${version} remotion`;
41
+ ? 'bunx --yes --location=global -p @remotion/cli remotion'
42
+ : `bunx --yes --location=global -p @remotion/cli@${version} remotion`;
43
43
  };
44
44
  exports.getNpmRemotionCommandPrefix = getNpmRemotionCommandPrefix;
45
45
  const normalizeServeUrlForRenderCommand = ({ locationHref, compositionId, }) => {
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/studio"
4
4
  },
5
5
  "name": "@remotion/studio",
6
- "version": "4.0.434",
6
+ "version": "4.0.436",
7
7
  "description": "APIs for interacting with the Remotion Studio",
8
8
  "main": "dist",
9
9
  "sideEffects": false,
@@ -26,13 +26,13 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "semver": "7.5.3",
29
- "remotion": "4.0.434",
30
- "@remotion/player": "4.0.434",
31
- "@remotion/media-utils": "4.0.434",
32
- "@remotion/renderer": "4.0.434",
33
- "@remotion/web-renderer": "4.0.434",
34
- "@remotion/studio-shared": "4.0.434",
35
- "@remotion/zod-types": "4.0.434",
29
+ "remotion": "4.0.436",
30
+ "@remotion/player": "4.0.436",
31
+ "@remotion/media-utils": "4.0.436",
32
+ "@remotion/renderer": "4.0.436",
33
+ "@remotion/web-renderer": "4.0.436",
34
+ "@remotion/studio-shared": "4.0.436",
35
+ "@remotion/zod-types": "4.0.436",
36
36
  "mediabunny": "1.37.0",
37
37
  "memfs": "3.4.3",
38
38
  "source-map": "0.7.3",
@@ -43,7 +43,7 @@
43
43
  "react": "19.2.3",
44
44
  "react-dom": "19.2.3",
45
45
  "@types/semver": "^7.3.4",
46
- "@remotion/eslint-config-internal": "4.0.434",
46
+ "@remotion/eslint-config-internal": "4.0.436",
47
47
  "eslint": "9.19.0",
48
48
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
49
49
  },