@remotion/cli 4.0.8 → 4.0.11

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.
@@ -13,24 +13,29 @@ const doesMatchPath = (path1, enumPaths) => {
13
13
  return item === p[index];
14
14
  }));
15
15
  };
16
- const stringifyDefaultProps = ({ props, enumPaths, }) => JSON.stringify(props, replacerWithPath(function (key, value, path) {
17
- /* Don't replace with arrow function */ const item = this[key];
18
- if (item instanceof Date) {
19
- return `__REMOVEQUOTE__new Date('${item.toISOString()}')__REMOVEQUOTE__`;
20
- }
21
- if (typeof item === 'string' && doesMatchPath(path, enumPaths)) {
22
- return `${item}__ADD_AS_CONST__`;
23
- }
24
- if (typeof item === 'string' && item.startsWith(remotion_1.Internals.FILE_TOKEN)) {
25
- return `__REMOVEQUOTE____WRAP_IN_STATIC_FILE_START__${decodeURIComponent(item.replace(remotion_1.Internals.FILE_TOKEN, ''))}__WRAP_IN_STATIC_FILE_END____REMOVEQUOTE__`;
26
- }
27
- return value;
28
- }))
29
- .replace(/"__REMOVEQUOTE__/g, '')
30
- .replace(/__REMOVEQUOTE__"/g, '')
31
- .replace(/__ADD_AS_CONST__"/g, '" as const')
32
- .replace(/__WRAP_IN_STATIC_FILE_START__/g, 'staticFile("')
33
- .replace(/__WRAP_IN_STATIC_FILE_END__/g, '")');
16
+ const stringifyDefaultProps = ({ props, enumPaths, }) => {
17
+ return JSON.stringify(props, replacerWithPath(function (key, value, path) {
18
+ /* Don't replace with arrow function! This function uses `this` */
19
+ const item = this[key];
20
+ if (typeof item === 'string' && doesMatchPath(path, enumPaths)) {
21
+ return `${item}__ADD_AS_CONST__`;
22
+ }
23
+ if (typeof item === 'string' && item.startsWith(remotion_1.Internals.FILE_TOKEN)) {
24
+ return `__REMOVEQUOTE____WRAP_IN_STATIC_FILE_START__${decodeURIComponent(item.replace(remotion_1.Internals.FILE_TOKEN, ''))}__WRAP_IN_STATIC_FILE_END____REMOVEQUOTE__`;
25
+ }
26
+ if (typeof item === 'string' && item.startsWith(remotion_1.Internals.DATE_TOKEN)) {
27
+ return `__REMOVEQUOTE____WRAP_IN_DATE_START__${decodeURIComponent(item.replace(remotion_1.Internals.DATE_TOKEN, ''))}__WRAP_IN_DATE_END____REMOVEQUOTE__`;
28
+ }
29
+ return value;
30
+ }))
31
+ .replace(/"__REMOVEQUOTE__/g, '')
32
+ .replace(/__REMOVEQUOTE__"/g, '')
33
+ .replace(/__ADD_AS_CONST__"/g, '" as const')
34
+ .replace(/__WRAP_IN_STATIC_FILE_START__/g, 'staticFile("')
35
+ .replace(/__WRAP_IN_STATIC_FILE_END__/g, '")')
36
+ .replace(/__WRAP_IN_DATE_START__/g, 'new Date("')
37
+ .replace(/__WRAP_IN_DATE_END__/g, '")');
38
+ };
34
39
  exports.stringifyDefaultProps = stringifyDefaultProps;
35
40
  function replacerWithPath(replacer) {
36
41
  const m = new Map();
@@ -9,6 +9,7 @@ const colors_1 = require("../helpers/colors");
9
9
  const get_effective_translation_1 = require("../helpers/get-effective-translation");
10
10
  const is_current_selected_still_1 = require("../helpers/is-current-selected-still");
11
11
  const use_keybinding_1 = require("../helpers/use-keybinding");
12
+ const canvas_ref_1 = require("../state/canvas-ref");
12
13
  const editor_zoom_gestures_1 = require("../state/editor-zoom-gestures");
13
14
  const preview_size_1 = require("../state/preview-size");
14
15
  const layout_1 = require("./layout");
@@ -29,11 +30,10 @@ const resetZoom = {
29
30
  const ZOOM_PX_FACTOR = 0.003;
30
31
  const Canvas = () => {
31
32
  const dimensions = (0, is_current_selected_still_1.useDimensions)();
32
- const ref = (0, react_1.useRef)(null);
33
33
  const { setSize, size: previewSize } = (0, react_1.useContext)(preview_size_1.PreviewSizeContext);
34
34
  const { editorZoomGestures } = (0, react_1.useContext)(editor_zoom_gestures_1.EditorZoomGesturesContext);
35
35
  const keybindings = (0, use_keybinding_1.useKeybinding)();
36
- const size = player_1.PlayerInternals.useElementSize(ref, {
36
+ const size = player_1.PlayerInternals.useElementSize(canvas_ref_1.canvasRef, {
37
37
  triggerOnWindowResize: false,
38
38
  shouldApplyCssTransforms: true,
39
39
  });
@@ -120,7 +120,7 @@ const Canvas = () => {
120
120
  });
121
121
  }, [editorZoomGestures, dimensions, isFit, setSize, size]);
122
122
  (0, react_1.useEffect)(() => {
123
- const { current } = ref;
123
+ const { current } = canvas_ref_1.canvasRef;
124
124
  if (!current) {
125
125
  return;
126
126
  }
@@ -219,6 +219,6 @@ const Canvas = () => {
219
219
  zoomOut.unregister();
220
220
  };
221
221
  }, [keybindings, onReset, onZoomIn, onZoomOut]);
222
- return ((0, jsx_runtime_1.jsxs)("div", { ref: ref, style: container, children: [size ? (0, jsx_runtime_1.jsx)(Preview_1.VideoPreview, { canvasSize: size }) : null, isFit ? null : ((0, jsx_runtime_1.jsx)("div", { style: resetZoom, className: "css-reset", children: (0, jsx_runtime_1.jsx)(ResetZoomButton_1.ResetZoomButton, { onClick: onReset }) }))] }));
222
+ return ((0, jsx_runtime_1.jsxs)("div", { ref: canvas_ref_1.canvasRef, style: container, children: [size ? (0, jsx_runtime_1.jsx)(Preview_1.VideoPreview, { canvasSize: size }) : null, isFit ? null : ((0, jsx_runtime_1.jsx)("div", { style: resetZoom, className: "css-reset", children: (0, jsx_runtime_1.jsx)(ResetZoomButton_1.ResetZoomButton, { onClick: onReset }) }))] }));
223
223
  };
224
224
  exports.Canvas = Canvas;
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export declare const FullScreenToggle: React.FC<{}>;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FullScreenToggle = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const canvas_ref_1 = require("../state/canvas-ref");
7
+ const preview_size_1 = require("../state/preview-size");
8
+ const ControlButton_1 = require("./ControlButton");
9
+ const FullScreenToggle = () => {
10
+ const { setSize } = (0, react_1.useContext)(preview_size_1.PreviewSizeContext);
11
+ const onClick = (0, react_1.useCallback)(() => {
12
+ var _a;
13
+ (_a = canvas_ref_1.canvasRef.current) === null || _a === void 0 ? void 0 : _a.requestFullscreen();
14
+ if (document.fullscreenElement)
15
+ setSize(() => ({
16
+ size: 'auto',
17
+ translation: {
18
+ x: 0,
19
+ y: 0,
20
+ },
21
+ }));
22
+ }, [setSize]);
23
+ return ((0, jsx_runtime_1.jsx)(ControlButton_1.ControlButton, { title: "Enter fullscreen preview", "aria-label": "Enter fullscreen preview", onClick: onClick, children: (0, jsx_runtime_1.jsx)("svg", { style: { width: 18, height: 18 }, viewBox: "0 0 448 512", fill: "#fff", children: (0, jsx_runtime_1.jsx)("path", { d: "M0 180V56c0-13.3 10.7-24 24-24h124c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H64v84c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12zM288 44v40c0 6.6 5.4 12 12 12h84v84c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12V56c0-13.3-10.7-24-24-24H300c-6.6 0-12 5.4-12 12zm148 276h-40c-6.6 0-12 5.4-12 12v84h-84c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h124c13.3 0 24-10.7 24-24V332c0-6.6-5.4-12-12-12zM160 468v-40c0-6.6-5.4-12-12-12H64v-84c0-6.6-5.4-12-12-12H12c-6.6 0-12 5.4-12 12v124c0 13.3 10.7 24 24 24h124c6.6 0 12-5.4 12-12z" }) }) }));
24
+ };
25
+ exports.FullScreenToggle = FullScreenToggle;
@@ -52,6 +52,6 @@ const li = {
52
52
  fontSize: 14,
53
53
  };
54
54
  const KeyboardShortcutsExplainer = () => {
55
- return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, use_keybinding_1.areKeyboardShortcutsDisabled)() ? ((0, jsx_runtime_1.jsxs)("div", { style: keyboardShortcutsDisabled, children: ["Keyboard shortcuts disabled either due to:", (0, jsx_runtime_1.jsxs)("ul", { style: ul, children: [(0, jsx_runtime_1.jsx)("li", { style: li, children: "a) --disable-keyboard-shortcuts being passed" }), (0, jsx_runtime_1.jsx)("li", { style: li, children: "b) Config.setKeyboardShortcutsEnabled(false) being set or" }), (0, jsx_runtime_1.jsx)("li", { style: li, children: " c) a Remotion version mismatch." })] })] })) : null, (0, jsx_runtime_1.jsxs)(layout_1.Row, { style: container, children: [(0, jsx_runtime_1.jsxs)(layout_1.Column, { children: [(0, jsx_runtime_1.jsx)("div", { style: title, children: "Playback" }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsxs)("div", { style: left, children: [(0, jsx_runtime_1.jsx)("kbd", { style: key, children: (0, jsx_runtime_1.jsx)(keys_1.ShiftIcon, {}) }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.3 }), (0, jsx_runtime_1.jsx)("kbd", { style: key, children: (0, jsx_runtime_1.jsx)(keys_1.ArrowLeft, {}) })] }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "1 second back" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: (0, jsx_runtime_1.jsx)(keys_1.ArrowLeft, {}) }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Previous frame" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "Space" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Play / Pause" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: (0, jsx_runtime_1.jsx)(keys_1.ArrowRight, {}) }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Next frame" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsxs)("div", { style: left, children: [(0, jsx_runtime_1.jsx)("kbd", { style: key, children: (0, jsx_runtime_1.jsx)(keys_1.ShiftIcon, {}) }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.3 }), (0, jsx_runtime_1.jsx)("kbd", { style: key, children: (0, jsx_runtime_1.jsx)(keys_1.ArrowRight, {}) })] }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "1 second forward" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "A" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Jump to beginning" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "E" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Jump to end" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "J" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Reverse playback" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "K" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Pause" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "L" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Play / Speed up" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "Enter" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Pause & return to playback start" })] }), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)("div", { style: title, children: "Sidebar" }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsxs)("div", { style: left, children: [(0, jsx_runtime_1.jsx)("kbd", { style: key, children: ShortcutHint_1.cmdOrCtrlCharacter }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.3 }), (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "B" })] }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Toggle left sidebar" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsxs)("div", { style: left, children: [(0, jsx_runtime_1.jsx)("kbd", { style: key, children: ShortcutHint_1.cmdOrCtrlCharacter }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.3 }), (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "J" })] }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Toggle right sidebar" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsxs)("div", { style: left, children: [(0, jsx_runtime_1.jsx)("kbd", { style: key, children: ShortcutHint_1.cmdOrCtrlCharacter }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.3 }), (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "G" })] }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Toggle both sidebars" })] }), (0, jsx_runtime_1.jsx)("br", {})] }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 8 }), (0, jsx_runtime_1.jsxs)(layout_1.Column, { children: [(0, jsx_runtime_1.jsx)("div", { style: title, children: "Navigation" }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "N" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "New composition" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "R" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Render composition" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "T" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Toggle checkerboard transparency" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "?" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Show keyboard shortcuts" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsxs)("div", { style: left, children: [(0, jsx_runtime_1.jsx)("kbd", { style: key, children: ShortcutHint_1.cmdOrCtrlCharacter }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.3 }), (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "K" })] }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Quick Switcher" })] }), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)("div", { style: title, children: "Playback range" }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "I" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Set In Point" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "O" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Set Out Point" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "X" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Clear In/Out Points" })] }), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)("div", { style: title, children: "Zoom" }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "+" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Zoom in" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "-" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Zoom out" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "0" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Reset zoom" })] })] })] })] }));
55
+ return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, use_keybinding_1.areKeyboardShortcutsDisabled)() ? ((0, jsx_runtime_1.jsxs)("div", { style: keyboardShortcutsDisabled, children: ["Keyboard shortcuts disabled either due to:", (0, jsx_runtime_1.jsxs)("ul", { style: ul, children: [(0, jsx_runtime_1.jsx)("li", { style: li, children: "a) --disable-keyboard-shortcuts being passed" }), (0, jsx_runtime_1.jsx)("li", { style: li, children: "b) Config.setKeyboardShortcutsEnabled(false) being set or" }), (0, jsx_runtime_1.jsx)("li", { style: li, children: " c) a Remotion version mismatch." })] })] })) : null, (0, jsx_runtime_1.jsxs)(layout_1.Row, { style: container, children: [(0, jsx_runtime_1.jsxs)(layout_1.Column, { children: [(0, jsx_runtime_1.jsx)("div", { style: title, children: "Playback" }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsxs)("div", { style: left, children: [(0, jsx_runtime_1.jsx)("kbd", { style: key, children: (0, jsx_runtime_1.jsx)(keys_1.ShiftIcon, {}) }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.3 }), (0, jsx_runtime_1.jsx)("kbd", { style: key, children: (0, jsx_runtime_1.jsx)(keys_1.ArrowLeft, {}) })] }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "1 second back" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: (0, jsx_runtime_1.jsx)(keys_1.ArrowLeft, {}) }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Previous frame" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "Space" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Play / Pause" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: (0, jsx_runtime_1.jsx)(keys_1.ArrowRight, {}) }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Next frame" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsxs)("div", { style: left, children: [(0, jsx_runtime_1.jsx)("kbd", { style: key, children: (0, jsx_runtime_1.jsx)(keys_1.ShiftIcon, {}) }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.3 }), (0, jsx_runtime_1.jsx)("kbd", { style: key, children: (0, jsx_runtime_1.jsx)(keys_1.ArrowRight, {}) })] }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "1 second forward" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "A" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Jump to beginning" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "E" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Jump to end" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "J" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Reverse playback" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "K" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Pause" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "L" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Play / Speed up" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "Enter" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Pause & return to playback start" })] }), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)("div", { style: title, children: "Sidebar" }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsxs)("div", { style: left, children: [(0, jsx_runtime_1.jsx)("kbd", { style: key, children: ShortcutHint_1.cmdOrCtrlCharacter }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.3 }), (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "B" })] }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Toggle left sidebar" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsxs)("div", { style: left, children: [(0, jsx_runtime_1.jsx)("kbd", { style: key, children: ShortcutHint_1.cmdOrCtrlCharacter }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.3 }), (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "J" })] }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Toggle right sidebar" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsxs)("div", { style: left, children: [(0, jsx_runtime_1.jsx)("kbd", { style: key, children: ShortcutHint_1.cmdOrCtrlCharacter }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.3 }), (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "G" })] }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Toggle both sidebars" })] }), (0, jsx_runtime_1.jsx)("br", {})] }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 8 }), (0, jsx_runtime_1.jsxs)(layout_1.Column, { children: [(0, jsx_runtime_1.jsx)("div", { style: title, children: "Navigation" }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "N" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "New composition" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "R" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Render composition" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "T" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Toggle checkerboard transparency" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "?" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Show keyboard shortcuts" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsxs)("div", { style: left, children: [(0, jsx_runtime_1.jsx)("kbd", { style: key, children: ShortcutHint_1.cmdOrCtrlCharacter }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.3 }), (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "K" })] }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Quick Switcher" })] }), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)("div", { style: title, children: "Playback range" }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "I" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Set In Point" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "O" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Set Out Point" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "X" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Clear In/Out Points" })] }), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)("div", { style: title, children: "Zoom" }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "+" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Zoom in" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "-" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Zoom out" })] }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)("div", { style: left, children: (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "0" }) }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Reset zoom" })] }), ' ', (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)("div", { style: title, children: "Props Editor" }), (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsxs)("div", { style: left, children: [(0, jsx_runtime_1.jsx)("kbd", { style: key, children: ShortcutHint_1.cmdOrCtrlCharacter }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.3 }), (0, jsx_runtime_1.jsx)("kbd", { style: key, children: "S" })] }), (0, jsx_runtime_1.jsx)("div", { style: right, children: "Save" })] })] })] })] }));
56
56
  };
