@remotion/studio 4.0.496 → 4.0.498

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.
Files changed (109) hide show
  1. package/dist/components/AudioWaveform.js +1 -11
  2. package/dist/components/Canvas.js +22 -203
  3. package/dist/components/Checkbox.js +1 -1
  4. package/dist/components/CompositionSelectorItem.js +2 -10
  5. package/dist/components/ConfigureLicenseModal.d.ts +4 -0
  6. package/dist/components/ConfigureLicenseModal.js +194 -0
  7. package/dist/components/Editor.d.ts +0 -1
  8. package/dist/components/Editor.js +2 -3
  9. package/dist/components/InspectorPanel/AlignmentControls.js +2 -0
  10. package/dist/components/InspectorPanel/CompositionInspector.js +2 -1
  11. package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +27 -2
  12. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +65 -8
  13. package/dist/components/InspectorPanel/use-composition-actions.js +7 -3
  14. package/dist/components/LicenseKeyValidation.d.ts +17 -0
  15. package/dist/components/LicenseKeyValidation.js +113 -0
  16. package/dist/components/Modals.js +2 -1
  17. package/dist/components/NewComposition/CodemodFooter.d.ts +1 -1
  18. package/dist/components/NewComposition/CodemodFooter.js +23 -4
  19. package/dist/components/NewComposition/InputDragger.d.ts +6 -0
  20. package/dist/components/NewComposition/InputDragger.js +12 -3
  21. package/dist/components/NewComposition/NewComposition.js +1 -1
  22. package/dist/components/NewComposition/use-rename-static-file.js +1 -1
  23. package/dist/components/RenderButton.js +0 -1
  24. package/dist/components/RenderModal/WebRenderModal.js +14 -8
  25. package/dist/components/SelectedOutlineElement.js +56 -88
  26. package/dist/components/SelectedOutlineOverlay.d.ts +1 -1
  27. package/dist/components/SelectedOutlineOverlay.js +10 -11
  28. package/dist/components/Timeline/MaxTimelineTracks.d.ts +0 -1
  29. package/dist/components/Timeline/MaxTimelineTracks.js +3 -3
  30. package/dist/components/Timeline/Timeline.js +19 -11
  31. package/dist/components/Timeline/TimelineAssetDropIndicator.d.ts +2 -0
  32. package/dist/components/Timeline/TimelineAssetDropIndicator.js +37 -0
  33. package/dist/components/Timeline/TimelineClipboardKeybindings.js +1 -7
  34. package/dist/components/Timeline/TimelineDragHandler.js +1 -1
  35. package/dist/components/Timeline/TimelineScrollable.js +3 -2
  36. package/dist/components/Timeline/TimelineSelection.d.ts +4 -0
  37. package/dist/components/Timeline/TimelineSelection.js +41 -6
  38. package/dist/components/Timeline/TimelineSequence.js +26 -14
  39. package/dist/components/Timeline/TimelineSequenceFrame.js +2 -4
  40. package/dist/components/Timeline/TimelineSequenceItem.js +7 -5
  41. package/dist/components/Timeline/TimelineSequencePropItem.js +4 -0
  42. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +23 -3
  43. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +135 -19
  44. package/dist/components/Timeline/TimelineTimeIndicators.d.ts +16 -0
  45. package/dist/components/Timeline/TimelineTimeIndicators.js +154 -35
  46. package/dist/components/Timeline/TimelineTranslateField.js +2 -1
  47. package/dist/components/Timeline/TimelineVideoInfo.d.ts +1 -0
  48. package/dist/components/Timeline/TimelineVideoInfo.js +4 -1
  49. package/dist/components/Timeline/call-update-keyframe-settings.d.ts +17 -0
  50. package/dist/components/Timeline/call-update-keyframe-settings.js +43 -1
  51. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +2 -0
  52. package/dist/components/Timeline/delete-selected-timeline-item.js +5 -4
  53. package/dist/components/Timeline/disable-sequence-interactivity.js +2 -0
  54. package/dist/components/Timeline/get-timeline-media-visualization-layout.d.ts +8 -0
  55. package/dist/components/Timeline/get-timeline-media-visualization-layout.js +10 -0
  56. package/dist/components/Timeline/get-timeline-video-info-widths.js +11 -3
  57. package/dist/components/Timeline/keyframe-clipboard.js +21 -5
  58. package/dist/components/Timeline/reset-selected-timeline-props.js +2 -0
  59. package/dist/components/Timeline/save-sequence-prop.d.ts +5 -3
  60. package/dist/components/Timeline/save-sequence-prop.js +43 -18
  61. package/dist/components/Timeline/should-clear-selection-on-pointer-down.d.ts +2 -0
  62. package/dist/components/Timeline/should-clear-selection-on-pointer-down.js +1 -1
  63. package/dist/components/Timeline/timeline-asset-drop-context.d.ts +1 -0
  64. package/dist/components/Timeline/timeline-asset-drop-context.js +5 -0
  65. package/dist/components/Timeline/timeline-scroll-logic.d.ts +7 -0
  66. package/dist/components/Timeline/timeline-scroll-logic.js +10 -1
  67. package/dist/components/Timeline/update-selected-easing.js +26 -23
  68. package/dist/components/Timeline/use-rename-sequence.js +2 -0
  69. package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.d.ts +5 -0
  70. package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.js +18 -9
  71. package/dist/components/Timeline/use-timeline-asset-drop.d.ts +1 -0
  72. package/dist/components/Timeline/use-timeline-asset-drop.js +168 -0
  73. package/dist/components/composition-menu-items.d.ts +15 -1
  74. package/dist/components/composition-menu-items.js +137 -107
  75. package/dist/components/drop-handler-data.d.ts +13 -0
  76. package/dist/components/drop-handler-data.js +117 -0
  77. package/dist/components/handle-drop.d.ts +13 -0
  78. package/dist/components/handle-drop.js +115 -0
  79. package/dist/components/import-assets.d.ts +26 -8
  80. package/dist/components/import-assets.js +161 -49
  81. package/dist/components/selected-outline-drag.d.ts +11 -1
  82. package/dist/components/selected-outline-drag.js +74 -1
  83. package/dist/esm/{chunk-0v4n7nkh.js → chunk-7a6q9hk2.js} +5271 -4259
  84. package/dist/esm/index.mjs +0 -19
  85. package/dist/esm/internals.mjs +5271 -4259
  86. package/dist/esm/previewEntry.mjs +5475 -4463
  87. package/dist/esm/renderEntry.mjs +1 -1
  88. package/dist/helpers/interactivity-enabled.d.ts +1 -1
  89. package/dist/helpers/interactivity-enabled.js +2 -2
  90. package/dist/helpers/is-video-with-last-frame-hold.d.ts +2 -0
  91. package/dist/helpers/is-video-with-last-frame-hold.js +9 -0
  92. package/dist/helpers/retry-payload.js +0 -1
  93. package/dist/helpers/url-state.d.ts +1 -0
  94. package/dist/helpers/url-state.js +5 -1
  95. package/dist/helpers/use-max-media-duration.js +5 -3
  96. package/dist/helpers/use-menu-structure.js +11 -3
  97. package/dist/icons/duplicate.d.ts +5 -0
  98. package/dist/icons/duplicate.js +10 -0
  99. package/dist/icons/snowflake.d.ts +5 -0
  100. package/dist/icons/snowflake.js +10 -0
  101. package/dist/icons/trash.d.ts +5 -0
  102. package/dist/icons/trash.js +8 -0
  103. package/dist/state/modals.d.ts +3 -1
  104. package/dist/visual-controls/VisualControls.js +1 -1
  105. package/package.json +11 -11
  106. package/dist/components/RenderModal/WebRenderModalLicense.d.ts +0 -9
  107. package/dist/components/RenderModal/WebRenderModalLicense.js +0 -189
  108. package/dist/components/RenderModal/WebRenderModalLicenseKeyDetails.d.ts +0 -13
  109. package/dist/components/RenderModal/WebRenderModalLicenseKeyDetails.js +0 -60