57
57
  exports.KeyboardShortcutsExplainer = KeyboardShortcutsExplainer;
@@ -9,6 +9,7 @@ const timeline_layout_1 = require("../helpers/timeline-layout");
9
9
  const loop_1 = require("../state/loop");
10
10
  const CheckboardToggle_1 = require("./CheckboardToggle");
11
11
  const FpsCounter_1 = require("./FpsCounter");
12
+ const FullscreenToggle_1 = require("./FullscreenToggle");
12
13
  const layout_1 = require("./layout");
13
14
  const LoopToggle_1 = require("./LoopToggle");
14
15
  const MuteToggle_1 = require("./MuteToggle");
@@ -45,6 +46,7 @@ const PreviewToolbar = () => {
45
46
  const { mediaMuted } = (0, react_1.useContext)(remotion_1.Internals.MediaVolumeContext);
46
47
  const { setMediaMuted } = (0, react_1.useContext)(remotion_1.Internals.SetMediaVolumeContext);
47
48
  const [loop, setLoop] = (0, react_1.useState)((0, loop_1.loadLoopOption)());
48
- return ((0, jsx_runtime_1.jsxs)("div", { style: container, className: "css-reset", children: [(0, jsx_runtime_1.jsxs)("div", { style: sideContainer, children: [(0, jsx_runtime_1.jsx)("div", { style: padding }), (0, jsx_runtime_1.jsx)(TimelineZoomControls_1.TimelineZoomControls, {})] }), (0, jsx_runtime_1.jsx)(layout_1.Flex, {}), (0, jsx_runtime_1.jsx)(SizeSelector_1.SizeSelector, {}), (0, jsx_runtime_1.jsx)(PlaybackRateSelector_1.PlaybackRateSelector, { setPlaybackRate: setPlaybackRate, playbackRate: playbackRate }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 2 }), (0, jsx_runtime_1.jsx)(PlayPause_1.PlayPause, { loop: loop, playbackRate: playbackRate }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 2 }), (0, jsx_runtime_1.jsx)(LoopToggle_1.LoopToggle, { loop: loop, setLoop: setLoop }), (0, jsx_runtime_1.jsx)(CheckboardToggle_1.CheckboardToggle, {}), (0, jsx_runtime_1.jsx)(TimelineInOutToggle_1.TimelineInOutPointToggle, {}), (0, jsx_runtime_1.jsx)(MuteToggle_1.MuteToggle, { muted: mediaMuted, setMuted: setMediaMuted }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 2 }), (0, jsx_runtime_1.jsx)(layout_1.Flex, {}), (0, jsx_runtime_1.jsxs)("div", { style: sideContainer, children: [(0, jsx_runtime_1.jsx)(layout_1.Flex, {}), (0, jsx_runtime_1.jsx)(FpsCounter_1.FpsCounter, { playbackSpeed: playbackRate }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 2 }), (0, jsx_runtime_1.jsx)(RenderButton_1.RenderButton, {}), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1.5 })] }), (0, jsx_runtime_1.jsx)(PlaybackKeyboardShortcutsManager_1.PlaybackKeyboardShortcutsManager, { setPlaybackRate: setPlaybackRate }), (0, jsx_runtime_1.jsx)(PlaybackRatePersistor_1.PlaybackRatePersistor, {})] }));
49
+ const isFullscreenSupported = document.fullscreenEnabled || document.webkitFullscreenEnabled;
50
+ return ((0, jsx_runtime_1.jsxs)("div", { style: container, className: "css-reset", children: [(0, jsx_runtime_1.jsxs)("div", { style: sideContainer, children: [(0, jsx_runtime_1.jsx)("div", { style: padding }), (0, jsx_runtime_1.jsx)(TimelineZoomControls_1.TimelineZoomControls, {})] }), (0, jsx_runtime_1.jsx)(layout_1.Flex, {}), (0, jsx_runtime_1.jsx)(SizeSelector_1.SizeSelector, {}), (0, jsx_runtime_1.jsx)(PlaybackRateSelector_1.PlaybackRateSelector, { setPlaybackRate: setPlaybackRate, playbackRate: playbackRate }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 2 }), (0, jsx_runtime_1.jsx)(PlayPause_1.PlayPause, { loop: loop, playbackRate: playbackRate }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 2 }), (0, jsx_runtime_1.jsx)(LoopToggle_1.LoopToggle, { loop: loop, setLoop: setLoop }), (0, jsx_runtime_1.jsx)(CheckboardToggle_1.CheckboardToggle, {}), (0, jsx_runtime_1.jsx)(TimelineInOutToggle_1.TimelineInOutPointToggle, {}), (0, jsx_runtime_1.jsx)(MuteToggle_1.MuteToggle, { muted: mediaMuted, setMuted: setMediaMuted }), isFullscreenSupported && (0, jsx_runtime_1.jsx)(FullscreenToggle_1.FullScreenToggle, {}), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 2 }), (0, jsx_runtime_1.jsx)(layout_1.Flex, {}), (0, jsx_runtime_1.jsxs)("div", { style: sideContainer, children: [(0, jsx_runtime_1.jsx)(layout_1.Flex, {}), (0, jsx_runtime_1.jsx)(FpsCounter_1.FpsCounter, { playbackSpeed: playbackRate }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 2 }), (0, jsx_runtime_1.jsx)(RenderButton_1.RenderButton, {}), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1.5 })] }), (0, jsx_runtime_1.jsx)(PlaybackKeyboardShortcutsManager_1.PlaybackKeyboardShortcutsManager, { setPlaybackRate: setPlaybackRate }), (0, jsx_runtime_1.jsx)(PlaybackRatePersistor_1.PlaybackRatePersistor, {})] }));
49
51
  };