@@ -212,7 +212,7 @@ var renderContent = (Root) => {
212
212
  renderToDOM(/* @__PURE__ */ jsx("div", {
213
213
  children: /* @__PURE__ */ jsx(DelayedSpinner, {})
214
214
  }));
215
- import("./chunk-0v4n7nkh.js").then(({ StudioInternals }) => {
215
+ import("./chunk-7a6q9hk2.js").then(({ StudioInternals }) => {
216
216
  window.remotion_isStudio = true;
217
217
  window.remotion_isReadOnlyStudio = true;
218
218
  window.remotion_inputProps = "{}";
@@ -1 +1 @@
1
- export declare const studioInteractivityEnabled: boolean;
1
+ export declare const isStudioInteractivityEnabled: () => boolean;
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.studioInteractivityEnabled = void 0;
3
+ exports.isStudioInteractivityEnabled = void 0;
4
4
  const studio_runtime_config_1 = require("./studio-runtime-config");
5
- exports.studioInteractivityEnabled = (0, studio_runtime_config_1.getStudioInteractivityEnabled)();
5
+ exports.isStudioInteractivityEnabled = studio_runtime_config_1.getStudioInteractivityEnabled;
@@ -0,0 +1,2 @@
1
+ import type { TSequence } from 'remotion';
2
+ export declare const isVideoWithLastFrameHold: (sequence: TSequence) => boolean;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isVideoWithLastFrameHold = void 0;
4
+ const isVideoWithLastFrameHold = (sequence) => {
5
+ var _a;
6
+ return (sequence.type === 'video' &&
7
+ ((_a = sequence.controls) === null || _a === void 0 ? void 0 : _a.componentIdentity) === 'dev.remotion.media.Video');
8
+ };
9
+ exports.isVideoWithLastFrameHold = isVideoWithLastFrameHold;
@@ -182,7 +182,6 @@ const makeClientRetryPayload = (job) => {
182
182
  compositionId: job.compositionId,
183
183
  initialFrame: job.type === 'client-still' ? job.frame : 0,
184
184
  initialLogLevel: job.logLevel,
185
- initialLicenseKey: job.licenseKey,
186
185
  defaultProps: job.inputProps,
187
186
  inFrameMark: job.type === 'client-video' ? job.startFrame : null,
188
187
  outFrameMark: job.type === 'client-video' ? job.endFrame : null,
@@ -1,5 +1,6 @@
1
1
  export declare const getUrlForRoute: (route: string) => string;
2
2
  export declare const pushUrl: (url: string) => void;
3
+ export declare const replaceUrl: (url: string) => void;
3
4
  export declare const clearUrl: () => void;
4
5
  export declare const reloadUrl: () => void;
5
6
  export declare const getRoute: () => string;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getRoute = exports.reloadUrl = exports.clearUrl = exports.pushUrl = exports.getUrlForRoute = void 0;
3
+ exports.getRoute = exports.reloadUrl = exports.clearUrl = exports.replaceUrl = exports.pushUrl = exports.getUrlForRoute = void 0;
4
4
  const getUrlHandlingType = () => {
5
5
  if (window.remotion_isReadOnlyStudio) {
6
6
  return 'query-string';
@@ -18,6 +18,10 @@ const pushUrl = (url) => {
18
18
  window.history.pushState({}, 'Studio', (0, exports.getUrlForRoute)(url));
19
19
  };
20
20
  exports.pushUrl = pushUrl;
21
+ const replaceUrl = (url) => {
22
+ window.history.replaceState({}, 'Studio', (0, exports.getUrlForRoute)(url));
23
+ };
24
+ exports.replaceUrl = replaceUrl;
21
25
  const clearUrl = () => {
22
26
  window.location.href = window.location.pathname;
23
27
  };
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useMaxMediaDuration = void 0;
4
4
  const react_1 = require("react");
5
+ const is_video_with_last_frame_hold_1 = require("./is-video-with-last-frame-hold");
5
6
  const use_media_metadata_1 = require("./use-media-metadata");
6
7
  const cache = new Map();
7
8
  const getCacheKey = (src, fps) => JSON.stringify([src, fps]);
@@ -16,7 +17,8 @@ const getSrc = (s) => {
16
17
  };
17
18
  const useMaxMediaDuration = (s, fps) => {
18
19
  var _a;
19
- const src = getSrc(s);
20
+ const holdsLastFrame = (0, is_video_with_last_frame_hold_1.isVideoWithLastFrameHold)(s);
21
+ const src = holdsLastFrame ? null : getSrc(s);
20
22
  const cacheKey = src ? getCacheKey(src, fps) : null;
21
23
  const [maxMediaDuration, setMaxMediaDuration] = (0, react_1.useState)(cacheKey ? ((_a = cache.get(cacheKey)) !== null && _a !== void 0 ? _a : null) : Infinity);
22
24
  (0, react_1.useEffect)(() => {
@@ -49,8 +51,8 @@ const useMaxMediaDuration = (s, fps) => {
49
51
  cancelled = true;
50
52
  };
51
53
  }, [cacheKey, fps, src]);
52
- if (maxMediaDuration !== null && (s.type === 'audio' || s.type === 'video')) {
53
- return maxMediaDuration;
54
+ if (holdsLastFrame) {
55
+ return Infinity;
54
56
  }
55
57
  return maxMediaDuration;
56
58
  };
@@ -269,16 +269,22 @@ const useMenuStructure = (closeMenu, readOnlyStudio) => {
269
269
  {
270
270
  id: 'license',
271
271
  value: 'license',
272
- label: 'License',
272
+ label: 'Configure License...',
273
273
  onClick: () => {
274
+ var _a;
275
+ var _b;
274
276
  closeMenu();
275
- openExternal('https://github.com/remotion-dev/remotion/blob/main/LICENSE.md');
277
+ setSelectedModal({
278
+ type: 'configure-license',
279
+ initialPublicLicenseKey: (_b = (_a = window.remotion_renderDefaults) === null || _a === void 0 ? void 0 : _a.publicLicenseKey) !== null && _b !== void 0 ? _b : null,
280
+ });
276
281
  },
277
282
  type: 'item',
278
283
  keyHint: null,
279
284
  leftItem: null,
280
285
  subMenu: null,
281
- quickSwitcherLabel: 'Help: License',
286
+ quickSwitcherLabel: 'Configure License...',
287
+ disabled: readOnlyStudio || type !== 'connected',
282
288
  },
283
289
  {
284
290
  id: 'acknowledgements',
@@ -671,6 +677,8 @@ const useMenuStructure = (closeMenu, readOnlyStudio) => {
671
677
  closeMenu,
672
678
  composition: currentComposition,
673
679
  connectionStatus: type,
680
+ includeCompositionManagementItems: true,
681
+ includeNewCompositionItem: true,
674
682
  resolvedLocation: resolvedCompositionLocation,
675
683
  setSelectedModal,
676
684
  readOnlyStudio,
@@ -0,0 +1,5 @@
1
+ import type { SVGProps } from 'react';
2
+ import React from 'react';
3
+ export declare const DuplicateIcon: React.FC<SVGProps<SVGSVGElement> & {
4
+ readonly color: string;
5
+ }>;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DuplicateIcon = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ // Font Awesome Pro v7.3.1, Copyright 2026 Fonticons, Inc.
6
+ // https://fontawesome.com/license (Commercial License)
7
+ const DuplicateIcon = ({ color, ...props }) => {
8
+ return (jsx_runtime_1.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 640 640", ...props, children: jsx_runtime_1.jsx("path", { fill: color, d: "M352 544L128 544C110.3 544 96 529.7 96 512L96 288C96 270.3 110.3 256 128 256L176 256L176 224L128 224C92.7 224 64 252.7 64 288L64 512C64 547.3 92.7 576 128 576L352 576C387.3 576 416 547.3 416 512L416 464L384 464L384 512C384 529.7 369.7 544 352 544zM288 384C270.3 384 256 369.7 256 352L256 128C256 110.3 270.3 96 288 96L512 96C529.7 96 544 110.3 544 128L544 352C544 369.7 529.7 384 512 384L288 384zM224 352C224 387.3 252.7 416 288 416L512 416C547.3 416 576 387.3 576 352L576 128C576 92.7 547.3 64 512 64L288 64C252.7 64 224 92.7 224 128L224 352z" }) }));
9
+ };
10
+ exports.DuplicateIcon = DuplicateIcon;
@@ -0,0 +1,5 @@
1
+ import type { SVGProps } from 'react';
2
+ import React from 'react';
3
+ export declare const SnowflakeIcon: React.FC<SVGProps<SVGSVGElement> & {
4
+ readonly color: string;
5
+ }>;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SnowflakeIcon = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ // Font Awesome Free v7.3.1, Copyright 2026 Fonticons, Inc.
6
+ // https://fontawesome.com/license/free
7
+ const SnowflakeIcon = ({ color, ...props }) => {
8
+ return (jsx_runtime_1.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 640 640", ...props, children: jsx_runtime_1.jsx("path", { fill: color, d: "M344.1 56C344.1 42.7 333.4 32 320.1 32C306.8 32 296.1 42.7 296.1 56L296.1 134.1L273.1 111.1C263.7 101.7 248.5 101.7 239.2 111.1C229.9 120.5 229.8 135.7 239.2 145L296.2 202L296.2 278.5L230 240.3L209.1 162.5C205.7 149.7 192.5 142.1 179.7 145.5C166.9 148.9 159.2 162 162.7 174.8L171.1 206.3L103.5 167.3C92 160.6 77.3 164.5 70.7 176C64.1 187.5 68 202.2 79.5 208.8L147.1 247.8L115.6 256.2C102.8 259.6 95.2 272.8 98.6 285.6C102 298.4 115.2 306 128 302.6L205.8 281.7L272 319.9L205.8 358.1L128 337.2C115.2 333.8 102 341.4 98.6 354.2C95.2 367 102.8 380.2 115.6 383.6L147.1 392L79.5 431C68 437.8 64.1 452.5 70.7 464C77.3 475.5 92 479.4 103.5 472.8L171.1 433.8L162.7 465.3C159.3 478.1 166.9 491.3 179.7 494.7C192.5 498.1 205.7 490.5 209.1 477.7L230 399.9L296.2 361.7L296.2 438.2L239.2 495.2C229.8 504.6 229.8 519.8 239.2 529.1C248.6 538.4 263.8 538.5 273.1 529.1L296.1 506.1L296.1 584.2C296.1 597.5 306.8 608.2 320.1 608.2C333.4 608.2 344.1 597.5 344.1 584.2L344.1 506.1L367.1 529.1C376.5 538.5 391.7 538.5 401 529.1C410.3 519.7 410.4 504.5 401 495.2L344 438.2L344 361.7L410.2 399.9L431.1 477.7C434.5 490.5 447.7 498.1 460.5 494.7C473.3 491.3 480.9 478.1 477.5 465.3L469.1 433.8L536.7 472.8C548.2 479.4 562.9 475.5 569.5 464C576.1 452.5 572.2 437.8 560.7 431.2L493.1 392.2L524.6 383.8C537.4 380.4 545 367.2 541.6 354.4C538.2 341.6 525 334 512.2 337.4L434.4 358.3L368.2 320.1L434.4 281.9L512.2 302.8C525 306.2 538.2 298.6 541.6 285.8C545 273 537.4 259.8 524.6 256.4L493.1 248L560.7 209C572.2 202.4 576.1 187.7 569.5 176.2C562.9 164.7 548.2 160.8 536.7 167.4L469.1 206.4L477.5 174.9C480.9 162.1 473.3 148.9 460.5 145.5C447.7 142.1 434.5 149.7 431.1 162.5L410.2 240.3L344 278.5L344 202L401 145C410.4 135.6 410.4 120.4 401 111.1C391.6 101.8 376.4 101.7 367.1 111.1L344.1 134.1L344.1 56z" }) }));
9
+ };
10
+ exports.SnowflakeIcon = SnowflakeIcon;
@@ -0,0 +1,5 @@
1
+ import type { SVGProps } from 'react';
2
+ import React from 'react';
3
+ export declare const TrashIcon: React.FC<SVGProps<SVGSVGElement> & {
4
+ readonly color: string;
5
+ }>;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TrashIcon = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const TrashIcon = ({ color, ...props }) => {
6
+ return (jsx_runtime_1.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 448 512", ...props, children: jsx_runtime_1.jsx("path", { fill: color, d: "M160.5 27.4C162.5 20.6 168.8 16 175.8 16h96.4c7.1 0 13.3 4.6 15.3 11.4l11 36.6h-149l11-36.6zM116.1 64H16C7.2 64 0 71.2 0 80s7.2 16 16 16h416c8.8 0 16-7.2 16-16s-7.2-16-16-16H331.9l-13.7-45.8C312.1-2.1 293.4-16 272.2-16h-96.4c-21.2 0-39.9 13.9-46 34.2L116.1 64zM28.7 144l22.9 308.7c2.5 33.4 30.3 59.3 63.8 59.3h217.1c33.5 0 61.3-25.9 63.8-59.3L419.2 144h-32.1l-22.7 306.4c-1.2 16.7-15.2 29.6-31.9 29.6H115.4c-16.8 0-30.7-12.9-31.9-29.6L60.8 144H28.7z" }) }));
7
+ };
8
+ exports.TrashIcon = TrashIcon;
@@ -29,7 +29,6 @@ export type WebRenderModalState = {
29
29
  initialKeyframeIntervalInSeconds: number | null;
30
30
  initialTransparent: boolean | null;
31
31
  initialMuted: boolean | null;
32
- initialLicenseKey: string | null;
33
32
  initialMediaCacheSizeInBytes: number | null;
34
33
  initialPageResponsiveness: WebRendererPageResponsiveness;
35
34
  };
@@ -143,6 +142,9 @@ export type ModalState = {
143
142
  relativePath: string;
144
143
  } | {
145
144
  type: 'input-props-override';
145
+ } | {
146
+ type: 'configure-license';
147
+ initialPublicLicenseKey: string | null;
146
148
  } | RenderModalState | WebRenderModalState | {
147
149
  type: 'render-progress';
148
150
  jobId: string;
@@ -70,7 +70,7 @@ const VisualControlsProvider = ({ children }) => {
70
70
  if (!env.isStudio) {
71
71
  return value;
72
72
  }
73
- if (!interactivity_enabled_1.studioInteractivityEnabled) {
73
+ if (!(0, interactivity_enabled_1.isStudioInteractivityEnabled)()) {
74
74
  return value;
75
75
  }
76
76
  if (!z) {
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.496",
6
+ "version": "4.0.498",
7
7
  "description": "APIs for interacting with the Remotion Studio",
8
8
  "main": "dist",
9
9
  "scripts": {
@@ -25,15 +25,15 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "semver": "7.5.3",
28
- "remotion": "4.0.496",
29
- "@remotion/canvas-capture": "4.0.496",
30
- "@remotion/player": "4.0.496",
31
- "@remotion/media-utils": "4.0.496",
32
- "@remotion/renderer": "4.0.496",
33
- "@remotion/web-renderer": "4.0.496",
34
- "@remotion/studio-shared": "4.0.496",
35
- "@remotion/timeline-utils": "4.0.496",
36
- "@remotion/zod-types": "4.0.496",
28
+ "remotion": "4.0.498",
29
+ "@remotion/canvas-capture": "4.0.498",
30
+ "@remotion/player": "4.0.498",
31
+ "@remotion/media-utils": "4.0.498",
32
+ "@remotion/renderer": "4.0.498",
33
+ "@remotion/web-renderer": "4.0.498",
34
+ "@remotion/studio-shared": "4.0.498",
35
+ "@remotion/timeline-utils": "4.0.498",
36
+ "@remotion/zod-types": "4.0.498",
37
37
  "@jridgewell/trace-mapping": "0.3.31",
38
38
  "mediabunny": "1.50.8",
39
39
  "memfs": "3.4.3",
@@ -44,7 +44,7 @@
44
44
  "react": "19.2.3",
45
45
  "react-dom": "19.2.3",
46
46
  "@types/semver": "7.5.3",
47
- "@remotion/eslint-config-internal": "4.0.496",
47
+ "@remotion/eslint-config-internal": "4.0.498",
48
48
  "eslint": "9.19.0",
49
49
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
50
50
  },
@@ -1,9 +0,0 @@
1
- import React from 'react';
2
- type WebRenderModalLicenseProps = {
3
- readonly licenseKey: string | null;
4
- readonly setLicenseKey: React.Dispatch<React.SetStateAction<string | null>>;
5
- readonly initialPublicLicenseKey: string | null;
6
- };
7
- export declare const row: React.CSSProperties;
8
- export declare const WebRenderModalLicense: React.FC<WebRenderModalLicenseProps>;
9
- export {};
@@ -1,189 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WebRenderModalLicense = exports.row = void 0;
4
- const jsx_runtime_1 = require("react/jsx-runtime");
5
- const react_1 = require("react");
6
- const colors_1 = require("../../helpers/colors");
7
- const Checkbox_1 = require("../Checkbox");
8
- const layout_1 = require("../layout");
9
- const RemInput_1 = require("../NewComposition/RemInput");
10
- const ValidationMessage_1 = require("../NewComposition/ValidationMessage");
11
- const WebRenderModalLicenseKeyDetails_1 = require("./WebRenderModalLicenseKeyDetails");
12
- exports.row = {
13
- display: 'flex',
14
- flexDirection: 'row',
15
- paddingLeft: 16,
16
- paddingRight: 16,
17
- };
18
- const tabContainer = {
19
- flex: 1,
20
- };
21
- const descriptionStyle = {
22
- color: colors_1.LIGHT_TEXT,
23
- fontSize: 14,
24
- fontFamily: 'sans-serif',
25
- paddingLeft: 16,
26
- paddingRight: 16,
27
- paddingTop: 16,
28
- paddingBottom: 8,
29
- lineHeight: 1.5,
30
- };
31
- const paddedDescriptionStyle = {
32
- color: colors_1.LIGHT_TEXT,
33
- fontSize: 14,
34
- fontFamily: 'sans-serif',
35
- padding: 9,
36
- border: '1px solid ' + colors_1.BLACK_ALPHA_60,
37
- borderRadius: 8,
38
- lineHeight: 1.5,
39
- marginLeft: 16,
40
- marginRight: 16,
41
- };
42
- const descriptionLink = {
43
- color: colors_1.WHITE,
44
- fontSize: 14,
45
- };
46
- const checkboxLabel = {
47
- fontSize: 14,
48
- lineHeight: '40px',
49
- color: colors_1.LIGHT_TEXT,
50
- flex: 1,
51
- fontFamily: 'sans-serif',
52
- cursor: 'pointer',
53
- userSelect: 'none',
54
- };
55
- const inputStyle = {
56
- minWidth: 250,
57
- };
58
- const justifyCenter = {
59
- display: 'flex',
60
- alignItems: 'center',
61
- gap: 10,
62
- flex: 1,
63
- };
64
- const codeStyle = {
65
- fontSize: 14,
66
- fontFamily: 'monospace',
67
- color: colors_1.BLUE,
68
- };
69
- const codeLine = {
70
- fontSize: 14,
71
- fontFamily: 'monospace',
72
- color: colors_1.LIGHT_TEXT,
73
- backgroundColor: colors_1.INPUT_BACKGROUND,
74
- padding: 6,
75
- borderRadius: 3,
76
- marginTop: 6,
77
- overflowX: 'auto',
78
- maxWidth: '100%',
79
- };
80
- const codeLineSmall = {
81
- ...codeLine,
82
- fontSize: 11,
83
- };
84
- const LICENSE_KEY_LENGTH = 55;
85
- const LICENSE_KEY_PREFIX = 'rm_pub_';
86
- const validateLicenseKey = (key) => {
87
- if (key.length === 0) {
88
- return { valid: false, message: null, details: null };
89
- }
90
- if (!key.startsWith(LICENSE_KEY_PREFIX)) {
91
- return {
92
- valid: false,
93
- message: `License key must start with "${LICENSE_KEY_PREFIX}"`,
94
- details: null,
95
- };
96
- }
97
- const afterPrefix = key.slice(LICENSE_KEY_PREFIX.length);
98
- if (!/^[a-zA-Z0-9]*$/.test(afterPrefix)) {
99
- return {
100
- valid: false,
101
- message: 'License key must contain only alphanumeric characters after the prefix',
102
- details: null,
103
- };
104
- }
105
- if (key.length !== LICENSE_KEY_LENGTH) {
106
- return {
107
- valid: false,
108
- message: `License key must be ${LICENSE_KEY_LENGTH} characters long`,
109
- details: null,
110
- };
111
- }
112
- return { valid: true, message: null, details: null };
113
- };
114
- const WebRenderModalLicense = ({ licenseKey, setLicenseKey, initialPublicLicenseKey, }) => {
115
- const [licenseValidation, setLicenseValidation] = (0, react_1.useState)({ valid: true, message: null, details: null });
116
- const [isLoading, setIsLoading] = (0, react_1.useState)(false);
117
- (0, react_1.useEffect)(() => {
118
- if (licenseKey === null || licenseKey === 'free-license') {
119
- return setLicenseValidation({
120
- valid: true,
121
- message: null,
122
- details: null,
123
- });
124
- }
125
- const validation = validateLicenseKey(licenseKey);
126
- if (!validation.valid) {
127
- return setLicenseValidation(validation);
128
- }
129
- setLicenseValidation({ valid: true, message: null, details: null });
130
- setIsLoading(true);
131
- (0, WebRenderModalLicenseKeyDetails_1.fetchLicenseKeyDetails)(licenseKey)
132
- .then((details) => {
133
- setIsLoading(false);
134
- if (details.isValid) {
135
- setLicenseValidation({ valid: true, message: null, details });
136
- }
137
- else {
138
- setLicenseValidation({
139
- valid: false,
140
- message: 'License key is invalid or has been reset',
141
- details: null,
142
- });
143
- }
144
- })
145
- .catch(() => {
146
- setIsLoading(false);
147
- setLicenseValidation({
148
- valid: false,
149
- message: 'Failed to fetch license key details',
150
- details: null,
151
- });
152
- });
153
- }, [licenseKey]);
154
- const onFreeLicenseChange = (0, react_1.useCallback)(() => {
155
- setLicenseKey('free-license');
156
- }, [setLicenseKey]);
157
- const onCompanyLicenseChange = (0, react_1.useCallback)(() => {
158
- setLicenseKey(initialPublicLicenseKey !== null && initialPublicLicenseKey !== void 0 ? initialPublicLicenseKey : '');
159
- }, [initialPublicLicenseKey, setLicenseKey]);
160
- const onLicenseKeyChange = (0, react_1.useCallback)((e) => {
161
- setLicenseKey(e.target.value);
162
- }, [setLicenseKey]);
163
- return (jsx_runtime_1.jsxs("div", { style: tabContainer, children: [
164
- jsx_runtime_1.jsxs("div", { style: descriptionStyle, children: ["Remotion is free if you are an individual or company with a headcount of 3 or less. See", ' ', jsx_runtime_1.jsx("a", { style: descriptionLink, href: "https://remotion.dev/license", children: "LICENSE.md" }),
165
- "."] }), jsx_runtime_1.jsx("div", { style: exports.row, children: jsx_runtime_1.jsxs("div", { style: justifyCenter, children: [
166
- jsx_runtime_1.jsx(Checkbox_1.Checkbox, { checked: licenseKey === 'free-license', onChange: onFreeLicenseChange, name: "free-license", rounded: true }), jsx_runtime_1.jsxs("div", { style: checkboxLabel, onClick: onFreeLicenseChange, children: ["I am eligible for the Free License, ", "don't", " print a warning"] })
167
- ] }) }), licenseKey === 'free-license' ? (jsx_runtime_1.jsxs("div", { style: paddedDescriptionStyle, children: ["Enjoy Remotion! Add the following to", ' ', jsx_runtime_1.jsx("code", { style: codeStyle, children: "remotion.config.ts" }),
168
- " to persist this setting:",
169
- jsx_runtime_1.jsx("div", { style: codeLine, children: "Config.setPublicLicenseKey('free-license');" })
170
- ] })) : null, jsx_runtime_1.jsx("div", { style: exports.row, children: jsx_runtime_1.jsxs("div", { style: justifyCenter, children: [
171
- jsx_runtime_1.jsx(Checkbox_1.Checkbox, { checked: licenseKey !== 'free-license' && licenseKey !== null, onChange: onCompanyLicenseChange, name: "company-license", rounded: true }), jsx_runtime_1.jsx("div", { style: checkboxLabel, onClick: onCompanyLicenseChange, children: "I have a Company License" })
172
- ] }) }), licenseKey !== 'free-license' && licenseKey !== null ? (jsx_runtime_1.jsxs("div", { style: paddedDescriptionStyle, children: ["Add your public license key from", ' ', jsx_runtime_1.jsx("a", { href: "https://remotion.pro/dashboard", target: "_blank", style: descriptionLink, children: "remotion.pro" }), ' ', "below.",
173
- jsx_runtime_1.jsx(layout_1.Spacing, { y: 1, block: true }), jsx_runtime_1.jsx(RemInput_1.RemotionInput, { value: licenseKey, onChange: onLicenseKeyChange, placeholder: "remotion.pro public license key (starts with rm_pub_)", status: licenseValidation.valid || licenseKey.length === 0
174
- ? 'ok'
175
- : 'error', rightAlign: false, style: inputStyle, autoFocus: true }), licenseValidation.message ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
176
- jsx_runtime_1.jsx(layout_1.Spacing, { y: 1, block: true }), jsx_runtime_1.jsx(ValidationMessage_1.ValidationMessage, { message: licenseValidation.message, align: "flex-start", type: "error" })
177
- ] })) : null, licenseValidation.valid && licenseKey.length > 0 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
178
- jsx_runtime_1.jsx(layout_1.Spacing, { y: 1, block: true }),
179
- "Add the following to", ' ', jsx_runtime_1.jsx("code", { style: codeStyle, children: "remotion.config.ts" }),
180
- " to persist this setting:",
181
- jsx_runtime_1.jsx("div", { style: codeLineSmall, children: "Config.setPublicLicenseKey('" + licenseKey + "');" })
182
- ] })) : null, isLoading && (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
183
- jsx_runtime_1.jsx(layout_1.Spacing, { y: 1, block: true }),
184
- "Loading license key details..."] })), licenseValidation.details && (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
185
- jsx_runtime_1.jsx(layout_1.Spacing, { y: 1, block: true }), jsx_runtime_1.jsx(WebRenderModalLicenseKeyDetails_1.WebRenderModalLicenseKeyDetails, { details: licenseValidation.details })
186
- ] }))] })) : null, licenseKey === null ? (jsx_runtime_1.jsxs("div", { style: descriptionStyle, children: ["If you are not eligible for the free license, you need to obtain a", ' ', jsx_runtime_1.jsx("a", { style: descriptionLink, target: "_blank", href: "https://remotion.pro/license", children: "Company License" }),
187
- "."] })) : null] }));
188
- };
189
- exports.WebRenderModalLicense = WebRenderModalLicense;
@@ -1,13 +0,0 @@
1
- import React from 'react';
2
- export type LicenseKeyDetails = {
3
- readonly isValid: boolean;
4
- readonly hasActiveSubscription: boolean;
5
- readonly projectName: string;
6
- readonly projectSlug: string;
7
- };
8
- type WebRenderModalLicenseKeyDetailsProps = {
9
- readonly details: LicenseKeyDetails;
10
- };
11
- export declare const fetchLicenseKeyDetails: (licenseKey: string) => Promise<LicenseKeyDetails>;
12
- export declare const WebRenderModalLicenseKeyDetails: React.FC<WebRenderModalLicenseKeyDetailsProps>;
13
- export {};
@@ -1,60 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WebRenderModalLicenseKeyDetails = exports.fetchLicenseKeyDetails = void 0;
4
- const jsx_runtime_1 = require("react/jsx-runtime");
5
- const colors_1 = require("../../helpers/colors");
6
- const check_circle_filled_1 = require("../../icons/check-circle-filled");
7
- const ValidationMessage_1 = require("../NewComposition/ValidationMessage");
8
- const textStyle = {
9
- color: colors_1.LIGHT_TEXT,
10
- fontSize: 14,
11
- fontFamily: 'sans-serif',
12
- lineHeight: 1.5,
13
- display: 'flex',
14
- alignItems: 'center',
15
- };
16
- const linkStyle = {
17
- fontSize: 14,
18
- fontFamily: 'sans-serif',
19
- lineHeight: 1.5,
20
- cursor: 'pointer',
21
- };
22
- const bulletStyle = {
23
- display: 'flex',
24
- alignItems: 'center',
25
- gap: 6,
26
- };
27
- const icon = {
28
- width: 14,
29
- height: 14,
30
- flexShrink: 0,
31
- };
32
- const PRO_HOST = 'https://remotion.pro';
33
- const fetchLicenseKeyDetails = async (licenseKey) => {
34
- const response = await fetch(`${PRO_HOST}/api/validate-license-key`, {
35
- method: 'POST',
36
- body: JSON.stringify({
37
- licenseKey,
38
- }),
39
- headers: {
40
- 'Content-Type': 'application/json',
41
- },
42
- });
43
- return response.json();
44
- };
45
- exports.fetchLicenseKeyDetails = fetchLicenseKeyDetails;
46
- const WebRenderModalLicenseKeyDetails = ({ details }) => {
47
- return (jsx_runtime_1.jsxs("div", { children: [
48
- jsx_runtime_1.jsxs("div", { style: bulletStyle, children: [
49
- jsx_runtime_1.jsx(check_circle_filled_1.CheckCircleFilled, { style: { ...icon, fill: colors_1.LIGHT_TEXT } }), jsx_runtime_1.jsxs("div", { style: textStyle, children: ["Belongs to\u00A0",
50
- jsx_runtime_1.jsx("a", { href: `${PRO_HOST}/projects/${details.projectSlug}`, target: "_blank", style: linkStyle, children: details.projectName }),
51
- "\u00A0-\u00A0",
52
- jsx_runtime_1.jsx("a", { href: `${PRO_HOST}/projects/${details.projectSlug}/usage#client-renders-usage`, target: "_blank", style: linkStyle, children: "View usage" })
53
- ] })
54
- ] }), details.hasActiveSubscription ? (jsx_runtime_1.jsxs("div", { style: bulletStyle, children: [
55
- jsx_runtime_1.jsx(check_circle_filled_1.CheckCircleFilled, { style: { ...icon, fill: colors_1.LIGHT_TEXT } }), jsx_runtime_1.jsx("div", { style: textStyle, children: "Active Company License" })
56
- ] })) : (jsx_runtime_1.jsxs("div", { style: bulletStyle, children: [
57
- jsx_runtime_1.jsx(ValidationMessage_1.WarningTriangle, { type: "warning", style: { ...icon, fill: colors_1.WARNING_COLOR } }), jsx_runtime_1.jsx("div", { style: textStyle, children: "No active Company License" })
58
- ] }))] }));
59
- };
60
- exports.WebRenderModalLicenseKeyDetails = WebRenderModalLicenseKeyDetails;