50
52
  exports.PreviewToolbar = PreviewToolbar;
@@ -17,4 +17,6 @@ export declare const DataEditor: React.FC<{
17
17
  setInputProps: React.Dispatch<React.SetStateAction<Record<string, unknown>>>;
18
18
  mayShowSaveButton: boolean;
19
19
  propsEditType: PropsEditType;
20
+ saving: boolean;
21
+ setSaving: React.Dispatch<React.SetStateAction<boolean>>;
20
22
  }>;
@@ -87,9 +87,8 @@ const getPersistedShowWarningState = () => {
87
87
  const setPersistedShowWarningState = (val) => {
88
88
  localStorage.setItem(persistanceKey, String(Boolean(val)));
89
89
  };
90
- const DataEditor = ({ unresolvedComposition, inputProps, setInputProps, mayShowSaveButton, propsEditType, }) => {
90
+ const DataEditor = ({ unresolvedComposition, inputProps, setInputProps, mayShowSaveButton, propsEditType, saving, setSaving, }) => {
91
91
  const [mode, setMode] = (0, react_1.useState)('schema');
92
- const [saving, setSaving] = (0, react_1.useState)(false);
93
92
  const [showWarning, setShowWarningWithoutPersistance] = (0, react_1.useState)(() => getPersistedShowWarningState());
94
93
  const inJSONEditor = mode === 'json';
95
94
  const serializedJSON = (0, react_1.useMemo)(() => {
@@ -221,7 +220,7 @@ const DataEditor = ({ unresolvedComposition, inputProps, setInputProps, mayShowS
221
220
  }, [unresolvedComposition.id, inputProps, schema, z]);
222
221
  (0, react_1.useEffect)(() => {
223
222
  setSaving(false);
224
- }, [fastRefreshes]);
223
+ }, [fastRefreshes, setSaving]);
225
224
  const onSave = (0, react_1.useCallback)((updater) => {
226
225
  var _a;
227
226
  if (schema === 'no-zod' || schema === 'no-schema' || z === null) {
@@ -240,7 +239,13 @@ const DataEditor = ({ unresolvedComposition, inputProps, setInputProps, mayShowS
240
239
  (0, NotificationCenter_1.sendErrorNotification)(`Cannot update default props: ${err.message}`);
241
240
  setSaving(false);
242
241
  });
243
- }, [unresolvedComposition.defaultProps, unresolvedComposition.id, schema, z]);
242
+ }, [
243
+ schema,
244
+ z,
245
+ setSaving,
246
+ unresolvedComposition.id,
247
+ unresolvedComposition.defaultProps,
248
+ ]);
244
249
  const connectionStatus = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx).type;
245
250
  const warnings = (0, react_1.useMemo)(() => {
246
251
  return (0, get_render_modal_warnings_1.getRenderModalWarnings)({
@@ -3,13 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FrameRangeSetting = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
- const InputDragger_1 = require("../NewComposition/InputDragger");
7
- const RemInput_1 = require("../NewComposition/RemInput");
8
6
  const layout_1 = require("./layout");
7
+ const MultiRangeSlider_1 = require("./MultiRangeSlider");
8
+ const numberWrapper = {
9
+ minWidth: '39px',
10
+ display: 'flex',
11
+ justifyContent: 'flex-end',
12
+ alignItems: 'center',
13
+ fontSize: '14px',
14
+ };
9
15
  const FrameRangeSetting = ({ startFrame, endFrame, setEndFrame, durationInFrames, setStartFrame }) => {
10
- const maxStartFrame = endFrame - 1;
11
16
  const minStartFrame = 0;
12
- const minEndFrame = startFrame + 1;
13
17
  const maxEndFrame = durationInFrames - 1;
14
18
  const onStartFrameChangedDirectly = (0, react_1.useCallback)((newStartFrame) => {
15
19
  setStartFrame(newStartFrame);
@@ -17,26 +21,6 @@ const FrameRangeSetting = ({ startFrame, endFrame, setEndFrame, durationInFrames
17
21
  const onEndFrameChangedDirectly = (0, react_1.useCallback)((newEndFrame) => {
18
22
  setEndFrame(newEndFrame);
19
23
  }, [setEndFrame]);
20
- const onStartFrameChanged = (0, react_1.useCallback)((e) => {
21
- setStartFrame((q) => {
22
- const newStartFrame = parseInt(e, 10);
23
- if (Number.isNaN(newStartFrame)) {
24
- return q;
25
- }
26
- const newStartFrameClamped = Math.min(maxStartFrame, Math.max(newStartFrame, minStartFrame));
27
- return newStartFrameClamped;
28
- });
29
- }, [maxStartFrame, setStartFrame]);
30
- const onEndFrameChanged = (0, react_1.useCallback)((e) => {
31
- setEndFrame((q) => {
32
- const newEndFrame = parseInt(e, 10);
33
- if (Number.isNaN(newEndFrame)) {
34
- return q;
35
- }
36
- const newEndFrameClamped = Math.min(maxEndFrame, Math.max(newEndFrame, minEndFrame));
37
- return newEndFrameClamped;
38
- });
39
- }, [maxEndFrame, minEndFrame, setEndFrame]);
40
- return ((0, jsx_runtime_1.jsxs)("div", { style: layout_1.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_1.label, children: "Frame range" }), (0, jsx_runtime_1.jsxs)("div", { style: layout_1.rightRow, children: [(0, jsx_runtime_1.jsx)(RemInput_1.RightAlignInput, { children: (0, jsx_runtime_1.jsx)(InputDragger_1.InputDragger, { value: startFrame, onTextChange: onStartFrameChanged, placeholder: `${minStartFrame}-${maxStartFrame}`, onValueChange: onStartFrameChangedDirectly, name: "startFrame", step: 1, min: minStartFrame, max: maxStartFrame, status: "ok", rightAlign: true }) }), (0, jsx_runtime_1.jsx)(RemInput_1.RightAlignInput, { children: (0, jsx_runtime_1.jsx)(InputDragger_1.InputDragger, { value: endFrame, onTextChange: onEndFrameChanged, placeholder: `${minEndFrame}-${maxEndFrame}`, onValueChange: onEndFrameChangedDirectly, name: "endFrame", step: 1, min: minEndFrame, max: maxEndFrame, status: "ok", rightAlign: true }) })] })] }));
24
+ return ((0, jsx_runtime_1.jsxs)("div", { style: layout_1.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_1.label, children: "Frame range" }), (0, jsx_runtime_1.jsxs)("div", { style: layout_1.rightRow, children: [(0, jsx_runtime_1.jsx)("div", { style: numberWrapper, children: startFrame }), (0, jsx_runtime_1.jsx)(MultiRangeSlider_1.MultiRangeSlider, { min: minStartFrame, max: maxEndFrame, start: startFrame, end: endFrame, step: 1, onLeftThumbDrag: onStartFrameChangedDirectly, onRightThumbDrag: onEndFrameChangedDirectly }), (0, jsx_runtime_1.jsx)("div", { style: numberWrapper, children: endFrame })] })] }));
41
25
  };
42
26
  exports.FrameRangeSetting = FrameRangeSetting;
@@ -0,0 +1,12 @@
1
+ import type { FC } from 'react';
2
+ interface MultiRangeSliderProps {
3
+ min: number;
4
+ max: number;
5
+ start: number;
6
+ end: number;
7
+ step: number;
8
+ onLeftThumbDrag: (newVal: number) => void;
9
+ onRightThumbDrag: (newVal: number) => void;
10
+ }
11
+ export declare const MultiRangeSlider: FC<MultiRangeSliderProps>;
12
+ export {};
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MultiRangeSlider = 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 container = {
8
+ borderColor: 'black',
9
+ borderStyle: 'solid',
10
+ height: 39,
11
+ width: 220,
12
+ position: 'relative',
13
+ backgroundColor: colors_1.INPUT_BACKGROUND,
14
+ marginLeft: 8,
15
+ marginRight: 8,
16
+ borderRadius: 2,
17
+ };
18
+ const slider = {
19
+ position: 'relative',
20
+ height: 38,
21
+ width: 220,
22
+ };
23
+ const sliderRange = {
24
+ position: 'absolute',
25
+ top: 0,
26
+ backgroundColor: colors_1.BLUE,
27
+ height: 39,
28
+ };
29
+ const MultiRangeSlider = ({ min, max, start, end, step, onLeftThumbDrag, onRightThumbDrag, }) => {
30
+ const getPercent = (0, react_1.useCallback)((value) => Math.round(((value - min) / (max - min)) * 100), [min, max]);
31
+ const rangeStyle = (0, react_1.useMemo)(() => {
32
+ const minPercent = getPercent(start);
33
+ const maxPercent = getPercent(end);
34
+ return {
35
+ ...sliderRange,
36
+ left: `${minPercent}%`,
37
+ width: `${maxPercent - minPercent}%`,
38
+ };
39
+ }, [end, getPercent, start]);
40
+ const onChangeLeft = (0, react_1.useCallback)((event) => {
41
+ const value = Math.min(Number(event.target.value), end - 1);
42
+ onLeftThumbDrag(value);
43
+ }, [end, onLeftThumbDrag]);
44
+ const onChangeRight = (0, react_1.useCallback)((event) => {
45
+ const value = Math.max(Number(event.target.value), start + 1);
46
+ onRightThumbDrag(value);
47
+ }, [onRightThumbDrag, start]);
48
+ return ((0, jsx_runtime_1.jsx)("div", { style: container, children: (0, jsx_runtime_1.jsxs)("div", { style: slider, children: [(0, jsx_runtime_1.jsx)("input", { type: "range", min: min, max: max, value: start, step: step, onChange: onChangeLeft, className: "__remotion_thumb" }), (0, jsx_runtime_1.jsx)("input", { type: "range", min: min, max: max, value: end, step: step, onChange: onChangeRight, className: "__remotion_thumb" }), (0, jsx_runtime_1.jsx)("div", { style: rangeStyle })] }) }));
49
+ };
50
+ exports.MultiRangeSlider = MultiRangeSlider;
@@ -118,6 +118,7 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
118
118
  const isMounted = (0, react_1.useRef)(true);
119
119
  const [state, dispatch] = (0, react_1.useReducer)(reducer, initialState);
120
120
  const [unclampedFrame, setFrame] = (0, react_1.useState)(() => initialFrame);
121
+ const [saving, setSaving] = (0, react_1.useState)(false);
121
122
  const [stillImageFormat, setStillImageFormat] = (0, react_1.useState)(() => initialStillImageFormat);
122
123
  const [videoImageFormat, setVideoImageFormat] = (0, react_1.useState)(() => initialVideoImageFormat);
123
124
  const [concurrency, setConcurrency] = (0, react_1.useState)(() => initialConcurrency);
@@ -584,7 +585,7 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
584
585
  return ((0, jsx_runtime_1.jsxs)("div", { style: outer, children: [(0, jsx_runtime_1.jsx)(ModalHeader_1.NewCompHeader, { title: `Render ${resolvedComposition.id}` }), (0, jsx_runtime_1.jsxs)("div", { style: container, children: [(0, jsx_runtime_1.jsx)(SegmentedControl_1.SegmentedControl, { items: renderTabOptions, needsWrapping: false }), (0, jsx_runtime_1.jsx)("div", { style: flexer }), (0, jsx_runtime_1.jsxs)(Button_1.Button, { autoFocus: true, onClick: trigger, disabled: renderDisabled, style: {
585
586
  ...buttonStyle,
586
587
  backgroundColor: outnameValidation.valid ? colors_1.BLUE : colors_1.BLUE_DISABLED,
587
- }, children: [state.type === 'idle' ? `Render ${renderMode}` : 'Rendering...', (0, jsx_runtime_1.jsx)(ShortcutHint_1.ShortcutHint, { keyToPress: "\u21B5", cmdOrCtrl: true })] })] }), (0, jsx_runtime_1.jsxs)("div", { style: horizontalLayout, children: [(0, jsx_runtime_1.jsxs)("div", { style: leftSidebar, children: [shownTabs.includes('general') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'general', onClick: () => setTab('general'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(file_1.FileIcon, { style: icon }) }), "General"] })) : null, shownTabs.includes('data') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'data', onClick: () => setTab('data'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(data_1.DataIcon, { style: icon }) }), "Input Props"] })) : null, shownTabs.includes('picture') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'picture', onClick: () => setTab('picture'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(frame_1.PicIcon, { style: icon }) }), "Picture"] })) : null, shownTabs.includes('audio') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'audio', onClick: () => setTab('audio'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(audio_1.AudioIcon, { style: icon }) }), "Audio"] })) : null, shownTabs.includes('gif') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'gif', onClick: () => setTab('gif'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(gif_1.GifIcon, { style: icon }) }), "GIF"] })) : null, shownTabs.includes('advanced') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'advanced', onClick: () => setTab('advanced'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(gear_1.GearIcon, { style: icon }) }), "Other"] })) : null] }), (0, jsx_runtime_1.jsx)("div", { style: rightPanel, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: tab === 'general' ? ((0, jsx_runtime_1.jsx)(RenderModalBasic_1.RenderModalBasic, { codec: codec, resolvedComposition: resolvedComposition, frame: frame, imageFormatOptions: imageFormatOptions, outName: outName, proResProfile: proResProfile, renderMode: renderMode, setVideoCodec: setCodec, setFrame: setFrame, setOutName: setOutName, setProResProfile: setProResProfile, endFrame: endFrame, setEndFrame: setEndFrame, setStartFrame: setStartFrame, startFrame: startFrame, validationMessage: outnameValidation.valid ? null : outnameValidation.error.message })) : tab === 'picture' ? ((0, jsx_runtime_1.jsx)(RenderModalPicture_1.RenderModalPicture, { renderMode: renderMode, scale: scale, setScale: setScale, pixelFormat: pixelFormat, setPixelFormat: setPixelFormat, imageFormatOptions: imageFormatOptions, crf: crf, setCrf: setCrf, customTargetVideoBitrate: customTargetVideoBitrate, maxCrf: maxCrf, minCrf: minCrf, jpegQuality: jpegQuality, qualityControlType: qualityControlType, setJpegQuality: setJpegQuality, setCustomTargetVideoBitrateValue: setCustomTargetVideoBitrateValue, setQualityControl: setQualityControl, videoImageFormat: videoImageFormat, stillImageFormat: stillImageFormat, shouldDisplayQualityControlPicker: supportsBothQualityControls })) : tab === 'audio' ? ((0, jsx_runtime_1.jsx)(RenderModalAudio_1.RenderModalAudio, { muted: muted, renderMode: renderMode, setMuted: setMuted, codec: codec, audioCodec: audioCodec, setAudioCodec: setAudioCodec, enforceAudioTrack: enforceAudioTrack, setEnforceAudioTrackState: setEnforceAudioTrackState, customTargetAudioBitrate: customTargetAudioBitrate, setCustomTargetAudioBitrateValue: setCustomTargetAudioBitrateValue, setShouldHaveCustomTargetAudioBitrate: setShouldHaveCustomTargetAudioBitrate, shouldHaveCustomTargetAudioBitrate: shouldHaveCustomTargetAudioBitrate })) : tab === 'gif' ? ((0, jsx_runtime_1.jsx)(RenderModalGif_1.RenderModalGif, { everyNthFrame: everyNthFrame, limitNumberOfGifLoops: limitNumberOfGifLoops, numberOfGifLoopsSetting: numberOfGifLoopsSetting, setEveryNthFrameSetting: setEveryNthFrameSetting, setLimitNumberOfGifLoops: setLimitNumberOfGifLoops, setNumberOfGifLoopsSetting: setNumberOfGifLoopsSetting })) : tab === 'data' ? ((0, jsx_runtime_1.jsx)(DataEditor_1.DataEditor, { inputProps: inputProps, setInputProps: setInputProps, unresolvedComposition: unresolvedComposition, mayShowSaveButton: false, propsEditType: "input-props" })) : ((0, jsx_runtime_1.jsx)(RenderModalAdvanced_1.RenderModalAdvanced, { concurrency: concurrency, maxConcurrency: maxConcurrency, minConcurrency: minConcurrency, renderMode: renderMode, setConcurrency: setConcurrency, setVerboseLogging: setVerboseLogging, verbose: verbose, delayRenderTimeout: delayRenderTimeout, setDelayRenderTimeout: setDelayRenderTimeout, disallowParallelEncoding: disallowParallelEncoding, setDisallowParallelEncoding: setDisallowParallelEncoding, setDisableWebSecurity: setDisableWebSecurity, setIgnoreCertificateErrors: setIgnoreCertificateErrors, setHeadless: setHeadless, headless: headless, ignoreCertificateErrors: ignoreCertificateErrors, disableWebSecurity: disableWebSecurity, openGlOption: openGlOption, setOpenGlOption: setOpenGlOption, setEnvVariables: setEnvVariables, envVariables: envVariables })) })] })] }));
588
+ }, children: [state.type === 'idle' ? `Render ${renderMode}` : 'Rendering...', (0, jsx_runtime_1.jsx)(ShortcutHint_1.ShortcutHint, { keyToPress: "\u21B5", cmdOrCtrl: true })] })] }), (0, jsx_runtime_1.jsxs)("div", { style: horizontalLayout, children: [(0, jsx_runtime_1.jsxs)("div", { style: leftSidebar, children: [shownTabs.includes('general') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'general', onClick: () => setTab('general'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(file_1.FileIcon, { style: icon }) }), "General"] })) : null, shownTabs.includes('data') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'data', onClick: () => setTab('data'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(data_1.DataIcon, { style: icon }) }), "Input Props"] })) : null, shownTabs.includes('picture') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'picture', onClick: () => setTab('picture'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(frame_1.PicIcon, { style: icon }) }), "Picture"] })) : null, shownTabs.includes('audio') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'audio', onClick: () => setTab('audio'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(audio_1.AudioIcon, { style: icon }) }), "Audio"] })) : null, shownTabs.includes('gif') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'gif', onClick: () => setTab('gif'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(gif_1.GifIcon, { style: icon }) }), "GIF"] })) : null, shownTabs.includes('advanced') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'advanced', onClick: () => setTab('advanced'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(gear_1.GearIcon, { style: icon }) }), "Other"] })) : null] }), (0, jsx_runtime_1.jsx)("div", { style: rightPanel, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: tab === 'general' ? ((0, jsx_runtime_1.jsx)(RenderModalBasic_1.RenderModalBasic, { codec: codec, resolvedComposition: resolvedComposition, frame: frame, imageFormatOptions: imageFormatOptions, outName: outName, proResProfile: proResProfile, renderMode: renderMode, setVideoCodec: setCodec, setFrame: setFrame, setOutName: setOutName, setProResProfile: setProResProfile, endFrame: endFrame, setEndFrame: setEndFrame, setStartFrame: setStartFrame, startFrame: startFrame, validationMessage: outnameValidation.valid ? null : outnameValidation.error.message })) : tab === 'picture' ? ((0, jsx_runtime_1.jsx)(RenderModalPicture_1.RenderModalPicture, { renderMode: renderMode, scale: scale, setScale: setScale, pixelFormat: pixelFormat, setPixelFormat: setPixelFormat, imageFormatOptions: imageFormatOptions, crf: crf, setCrf: setCrf, customTargetVideoBitrate: customTargetVideoBitrate, maxCrf: maxCrf, minCrf: minCrf, jpegQuality: jpegQuality, qualityControlType: qualityControlType, setJpegQuality: setJpegQuality, setCustomTargetVideoBitrateValue: setCustomTargetVideoBitrateValue, setQualityControl: setQualityControl, videoImageFormat: videoImageFormat, stillImageFormat: stillImageFormat, shouldDisplayQualityControlPicker: supportsBothQualityControls })) : tab === 'audio' ? ((0, jsx_runtime_1.jsx)(RenderModalAudio_1.RenderModalAudio, { muted: muted, renderMode: renderMode, setMuted: setMuted, codec: codec, audioCodec: audioCodec, setAudioCodec: setAudioCodec, enforceAudioTrack: enforceAudioTrack, setEnforceAudioTrackState: setEnforceAudioTrackState, customTargetAudioBitrate: customTargetAudioBitrate, setCustomTargetAudioBitrateValue: setCustomTargetAudioBitrateValue, setShouldHaveCustomTargetAudioBitrate: setShouldHaveCustomTargetAudioBitrate, shouldHaveCustomTargetAudioBitrate: shouldHaveCustomTargetAudioBitrate })) : tab === 'gif' ? ((0, jsx_runtime_1.jsx)(RenderModalGif_1.RenderModalGif, { everyNthFrame: everyNthFrame, limitNumberOfGifLoops: limitNumberOfGifLoops, numberOfGifLoopsSetting: numberOfGifLoopsSetting, setEveryNthFrameSetting: setEveryNthFrameSetting, setLimitNumberOfGifLoops: setLimitNumberOfGifLoops, setNumberOfGifLoopsSetting: setNumberOfGifLoopsSetting })) : tab === 'data' ? ((0, jsx_runtime_1.jsx)(DataEditor_1.DataEditor, { inputProps: inputProps, setInputProps: setInputProps, unresolvedComposition: unresolvedComposition, mayShowSaveButton: false, propsEditType: "input-props", saving: saving, setSaving: setSaving })) : ((0, jsx_runtime_1.jsx)(RenderModalAdvanced_1.RenderModalAdvanced, { concurrency: concurrency, maxConcurrency: maxConcurrency, minConcurrency: minConcurrency, renderMode: renderMode, setConcurrency: setConcurrency, setVerboseLogging: setVerboseLogging, verbose: verbose, delayRenderTimeout: delayRenderTimeout, setDelayRenderTimeout: setDelayRenderTimeout, disallowParallelEncoding: disallowParallelEncoding, setDisallowParallelEncoding: setDisallowParallelEncoding, setDisableWebSecurity: setDisableWebSecurity, setIgnoreCertificateErrors: setIgnoreCertificateErrors, setHeadless: setHeadless, headless: headless, ignoreCertificateErrors: ignoreCertificateErrors, disableWebSecurity: disableWebSecurity, openGlOption: openGlOption, setOpenGlOption: setOpenGlOption, setEnvVariables: setEnvVariables, envVariables: envVariables })) })] })] }));
588
589
  };
589
590
  const RenderModalWithLoader = (props) => {
590
591
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import type { AnyZodObject, z } from 'zod';
3
3
  export declare const SchemaEditor: React.FC<{
4
4
  schema: AnyZodObject;
5
- value: unknown;
5
+ value: Record<string, unknown>;
6
6
  setValue: React.Dispatch<React.SetStateAction<Record<string, unknown>>>;
7
7
  zodValidationResult: z.SafeParseReturnType<unknown, unknown>;
8
8
  defaultProps: Record<string, unknown>;
@@ -3,8 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SchemaEditor = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
+ const use_keybinding_1 = require("../../../helpers/use-keybinding");
6
7
  const get_zod_if_possible_1 = require("../../get-zod-if-possible");
7
8
  const is_menu_item_1 = require("../../Menu/is-menu-item");
9
+ const deep_equal_1 = require("./deep-equal");
8
10
  const SchemaErrorMessages_1 = require("./SchemaErrorMessages");
9
11
  const ZodObjectEditor_1 = require("./ZodObjectEditor");
10
12
  const scrollable = {
@@ -13,10 +15,34 @@ const scrollable = {
13
15
  overflowY: 'auto',
14
16
  };
15
17
  const SchemaEditor = ({ schema, value, setValue, zodValidationResult, defaultProps, onSave, showSaveButton, saving, saveDisabledByParent, }) => {
18
+ const keybindings = (0, use_keybinding_1.useKeybinding)();
16
19
  const z = (0, get_zod_if_possible_1.useZodIfPossible)();
17
20
  if (!z) {
18
21
  throw new Error('expected zod');
19
22
  }
23
+ const hasChanged = (0, react_1.useMemo)(() => {
24
+ return !(0, deep_equal_1.deepEqual)(defaultProps, value);
25
+ }, [defaultProps, value]);
26
+ const onQuickSave = (0, react_1.useCallback)(() => {
27
+ if (hasChanged && showSaveButton) {
28
+ onSave(() => {
29
+ return value;
30
+ });
31
+ }
32
+ }, [hasChanged, onSave, showSaveButton, value]);
33
+ (0, react_1.useEffect)(() => {
34
+ const save = keybindings.registerKeybinding({
35
+ event: 'keydown',
36
+ key: 's',
37
+ commandCtrlKey: true,
38
+ callback: onQuickSave,
39
+ preventDefault: true,
40
+ triggerIfInputFieldFocused: true,
41
+ });
42
+ return () => {
43
+ save.unregister();
44
+ };
45
+ }, [keybindings, onQuickSave, onSave]);
20
46
  const def = schema._def;
21
47
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
48
  const typeName = def.typeName;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SchemaSaveButton = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
+ const colors_1 = require("../../../helpers/colors");
6
7
  const InlineAction_1 = require("../../InlineAction");
7
8
  const icon = {
8
9
  height: 14,
@@ -10,7 +11,7 @@ const icon = {
10
11
  };
11
12
  const SchemaSaveButton = ({ onClick, disabled }) => {
12
13
  const renderAction = (0, react_1.useCallback)((color) => {
13
- return ((0, jsx_runtime_1.jsx)("svg", { style: icon, viewBox: "0 0 448 512", children: (0, jsx_runtime_1.jsx)("path", { fill: disabled ? 'grey' : color, d: "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V173.3c0-17-6.7-33.3-18.7-45.3L352 50.7C340 38.7 323.7 32 306.7 32H64zm0 96c0-17.7 14.3-32 32-32H288c17.7 0 32 14.3 32 32v64c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V128zM224 288a64 64 0 1 1 0 128 64 64 0 1 1 0-128z" }) }));
14
+ return ((0, jsx_runtime_1.jsx)("svg", { style: icon, viewBox: "0 0 448 512", children: (0, jsx_runtime_1.jsx)("path", { fill: disabled ? colors_1.LIGHT_TEXT : color, d: "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V173.3c0-17-6.7-33.3-18.7-45.3L352 50.7C340 38.7 323.7 32 306.7 32H64zm0 96c0-17.7 14.3-32 32-32H288c17.7 0 32 14.3 32 32v64c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V128zM224 288a64 64 0 1 1 0 128 64 64 0 1 1 0-128z" }) }));
14
15
  }, [disabled]);
15
16
  return ((0, jsx_runtime_1.jsx)(InlineAction_1.InlineAction, { renderAction: renderAction, onClick: onClick, disabled: disabled }));
16
17
  };
@@ -4,8 +4,10 @@ exports.RightPanel = exports.rightSidebarTabs = exports.persistSelectedPanel = v
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
+ const ShortcutHint_1 = require("../../preview-server/error-overlay/remotion-overlay/ShortcutHint");
7
8
  const colors_1 = require("../helpers/colors");
8
9
  const DataEditor_1 = require("./RenderModal/DataEditor");
10
+ const deep_equal_1 = require("./RenderModal/SchemaEditor/deep-equal");
9
11
  const RenderQueue_1 = require("./RenderQueue");
10
12
  const RendersTab_1 = require("./RendersTab");
11
13
  const Tabs_1 = require("./Tabs");
@@ -16,17 +18,10 @@ const container = {
16
18
  display: 'flex',
17
19
  flexDirection: 'column',
18
20
  };
19
- const PropsEditor = ({ composition }) => {
20
- const { props, updateProps } = (0, react_1.useContext)(remotion_1.Internals.EditorPropsContext);
21
- const setInputProps = (0, react_1.useCallback)((newProps) => {
22
- updateProps({
23
- id: composition.id,
24
- defaultProps: composition.defaultProps,
25
- newProps,
26
- });
27
- }, [composition.defaultProps, composition.id, updateProps]);
28
- const actualProps = (0, react_1.useMemo)(() => { var _a, _b; return (_b = (_a = props[composition.id]) !== null && _a !== void 0 ? _a : composition.defaultProps) !== null && _b !== void 0 ? _b : {}; }, [composition.defaultProps, composition.id, props]);
29
- return ((0, jsx_runtime_1.jsx)(DataEditor_1.DataEditor, { unresolvedComposition: composition, inputProps: actualProps, setInputProps: setInputProps, mayShowSaveButton: true, propsEditType: "default-props" }, composition.id));
21
+ const circle = {
22
+ width: 8,
23
+ height: 8,
24
+ borderRadius: 4,
30
25
  };
31
26
  const localStorageKey = 'remotion.sidebarPanel';
32
27
  const getSelectedPanel = () => {
@@ -45,6 +40,8 @@ const persistSelectedPanel = (panel) => {
45
40
  exports.persistSelectedPanel = persistSelectedPanel;
46
41
  exports.rightSidebarTabs = (0, react_1.createRef)();
47
42
  const RightPanel = () => {
43
+ const { props, updateProps } = (0, react_1.useContext)(remotion_1.Internals.EditorPropsContext);
44
+ const [saving, setSaving] = (0, react_1.useState)(false);
48
45
  const [panel, setPanel] = (0, react_1.useState)(() => getSelectedPanel());
49
46
  const onCompositionsSelected = (0, react_1.useCallback)(() => {
50
47
  setPanel('input-props');
@@ -63,6 +60,14 @@ const RightPanel = () => {
63
60
  };
64
61
  }, []);
65
62
  const { compositions, currentComposition } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
63
+ const circleStyle = (0, react_1.useMemo)(() => {
64
+ const onTabColor = saving ? colors_1.LIGHT_TEXT : 'white';
65
+ return {
66
+ ...circle,
67
+ backgroundColor: panel === 'input-props' ? onTabColor : colors_1.LIGHT_TEXT,
68
+ cursor: 'help',
69
+ };
70
+ }, [panel, saving]);
66
71
  const composition = (0, react_1.useMemo)(() => {
67
72
  for (const comp of compositions) {
68
73
  if (comp.id === currentComposition) {
@@ -71,9 +76,37 @@ const RightPanel = () => {
71
76
  }
72
77
  return null;
73
78
  }, [compositions, currentComposition]);
79
+ const saveToolTip = (0, react_1.useMemo)(() => {
80
+ return process.env.KEYBOARD_SHORTCUTS_ENABLED
81
+ ? `Save using ${ShortcutHint_1.cmdOrCtrlCharacter}+S`
82
+ : 'There are unsaved changes';
83
+ }, []);
84
+ const setInputProps = (0, react_1.useCallback)((newProps) => {
85
+ if (composition === null) {
86
+ return;
87
+ }
88
+ updateProps({
89
+ id: composition.id,
90
+ defaultProps: composition.defaultProps,
91
+ newProps,
92
+ });
93
+ }, [composition, updateProps]);
94
+ const actualProps = (0, react_1.useMemo)(() => {
95
+ var _a, _b;
96
+ if (composition === null) {
97
+ return {};
98
+ }
99
+ return (_b = (_a = props[composition.id]) !== null && _a !== void 0 ? _a : composition.defaultProps) !== null && _b !== void 0 ? _b : {};
100
+ }, [composition, props]);
101
+ const unsavedChangesExist = (0, react_1.useMemo)(() => {
102
+ if (composition === null || composition.defaultProps === undefined) {
103
+ return false;
104
+ }
105
+ return !(0, deep_equal_1.deepEqual)(composition.defaultProps, actualProps);
106
+ }, [actualProps, composition]);
74
107
  if (composition === null) {
75
108
  return null;
76
109
  }
77
- return ((0, jsx_runtime_1.jsxs)("div", { style: container, className: "css-reset", children: [(0, jsx_runtime_1.jsx)("div", { style: tabsContainer, children: (0, jsx_runtime_1.jsxs)(Tabs_1.Tabs, { children: [(0, jsx_runtime_1.jsx)(Tabs_1.Tab, { selected: panel === 'input-props', onClick: onCompositionsSelected, children: "Props" }), (0, jsx_runtime_1.jsx)(RendersTab_1.RendersTab, { onClick: onRendersSelected, selected: panel === 'renders' })] }) }), panel === 'renders' ? ((0, jsx_runtime_1.jsx)(RenderQueue_1.RenderQueue, {})) : ((0, jsx_runtime_1.jsx)(PropsEditor, { composition: composition }))] }));
110
+ return ((0, jsx_runtime_1.jsxs)("div", { style: container, className: "css-reset", children: [(0, jsx_runtime_1.jsx)("div", { style: tabsContainer, children: (0, jsx_runtime_1.jsxs)(Tabs_1.Tabs, { children: [(0, jsx_runtime_1.jsxs)(Tabs_1.Tab, { selected: panel === 'input-props', onClick: onCompositionsSelected, style: { justifyContent: 'space-between' }, children: ["Props", unsavedChangesExist ? ((0, jsx_runtime_1.jsx)("div", { title: saveToolTip, style: circleStyle })) : null] }), (0, jsx_runtime_1.jsx)(RendersTab_1.RendersTab, { onClick: onRendersSelected, selected: panel === 'renders' })] }) }), panel === 'renders' ? ((0, jsx_runtime_1.jsx)(RenderQueue_1.RenderQueue, {})) : ((0, jsx_runtime_1.jsx)(DataEditor_1.DataEditor, { unresolvedComposition: composition, inputProps: actualProps, setInputProps: setInputProps, mayShowSaveButton: true, propsEditType: "default-props", saving: saving, setSaving: setSaving }, composition.id))] }));
78
111
  };
79
112
  exports.RightPanel = RightPanel;
@@ -11,6 +11,7 @@ const NotificationCenter_1 = require("../components/Notifications/NotificationCe
11
11
  const SizeSelector_1 = require("../components/SizeSelector");
12
12
  const TimelineInOutToggle_1 = require("../components/TimelineInOutToggle");
13
13
  const Checkmark_1 = require("../icons/Checkmark");
14
+ const canvas_ref_1 = require("../state/canvas-ref");
14
15
  const checkerboard_1 = require("../state/checkerboard");
15
16
  const editor_zoom_gestures_1 = require("../state/editor-zoom-gestures");
16
17
  const modals_1 = require("../state/modals");
@@ -36,6 +37,7 @@ const useMenuStructure = (closeMenu) => {
36
37
  const { type } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
37
38
  const { setSidebarCollapsedState, sidebarCollapsedStateLeft, sidebarCollapsedStateRight, } = (0, react_1.useContext)(sidebar_1.SidebarContext);
38
39
  const sizes = (0, SizeSelector_1.getUniqueSizes)(size);
40
+ const isFullscreenSupported = document.fullscreenEnabled || document.webkitFullscreenEnabled;
39
41
  const structure = (0, react_1.useMemo)(() => {
40
42
  const struct = [
41
43
  {
@@ -474,7 +476,28 @@ const useMenuStructure = (closeMenu) => {
474
476
  value: 'clear-marks',
475
477
  quickSwitcherLabel: 'Timeline: Clear In and Out Mark',
476
478
  },
477
- ],
479
+ {
480
+ id: 'fullscreen-divider',
481
+ type: 'divider',
482
+ },
483
+ isFullscreenSupported
484
+ ? {
485
+ id: 'fullscreen',
486
+ keyHint: null,
487
+ label: 'Fullscreen',
488
+ leftItem: null,
489
+ onClick: () => {
490
+ var _a;
491
+ closeMenu();
492
+ (_a = canvas_ref_1.canvasRef.current) === null || _a === void 0 ? void 0 : _a.requestFullscreen();
493
+ },
494
+ subMenu: null,
495
+ type: 'item',
496
+ value: 'fullscreen',
497
+ quickSwitcherLabel: 'Go Fullscreen',
498
+ }
499
+ : null,
500
+ ].filter(remotion_1.Internals.truthy),
478
501
  },
479
502
  'EyeDropper' in window
480
503
  ? {
@@ -639,6 +662,7 @@ const useMenuStructure = (closeMenu) => {
639
662
  sidebarCollapsedStateLeft,
640
663
  sidebarCollapsedStateRight,
641
664
  checkerboard,
665
+ isFullscreenSupported,
642
666
  closeMenu,
643
667
  setSelectedModal,
644
668
  type,
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export declare const canvasRef: import("react").RefObject<HTMLDivElement>;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.canvasRef = void 0;
4
+ const react_1 = require("react");
5
+ exports.canvasRef = (0, react_1.createRef)();
@@ -13,7 +13,6 @@ const button = {
13
13
  fontSize: 14,
14
14
  color: 'white',
15
15
  flexDirection: 'row',
16
- display: 'flex',
17
16
  };
18
17
  const ButtonRefForwardFunction = ({ children, onClick, title, disabled, style, id, autoFocus, buttonContainerStyle, }, ref) => {
19
18
  const combined = (0, react_1.useMemo)(() => {
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.updateDefaultPropsHandler = void 0;
4
4
  const node_fs_1 = require("node:fs");
5
- const remotion_1 = require("remotion");
6
5
  const update_default_props_1 = require("../../codemods/update-default-props");
7
6
  const project_info_1 = require("../project-info");
8
7
  const can_update_default_props_1 = require("./can-update-default-props");
@@ -16,7 +15,7 @@ const updateDefaultPropsHandler = async ({ input: { compositionId, defaultProps,
16
15
  const updated = await (0, update_default_props_1.updateDefaultProps)({
17
16
  compositionId,
18
17
  input: (0, node_fs_1.readFileSync)(projectInfo.videoFile, 'utf-8'),
19
- newDefaultProps: remotion_1.Internals.deserializeJSONWithCustomFields(defaultProps),
18
+ newDefaultProps: JSON.parse(defaultProps),
20
19
  enumPaths,
21
20
  });
22
21
  (0, node_fs_1.writeFileSync)(projectInfo.videoFile, updated);
@@ -278,7 +278,7 @@ const renderVideoFlow = async ({ remotionRoot, fullEntryPoint, indent, logLevel,
278
278
  proResProfile,
279
279
  jpegQuality: jpegQuality !== null && jpegQuality !== void 0 ? jpegQuality : renderer_1.RenderInternals.DEFAULT_JPEG_QUALITY,
280
280
  chromiumOptions,
281
- timeoutInMilliseconds: config_1.ConfigInternals.getCurrentPuppeteerTimeout(),
281
+ timeoutInMilliseconds: puppeteerTimeout,
282
282
  scale,
283
283
  port,
284
284
  numberOfGifLoops,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/cli",
3
- "version": "4.0.8",
3
+ "version": "4.0.11",
4
4
  "description": "CLI for Remotion",
5
5
  "main": "dist/index.js",
6
6
  "sideEffects": false,
@@ -35,11 +35,11 @@
35
35
  "prompts": "2.4.1",
36
36
  "semver": "7.5.3",
37
37
  "source-map": "0.6.1",
38
- "@remotion/bundler": "4.0.8",
39
- "@remotion/media-utils": "4.0.8",
40
- "remotion": "4.0.8",
41
- "@remotion/renderer": "4.0.8",
42
- "@remotion/player": "4.0.8"
38
+ "@remotion/bundler": "4.0.11",
39
+ "@remotion/player": "4.0.11",
40
+ "@remotion/media-utils": "4.0.11",
41
+ "remotion": "4.0.11",
42
+ "@remotion/renderer": "4.0.11"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "react": ">=16.8.0",
@@ -65,8 +65,8 @@
65
65
  "typescript": "4.9.5",
66
66
  "vitest": "0.31.1",
67
67
  "zod": "^3.21.4",
68
- "@remotion/tailwind": "4.0.8",
69
- "@remotion/zod-types": "4.0.8"
68
+ "@remotion/tailwind": "4.0.11",
69
+ "@remotion/zod-types": "4.0.11"
70
70
  },
71
71
  "keywords": [
72
72
  "remotion",
package/styles/styles.css CHANGED
@@ -42,3 +42,56 @@ input[type='color'].__remotion_color_picker::-webkit-color-swatch-wrapper {
42
42
  input[type='color'].__remotion_color_picker::-webkit-color-swatch {
43
43
  border: none;
44
44
  }
45
+
46
+ .__remotion_thumb,
47
+ .__remotion_thumb::-webkit-slider-thumb {
48
+ -webkit-appearance: none;
49
+ -webkit-tap-highlight-color: transparent;
50
+ }
51
+
52
+ .__remotion_thumb {
53
+ pointer-events: none;
54
+ position: absolute;
55
+ height: 0;
56
+ outline: none;
57
+ top: 51%;
58
+ width: 100%;
59
+ z-index: 2;
60
+ }
61
+
62
+ /* For Firefox browsers */
63
+ .__remotion_thumb::-moz-range-thumb {
64
+ border: none;
65
+ border-radius: 0;
66
+ cursor: pointer;
67
+ height: 40px;
68
+ width: 10px;
69
+ pointer-events: all;
70
+ border-color: black;
71
+ background-color: white;
72
+ position: relative;
73
+ }
74
+
75
+ .__remotion_thumb::-moz-range-thumb {
76
+ border-width: 1px;
77
+ border-style: solid;
78
+ }
79
+
80
+ /* For Chrome browsers */
81
+ .__remotion_thumb::-webkit-slider-thumb {
82
+ border: 1px solid black;
83
+ border-radius: 2px;
84
+ cursor: pointer;
85
+ height: 40px;
86
+ width: 10px;
87
+ pointer-events: all;
88
+ border-color: black;
89
+ background-color: white;
90
+ position: relative;
91
+ }
92
+
93
+ .__remotion_thumb::-webkit-slider-thumb {
94
+ border-width: 1px;
95
+ border-style: solid;
96
+ border-color: black;
97
+ }