Add .gitignore to exclude all node packages and lock files

This commit is contained in:
Adolfo Reyna
2026-02-23 21:56:04 -05:00
parent faae96c9ed
commit dcc5c6c044
9747 changed files with 1555105 additions and 2 deletions
@@ -0,0 +1,4 @@
import React from 'react';
export declare const FastRefreshProvider: React.FC<{
readonly children: React.ReactNode;
}>;
@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FastRefreshProvider = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const fast_refresh_context_1 = require("./fast-refresh-context");
const FastRefreshProvider = ({ children }) => {
const [fastRefreshes, setFastRefreshes] = (0, react_1.useState)(0);
const [manualRefreshes, setManualRefreshes] = (0, react_1.useState)(0);
const increaseManualRefreshes = (0, react_1.useCallback)(() => {
setManualRefreshes((i) => i + 1);
}, []);
(0, react_1.useEffect)(() => {
if (typeof __webpack_module__ !== 'undefined') {
if (__webpack_module__.hot) {
__webpack_module__.hot.addStatusHandler((status) => {
if (status === 'idle') {
setFastRefreshes((i) => i + 1);
}
});
}
}
}, []);
const value = (0, react_1.useMemo)(() => ({ fastRefreshes, manualRefreshes, increaseManualRefreshes }), [fastRefreshes, manualRefreshes, increaseManualRefreshes]);
return ((0, jsx_runtime_1.jsx)(fast_refresh_context_1.FastRefreshContext.Provider, { value: value, children: children }));
};
exports.FastRefreshProvider = FastRefreshProvider;
@@ -0,0 +1,5 @@
import type { PropsWithChildren } from 'react';
import React from 'react';
export declare const ResolveCompositionConfigInStudio: React.FC<PropsWithChildren<{
readonly children: React.ReactNode;
}>>;
@@ -0,0 +1,273 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ResolveCompositionConfigInStudio = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const remotion_1 = require("remotion");
const fast_refresh_context_1 = require("./fast-refresh-context");
const ResolveCompositionConfigInStudio = ({ children }) => {
const [currentRenderModalComposition, setCurrentRenderModalComposition] = (0, react_1.useState)(null);
const { compositions, canvasContent, currentCompositionMetadata } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
const { fastRefreshes, manualRefreshes } = (0, react_1.useContext)(fast_refresh_context_1.FastRefreshContext);
// don't do anything, this component should should re-render if the value changes
if (manualRefreshes) {
/** */
}
const selectedComposition = (0, react_1.useMemo)(() => {
return compositions.find((c) => canvasContent &&
canvasContent.type === 'composition' &&
canvasContent.compositionId === c.id);
}, [canvasContent, compositions]);
const renderModalComposition = compositions.find((c) => c.id === currentRenderModalComposition);
const { props: allEditorProps } = (0, react_1.useContext)(remotion_1.Internals.EditorPropsContext);
const env = remotion_1.Internals.getRemotionEnvironment();
const inputProps = (0, react_1.useMemo)(() => {
var _a;
return typeof window === 'undefined' || env.isPlayer
? {}
: ((_a = (0, remotion_1.getInputProps)()) !== null && _a !== void 0 ? _a : {});
}, [env.isPlayer]);
const [resolvedConfigs, setResolvedConfigs] = (0, react_1.useState)({});
const selectedEditorProps = (0, react_1.useMemo)(() => {
var _a;
return selectedComposition
? ((_a = allEditorProps[selectedComposition.id]) !== null && _a !== void 0 ? _a : {})
: {};
}, [allEditorProps, selectedComposition]);
const renderModalProps = (0, react_1.useMemo)(() => {
var _a;
return renderModalComposition
? ((_a = allEditorProps[renderModalComposition.id]) !== null && _a !== void 0 ? _a : {})
: {};
}, [allEditorProps, renderModalComposition]);
const hasResolution = Boolean(currentCompositionMetadata);
const doResolution = (0, react_1.useCallback)(({ calculateMetadata, combinedProps, compositionDurationInFrames, compositionFps, compositionHeight, compositionId, compositionWidth, defaultProps, }) => {
const controller = new AbortController();
if (hasResolution) {
return controller;
}
const { signal } = controller;
const result = remotion_1.Internals.resolveVideoConfigOrCatch({
compositionId,
calculateMetadata: calculateMetadata,
inputProps: combinedProps,
signal,
defaultProps,
compositionDurationInFrames,
compositionFps,
compositionHeight,
compositionWidth,
});
if (result.type === 'error') {
setResolvedConfigs((r) => ({
...r,
[compositionId]: {
type: 'error',
error: result.error,
},
}));
return controller;
}
const promOrNot = result.result;
if (typeof promOrNot === 'object' && 'then' in promOrNot) {
setResolvedConfigs((r) => {
const prev = r[compositionId];
if ((prev === null || prev === void 0 ? void 0 : prev.type) === 'success' ||
(prev === null || prev === void 0 ? void 0 : prev.type) === 'success-and-refreshing') {
return {
...r,
[compositionId]: {
type: 'success-and-refreshing',
result: prev.result,
},
};
}
return {
...r,
[compositionId]: {
type: 'loading',
},
};
});
promOrNot
.then((c) => {
if (controller.signal.aborted) {
return;
}
setResolvedConfigs((r) => ({
...r,
[compositionId]: {
type: 'success',
result: c,
},
}));
})
.catch((err) => {
if (controller.signal.aborted) {
return;
}
setResolvedConfigs((r) => ({
...r,
[compositionId]: {
type: 'error',
error: err,
},
}));
});
}
else {
setResolvedConfigs((r) => ({
...r,
[compositionId]: {
type: 'success',
result: promOrNot,
},
}));
}
return controller;
}, [hasResolution]);
const currentComposition = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition' ? canvasContent.compositionId : null;
(0, react_1.useImperativeHandle)(remotion_1.Internals.resolveCompositionsRef, () => {
return {
setCurrentRenderModalComposition: (id) => {
setCurrentRenderModalComposition(id);
},
reloadCurrentlySelectedComposition: () => {
var _a, _b, _c, _d, _e, _f;
if (!currentComposition) {
return;
}
const composition = compositions.find((c) => c.id === currentComposition);
if (!composition) {
throw new Error(`Could not find composition with id ${currentComposition}`);
}
const editorProps = (_a = allEditorProps[currentComposition]) !== null && _a !== void 0 ? _a : {};
const defaultProps = {
...((_b = composition.defaultProps) !== null && _b !== void 0 ? _b : {}),
...(editorProps !== null && editorProps !== void 0 ? editorProps : {}),
};
const props = {
...defaultProps,
...(inputProps !== null && inputProps !== void 0 ? inputProps : {}),
};
doResolution({
defaultProps,
calculateMetadata: composition.calculateMetadata,
combinedProps: props,
compositionDurationInFrames: (_c = composition.durationInFrames) !== null && _c !== void 0 ? _c : null,
compositionFps: (_d = composition.fps) !== null && _d !== void 0 ? _d : null,
compositionHeight: (_e = composition.height) !== null && _e !== void 0 ? _e : null,
compositionWidth: (_f = composition.width) !== null && _f !== void 0 ? _f : null,
compositionId: composition.id,
});
},
};
}, [
allEditorProps,
compositions,
currentComposition,
doResolution,
inputProps,
]);
const isTheSame = (selectedComposition === null || selectedComposition === void 0 ? void 0 : selectedComposition.id) === (renderModalComposition === null || renderModalComposition === void 0 ? void 0 : renderModalComposition.id);
const currentDefaultProps = (0, react_1.useMemo)(() => {
var _a;
return {
...((_a = selectedComposition === null || selectedComposition === void 0 ? void 0 : selectedComposition.defaultProps) !== null && _a !== void 0 ? _a : {}),
...(selectedEditorProps !== null && selectedEditorProps !== void 0 ? selectedEditorProps : {}),
};
}, [selectedComposition === null || selectedComposition === void 0 ? void 0 : selectedComposition.defaultProps, selectedEditorProps]);
const originalProps = (0, react_1.useMemo)(() => {
return {
...currentDefaultProps,
...(inputProps !== null && inputProps !== void 0 ? inputProps : {}),
};
}, [currentDefaultProps, inputProps]);
const canResolve = selectedComposition && Boolean(selectedComposition.calculateMetadata);
const shouldIgnoreUpdate = typeof window !== 'undefined' &&
window.remotion_ignoreFastRefreshUpdate &&
fastRefreshes <= window.remotion_ignoreFastRefreshUpdate;
(0, react_1.useEffect)(() => {
var _a, _b, _c, _d;
if (shouldIgnoreUpdate) {
return;
}
if (canResolve) {
const controller = doResolution({
calculateMetadata: selectedComposition.calculateMetadata,
combinedProps: originalProps,
compositionDurationInFrames: (_a = selectedComposition.durationInFrames) !== null && _a !== void 0 ? _a : null,
compositionFps: (_b = selectedComposition.fps) !== null && _b !== void 0 ? _b : null,
compositionHeight: (_c = selectedComposition.height) !== null && _c !== void 0 ? _c : null,
compositionWidth: (_d = selectedComposition.width) !== null && _d !== void 0 ? _d : null,
defaultProps: currentDefaultProps,
compositionId: selectedComposition.id,
});
return () => {
controller.abort();
};
}
}, [
canResolve,
currentDefaultProps,
doResolution,
originalProps,
selectedComposition === null || selectedComposition === void 0 ? void 0 : selectedComposition.calculateMetadata,
selectedComposition === null || selectedComposition === void 0 ? void 0 : selectedComposition.durationInFrames,
selectedComposition === null || selectedComposition === void 0 ? void 0 : selectedComposition.fps,
selectedComposition === null || selectedComposition === void 0 ? void 0 : selectedComposition.height,
selectedComposition === null || selectedComposition === void 0 ? void 0 : selectedComposition.id,
selectedComposition === null || selectedComposition === void 0 ? void 0 : selectedComposition.width,
shouldIgnoreUpdate,
]);
(0, react_1.useEffect)(() => {
var _a, _b, _c, _d, _e;
if (renderModalComposition && !isTheSame) {
const combinedProps = {
...((_a = renderModalComposition.defaultProps) !== null && _a !== void 0 ? _a : {}),
...(renderModalProps !== null && renderModalProps !== void 0 ? renderModalProps : {}),
...(inputProps !== null && inputProps !== void 0 ? inputProps : {}),
};
const controller = doResolution({
calculateMetadata: renderModalComposition.calculateMetadata,
compositionDurationInFrames: (_b = renderModalComposition.durationInFrames) !== null && _b !== void 0 ? _b : null,
compositionFps: (_c = renderModalComposition.fps) !== null && _c !== void 0 ? _c : null,
compositionHeight: (_d = renderModalComposition.height) !== null && _d !== void 0 ? _d : null,
compositionId: renderModalComposition.id,
compositionWidth: (_e = renderModalComposition.width) !== null && _e !== void 0 ? _e : null,
defaultProps: currentDefaultProps,
combinedProps,
});
return () => {
controller.abort();
};
}
}, [
currentDefaultProps,
doResolution,
inputProps,
isTheSame,
renderModalComposition,
renderModalProps,
]);
const resolvedConfigsIncludingStaticOnes = (0, react_1.useMemo)(() => {
const staticComps = compositions.filter((c) => {
return c.calculateMetadata === null;
});
return {
...resolvedConfigs,
...staticComps.reduce((acc, curr) => {
var _a;
return {
...acc,
[curr.id]: {
type: 'success',
result: { ...curr, defaultProps: (_a = curr.defaultProps) !== null && _a !== void 0 ? _a : {} },
},
};
}, {}),
};
}, [compositions, resolvedConfigs]);
return ((0, jsx_runtime_1.jsx)(remotion_1.Internals.ResolveCompositionContext.Provider, { value: resolvedConfigsIncludingStaticOnes, children: children }));
};
exports.ResolveCompositionConfigInStudio = ResolveCompositionConfigInStudio;
@@ -0,0 +1,5 @@
import React from 'react';
export declare const Studio: React.FC<{
readonly rootComponent: React.FC;
readonly readOnly: boolean;
}>;
@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Studio = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const react_dom_1 = require("react-dom");
const remotion_1 = require("remotion");
const Editor_1 = require("./components/Editor");
const EditorContexts_1 = require("./components/EditorContexts");
const ServerDisconnected_1 = require("./components/Notifications/ServerDisconnected");
const fast_refresh_context_1 = require("./fast-refresh-context");
const FastRefreshProvider_1 = require("./FastRefreshProvider");
const inject_css_1 = require("./helpers/inject-css");
const ResolveCompositionConfigInStudio_1 = require("./ResolveCompositionConfigInStudio");
const getServerDisconnectedDomElement = () => {
return document.getElementById('server-disconnected-overlay');
};
const StudioInner = ({ rootComponent, readOnly }) => {
var _a;
const { fastRefreshes, manualRefreshes } = (0, react_1.useContext)(fast_refresh_context_1.FastRefreshContext);
return ((0, jsx_runtime_1.jsx)(remotion_1.Internals.CompositionManagerProvider, { onlyRenderComposition: null, currentCompositionMetadata: null, initialCompositions: [], initialCanvasContent: null, children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.RemotionRootContexts, { frameState: null, audioEnabled: window.remotion_audioEnabled, videoEnabled: window.remotion_videoEnabled, logLevel: window.remotion_logLevel, numberOfAudioTags: window.remotion_numberOfAudioTags, audioLatencyHint: (_a = window.remotion_audioLatencyHint) !== null && _a !== void 0 ? _a : 'interactive', nonceContextSeed: fastRefreshes + manualRefreshes, children: (0, jsx_runtime_1.jsx)(ResolveCompositionConfigInStudio_1.ResolveCompositionConfigInStudio, { children: (0, jsx_runtime_1.jsxs)(EditorContexts_1.EditorContexts, { readOnlyStudio: readOnly, children: [(0, jsx_runtime_1.jsx)(Editor_1.Editor, { readOnlyStudio: readOnly, Root: rootComponent }), readOnly
? null
: (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)(ServerDisconnected_1.ServerDisconnected, {}), getServerDisconnectedDomElement())] }) }) }) }));
};
const Studio = ({ rootComponent, readOnly }) => {
(0, react_1.useLayoutEffect)(() => {
(0, inject_css_1.injectCSS)();
}, []);
return ((0, jsx_runtime_1.jsx)(FastRefreshProvider_1.FastRefreshProvider, { children: (0, jsx_runtime_1.jsx)(StudioInner, { rootComponent: rootComponent, readOnly: readOnly }) }));
};
exports.Studio = Studio;
@@ -0,0 +1,4 @@
import type { CompositionProps, StillProps } from 'remotion';
import type { AnyZodObject } from 'zod';
export declare const createComposition: <Schema extends AnyZodObject, Props extends Record<string, unknown>>({ ...other }: CompositionProps<Schema, Props>) => () => import("react/jsx-runtime").JSX.Element;
export declare const createStill: <Schema extends AnyZodObject, Props extends Record<string, unknown>>({ ...other }: StillProps<Schema, Props>) => () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createStill = exports.createComposition = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const remotion_1 = require("remotion");
const createComposition = ({ ...other }) => () => {
// @ts-expect-error
return (0, jsx_runtime_1.jsx)(remotion_1.Composition, { ...other });
};
exports.createComposition = createComposition;
const createStill = ({ ...other }) => () => {
// @ts-expect-error
return (0, jsx_runtime_1.jsx)(remotion_1.Still, { ...other });
};
exports.createStill = createStill;
@@ -0,0 +1,3 @@
import type { DeleteStaticFileResponse } from '@remotion/studio-shared';
export declare const deleteStaticFile: (relativePath: string) => Promise<DeleteStaticFileResponse>;
export { DeleteStaticFileResponse };
@@ -0,0 +1,19 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.deleteStaticFile = void 0;
const remotion_1 = require("remotion");
const call_api_1 = require("../components/call-api");
const deleteStaticFile = async (relativePath) => {
if (!(0, remotion_1.getRemotionEnvironment)().isStudio) {
throw new Error('deleteStaticFile() is only available in the Studio');
}
if (window.remotion_isReadOnlyStudio) {
throw new Error('deleteStaticFile() is not available in Read-Only Studio');
}
if (relativePath.startsWith(window.remotion_staticBase)) {
relativePath = relativePath.substring(window.remotion_staticBase.length + 1);
}
const res = await (0, call_api_1.callApi)('/api/delete-static-file', { relativePath });
return res;
};
exports.deleteStaticFile = deleteStaticFile;
@@ -0,0 +1,7 @@
import type { JSONPath } from '../components/RenderModal/SchemaEditor/zod-types';
export declare const focusDefaultPropsPath: ({ path, scrollBehavior, }: {
path: JSONPath;
scrollBehavior?: ScrollBehavior;
}) => {
success: boolean;
};
@@ -0,0 +1,22 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.focusDefaultPropsPath = void 0;
const scroll_to_default_props_path_1 = require("../components/RenderModal/SchemaEditor/scroll-to-default-props-path");
const focusDefaultPropsPath = ({ path, scrollBehavior, }) => {
const currentlyActive = document.querySelector(`.${scroll_to_default_props_path_1.DEFAULT_PROPS_PATH_ACTIVE_CLASSNAME}`);
if (currentlyActive !== null) {
currentlyActive.classList.remove(scroll_to_default_props_path_1.DEFAULT_PROPS_PATH_ACTIVE_CLASSNAME);
}
const query = document.querySelector(`.${scroll_to_default_props_path_1.DEFAULT_PROPS_PATH_CLASSNAME}[data-json-path="${path.join('.')}"]`);
if (query === null) {
return {
success: false,
};
}
query.scrollIntoView({ behavior: scrollBehavior });
query.classList.add(scroll_to_default_props_path_1.DEFAULT_PROPS_PATH_ACTIVE_CLASSNAME);
return {
success: true,
};
};
exports.focusDefaultPropsPath = focusDefaultPropsPath;
@@ -0,0 +1,17 @@
export declare const getStaticFiles: () => StaticFile[];
export type StaticFile = {
/**
* A string that you can pass to the `src` attribute of an `<Audio>`, `<Img>`, `<Video>`, `<Html5Audio>`, `<Html5Video>` or `<OffthreadVideo>` element.
*/
src: string;
/**
* The filepath of the file, relative to the public folder.
* Example: `subfolder/image.png`
*/
name: string;
sizeInBytes: number;
/**
* UNIX timestamp in milliseconds
*/
lastModified: number;
};
@@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getStaticFiles = void 0;
let warnedServer = false;
let warnedPlayer = false;
const warnServerOnce = () => {
if (warnedServer) {
return;
}
warnedServer = true;
// eslint-disable-next-line no-console
console.warn('Called getStaticFiles() on the server. The API is only available in the browser. An empty array was returned.');
};
const warnPlayerOnce = () => {
if (warnedPlayer) {
return;
}
warnedPlayer = true;
// eslint-disable-next-line no-console
console.warn('Called getStaticFiles() while using the Remotion Player. The API is only available while using the Remotion Studio. An empty array was returned.');
};
/*
* @description Gets an array containing all files in the `public/` folder. You can reference them by using `staticFile()`.
* @see [Documentation](https://www.remotion.dev/docs/studio/get-static-files)
*/
const getStaticFiles = () => {
if (typeof document === 'undefined') {
warnServerOnce();
return [];
}
if (window.remotion_isPlayer) {
warnPlayerOnce();
return [];
}
return window.remotion_staticFiles;
};
exports.getStaticFiles = getStaticFiles;
@@ -0,0 +1,2 @@
import type { ZodType } from '../components/get-zod-if-possible';
export declare const getZodSchemaFromPrimitive: (value: unknown, z: ZodType) => import("zod").ZodString | import("zod").ZodNumber;
@@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getZodSchemaFromPrimitive = void 0;
const getZodSchemaFromPrimitive = (value, z) => {
if (typeof value === 'string') {
return z.string();
}
if (typeof value === 'number') {
return z.number();
}
let stringified;
try {
stringified = JSON.stringify(value);
}
catch (_a) { }
throw new Error(`visualControl(): Specify a schema for this value: ${stringified !== null && stringified !== void 0 ? stringified : '[non-serializable value]'}. See https://remotion.dev/docs/studio/visual-control`);
};
exports.getZodSchemaFromPrimitive = getZodSchemaFromPrimitive;
@@ -0,0 +1,6 @@
/**
* Selects a composition in the Remotion Studio.
* @param compositionId - The ID of the composition to select.
* @see [Documentation](/docs/studio/go-to-composition)
*/
export declare const goToComposition: (compositionId: string) => void;
@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.goToComposition = void 0;
const remotion_1 = require("remotion");
/**
* Selects a composition in the Remotion Studio.
* @param compositionId - The ID of the composition to select.
* @see [Documentation](/docs/studio/go-to-composition)
*/
const goToComposition = (compositionId) => {
var _a;
(_a = remotion_1.Internals.compositionSelectorRef.current) === null || _a === void 0 ? void 0 : _a.selectComposition(compositionId);
};
exports.goToComposition = goToComposition;
@@ -0,0 +1,11 @@
import type { _InternalTypes } from 'remotion';
import type { AnyZodObject } from 'zod';
export type UpdateDefaultPropsFunction = (currentValues: {
schema: AnyZodObject | null;
savedDefaultProps: Record<string, unknown>;
unsavedDefaultProps: Record<string, unknown>;
}) => Record<string, unknown>;
export declare const calcNewProps: (compositionId: string, defaultProps: UpdateDefaultPropsFunction) => {
composition: _InternalTypes["AnyComposition"];
generatedDefaultProps: Record<string, unknown>;
};
@@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.calcNewProps = void 0;
const remotion_1 = require("remotion");
const calcNewProps = (compositionId, defaultProps) => {
var _a, _b;
if (!(0, remotion_1.getRemotionEnvironment)().isStudio) {
throw new Error('saveDefaultProps can only be called in the Remotion Studio.');
}
const { compositionsRef, editorPropsProviderRef } = remotion_1.Internals;
const compositionsStore = compositionsRef.current;
if (!compositionsStore) {
throw new Error('No compositions ref found. Are you in the Remotion Studio and are the Remotion versions aligned?');
}
const compositions = compositionsStore.getCompositions();
const composition = compositions.find((c) => c.id === compositionId);
if (!composition) {
throw new Error(`No composition with the ID ${compositionId} found. Available compositions: ${compositions.map((c) => c.id).join(', ')}`);
}
const propsStore = editorPropsProviderRef.current;
if (!propsStore) {
throw new Error('No props store found. Are you in the Remotion Studio and are the Remotion versions aligned?');
}
const savedDefaultProps = (_a = composition.defaultProps) !== null && _a !== void 0 ? _a : {};
const unsavedDefaultProps = (_b = propsStore.getProps()[compositionId]) !== null && _b !== void 0 ? _b : savedDefaultProps;
const generatedDefaultProps = defaultProps({
schema: composition.schema,
savedDefaultProps,
unsavedDefaultProps,
});
return {
composition,
generatedDefaultProps,
};
};
exports.calcNewProps = calcNewProps;
@@ -0,0 +1,2 @@
import type { InstallPackageResponse } from '@remotion/studio-shared';
export declare const installPackages: (packageNames: string[]) => Promise<InstallPackageResponse>;
@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.installPackages = void 0;
const remotion_1 = require("remotion");
const call_api_1 = require("../components/call-api");
const installPackages = (packageNames) => {
if (!(0, remotion_1.getRemotionEnvironment)().isStudio) {
throw new Error('installPackages() is only available in the Studio');
}
if (window.remotion_isReadOnlyStudio) {
throw new Error('installPackages() is not available in Read-Only Studio');
}
return (0, call_api_1.callApi)('/api/install-package', { packageNames });
};
exports.installPackages = installPackages;
@@ -0,0 +1 @@
export declare const pause: () => void;
@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.pause = void 0;
const remotion_1 = require("remotion");
/*
* @description Pause the current composition.
* @see [Documentation](https://www.remotion.dev/docs/studio/pause)
*/
const pause = () => {
var _a;
(_a = remotion_1.Internals.timeValueRef.current) === null || _a === void 0 ? void 0 : _a.pause();
};
exports.pause = pause;
@@ -0,0 +1,2 @@
import type { SyntheticEvent } from 'react';
export declare const play: (e?: SyntheticEvent | PointerEvent) => void;
@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.play = void 0;
const remotion_1 = require("remotion");
/*
* @description Play the current composition.
* @see [Documentation](https://www.remotion.dev/docs/studio/play)
*/
const play = (e) => {
var _a;
(_a = remotion_1.Internals.timeValueRef.current) === null || _a === void 0 ? void 0 : _a.play(e);
};
exports.play = play;
@@ -0,0 +1 @@
export declare const reevaluateComposition: () => void;
@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.reevaluateComposition = void 0;
const remotion_1 = require("remotion");
const reevaluateComposition = () => {
var _a;
(_a = remotion_1.Internals.resolveCompositionsRef.current) === null || _a === void 0 ? void 0 : _a.reloadCurrentlySelectedComposition();
};
exports.reevaluateComposition = reevaluateComposition;
@@ -0,0 +1,6 @@
/**
* @description Restarts the Remotion Studio.
* @see [Documentation](https://www.remotion.dev/docs/studio/restart-studio)
*/
import type { RestartStudioResponse } from '@remotion/studio-shared';
export declare const restartStudio: () => Promise<RestartStudioResponse>;
@@ -0,0 +1,19 @@
"use strict";
/**
* @description Restarts the Remotion Studio.
* @see [Documentation](https://www.remotion.dev/docs/studio/restart-studio)
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.restartStudio = void 0;
const remotion_1 = require("remotion");
const call_api_1 = require("../components/call-api");
const restartStudio = () => {
if (!(0, remotion_1.getRemotionEnvironment)().isStudio) {
throw new Error('restartStudio() is only available in the Studio');
}
if (window.remotion_isReadOnlyStudio) {
throw new Error('restartStudio() is not available in read-only Studio');
}
return (0, call_api_1.callApi)('/api/restart-studio', {});
};
exports.restartStudio = restartStudio;
@@ -0,0 +1,5 @@
import type { UpdateDefaultPropsFunction } from './helpers/calc-new-props';
export declare const saveDefaultProps: ({ compositionId, defaultProps, }: {
compositionId: string;
defaultProps: UpdateDefaultPropsFunction;
}) => Promise<void>;
@@ -0,0 +1,80 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.saveDefaultProps = void 0;
const remotion_1 = require("remotion");
const extract_enum_json_paths_1 = require("../components/RenderModal/SchemaEditor/extract-enum-json-paths");
const actions_1 = require("../components/RenderQueue/actions");
const calc_new_props_1 = require("./helpers/calc-new-props");
/*
* @description Saves the defaultProps for a composition back to the root file.
* @see [Documentation](https://www.remotion.dev/docs/studio/save-default-props)
*/
const saveDefaultProps = async ({ compositionId, defaultProps, }) => {
if (!(0, remotion_1.getRemotionEnvironment)().isStudio) {
throw new Error('saveDefaultProps() is only available in the Studio');
}
if (window.remotion_isReadOnlyStudio) {
throw new Error('saveDefaultProps() is not available in read-only Studio');
}
try {
await Promise.resolve().then(() => __importStar(require('zod')));
}
catch (_a) {
throw new Error('"zod" is required to use saveDefaultProps(), but is not installed.');
}
const z = await Promise.resolve().then(() => __importStar(require('zod')));
let zodTypes = null;
try {
zodTypes = await Promise.resolve().then(() => __importStar(require('@remotion/zod-types')));
}
catch (_b) { }
const { generatedDefaultProps, composition } = (0, calc_new_props_1.calcNewProps)(compositionId, defaultProps);
const res = await (0, actions_1.callUpdateDefaultPropsApi)(compositionId, generatedDefaultProps, composition.schema
? (0, extract_enum_json_paths_1.extractEnumJsonPaths)({
schema: composition.schema,
zodRuntime: z,
currentPath: [],
zodTypes,
})
: []);
if (res.success) {
return Promise.resolve();
}
const err = new Error(res.reason);
err.stack = res.stack;
return Promise.reject(err);
};
exports.saveDefaultProps = saveDefaultProps;
@@ -0,0 +1,7 @@
import type { CompletedClientRender } from '@remotion/studio-shared';
export declare const saveOutputFile: ({ blob, filePath, }: {
blob: Blob;
filePath: string;
}) => Promise<void>;
export declare const registerClientRender: (render: CompletedClientRender) => Promise<void>;
export declare const unregisterClientRender: (id: string) => Promise<void>;
@@ -0,0 +1,45 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.unregisterClientRender = exports.registerClientRender = exports.saveOutputFile = void 0;
const throwIfNotOk = async (response) => {
if (!response.ok) {
try {
const jsonResponse = await response.json();
throw new Error(jsonResponse.error);
}
catch (parseError) {
if (parseError instanceof Error && parseError.message) {
throw parseError;
}
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
}
};
const saveOutputFile = async ({ blob, filePath, }) => {
const url = new URL('/api/upload-output', window.location.origin);
url.search = new URLSearchParams({ filePath }).toString();
const response = await fetch(url, {
method: 'POST',
body: blob,
});
await throwIfNotOk(response);
};
exports.saveOutputFile = saveOutputFile;
const registerClientRender = async (render) => {
const response = await fetch('/api/register-client-render', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(render),
});
await throwIfNotOk(response);
};
exports.registerClientRender = registerClientRender;
const unregisterClientRender = async (id) => {
const response = await fetch('/api/unregister-client-render', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id }),
});
await throwIfNotOk(response);
};
exports.unregisterClientRender = unregisterClientRender;
@@ -0,0 +1 @@
export declare const seek: (frame: number) => void;
@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.seek = void 0;
const remotion_1 = require("remotion");
/*
* @description Jump to a different time in the timeline.
* @see [Documentation](https://www.remotion.dev/docs/studio/seek)
*/
const seek = (frame) => {
var _a;
(_a = remotion_1.Internals.timeValueRef.current) === null || _a === void 0 ? void 0 : _a.seek(Math.max(0, frame));
};
exports.seek = seek;
@@ -0,0 +1,2 @@
import type { SyntheticEvent } from 'react';
export declare const toggle: (e?: SyntheticEvent | PointerEvent) => void;
@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.toggle = void 0;
const remotion_1 = require("remotion");
/*
* @description Toggle playback of the current composition.
* @see [Documentation](https://www.remotion.dev/docs/studio/toggle)
*/
const toggle = (e) => {
var _a;
(_a = remotion_1.Internals.timeValueRef.current) === null || _a === void 0 ? void 0 : _a.toggle(e);
};
exports.toggle = toggle;
@@ -0,0 +1,5 @@
import type { UpdateDefaultPropsFunction } from './helpers/calc-new-props';
export declare const updateDefaultProps: ({ compositionId, defaultProps, }: {
compositionId: string;
defaultProps: UpdateDefaultPropsFunction;
}) => void;
@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateDefaultProps = void 0;
const remotion_1 = require("remotion");
const calc_new_props_1 = require("./helpers/calc-new-props");
const updateDefaultProps = ({ compositionId, defaultProps, }) => {
const { generatedDefaultProps, composition } = (0, calc_new_props_1.calcNewProps)(compositionId, defaultProps);
const propsStore = remotion_1.Internals.editorPropsProviderRef.current;
if (!propsStore) {
throw new Error('No props store found. Are you in the Remotion Studio and are the Remotion versions aligned?');
}
propsStore.setProps((prev) => {
return {
...prev,
[composition.id]: generatedDefaultProps,
};
});
window.dispatchEvent(new CustomEvent(remotion_1.Internals.PROPS_UPDATED_EXTERNALLY, {
detail: {
resetUnsaved: null,
},
}));
};
exports.updateDefaultProps = updateDefaultProps;
@@ -0,0 +1,2 @@
import { type VisualControlRef } from '../visual-controls/VisualControls';
export declare const visualControl: VisualControlRef['globalVisualControl'];
@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.visualControl = void 0;
const remotion_1 = require("remotion");
const VisualControls_1 = require("../visual-controls/VisualControls");
const visualControl = (key, value, schema) => {
if ((0, remotion_1.getRemotionEnvironment)().isRendering) {
return value;
}
if (!VisualControls_1.visualControlRef.current) {
return value;
}
return VisualControls_1.visualControlRef.current.globalVisualControl(key, value, schema);
};
exports.visualControl = visualControl;
@@ -0,0 +1,7 @@
import { type StaticFile } from './get-static-files';
type WatcherCallback = (newFiles: StaticFile[]) => void;
export declare const WATCH_REMOTION_STATIC_FILES = "remotion_staticFilesChanged";
export declare const watchPublicFolder: (callback: WatcherCallback) => {
cancel: () => void;
};
export {};
@@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.watchPublicFolder = exports.WATCH_REMOTION_STATIC_FILES = void 0;
const remotion_1 = require("remotion");
const get_static_files_1 = require("./get-static-files");
exports.WATCH_REMOTION_STATIC_FILES = 'remotion_staticFilesChanged';
/*
* @description Watches for changes in the public directory and calls a callback function when a file is added, removed, or modified.
* @see [Documentation](https://www.remotion.dev/docs/studio/watch-public-folder)
*/
const watchPublicFolder = (callback) => {
if (!(0, remotion_1.getRemotionEnvironment)().isStudio) {
// eslint-disable-next-line no-console
console.warn('The watchPublicFolder() API is only available while using the Remotion Studio.');
return { cancel: () => undefined };
}
if (window.remotion_isReadOnlyStudio) {
throw new Error('watchPublicFolder() is not available in read-only Studio');
}
const emitUpdate = () => {
callback((0, get_static_files_1.getStaticFiles)());
};
window.addEventListener(exports.WATCH_REMOTION_STATIC_FILES, emitUpdate);
const cancel = () => {
return window.removeEventListener(exports.WATCH_REMOTION_STATIC_FILES, emitUpdate);
};
return { cancel };
};
exports.watchPublicFolder = watchPublicFolder;
@@ -0,0 +1,9 @@
import type { StaticFile } from './get-static-files';
type WatcherCallback = (newData: StaticFile | null) => void;
export type WatchRemotionStaticFilesPayload = {
files: StaticFile[];
};
export declare const watchStaticFile: (fileName: string, callback: WatcherCallback) => {
cancel: () => void;
};
export {};
@@ -0,0 +1,47 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.watchStaticFile = void 0;
const remotion_1 = require("remotion");
const watch_public_folder_1 = require("./watch-public-folder");
/*
* @description Watches for changes in a specific static file and invokes a callback function when the file changes, enabling dynamic updates in your Remotion projects.
* @see [Documentation](https://www.remotion.dev/docs/studio/watch-static-file)
*/
const watchStaticFile = (fileName, callback) => {
if (!(0, remotion_1.getRemotionEnvironment)().isStudio) {
// eslint-disable-next-line no-console
console.warn('watchStaticFile() is only available while using the Remotion Studio.');
return { cancel: () => undefined };
}
if (window.remotion_isReadOnlyStudio) {
// eslint-disable-next-line no-console
console.warn('watchStaticFile() is only available in an interactive Studio.');
return { cancel: () => undefined };
}
const withoutStaticBase = fileName.startsWith(window.remotion_staticBase)
? fileName.replace(window.remotion_staticBase, '')
: fileName;
const withoutLeadingSlash = withoutStaticBase.startsWith('/')
? withoutStaticBase.slice(1)
: withoutStaticBase;
let prevFileData = window.remotion_staticFiles.find((file) => file.name === withoutLeadingSlash);
const { cancel } = (0, watch_public_folder_1.watchPublicFolder)((staticFiles) => {
// Check for user specified file
const newFileData = staticFiles.find((file) => file.name === withoutLeadingSlash);
if (!newFileData) {
// File is deleted
if (prevFileData !== undefined) {
callback(null);
}
prevFileData = undefined;
return;
}
if (prevFileData === undefined ||
prevFileData.lastModified !== newFileData.lastModified) {
callback(newFileData); // File is added or modified
prevFileData = newFileData;
}
});
return { cancel };
};
exports.watchStaticFile = watchStaticFile;
@@ -0,0 +1,4 @@
export declare const writeStaticFile: ({ contents, filePath, }: {
contents: string | ArrayBuffer;
filePath: string;
}) => Promise<void>;
@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.writeStaticFile = void 0;
const writeStaticFile = async ({ contents, filePath, }) => {
if (window.remotion_isReadOnlyStudio) {
throw new Error('writeStaticFile() is not available in read-only Studio');
}
const url = new URL(`${window.remotion_staticBase}/api/add-asset`, window.location.origin);
if (filePath.includes('\\')) {
return Promise.reject(new Error('File path cannot contain backslashes'));
}
url.search = new URLSearchParams({
filePath,
}).toString();
const response = await fetch(url, {
method: 'POST',
body: contents,
});
if (!response.ok) {
const jsonResponse = await response.json();
throw new Error(jsonResponse.error);
}
};
exports.writeStaticFile = writeStaticFile;
@@ -0,0 +1,7 @@
import React from 'react';
type AskAiModalRef = {
toggle: () => void;
};
export declare const askAiModalRef: React.RefObject<AskAiModalRef | null>;
export declare const AskAiModal: React.FC;
export {};
@@ -0,0 +1,68 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AskAiModal = exports.askAiModalRef = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const remotion_1 = require("remotion");
const ModalContainer_1 = require("./ModalContainer");
const ModalHeader_1 = require("./ModalHeader");
const container = {
height: 'calc(100vh - 100px)',
width: 'calc(100vw - 160px)',
maxWidth: 800,
maxHeight: 900,
display: 'block',
};
exports.askAiModalRef = (0, react_1.createRef)();
const AskAiModal = () => {
const [state, setState] = (0, react_1.useState)('never-opened');
const iframe = (0, react_1.useRef)(null);
(0, react_1.useImperativeHandle)(exports.askAiModalRef, () => ({
toggle: () => {
setState((s) => {
var _a, _b, _c;
if (s === 'visible') {
(_a = iframe.current) === null || _a === void 0 ? void 0 : _a.blur();
(_c = (_b = iframe.current) === null || _b === void 0 ? void 0 : _b.contentWindow) === null || _c === void 0 ? void 0 : _c.blur();
}
return s === 'visible' ? 'hidden' : 'visible';
});
},
}), []);
(0, react_1.useEffect)(() => {
const onMessage = (event) => {
var _a;
try {
const json = typeof event.data === 'string' ? JSON.parse(event.data) : event.data;
if (json.type === 'cmd-i') {
(_a = exports.askAiModalRef.current) === null || _a === void 0 ? void 0 : _a.toggle();
}
}
catch (_b) { }
};
window.addEventListener('message', onMessage);
return () => {
window.removeEventListener('message', onMessage);
};
}, []);
const onQuit = (0, react_1.useCallback)(() => {
setState('hidden');
}, [setState]);
// When re-toggling the modal, focus the text box
(0, react_1.useEffect)(() => {
var _a;
if (!iframe.current) {
return;
}
if (state === 'visible') {
(_a = iframe.current.contentWindow) === null || _a === void 0 ? void 0 : _a.postMessage({
type: 'focus',
}, '*');
}
}, [state]);
if (state === 'never-opened') {
return null;
}
return ((0, jsx_runtime_1.jsx)(remotion_1.AbsoluteFill, { style: { display: state === 'visible' ? 'block' : 'none' }, children: (0, jsx_runtime_1.jsxs)(ModalContainer_1.ModalContainer, { noZIndex: state === 'hidden', onOutsideClick: onQuit, onEscape: onQuit, children: [(0, jsx_runtime_1.jsx)(ModalHeader_1.ModalHeader, { title: "Ask AI", onClose: onQuit }), (0, jsx_runtime_1.jsx)("iframe", { ref: iframe, frameBorder: 0, style: container, src: "https://www.remotion.dev/ai-embed", allow: "clipboard-read; clipboard-write" })] }) }));
};
exports.AskAiModal = AskAiModal;
@@ -0,0 +1,4 @@
import React from 'react';
export declare const AssetSelector: React.FC<{
readonly readOnlyStudio: boolean;
}>;
@@ -0,0 +1,165 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AssetSelector = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = __importStar(require("react"));
const get_static_files_1 = require("../api/get-static-files");
const write_static_file_1 = require("../api/write-static-file");
const client_id_1 = require("../helpers/client-id");
const colors_1 = require("../helpers/colors");
const create_folder_tree_1 = require("../helpers/create-folder-tree");
const persist_open_folders_1 = require("../helpers/persist-open-folders");
const use_asset_drag_events_1 = __importDefault(require("../helpers/use-asset-drag-events"));
const folders_1 = require("../state/folders");
const z_index_1 = require("../state/z-index");
const AssetSelectorItem_1 = require("./AssetSelectorItem");
const styles_1 = require("./Menu/styles");
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
const container = {
display: 'flex',
flexDirection: 'column',
flex: 1,
overflow: 'hidden',
backgroundColor: colors_1.BACKGROUND,
};
// Some redundancy with packages/cli/src/editor/components/RenderModal/SchemaEditor/SchemaErrorMessages.tsx
const emptyState = {
display: 'flex',
flex: 1,
justifyContent: 'center',
alignItems: 'center',
textAlign: 'center',
padding: '0 12px',
};
const label = {
color: colors_1.LIGHT_TEXT,
lineHeight: 1.5,
fontSize: 14,
};
const list = {
height: '100%',
overflowY: 'auto',
};
const AssetSelector = ({ readOnlyStudio }) => {
const { tabIndex } = (0, z_index_1.useZIndex)();
const { assetFoldersExpanded, setAssetFoldersExpanded } = (0, react_1.useContext)(folders_1.FolderContext);
const [dropLocation, setDropLocation] = (0, react_1.useState)(null);
const { subscribeToEvent } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
const connectionStatus = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx)
.previewServerState.type;
const shouldAllowUpload = connectionStatus === 'connected' && !readOnlyStudio;
const [{ publicFolderExists, staticFiles }, setState] = react_1.default.useState(() => {
return {
staticFiles: (0, get_static_files_1.getStaticFiles)(),
publicFolderExists: window.remotion_publicFolderExists,
};
});
const assetTree = (0, react_1.useMemo)(() => {
return (0, create_folder_tree_1.buildAssetFolderStructure)(staticFiles, null, assetFoldersExpanded);
}, [assetFoldersExpanded, staticFiles]);
(0, react_1.useEffect)(() => {
const onUpdate = () => {
setState({
staticFiles: (0, get_static_files_1.getStaticFiles)(),
publicFolderExists: window.remotion_publicFolderExists,
});
};
const unsub = subscribeToEvent('new-public-folder', onUpdate);
return () => {
unsub();
};
}, [subscribeToEvent]);
const toggleFolder = (0, react_1.useCallback)((folderName, parentName) => {
setAssetFoldersExpanded((p) => {
var _a;
const key = [parentName, folderName].filter(Boolean).join('/');
const prev = (_a = p[key]) !== null && _a !== void 0 ? _a : false;
const foldersExpandedState = {
...p,
[key]: !prev,
};
(0, persist_open_folders_1.persistExpandedFolders)('assets', foldersExpandedState);
return foldersExpandedState;
});
}, [setAssetFoldersExpanded]);
const { isDropDiv, onDragEnter, onDragLeave } = (0, use_asset_drag_events_1.default)({
name: null,
parentFolder: null,
dropLocation,
setDropLocation,
});
const onDragOver = (0, react_1.useCallback)((e) => {
e.preventDefault();
}, []);
const onDrop = (0, react_1.useCallback)(async (e) => {
try {
e.preventDefault();
e.stopPropagation();
const { files } = e.dataTransfer;
const assetPath = dropLocation !== null && dropLocation !== void 0 ? dropLocation : null;
const makePath = (file) => {
return [assetPath, file.name].filter(Boolean).join('/');
};
for (const file of files) {
const body = await file.arrayBuffer();
await (0, write_static_file_1.writeStaticFile)({
contents: body,
filePath: makePath(file),
});
}
if (files.length === 1) {
(0, NotificationCenter_1.showNotification)(`Created ${makePath(files[0])}`, 3000);
}
else {
(0, NotificationCenter_1.showNotification)(`Added ${files.length} files to ${assetPath}`, 3000);
}
}
catch (error) {
(0, NotificationCenter_1.showNotification)(`Error during upload: ${error}`, 3000);
}
finally {
setDropLocation(null);
}
}, [dropLocation]);
return ((0, jsx_runtime_1.jsx)("div", { style: container, onDragOver: shouldAllowUpload ? onDragOver : undefined, onDrop: shouldAllowUpload ? onDrop : undefined, children: staticFiles.length === 0 ? (publicFolderExists ? ((0, jsx_runtime_1.jsx)("div", { style: emptyState, children: (0, jsx_runtime_1.jsxs)("div", { style: label, children: ["To add assets, place a file in the", ' ', (0, jsx_runtime_1.jsx)("code", { style: styles_1.inlineCodeSnippet, children: "public" }), " folder of your project or drag and drop a file here."] }) })) : ((0, jsx_runtime_1.jsx)("div", { style: emptyState, children: (0, jsx_runtime_1.jsxs)("div", { style: label, children: ["To add assets, create a folder called", ' ', (0, jsx_runtime_1.jsx)("code", { style: styles_1.inlineCodeSnippet, children: "public" }), " in the root of your project and place a file in it."] }) }))) : ((0, jsx_runtime_1.jsx)("div", { className: "__remotion-vertical-scrollbar", style: {
...list,
backgroundColor: isDropDiv ? colors_1.CLEAR_HOVER : colors_1.BACKGROUND,
}, onDragEnter: onDragEnter, onDragLeave: onDragLeave, children: (0, jsx_runtime_1.jsx)(AssetSelectorItem_1.AssetFolderTree, { item: assetTree, level: 0, parentFolder: null, name: null, tabIndex: tabIndex, toggleFolder: toggleFolder, dropLocation: dropLocation, setDropLocation: setDropLocation }) })) }));
};
exports.AssetSelector = AssetSelector;
@@ -0,0 +1,12 @@
import React from 'react';
import type { AssetStructure } from '../helpers/create-folder-tree';
export declare const AssetFolderTree: React.FC<{
readonly item: AssetStructure;
readonly name: string | null;
readonly parentFolder: string | null;
readonly level: number;
readonly tabIndex: number;
readonly toggleFolder: (folderName: string, parentName: string | null) => void;
readonly dropLocation: string | null;
readonly setDropLocation: React.Dispatch<React.SetStateAction<string | null>>;
}>;
@@ -0,0 +1,237 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AssetFolderTree = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = __importStar(require("react"));
const remotion_1 = require("remotion");
const no_react_1 = require("remotion/no-react");
const colors_1 = require("../helpers/colors");
const copy_text_1 = require("../helpers/copy-text");
const mobile_layout_1 = require("../helpers/mobile-layout");
const url_state_1 = require("../helpers/url-state");
const use_asset_drag_events_1 = __importDefault(require("../helpers/use-asset-drag-events"));
const clipboard_1 = require("../icons/clipboard");
const file_1 = require("../icons/file");
const folder_1 = require("../icons/folder");
const sidebar_1 = require("../state/sidebar");
const InlineAction_1 = require("./InlineAction");
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
const actions_1 = require("./RenderQueue/actions");
const layout_1 = require("./layout");
const ASSET_ITEM_HEIGHT = 32;
const iconStyle = {
width: 18,
height: 18,
flexShrink: 0,
};
const itemStyle = {
paddingRight: 10,
paddingTop: 6,
paddingBottom: 6,
fontSize: 13,
display: 'flex',
textDecoration: 'none',
cursor: 'default',
alignItems: 'center',
marginBottom: 1,
appearance: 'none',
border: 'none',
width: '100%',
textAlign: 'left',
backgroundColor: colors_1.BACKGROUND,
height: ASSET_ITEM_HEIGHT,
userSelect: 'none',
WebkitUserSelect: 'none',
};
const labelStyle = {
textAlign: 'left',
textDecoration: 'none',
fontSize: 13,
flex: '1 1 0%',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
};
const revealIconStyle = {
height: 12,
color: 'currentColor',
};
const AssetFolderItem = ({ tabIndex, item, level, parentFolder, toggleFolder, dropLocation, setDropLocation, }) => {
const [hovered, setHovered] = (0, react_1.useState)(false);
const openFolderTimerRef = (0, react_1.useRef)(null);
const { isDropDiv, onDragEnter, onDragLeave } = (0, use_asset_drag_events_1.default)({
name: item.name,
parentFolder,
dropLocation,
setDropLocation,
});
const onPointerEnter = (0, react_1.useCallback)(() => {
setHovered(true);
}, []);
const onPointerLeave = (0, react_1.useCallback)(() => {
setHovered(false);
}, []);
const folderStyle = (0, react_1.useMemo)(() => {
return {
...itemStyle,
paddingLeft: 4 + level * 8,
backgroundColor: hovered ? colors_1.CLEAR_HOVER : 'transparent',
};
}, [hovered, level]);
const label = (0, react_1.useMemo)(() => {
return {
...labelStyle,
color: hovered ? 'white' : colors_1.LIGHT_TEXT,
};
}, [hovered]);
const onClick = (0, react_1.useCallback)(() => {
toggleFolder(item.name, parentFolder);
}, [item.name, parentFolder, toggleFolder]);
const Icon = item.expanded ? folder_1.ExpandedFolderIcon : folder_1.CollapsedFolderIcon;
return ((0, jsx_runtime_1.jsxs)("div", { onDragEnter: onDragEnter, onDragLeave: onDragLeave, style: {
backgroundColor: isDropDiv ? colors_1.CLEAR_HOVER : colors_1.BACKGROUND,
}, children: [(0, jsx_runtime_1.jsx)("div", { style: folderStyle, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, tabIndex: tabIndex, title: item.name, onClick: onClick, onDragEnter: () => {
if (!item.expanded) {
openFolderTimerRef.current = window.setTimeout(() => {
toggleFolder(item.name, parentFolder);
}, 1000);
}
}, onDragLeave: () => {
if (openFolderTimerRef.current) {
clearTimeout(openFolderTimerRef.current);
}
}, children: (0, jsx_runtime_1.jsxs)(layout_1.Row, { children: [(0, jsx_runtime_1.jsx)(Icon, { style: iconStyle, color: hovered ? 'white' : colors_1.LIGHT_TEXT }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, jsx_runtime_1.jsx)("div", { style: label, children: item.name })] }) }), item.expanded ? ((0, jsx_runtime_1.jsx)(exports.AssetFolderTree, { item: item.items, name: item.name, level: level, parentFolder: parentFolder, tabIndex: tabIndex, toggleFolder: toggleFolder, dropLocation: dropLocation, setDropLocation: setDropLocation }, item.name)) : null] }));
};
const AssetFolderTree = ({ item, level, name, parentFolder, toggleFolder, tabIndex, dropLocation, setDropLocation, }) => {
const combinedParents = (0, react_1.useMemo)(() => {
return [parentFolder, name].filter(no_react_1.NoReactInternals.truthy).join('/');
}, [name, parentFolder]);
return ((0, jsx_runtime_1.jsxs)("div", { children: [item.folders.map((folder) => {
return ((0, jsx_runtime_1.jsx)(AssetFolderItem, { item: folder, tabIndex: tabIndex, level: level + 1, parentFolder: combinedParents, toggleFolder: toggleFolder, dropLocation: dropLocation, setDropLocation: setDropLocation }, folder.name));
}), item.files.map((file) => {
return ((0, jsx_runtime_1.jsx)(AssetSelectorItem, { item: file, tabIndex: tabIndex, level: level, parentFolder: combinedParents }, file.src));
})] }));
};
exports.AssetFolderTree = AssetFolderTree;
const AssetSelectorItem = ({ item, tabIndex, level, parentFolder }) => {
const isMobileLayout = (0, mobile_layout_1.useMobileLayout)();
const [hovered, setHovered] = (0, react_1.useState)(false);
const { setSidebarCollapsedState } = (0, react_1.useContext)(sidebar_1.SidebarContext);
const onPointerEnter = (0, react_1.useCallback)(() => {
setHovered(true);
}, []);
const { setCanvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionSetters);
const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
const selected = (0, react_1.useMemo)(() => {
if (canvasContent && canvasContent.type === 'asset') {
const nameWOParent = canvasContent.asset.split('/').pop();
return nameWOParent === item.name;
}
return false;
}, [canvasContent, item.name]);
const onPointerLeave = (0, react_1.useCallback)(() => {
setHovered(false);
}, []);
const onClick = (0, react_1.useCallback)(() => {
const relativePath = parentFolder
? parentFolder + '/' + item.name
: item.name;
setCanvasContent({ type: 'asset', asset: relativePath });
(0, url_state_1.pushUrl)(`/assets/${relativePath}`);
if (isMobileLayout) {
setSidebarCollapsedState({ left: 'collapsed', right: 'collapsed' });
}
}, [
isMobileLayout,
item.name,
parentFolder,
setCanvasContent,
setSidebarCollapsedState,
]);
const style = (0, react_1.useMemo)(() => {
return {
...itemStyle,
color: hovered || selected ? 'white' : colors_1.LIGHT_TEXT,
backgroundColor: hovered
? selected
? colors_1.SELECTED_BACKGROUND
: colors_1.CLEAR_HOVER
: selected
? colors_1.SELECTED_BACKGROUND
: 'transparent',
paddingLeft: 12 + level * 8,
};
}, [hovered, level, selected]);
const label = (0, react_1.useMemo)(() => {
return {
...labelStyle,
color: hovered || selected ? 'white' : colors_1.LIGHT_TEXT,
};
}, [hovered, selected]);
const renderFileExplorerAction = (0, react_1.useCallback)((color) => {
return (0, jsx_runtime_1.jsx)(folder_1.ExpandedFolderIcon, { style: revealIconStyle, color: color });
}, []);
const renderCopyAction = (0, react_1.useCallback)((color) => {
return (0, jsx_runtime_1.jsx)(clipboard_1.ClipboardIcon, { style: revealIconStyle, color: color });
}, []);
const revealInExplorer = react_1.default.useCallback((e) => {
e.stopPropagation();
(0, actions_1.openInFileExplorer)({
directory: window.remotion_publicFolderExists +
'/' +
parentFolder +
'/' +
item.name,
}).catch((err) => {
(0, NotificationCenter_1.showNotification)(`Could not open file: ${err.message}`, 2000);
});
}, [item.name, parentFolder]);
const copyToClipboard = (0, react_1.useCallback)((e) => {
e.stopPropagation();
const content = `staticFile("${[parentFolder, item.name].join('/')}")`;
(0, copy_text_1.copyText)(content)
.then(() => {
(0, NotificationCenter_1.showNotification)(`Copied '${content}' to clipboard`, 1000);
})
.catch((err) => {
(0, NotificationCenter_1.showNotification)(`Could not copy: ${err.message}`, 2000);
});
}, [item.name, parentFolder]);
return ((0, jsx_runtime_1.jsx)(layout_1.Row, { align: "center", children: (0, jsx_runtime_1.jsxs)("div", { style: style, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, onClick: onClick, tabIndex: tabIndex, title: item.name, children: [(0, jsx_runtime_1.jsx)(file_1.FileIcon, { style: iconStyle, color: colors_1.LIGHT_TEXT }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, jsx_runtime_1.jsx)("div", { style: label, children: item.name }), hovered ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.5 }), (0, jsx_runtime_1.jsx)(InlineAction_1.InlineAction, { title: "Copy staticFile() name", renderAction: renderCopyAction, onClick: copyToClipboard }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.5 }), (0, jsx_runtime_1.jsx)(InlineAction_1.InlineAction, { title: "Open in Explorer", renderAction: renderFileExplorerAction, onClick: revealInExplorer })] })) : null] }) }));
};
@@ -0,0 +1,10 @@
import React from 'react';
export declare const AudioWaveform: React.FC<{
readonly src: string;
readonly visualizationWidth: number;
readonly startFrom: number;
readonly durationInFrames: number;
readonly volume: string | number;
readonly doesVolumeChange: boolean;
readonly playbackRate: number;
}>;
@@ -0,0 +1,122 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AudioWaveform = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const media_utils_1 = require("@remotion/media-utils");
const react_1 = require("react");
const remotion_1 = require("remotion");
const colors_1 = require("../helpers/colors");
const timeline_layout_1 = require("../helpers/timeline-layout");
const AudioWaveformBar_1 = require("./AudioWaveformBar");
const container = {
display: 'flex',
flexDirection: 'row',
alignItems: 'flex-end',
position: 'absolute',
height: (0, timeline_layout_1.getTimelineLayerHeight)('other'),
};
const errorMessage = {
fontSize: 13,
paddingTop: 6,
paddingBottom: 6,
paddingLeft: 12,
paddingRight: 12,
alignSelf: 'flex-start',
maxWidth: 450,
opacity: 0.75,
};
const canvasStyle = {
position: 'absolute',
};
const AudioWaveform = ({ src, startFrom, durationInFrames, visualizationWidth, volume, doesVolumeChange, playbackRate, }) => {
const [metadata, setMetadata] = (0, react_1.useState)(null);
const [error, setError] = (0, react_1.useState)(null);
const mountState = (0, react_1.useRef)({ isMounted: true });
const vidConf = remotion_1.Internals.useUnsafeVideoConfig();
if (vidConf === null) {
throw new Error('Expected video config');
}
const canvas = (0, react_1.useRef)(null);
(0, react_1.useEffect)(() => {
const { current } = mountState;
current.isMounted = true;
return () => {
current.isMounted = false;
};
}, []);
(0, react_1.useEffect)(() => {
if (!canvas.current) {
return;
}
const context = canvas.current.getContext('2d');
if (!context) {
return;
}
context.clearRect(0, 0, visualizationWidth, (0, timeline_layout_1.getTimelineLayerHeight)('other'));
if (!doesVolumeChange || typeof volume === 'number') {
// The volume is a number, meaning it could change on each frame-
// User did not use the (f: number) => number syntax, so we can't draw
// a visualization.
return;
}
const volumes = volume.split(',').map((v) => Number(v));
context.beginPath();
context.moveTo(0, (0, timeline_layout_1.getTimelineLayerHeight)('other'));
volumes.forEach((v, index) => {
const x = (index / (volumes.length - 1)) * visualizationWidth;
const y = (1 - v) * ((0, timeline_layout_1.getTimelineLayerHeight)('other') - timeline_layout_1.TIMELINE_BORDER * 2) + 1;
if (index === 0) {
context.moveTo(x, y);
}
else {
context.lineTo(x, y);
}
});
context.strokeStyle = colors_1.LIGHT_TRANSPARENT;
context.stroke();
}, [visualizationWidth, metadata, startFrom, volume, doesVolumeChange]);
(0, react_1.useEffect)(() => {
setError(null);
(0, media_utils_1.getAudioData)(src)
.then((data) => {
if (mountState.current.isMounted) {
setMetadata(data);
}
})
.catch((err) => {
if (mountState.current.isMounted) {
setError(err);
}
});
}, [src, vidConf.fps]);
const normalized = (0, react_1.useMemo)(() => {
if (!metadata || metadata.numberOfChannels === 0) {
return [];
}
const numberOfSamples = Math.floor(visualizationWidth / (AudioWaveformBar_1.WAVEFORM_BAR_LENGTH + AudioWaveformBar_1.WAVEFORM_BAR_MARGIN));
return (0, media_utils_1.getWaveformPortion)({
audioData: metadata,
startTimeInSeconds: startFrom / vidConf.fps,
durationInSeconds: Math.min((durationInFrames / vidConf.fps) * playbackRate, metadata.durationInSeconds),
numberOfSamples,
normalize: false,
});
}, [
durationInFrames,
vidConf.fps,
metadata,
playbackRate,
startFrom,
visualizationWidth,
]);
if (error) {
return ((0, jsx_runtime_1.jsx)("div", { style: container, children: (0, jsx_runtime_1.jsx)("div", { style: errorMessage, children: "No waveform available. Audio might not support CORS." }) }));
}
if (!metadata) {
return null;
}
return ((0, jsx_runtime_1.jsxs)("div", { style: container, children: [normalized.map((w) => {
return ((0, jsx_runtime_1.jsx)(AudioWaveformBar_1.AudioWaveformBar, { amplitude: w.amplitude * (typeof volume === 'number' ? volume : 1) }, w.index));
}), (0, jsx_runtime_1.jsx)("canvas", { ref: canvas, style: canvasStyle, width: visualizationWidth, height: (0, timeline_layout_1.getTimelineLayerHeight)('other') })] }));
};
exports.AudioWaveform = AudioWaveform;
@@ -0,0 +1,14 @@
import React from 'react';
export declare const WAVEFORM_BAR_LENGTH = 2;
export declare const WAVEFORM_BAR_MARGIN = 1;
/**
*
* consider a sinus wave with an amplitude going from [-1, 1].
* if we sample it infinitely, and convert all negative samples from negative to positive
* what is the average of all samples?
*
* Answer: 2 / Math.PI = 0.6366
*/
export declare const AudioWaveformBar: React.FC<{
readonly amplitude: number;
}>;
@@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AudioWaveformBar = exports.WAVEFORM_BAR_MARGIN = exports.WAVEFORM_BAR_LENGTH = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const timeline_layout_1 = require("../helpers/timeline-layout");
exports.WAVEFORM_BAR_LENGTH = 2;
exports.WAVEFORM_BAR_MARGIN = 1;
const container = {
width: exports.WAVEFORM_BAR_LENGTH,
backgroundColor: 'rgba(255, 255, 255, 0.6)',
marginLeft: exports.WAVEFORM_BAR_MARGIN,
borderRadius: 2,
};
// Sonnet:
/**
*
* consider a sinus wave with an amplitude going from [-1, 1].
* if we sample it infinitely, and convert all negative samples from negative to positive
* what is the average of all samples?
*
* Answer: 2 / Math.PI = 0.6366
*/
const AudioWaveformBar = ({ amplitude }) => {
const style = (0, react_1.useMemo)(() => {
return {
...container,
height: (0, timeline_layout_1.getTimelineLayerHeight)('other') * amplitude * (1 / 0.6366),
};
}, [amplitude]);
return (0, jsx_runtime_1.jsx)("div", { style: style });
};
exports.AudioWaveformBar = AudioWaveformBar;
@@ -0,0 +1,12 @@
import React from 'react';
export type ButtonProps = {
readonly onClick: () => void;
readonly disabled?: boolean;
readonly children: React.ReactNode;
readonly style?: React.CSSProperties;
readonly buttonContainerStyle?: React.CSSProperties;
readonly autoFocus?: boolean;
readonly title?: string;
readonly id?: string;
};
export declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Button = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const colors_1 = require("../helpers/colors");
const button = {
border: `1px solid ${colors_1.INPUT_BORDER_COLOR_UNHOVERED}`,
borderRadius: 4,
backgroundColor: colors_1.INPUT_BACKGROUND,
appearance: 'none',
fontFamily: 'inherit',
fontSize: 14,
color: 'white',
flexDirection: 'row',
};
const ButtonRefForwardFunction = ({ children, onClick, title, disabled, style, id, autoFocus, buttonContainerStyle, }, ref) => {
const combined = (0, react_1.useMemo)(() => {
return {
...button,
...(style !== null && style !== void 0 ? style : {}),
};
}, [style]);
const buttonContainer = (0, react_1.useMemo)(() => {
return {
padding: 10,
cursor: disabled ? 'inherit' : 'pointer',
fontSize: 14,
opacity: disabled ? 0.7 : 1,
...(buttonContainerStyle !== null && buttonContainerStyle !== void 0 ? buttonContainerStyle : {}),
};
}, [buttonContainerStyle, disabled]);
return ((0, jsx_runtime_1.jsx)("button", { ref: ref, id: id, style: combined, type: "button", disabled: disabled, onClick: onClick, autoFocus: autoFocus, title: title, children: (0, jsx_runtime_1.jsx)("div", { className: "css-reset", style: buttonContainer, children: children }) }));
};
exports.Button = (0, react_1.forwardRef)(ButtonRefForwardFunction);
@@ -0,0 +1,7 @@
import type { Size } from '@remotion/player';
import React from 'react';
import type { CanvasContent } from 'remotion';
export declare const Canvas: React.FC<{
readonly canvasContent: CanvasContent;
readonly size: Size;
}>;
@@ -0,0 +1,267 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Canvas = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const remotion_1 = require("remotion");
const colors_1 = require("../helpers/colors");
const get_asset_metadata_1 = require("../helpers/get-asset-metadata");
const get_effective_translation_1 = require("../helpers/get-effective-translation");
const smooth_zoom_1 = require("../helpers/smooth-zoom");
const use_keybinding_1 = require("../helpers/use-keybinding");
const canvas_ref_1 = require("../state/canvas-ref");
const editor_guides_1 = require("../state/editor-guides");
const editor_zoom_gestures_1 = require("../state/editor-zoom-gestures");
const EditorGuides_1 = __importDefault(require("./EditorGuides"));
const EditorRuler_1 = require("./EditorRuler");
const use_is_ruler_visible_1 = require("./EditorRuler/use-is-ruler-visible");
const Preview_1 = require("./Preview");
const ResetZoomButton_1 = require("./ResetZoomButton");
const layout_1 = require("./layout");
const container = {
flex: 1,
display: 'flex',
overflow: 'hidden',
position: 'relative',
backgroundColor: colors_1.BACKGROUND,
};
const resetZoom = {
position: 'absolute',
top: layout_1.SPACING_UNIT * 2,
right: layout_1.SPACING_UNIT * 2,
};
const ZOOM_PX_FACTOR = 0.003;
const Canvas = ({ canvasContent, size }) => {
const { setSize, size: previewSize } = (0, react_1.useContext)(remotion_1.Internals.PreviewSizeContext);
const { editorZoomGestures } = (0, react_1.useContext)(editor_zoom_gestures_1.EditorZoomGesturesContext);
const keybindings = (0, use_keybinding_1.useKeybinding)();
const config = remotion_1.Internals.useUnsafeVideoConfig();
const areRulersVisible = (0, use_is_ruler_visible_1.useIsRulerVisible)();
const { editorShowGuides } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
const [assetResolution, setAssetResolution] = (0, react_1.useState)(null);
const contentDimensions = (0, react_1.useMemo)(() => {
if ((canvasContent.type === 'asset' ||
canvasContent.type === 'output' ||
canvasContent.type === 'output-blob') &&
assetResolution &&
assetResolution.type === 'found') {
return assetResolution.dimensions;
}
if (config) {
return { width: config.width, height: config.height };
}
return null;
}, [assetResolution, config, canvasContent]);
const isFit = previewSize.size === 'auto';
const onWheel = (0, react_1.useCallback)((e) => {
if (!editorZoomGestures) {
return;
}
if (!size) {
return;
}
if (!contentDimensions || contentDimensions === 'none') {
return;
}
const wantsToZoom = e.ctrlKey || e.metaKey;
if (!wantsToZoom && isFit) {
return;
}
e.preventDefault();
setSize((prevSize) => {
const scale = remotion_1.Internals.calculateScale({
canvasSize: size,
compositionHeight: contentDimensions.height,
compositionWidth: contentDimensions.width,
previewSize: prevSize.size,
});
// Zoom in/out
if (wantsToZoom) {
const oldSize = prevSize.size === 'auto' ? scale : prevSize.size;
const smoothened = (0, smooth_zoom_1.smoothenZoom)(oldSize);
const added = smoothened + e.deltaY * ZOOM_PX_FACTOR;
const unsmoothened = (0, smooth_zoom_1.unsmoothenZoom)(added);
const { centerX, centerY } = (0, get_effective_translation_1.getCenterPointWhileScrolling)({
size,
clientX: e.clientX,
clientY: e.clientY,
compositionWidth: contentDimensions.width,
compositionHeight: contentDimensions.height,
scale,
translation: prevSize.translation,
});
const zoomDifference = unsmoothened - oldSize;
const uvCoordinatesX = centerX / contentDimensions.width;
const uvCoordinatesY = centerY / contentDimensions.height;
const correctionLeft = -uvCoordinatesX * (zoomDifference * contentDimensions.width) +
(1 - uvCoordinatesX) * zoomDifference * contentDimensions.width;
const correctionTop = -uvCoordinatesY * (zoomDifference * contentDimensions.height) +
(1 - uvCoordinatesY) * zoomDifference * contentDimensions.height;
return {
translation: (0, get_effective_translation_1.getEffectiveTranslation)({
translation: {
x: prevSize.translation.x - correctionLeft / 2,
y: prevSize.translation.y - correctionTop / 2,
},
canvasSize: size,
compositionHeight: contentDimensions.height,
compositionWidth: contentDimensions.width,
scale,
}),
size: unsmoothened,
};
}
const effectiveTranslation = (0, get_effective_translation_1.getEffectiveTranslation)({
translation: prevSize.translation,
canvasSize: size,
compositionHeight: contentDimensions.height,
compositionWidth: contentDimensions.width,
scale,
});
// Pan
return {
...prevSize,
translation: (0, get_effective_translation_1.getEffectiveTranslation)({
translation: {
x: effectiveTranslation.x + e.deltaX,
y: effectiveTranslation.y + e.deltaY,
},
canvasSize: size,
compositionHeight: contentDimensions.height,
compositionWidth: contentDimensions.width,
scale,
}),
};
});
}, [editorZoomGestures, contentDimensions, isFit, setSize, size]);
(0, react_1.useEffect)(() => {
const { current } = canvas_ref_1.canvasRef;
if (!current) {
return;
}
current.addEventListener('wheel', onWheel, { passive: false });
return () =>
// @ts-expect-error
current.removeEventListener('wheel', onWheel, {
passive: false,
});
}, [onWheel]);
const onReset = (0, react_1.useCallback)(() => {
setSize(() => {
return {
translation: {
x: 0,
y: 0,
},
size: 'auto',
};
});
}, [setSize]);
const onZoomIn = (0, react_1.useCallback)(() => {
if (!contentDimensions || contentDimensions === 'none') {
return;
}
if (!size) {
return;
}
setSize((prevSize) => {
const scale = remotion_1.Internals.calculateScale({
canvasSize: size,
compositionHeight: contentDimensions.height,
compositionWidth: contentDimensions.width,
previewSize: prevSize.size,
});
return {
translation: {
x: 0,
y: 0,
},
size: Math.min(smooth_zoom_1.MAX_ZOOM, scale * 2),
};
});
}, [contentDimensions, setSize, size]);
const onZoomOut = (0, react_1.useCallback)(() => {
if (!contentDimensions || contentDimensions === 'none') {
return;
}
if (!size) {
return;
}
setSize((prevSize) => {
const scale = remotion_1.Internals.calculateScale({
canvasSize: size,
compositionHeight: contentDimensions.height,
compositionWidth: contentDimensions.width,
previewSize: prevSize.size,
});
return {
translation: {
x: 0,
y: 0,
},
size: Math.max(smooth_zoom_1.MIN_ZOOM, scale / 2),
};
});
}, [contentDimensions, setSize, size]);
(0, react_1.useEffect)(() => {
const resetBinding = keybindings.registerKeybinding({
event: 'keydown',
key: '0',
commandCtrlKey: false,
callback: onReset,
preventDefault: true,
triggerIfInputFieldFocused: false,
keepRegisteredWhenNotHighestContext: false,
});
const zoomIn = keybindings.registerKeybinding({
event: 'keydown',
key: '+',
commandCtrlKey: false,
callback: onZoomIn,
preventDefault: true,
triggerIfInputFieldFocused: false,
keepRegisteredWhenNotHighestContext: false,
});
const zoomOut = keybindings.registerKeybinding({
event: 'keydown',
key: '-',
commandCtrlKey: false,
callback: onZoomOut,
preventDefault: true,
triggerIfInputFieldFocused: false,
keepRegisteredWhenNotHighestContext: false,
});
return () => {
resetBinding.unregister();
zoomIn.unregister();
zoomOut.unregister();
};
}, [keybindings, onReset, onZoomIn, onZoomOut]);
const fetchMetadata = (0, react_1.useCallback)(async () => {
setAssetResolution(null);
if (canvasContent.type === 'composition') {
return;
}
const metadata = await (0, get_asset_metadata_1.getAssetMetadata)(canvasContent, canvasContent.type === 'asset');
setAssetResolution(metadata);
}, [canvasContent]);
(0, react_1.useEffect)(() => {
if (canvasContent.type !== 'asset') {
return;
}
const file = (0, remotion_1.watchStaticFile)(canvasContent.asset, () => {
fetchMetadata();
});
return () => {
file.cancel();
};
}, [canvasContent, fetchMetadata]);
(0, react_1.useEffect)(() => {
fetchMetadata();
}, [fetchMetadata]);
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { ref: canvas_ref_1.canvasRef, style: container, children: [size ? ((0, jsx_runtime_1.jsx)(Preview_1.VideoPreview, { canvasContent: canvasContent, contentDimensions: contentDimensions, canvasSize: size, assetMetadata: assetResolution })) : 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 }) })), editorShowGuides && canvasContent.type === 'composition' && ((0, jsx_runtime_1.jsx)(EditorGuides_1.default, { canvasSize: size, contentDimensions: contentDimensions, assetMetadata: assetResolution }))] }), areRulersVisible && ((0, jsx_runtime_1.jsx)(EditorRuler_1.EditorRulers, { contentDimensions: contentDimensions, canvasSize: size, assetMetadata: assetResolution, containerRef: canvas_ref_1.canvasRef }))] }));
};
exports.Canvas = Canvas;
@@ -0,0 +1 @@
export declare const CanvasIfSizeIsAvailable: React.FC;
@@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CanvasIfSizeIsAvailable = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const remotion_1 = require("remotion");
const editor_rulers_1 = require("../state/editor-rulers");
const CanvasOrLoading_1 = require("./CanvasOrLoading");
const use_is_ruler_visible_1 = require("./EditorRuler/use-is-ruler-visible");
const CanvasIfSizeIsAvailable = () => {
const rulersAreVisible = (0, use_is_ruler_visible_1.useIsRulerVisible)();
const context = (0, react_1.useContext)(remotion_1.Internals.CurrentScaleContext);
const sizeWithRulersApplied = (0, react_1.useMemo)(() => {
const size = context && context.type === 'canvas-size' ? context.canvasSize : null;
if (!rulersAreVisible) {
return size;
}
if (!size) {
return null;
}
return {
...size,
width: size.width - editor_rulers_1.RULER_WIDTH,
height: size.height - editor_rulers_1.RULER_WIDTH,
};
}, [context, rulersAreVisible]);
if (!sizeWithRulersApplied) {
return null;
}
return (0, jsx_runtime_1.jsx)(CanvasOrLoading_1.CanvasOrLoading, { size: sizeWithRulersApplied });
};
exports.CanvasIfSizeIsAvailable = CanvasIfSizeIsAvailable;
@@ -0,0 +1,5 @@
import type { Size } from '@remotion/player';
import React from 'react';
export declare const CanvasOrLoading: React.FC<{
readonly size: Size;
}>;
@@ -0,0 +1,77 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CanvasOrLoading = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const remotion_1 = require("remotion");
const ErrorLoader_1 = require("../error-overlay/remotion-overlay/ErrorLoader");
const colors_1 = require("../helpers/colors");
const timeline_zoom_1 = require("../state/timeline-zoom");
const Canvas_1 = require("./Canvas");
const FramePersistor_1 = require("./FramePersistor");
const is_menu_item_1 = require("./Menu/is-menu-item");
const RefreshCompositionOverlay_1 = require("./RefreshCompositionOverlay");
const RunningCalculateMetadata_1 = require("./RunningCalculateMetadata");
const imperative_state_1 = require("./Timeline/imperative-state");
const timeline_scroll_logic_1 = require("./Timeline/timeline-scroll-logic");
const ZoomPersistor_1 = require("./ZoomPersistor");
const container = {
color: 'white',
flex: 1,
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
backgroundColor: colors_1.BACKGROUND,
flexDirection: 'column',
};
const CanvasOrLoading = ({ size }) => {
const resolved = remotion_1.Internals.useResolvedVideoConfig(null);
const { setZoom } = (0, react_1.useContext)(timeline_zoom_1.TimelineZoomCtx);
const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
(0, react_1.useEffect)(() => {
if ((resolved === null || resolved === void 0 ? void 0 : resolved.type) !== 'success' &&
(resolved === null || resolved === void 0 ? void 0 : resolved.type) !== 'success-and-refreshing') {
return;
}
const c = resolved.result;
setTimeout(() => {
(0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
direction: 'center',
frame: (0, imperative_state_1.getCurrentFrame)(),
durationInFrames: c.durationInFrames,
});
});
}, [resolved, setZoom]);
if (!canvasContent) {
const compname = window.location.pathname.replace('/', '');
return ((0, jsx_runtime_1.jsx)("div", { style: container, className: "css-reset", children: (0, jsx_runtime_1.jsxs)("div", { style: RunningCalculateMetadata_1.loaderLabel, children: ["Composition with ID ", compname, " not found."] }) }));
}
const content = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ZoomPersistor_1.ZoomPersistor, {}), (0, jsx_runtime_1.jsx)(Canvas_1.Canvas, { size: size, canvasContent: canvasContent }), (resolved === null || resolved === void 0 ? void 0 : resolved.type) === 'success-and-refreshing' ? ((0, jsx_runtime_1.jsx)(RefreshCompositionOverlay_1.RefreshCompositionOverlay, {})) : null] }));
if (canvasContent.type === 'asset' ||
canvasContent.type === 'output' ||
canvasContent.type === 'output-blob') {
return content;
}
if (!resolved) {
return null;
}
if (resolved.type === 'loading') {
return ((0, jsx_runtime_1.jsx)("div", { style: container, className: "css-reset", children: (0, jsx_runtime_1.jsx)(RunningCalculateMetadata_1.RunningCalculateMetadata, {}) }));
}
if (resolved.type === 'error') {
return (0, jsx_runtime_1.jsx)(ErrorLoading, { error: resolved.error });
}
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(FramePersistor_1.FramePersistor, {}), " ", content] }));
};
exports.CanvasOrLoading = CanvasOrLoading;
const loaderContainer = {
marginLeft: 'auto',
marginRight: 'auto',
width: '100%',
position: 'absolute',
height: '100%',
overflowY: 'auto',
};
const ErrorLoading = ({ error }) => {
return ((0, jsx_runtime_1.jsx)("div", { style: loaderContainer, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: (0, jsx_runtime_1.jsx)(ErrorLoader_1.ErrorLoader, { canHaveDismissButton: false, keyboardShortcuts: false, error: error, onRetry: () => { var _a; return (_a = remotion_1.Internals.resolveCompositionsRef.current) === null || _a === void 0 ? void 0 : _a.reloadCurrentlySelectedComposition(); }, calculateMetadata: true }, error.stack) }));
};
@@ -0,0 +1,2 @@
import React from 'react';
export declare const CheckboardToggle: React.FC;
@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CheckboardToggle = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const no_react_1 = require("remotion/no-react");
const colors_1 = require("../helpers/colors");
const use_keybinding_1 = require("../helpers/use-keybinding");
const checkerboard_1 = require("../state/checkerboard");
const ControlButton_1 = require("./ControlButton");
const accessibilityLabel = [
'Show transparency as checkerboard',
(0, use_keybinding_1.areKeyboardShortcutsDisabled)() ? null : '(T)',
]
.filter(no_react_1.NoReactInternals.truthy)
.join(' ');
const CheckboardToggle = () => {
const { checkerboard, setCheckerboard } = (0, react_1.useContext)(checkerboard_1.CheckerboardContext);
const onClick = (0, react_1.useCallback)(() => {
setCheckerboard((c) => {
return !c;
});
}, [setCheckerboard]);
return ((0, jsx_runtime_1.jsx)(ControlButton_1.ControlButton, { title: accessibilityLabel, "aria-label": accessibilityLabel, onClick: onClick, children: (0, jsx_runtime_1.jsx)("svg", { "aria-hidden": "true", focusable: "false", "data-prefix": "fas", "data-icon": "game-board-alt", className: "svg-inline--fa fa-game-board-alt fa-w-16", role: "img", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 512 512", style: { width: 16, height: 16 }, children: (0, jsx_runtime_1.jsx)("path", { fill: checkerboard ? colors_1.BLUE : 'white', d: "M480 0H32A32 32 0 0 0 0 32v448a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32V32a32 32 0 0 0-32-32zm-32 256H256v192H64V256h192V64h192z" }) }) }));
};
exports.CheckboardToggle = CheckboardToggle;
@@ -0,0 +1,8 @@
import React from 'react';
export declare const Checkbox: React.FC<{
readonly checked: boolean;
readonly onChange: React.ChangeEventHandler<HTMLInputElement>;
readonly name: string;
readonly rounded?: boolean;
readonly disabled?: boolean;
}>;
@@ -0,0 +1,54 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Checkbox = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const colors_1 = require("../helpers/colors");
const Checkmark_1 = require("../icons/Checkmark");
const size = 20;
const background = {
height: size,
width: size,
position: 'relative',
};
const bullet = {
width: 10,
height: 10,
backgroundColor: colors_1.LIGHT_TEXT,
borderRadius: '50%',
};
const box = {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
position: 'absolute',
height: size,
width: size,
top: 0,
left: 0,
pointerEvents: 'none',
color: 'white',
};
const Checkbox = ({ checked, onChange, disabled, name, rounded }) => {
const ref = (0, react_1.useRef)(null);
const input = (0, react_1.useMemo)(() => {
return {
appearance: 'none',
background: disabled ? 'transparent' : colors_1.INPUT_BACKGROUND,
border: '1px solid ' + colors_1.INPUT_BORDER_COLOR_UNHOVERED,
height: size,
width: size,
top: 0,
left: 0,
position: 'absolute',
margin: 0,
};
}, [disabled]);
(0, react_1.useEffect)(() => {
if (ref.current) {
ref.current.style.setProperty('border-radius', rounded ? '50%' : '0%', 'important');
}
}, [rounded]);
return ((0, jsx_runtime_1.jsxs)("div", { style: background, children: [(0, jsx_runtime_1.jsx)("input", { ref: ref, style: input, type: 'checkbox', checked: checked, onChange: onChange, disabled: disabled, name: name }), (0, jsx_runtime_1.jsx)("div", { style: box, children: checked ? rounded ? (0, jsx_runtime_1.jsx)("div", { style: bullet }) : (0, jsx_runtime_1.jsx)(Checkmark_1.Checkmark, {}) : null })] }));
};
exports.Checkbox = Checkbox;
@@ -0,0 +1,4 @@
import React from 'react';
export declare const CheckerboardProvider: React.FC<{
readonly children: React.ReactNode;
}>;
@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CheckerboardProvider = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const checkerboard_1 = require("../state/checkerboard");
const CheckerboardProvider = ({ children }) => {
const [checkerboard, setCheckerboardState] = (0, react_1.useState)(() => (0, checkerboard_1.loadCheckerboardOption)());
const setCheckerboard = (0, react_1.useCallback)((newValue) => {
setCheckerboardState((prevState) => {
const newVal = newValue(prevState);
(0, checkerboard_1.persistCheckerboardOption)(newVal);
return newVal;
});
}, []);
const checkerboardCtx = (0, react_1.useMemo)(() => {
return {
checkerboard,
setCheckerboard,
};
}, [checkerboard, setCheckerboard]);
return ((0, jsx_runtime_1.jsx)(checkerboard_1.CheckerboardContext.Provider, { value: checkerboardCtx, children: children }));
};
exports.CheckerboardProvider = CheckerboardProvider;
@@ -0,0 +1,4 @@
import type React from 'react';
export declare const CompSelectorRef: React.FC<{
readonly children: React.ReactNode;
}>;
@@ -0,0 +1,82 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CompSelectorRef = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const remotion_1 = require("remotion");
const persist_open_folders_1 = require("../helpers/persist-open-folders");
const InitialCompositionLoader_1 = require("./InitialCompositionLoader");
const CompSelectorRef = ({ children }) => {
const { compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
const [foldersExpanded, setFoldersExpanded] = (0, react_1.useState)((0, persist_open_folders_1.loadExpandedFolders)('compositions'));
const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
const toggleFolder = (0, react_1.useCallback)((folderName, parentName) => {
setFoldersExpanded((p) => {
var _a;
const key = (0, persist_open_folders_1.openFolderKey)({ folderName, parentName });
const prev = (_a = p[key]) !== null && _a !== void 0 ? _a : false;
const foldersExpandedState = {
...p,
[key]: !prev,
};
(0, persist_open_folders_1.persistExpandedFolders)('compositions', foldersExpandedState);
return foldersExpandedState;
});
}, []);
(0, react_1.useImperativeHandle)(remotion_1.Internals.compositionSelectorRef, () => {
return {
expandComposition: (compName) => {
const compositionToExpand = compositions.find((c) => c.id === compName);
if (!compositionToExpand) {
return;
}
const { folderName, parentFolderName } = compositionToExpand;
if (folderName === null) {
return;
}
setFoldersExpanded((previousState) => {
const foldersExpandedState = {
...previousState,
};
const currentFolder = folderName;
const currentParentName = parentFolderName;
const key = (0, persist_open_folders_1.openFolderKey)({
folderName: currentFolder,
parentName: currentParentName,
});
const splitted = key.split('/');
for (let i = 0; i < splitted.length - 1; i++) {
const allExceptLast = i === 0
? (0, persist_open_folders_1.openFolderKey)({
folderName: splitted.filter((s) => s !== 'no-parent')[0],
parentName: null,
})
: splitted.slice(0, i + 1).join('/');
foldersExpandedState[allExceptLast] = true;
}
(0, persist_open_folders_1.persistExpandedFolders)('compositions', foldersExpandedState);
return foldersExpandedState;
});
},
selectComposition: (compName) => {
const comp = compositions.find((c) => c.id === compName);
if (!comp) {
throw new Error(`Composition ${compName} not found`);
}
selectComposition(comp, true);
},
toggleFolder: (folderName, parentName) => {
toggleFolder(folderName, parentName);
},
};
}, [compositions, selectComposition, toggleFolder]);
const contextValue = (0, react_1.useMemo)(() => {
return {
foldersExpanded,
setFoldersExpanded,
toggleFolder,
};
}, [foldersExpanded, setFoldersExpanded, toggleFolder]);
return ((0, jsx_runtime_1.jsx)(persist_open_folders_1.ExpandedFoldersContext.Provider, { value: contextValue, children: children }));
};
exports.CompSelectorRef = CompSelectorRef;
@@ -0,0 +1,6 @@
import React from 'react';
import type { ComboboxValue } from './NewComposition/ComboBox';
export declare const CompositionContextButton: React.FC<{
readonly visible: boolean;
readonly values: ComboboxValue[];
}>;
@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CompositionContextButton = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const client_id_1 = require("../helpers/client-id");
const ellipsis_1 = require("../icons/ellipsis");
const InlineDropdown_1 = require("./InlineDropdown");
const CompositionContextButton = ({ visible, values }) => {
const iconStyle = (0, react_1.useMemo)(() => {
return {
style: {
height: 12,
},
};
}, []);
const connectionStatus = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx)
.previewServerState.type;
const renderAction = (0, react_1.useCallback)((color) => {
return (0, jsx_runtime_1.jsx)(ellipsis_1.EllipsisIcon, { fill: color, svgProps: iconStyle });
}, [iconStyle]);
if (!visible || connectionStatus !== 'connected') {
return null;
}
return (0, jsx_runtime_1.jsx)(InlineDropdown_1.InlineDropdown, { renderAction: renderAction, values: values });
};
exports.CompositionContextButton = CompositionContextButton;
@@ -0,0 +1,7 @@
import React from 'react';
export declare const useCompositionNavigation: () => {
navigateToNextComposition: () => void;
navigateToPreviousComposition: () => void;
};
export declare const getKeysToExpand: (initialFolderName: string, parentFolderName: string | null, initial?: string[]) => string[];
export declare const CompositionSelector: React.FC;
@@ -0,0 +1,95 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CompositionSelector = exports.getKeysToExpand = exports.useCompositionNavigation = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const remotion_1 = require("remotion");
const colors_1 = require("../helpers/colors");
const create_folder_tree_1 = require("../helpers/create-folder-tree");
const persist_open_folders_1 = require("../helpers/persist-open-folders");
const z_index_1 = require("../state/z-index");
const CompositionSelectorItem_1 = require("./CompositionSelectorItem");
const CurrentComposition_1 = require("./CurrentComposition");
const InitialCompositionLoader_1 = require("./InitialCompositionLoader");
const useCompositionNavigation = () => {
const { compositions, canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
const navigateToNextComposition = (0, react_1.useCallback)(() => {
if (!canvasContent ||
canvasContent.type !== 'composition' ||
compositions.length <= 1) {
return;
}
const currentIndex = compositions.findIndex((c) => c.id === canvasContent.compositionId);
if (currentIndex === -1) {
return;
}
const nextIndex = (currentIndex + 1) % compositions.length;
const nextComposition = compositions[nextIndex];
selectComposition(nextComposition, true);
}, [canvasContent, compositions, selectComposition]);
const navigateToPreviousComposition = (0, react_1.useCallback)(() => {
if (!canvasContent ||
canvasContent.type !== 'composition' ||
compositions.length <= 1) {
return;
}
const currentIndex = compositions.findIndex((c) => c.id === canvasContent.compositionId);
if (currentIndex === -1) {
return;
}
const previousIndex = (currentIndex - 1 + compositions.length) % compositions.length;
const previousComposition = compositions[previousIndex];
selectComposition(previousComposition, true);
}, [canvasContent, compositions, selectComposition]);
return (0, react_1.useMemo)(() => ({
navigateToNextComposition,
navigateToPreviousComposition,
}), [navigateToNextComposition, navigateToPreviousComposition]);
};
exports.useCompositionNavigation = useCompositionNavigation;
const container = {
display: 'flex',
flexDirection: 'column',
flex: 1,
overflow: 'hidden',
backgroundColor: colors_1.BACKGROUND,
};
const getKeysToExpand = (initialFolderName, parentFolderName, initial = []) => {
initial.push((0, persist_open_folders_1.openFolderKey)({
folderName: initialFolderName,
parentName: parentFolderName,
}));
const { name, parent } = (0, create_folder_tree_1.splitParentIntoNameAndParent)(parentFolderName);
if (!name) {
return initial;
}
return (0, exports.getKeysToExpand)(name, parent, initial);
};
exports.getKeysToExpand = getKeysToExpand;
const CompositionSelector = () => {
const { compositions, canvasContent, folders } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
const { foldersExpanded } = (0, react_1.useContext)(persist_open_folders_1.ExpandedFoldersContext);
const { tabIndex } = (0, z_index_1.useZIndex)();
const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
const items = (0, react_1.useMemo)(() => {
return (0, create_folder_tree_1.createFolderTree)(compositions, folders, foldersExpanded);
}, [compositions, folders, foldersExpanded]);
const showCurrentComposition = canvasContent && canvasContent.type === 'composition';
const list = (0, react_1.useMemo)(() => {
return {
height: showCurrentComposition
? `calc(100% - ${CurrentComposition_1.CURRENT_COMPOSITION_HEIGHT}px)`
: '100%',
overflowY: 'auto',
};
}, [showCurrentComposition]);
const toggleFolder = (0, react_1.useCallback)((folderName, parentName) => {
var _a;
(_a = remotion_1.Internals.compositionSelectorRef.current) === null || _a === void 0 ? void 0 : _a.toggleFolder(folderName, parentName);
}, []);
return ((0, jsx_runtime_1.jsxs)("div", { style: container, children: [showCurrentComposition ? (0, jsx_runtime_1.jsx)(CurrentComposition_1.CurrentComposition, {}) : null, (0, jsx_runtime_1.jsx)("div", { className: "__remotion-vertical-scrollbar", style: list, children: items.map((c) => {
return ((0, jsx_runtime_1.jsx)(CompositionSelectorItem_1.CompositionSelectorItem, { level: 0, currentComposition: showCurrentComposition ? canvasContent.compositionId : null, selectComposition: selectComposition, toggleFolder: toggleFolder, tabIndex: tabIndex, item: c }, c.key + c.type));
}) })] }));
};
exports.CompositionSelector = CompositionSelector;
@@ -0,0 +1,22 @@
import React from 'react';
import { type _InternalTypes } from 'remotion';
export type CompositionSelectorItemType = {
key: string;
type: 'composition';
composition: _InternalTypes['AnyComposition'];
} | {
key: string;
type: 'folder';
folderName: string;
parentName: string | null;
items: CompositionSelectorItemType[];
expanded: boolean;
};
export declare const CompositionSelectorItem: React.FC<{
readonly item: CompositionSelectorItemType;
readonly currentComposition: string | null;
readonly tabIndex: number;
readonly selectComposition: (c: _InternalTypes['AnyComposition'], push: boolean) => void;
readonly toggleFolder: (folderName: string, parentName: string | null) => void;
readonly level: number;
}>;
@@ -0,0 +1,182 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CompositionSelectorItem = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const colors_1 = require("../helpers/colors");
const is_composition_still_1 = require("../helpers/is-composition-still");
const folder_1 = require("../icons/folder");
const still_1 = require("../icons/still");
const video_1 = require("../icons/video");
const modals_1 = require("../state/modals");
const CompositionContextButton_1 = require("./CompositionContextButton");
const ContextMenu_1 = require("./ContextMenu");
const layout_1 = require("./layout");
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
const SidebarRenderButton_1 = require("./SidebarRenderButton");
const COMPOSITION_ITEM_HEIGHT = 32;
const itemStyle = {
paddingRight: 10,
paddingTop: 6,
paddingBottom: 6,
fontSize: 13,
display: 'flex',
textDecoration: 'none',
cursor: 'default',
alignItems: 'center',
marginBottom: 1,
appearance: 'none',
border: 'none',
width: '100%',
textAlign: 'left',
backgroundColor: colors_1.BACKGROUND,
height: COMPOSITION_ITEM_HEIGHT,
};
const labelStyle = {
textAlign: 'left',
textDecoration: 'none',
fontSize: 13,
flex: 1,
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
};
const iconStyle = {
width: 18,
height: 18,
flexShrink: 0,
};
const CompositionSelectorItem = ({ item, level, currentComposition, tabIndex, selectComposition, toggleFolder, }) => {
const selected = (0, react_1.useMemo)(() => {
if (item.type === 'composition') {
return currentComposition === item.composition.id;
}
return false;
}, [item, currentComposition]);
const [hovered, setHovered] = (0, react_1.useState)(false);
const onPointerEnter = (0, react_1.useCallback)(() => {
setHovered(true);
}, []);
const onPointerLeave = (0, react_1.useCallback)(() => {
setHovered(false);
}, []);
const style = (0, react_1.useMemo)(() => {
return {
...itemStyle,
backgroundColor: (0, colors_1.getBackgroundFromHoverState)({ hovered, selected }),
paddingLeft: 12 + level * 8,
};
}, [hovered, level, selected]);
const label = (0, react_1.useMemo)(() => {
return {
...labelStyle,
color: selected || hovered ? 'white' : colors_1.LIGHT_TEXT,
};
}, [hovered, selected]);
const onClick = (0, react_1.useCallback)((evt) => {
evt.preventDefault();
if (item.type === 'composition') {
selectComposition(item.composition, true);
}
else {
toggleFolder(item.folderName, item.parentName);
}
}, [item, selectComposition, toggleFolder]);
const onKeyPress = (0, react_1.useCallback)((evt) => {
if (evt.key === 'Enter') {
onClick(evt);
}
}, [onClick]);
const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
const contextMenu = (0, react_1.useMemo)(() => {
if (item.type === 'composition') {
return [
{
id: 'duplicate',
keyHint: null,
label: `Duplicate...`,
leftItem: null,
onClick: () => {
setSelectedModal({
type: 'duplicate-comp',
compositionId: item.composition.id,
compositionType: item.composition.durationInFrames === 1
? 'still'
: 'composition',
});
},
quickSwitcherLabel: null,
subMenu: null,
type: 'item',
value: 'duplicate',
},
{
id: 'rename',
keyHint: null,
label: `Rename...`,
leftItem: null,
onClick: () => {
setSelectedModal({
type: 'rename-comp',
compositionId: item.composition.id,
});
},
quickSwitcherLabel: null,
subMenu: null,
type: 'item',
value: 'rename',
},
{
id: 'delete',
keyHint: null,
label: `Delete...`,
leftItem: null,
onClick: () => {
setSelectedModal({
type: 'delete-comp',
compositionId: item.composition.id,
});
},
quickSwitcherLabel: null,
subMenu: null,
type: 'item',
value: 'delete',
},
{
type: 'divider',
id: 'copy-id-divider',
},
{
id: 'copy-id',
keyHint: null,
label: `Copy ID`,
leftItem: null,
onClick: () => {
navigator.clipboard
.writeText(item.composition.id)
.catch((err) => {
(0, NotificationCenter_1.showNotification)(`Could not copy to clipboard: ${err.message}`, 1000);
})
.then(() => {
(0, NotificationCenter_1.showNotification)('Copied to clipboard', 1000);
});
},
quickSwitcherLabel: null,
subMenu: null,
type: 'item',
value: 'remove',
},
];
}
return [];
}, [item, setSelectedModal]);
if (item.type === 'folder') {
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("button", { style: style, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, tabIndex: tabIndex, onClick: onClick, type: "button", title: item.folderName, children: [item.expanded ? ((0, jsx_runtime_1.jsx)(folder_1.ExpandedFolderIcon, { style: iconStyle, color: hovered || selected ? 'white' : colors_1.LIGHT_TEXT })) : ((0, jsx_runtime_1.jsx)(folder_1.CollapsedFolderIcon, { color: hovered || selected ? 'white' : colors_1.LIGHT_TEXT, style: iconStyle })), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, jsx_runtime_1.jsx)("div", { style: label, children: item.folderName })] }), item.expanded
? item.items.map((childItem) => {
return ((0, jsx_runtime_1.jsx)(exports.CompositionSelectorItem, { currentComposition: currentComposition, selectComposition: selectComposition, item: childItem, tabIndex: tabIndex, level: level + 1, toggleFolder: toggleFolder }, childItem.key + childItem.type));
})
: null] }));
}
return ((0, jsx_runtime_1.jsx)(ContextMenu_1.ContextMenu, { values: contextMenu, children: (0, jsx_runtime_1.jsx)(layout_1.Row, { align: "center", children: (0, jsx_runtime_1.jsxs)("a", { style: style, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, tabIndex: tabIndex, onClick: onClick, onKeyPress: onKeyPress, type: "button", title: item.composition.id, className: "__remotion-composition", "data-compname": item.composition.id, children: [(0, is_composition_still_1.isCompositionStill)(item.composition) ? ((0, jsx_runtime_1.jsx)(still_1.StillIcon, { color: hovered || selected ? 'white' : colors_1.LIGHT_TEXT, style: iconStyle })) : ((0, jsx_runtime_1.jsx)(video_1.FilmIcon, { color: hovered || selected ? 'white' : colors_1.LIGHT_TEXT, style: iconStyle })), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, jsx_runtime_1.jsx)("div", { style: label, children: item.composition.id }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.5 }), (0, jsx_runtime_1.jsx)(CompositionContextButton_1.CompositionContextButton, { values: contextMenu, visible: hovered }), (0, jsx_runtime_1.jsx)(SidebarRenderButton_1.SidebarRenderButton, { visible: hovered, composition: item.composition })] }) }) }));
};
exports.CompositionSelectorItem = CompositionSelectorItem;
@@ -0,0 +1,6 @@
import React from 'react';
import type { ComboboxValue } from './NewComposition/ComboBox';
export declare const ContextMenu: React.FC<{
readonly children: React.ReactNode;
readonly values: ComboboxValue[];
}>;
@@ -0,0 +1,98 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ContextMenu = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const player_1 = require("@remotion/player");
const react_1 = require("react");
const react_dom_1 = __importDefault(require("react-dom"));
const mobile_layout_1 = require("../helpers/mobile-layout");
const noop_1 = require("../helpers/noop");
const z_index_1 = require("../state/z-index");
const portals_1 = require("./Menu/portals");
const styles_1 = require("./Menu/styles");
const MenuContent_1 = require("./NewComposition/MenuContent");
const ContextMenu = ({ children, values }) => {
const ref = (0, react_1.useRef)(null);
const [opened, setOpened] = (0, react_1.useState)({ type: 'not-open' });
const { currentZIndex } = (0, z_index_1.useZIndex)();
const style = (0, react_1.useMemo)(() => {
return {};
}, []);
const size = player_1.PlayerInternals.useElementSize(ref, {
triggerOnWindowResize: true,
shouldApplyCssTransforms: true,
});
const isMobileLayout = (0, mobile_layout_1.useMobileLayout)();
(0, react_1.useEffect)(() => {
const { current } = ref;
if (!current) {
return;
}
const onClick = (e) => {
e.preventDefault();
e.stopPropagation();
setOpened({ type: 'open', left: e.clientX, top: e.clientY });
return false;
};
current.addEventListener('contextmenu', onClick);
return () => {
current.removeEventListener('contextmenu', onClick);
};
}, [size]);
const spaceToBottom = (0, react_1.useMemo)(() => {
if (size && opened.type === 'open') {
return size.windowSize.height - opened.top;
}
return 0;
}, [opened, size]);
const spaceToTop = (0, react_1.useMemo)(() => {
if (size && opened.type === 'open') {
return opened.top;
}
return 0;
}, [opened, size]);
const portalStyle = (0, react_1.useMemo)(() => {
if (opened.type === 'not-open') {
return;
}
if (!size) {
return;
}
const spaceToRight = size.windowSize.width - size.left;
const spaceToLeft = size.left + size.width;
const minSpaceRequired = isMobileLayout
? styles_1.MAX_MOBILE_MENU_WIDTH
: styles_1.MAX_MENU_WIDTH;
const verticalLayout = spaceToTop > spaceToBottom ? 'bottom' : 'top';
const canOpenOnLeft = spaceToLeft >= minSpaceRequired;
const canOpenOnRight = spaceToRight >= minSpaceRequired;
const horizontalLayout = canOpenOnRight ? 'left' : 'right';
return {
...styles_1.menuContainerTowardsTop,
...(verticalLayout === 'top'
? {
top: opened.top,
}
: {
bottom: size.windowSize.height - opened.top,
}),
...(horizontalLayout === 'left'
? {
left: opened.left,
}
: {
right: canOpenOnLeft ? size.windowSize.width - opened.left : 0,
}),
};
}, [opened, size, isMobileLayout, spaceToTop, spaceToBottom]);
const onHide = (0, react_1.useCallback)(() => {
setOpened({ type: 'not-open' });
}, []);
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { ref: ref, onContextMenu: () => false, style: style, children: children }), portalStyle
? react_dom_1.default.createPortal((0, jsx_runtime_1.jsx)("div", { style: styles_1.fullScreenOverlay, children: (0, jsx_runtime_1.jsx)("div", { style: styles_1.outerPortal, className: "css-reset", children: (0, jsx_runtime_1.jsx)(z_index_1.HigherZIndex, { onOutsideClick: onHide, onEscape: onHide, children: (0, jsx_runtime_1.jsx)("div", { style: portalStyle, children: (0, jsx_runtime_1.jsx)(MenuContent_1.MenuContent, { onNextMenu: noop_1.noop, onPreviousMenu: noop_1.noop, values: values, onHide: onHide, leaveLeftSpace: true, preselectIndex: false, topItemCanBeUnselected: false, fixedHeight: null }) }) }) }) }), (0, portals_1.getPortal)(currentZIndex))
: null] }));
};
exports.ContextMenu = ContextMenu;
@@ -0,0 +1,5 @@
import React from 'react';
export declare const CONTROL_BUTTON_PADDING = 6;
export declare const ControlButton: (props: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement> & {
readonly title: string;
}) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ControlButton = exports.CONTROL_BUTTON_PADDING = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const z_index_1 = require("../state/z-index");
exports.CONTROL_BUTTON_PADDING = 6;
const ControlButton = (props) => {
const style = (0, react_1.useMemo)(() => {
return {
opacity: props.disabled ? 0.5 : 1,
display: 'inline-flex',
background: 'none',
border: 'none',
padding: exports.CONTROL_BUTTON_PADDING,
};
}, [props.disabled]);
const { tabIndex } = (0, z_index_1.useZIndex)();
return ((0, jsx_runtime_1.jsx)("button", { type: 'button', tabIndex: tabIndex, ...props, style: style }));
};
exports.ControlButton = ControlButton;
@@ -0,0 +1,6 @@
import React from 'react';
export declare const CopyButton: React.FC<{
readonly textToCopy: string;
readonly label: string;
readonly labelWhenCopied: string;
}>;
@@ -0,0 +1,43 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CopyButton = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const copy_text_1 = require("../helpers/copy-text");
const Button_1 = require("./Button");
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
const layout_1 = require("./layout");
const iconStyle = {
width: 16,
height: 16,
color: 'white',
};
const buttonContainerStyle = {
display: 'flex',
minWidth: '114px',
};
const copyIcon = ((0, jsx_runtime_1.jsx)("svg", { "aria-hidden": "true", focusable: "false", "data-prefix": "far", "data-icon": "clipboard", className: "svg-inline--fa fa-clipboard fa-w-12", role: "img", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 384 512", style: iconStyle, children: (0, jsx_runtime_1.jsx)("path", { fill: "currentColor", d: "M336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 40c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm144 418c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V118c0-3.3 2.7-6 6-6h42v36c0 6.6 5.4 12 12 12h168c6.6 0 12-5.4 12-12v-36h42c3.3 0 6 2.7 6 6z" }) }));
const labelStyle = {
fontSize: 14,
};
const CopyButton = ({ textToCopy, label, labelWhenCopied }) => {
const [copied, setCopied] = (0, react_1.useState)(false);
const onClick = (0, react_1.useCallback)(() => {
(0, copy_text_1.copyText)(textToCopy)
.then(() => {
setCopied(Date.now());
})
.catch((err) => {
(0, NotificationCenter_1.showNotification)(`Could not copy: ${err.message}`, 2000);
});
}, [textToCopy]);
(0, react_1.useEffect)(() => {
if (!copied) {
return;
}
const to = setTimeout(() => setCopied(false), 2000);
return () => clearTimeout(to);
}, [copied]);
return ((0, jsx_runtime_1.jsxs)(Button_1.Button, { onClick: onClick, buttonContainerStyle: buttonContainerStyle, children: [copyIcon, (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1.5 }), ' ', (0, jsx_runtime_1.jsx)("span", { style: labelStyle, children: copied ? labelWhenCopied : label })] }));
};
exports.CopyButton = CopyButton;
@@ -0,0 +1,2 @@
export declare const CURRENT_COMPOSITION_HEIGHT = 80;
export declare const CurrentComposition: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,45 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CurrentComposition = exports.CURRENT_COMPOSITION_HEIGHT = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const remotion_1 = require("remotion");
const colors_1 = require("../helpers/colors");
const is_composition_still_1 = require("../helpers/is-composition-still");
const render_frame_1 = require("../state/render-frame");
exports.CURRENT_COMPOSITION_HEIGHT = 80;
const container = {
height: exports.CURRENT_COMPOSITION_HEIGHT,
display: 'block',
borderBottom: `1px solid ${colors_1.BORDER_COLOR}`,
padding: 12,
color: 'white',
backgroundColor: colors_1.BACKGROUND,
};
const title = {
fontWeight: 'bold',
fontSize: 12,
whiteSpace: 'nowrap',
lineHeight: '18px',
backgroundColor: colors_1.BACKGROUND,
};
const subtitle = {
fontSize: 12,
opacity: 0.8,
whiteSpace: 'nowrap',
lineHeight: '18px',
backgroundColor: colors_1.BACKGROUND,
};
const row = {
display: 'flex',
flexDirection: 'row',
lineHeight: '18px',
backgroundColor: colors_1.BACKGROUND,
};
const CurrentComposition = () => {
const video = remotion_1.Internals.useVideo();
if (!video) {
return (0, jsx_runtime_1.jsx)("div", { style: container });
}
return ((0, jsx_runtime_1.jsx)("div", { style: container, children: (0, jsx_runtime_1.jsx)("div", { style: row, children: (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { style: title, children: video.id }), (0, jsx_runtime_1.jsxs)("div", { style: subtitle, children: [video.width, "x", video.height, (0, is_composition_still_1.isCompositionStill)(video) ? null : `, ${video.fps} FPS`] }), (0, is_composition_still_1.isCompositionStill)(video) ? ((0, jsx_runtime_1.jsx)("div", { style: subtitle, children: "Still" })) : ((0, jsx_runtime_1.jsxs)("div", { style: subtitle, children: ["Duration ", (0, render_frame_1.renderFrame)(video.durationInFrames, video.fps)] }))] }) }) }));
};
exports.CurrentComposition = CurrentComposition;
@@ -0,0 +1,5 @@
import type React from 'react';
export declare const TitleUpdater: React.FC;
export declare const CurrentCompositionKeybindings: React.FC<{
readonly readOnlyStudio: boolean;
}>;
@@ -0,0 +1,74 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CurrentCompositionKeybindings = exports.TitleUpdater = void 0;
const react_1 = require("react");
const remotion_1 = require("remotion");
const client_id_1 = require("../helpers/client-id");
const document_title_1 = require("../helpers/document-title");
const use_keybinding_1 = require("../helpers/use-keybinding");
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
const context_1 = require("./RenderQueue/context");
const TitleUpdater = () => {
const renderQueue = (0, react_1.useContext)(context_1.RenderQueueContext);
const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
const { jobs } = renderQueue;
(0, react_1.useEffect)(() => {
if (!canvasContent) {
(0, document_title_1.setCurrentCanvasContentId)(null);
return;
}
if (canvasContent.type === 'composition') {
(0, document_title_1.setCurrentCanvasContentId)(canvasContent.compositionId);
return;
}
if (canvasContent.type === 'output') {
(0, document_title_1.setCurrentCanvasContentId)(canvasContent.path);
return;
}
if (canvasContent.type === 'output-blob') {
(0, document_title_1.setCurrentCanvasContentId)(canvasContent.displayName);
return;
}
(0, document_title_1.setCurrentCanvasContentId)(canvasContent.asset);
}, [canvasContent]);
(0, react_1.useEffect)(() => {
(0, document_title_1.setRenderJobs)(jobs);
}, [jobs]);
return null;
};
exports.TitleUpdater = TitleUpdater;
const CurrentCompositionKeybindings = ({ readOnlyStudio }) => {
const keybindings = (0, use_keybinding_1.useKeybinding)();
const video = remotion_1.Internals.useVideo();
const { type } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx).previewServerState;
const openRenderModal = (0, react_1.useCallback)(() => {
if (!video) {
return;
}
if (readOnlyStudio) {
return (0, NotificationCenter_1.showNotification)('Studio is read-only', 2000);
}
if (type !== 'connected') {
(0, NotificationCenter_1.showNotification)('Studio server is offline', 2000);
return;
}
const renderButton = document.getElementById('render-modal-button');
renderButton.click();
}, [readOnlyStudio, type, video]);
(0, react_1.useEffect)(() => {
const binding = keybindings.registerKeybinding({
event: 'keydown',
key: 'r',
commandCtrlKey: false,
callback: openRenderModal,
preventDefault: true,
triggerIfInputFieldFocused: false,
keepRegisteredWhenNotHighestContext: false,
});
return () => {
binding.unregister();
};
}, [keybindings, openRenderModal]);
return null;
};
exports.CurrentCompositionKeybindings = CurrentCompositionKeybindings;
@@ -0,0 +1,6 @@
import React from 'react';
export declare const BUFFER_STATE_DELAY_IN_MILLISECONDS: number;
export declare const Editor: React.FC<{
readonly Root: React.FC;
readonly readOnlyStudio: boolean;
}>;
@@ -0,0 +1,101 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.Editor = exports.BUFFER_STATE_DELAY_IN_MILLISECONDS = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const player_1 = require("@remotion/player");
const react_1 = __importStar(require("react"));
const remotion_1 = require("remotion");
const colors_1 = require("../helpers/colors");
const noop_1 = require("../helpers/noop");
const canvas_ref_1 = require("../state/canvas-ref");
const timeline_zoom_1 = require("../state/timeline-zoom");
const z_index_1 = require("../state/z-index");
const EditorContent_1 = require("./EditorContent");
const GlobalKeybindings_1 = require("./GlobalKeybindings");
const Modals_1 = require("./Modals");
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
const TopPanel_1 = require("./TopPanel");
const background = {
backgroundColor: colors_1.BACKGROUND,
display: 'flex',
width: '100%',
height: '100%',
flexDirection: 'column',
position: 'absolute',
};
const DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS = 300;
exports.BUFFER_STATE_DELAY_IN_MILLISECONDS = typeof process.env.BUFFER_STATE_DELAY_IN_MILLISECONDS === 'undefined' ||
process.env.BUFFER_STATE_DELAY_IN_MILLISECONDS === null
? DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS
: Number(process.env.BUFFER_STATE_DELAY_IN_MILLISECONDS);
const Editor = ({ Root, readOnlyStudio }) => {
const size = player_1.PlayerInternals.useElementSize(canvas_ref_1.drawRef, {
triggerOnWindowResize: false,
shouldApplyCssTransforms: true,
});
(0, react_1.useEffect)(() => {
if (readOnlyStudio) {
return;
}
const listenToChanges = (e) => {
if (window.remotion_unsavedProps) {
e.returnValue = 'Are you sure you want to leave?';
}
};
window.addEventListener('beforeunload', listenToChanges);
return () => {
window.removeEventListener('beforeunload', listenToChanges);
};
}, [readOnlyStudio]);
const [canvasMounted, setCanvasMounted] = react_1.default.useState(false);
const onMounted = (0, react_1.useCallback)(() => {
setCanvasMounted(true);
}, []);
const value = (0, react_1.useMemo)(() => {
if (!size) {
return null;
}
return {
type: 'canvas-size',
canvasSize: size,
};
}, [size]);
const MemoRoot = (0, react_1.useMemo)(() => {
return react_1.default.memo(Root);
}, [Root]);
return ((0, jsx_runtime_1.jsx)(z_index_1.HigherZIndex, { onEscape: noop_1.noop, onOutsideClick: noop_1.noop, children: (0, jsx_runtime_1.jsxs)(timeline_zoom_1.TimelineZoomContext, { children: [(0, jsx_runtime_1.jsx)(remotion_1.Internals.CurrentScaleContext.Provider, { value: value, children: (0, jsx_runtime_1.jsxs)("div", { style: background, children: [canvasMounted ? (0, jsx_runtime_1.jsx)(MemoRoot, {}) : null, (0, jsx_runtime_1.jsxs)(remotion_1.Internals.CanUseRemotionHooksProvider, { children: [(0, jsx_runtime_1.jsx)(EditorContent_1.EditorContent, { readOnlyStudio: readOnlyStudio, children: (0, jsx_runtime_1.jsx)(TopPanel_1.TopPanel, { drawRef: canvas_ref_1.drawRef, bufferStateDelayInMilliseconds: exports.BUFFER_STATE_DELAY_IN_MILLISECONDS, onMounted: onMounted, readOnlyStudio: readOnlyStudio }) }), (0, jsx_runtime_1.jsx)(GlobalKeybindings_1.GlobalKeybindings, {})] })] }) }), (0, jsx_runtime_1.jsx)(Modals_1.Modals, { readOnlyStudio: readOnlyStudio }), (0, jsx_runtime_1.jsx)(NotificationCenter_1.NotificationCenter, {})] }) }));
};
exports.Editor = Editor;
@@ -0,0 +1,5 @@
import React from 'react';
export declare const EditorContent: React.FC<{
readonly readOnlyStudio: boolean;
readonly children: React.ReactNode;
}>;
@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EditorContent = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const remotion_1 = require("remotion");
const is_current_selected_still_1 = require("../helpers/is-current-selected-still");
const InitialCompositionLoader_1 = require("./InitialCompositionLoader");
const MenuToolbar_1 = require("./MenuToolbar");
const SplitterContainer_1 = require("./Splitter/SplitterContainer");
const SplitterElement_1 = require("./Splitter/SplitterElement");
const SplitterHandle_1 = require("./Splitter/SplitterHandle");
const Timeline_1 = require("./Timeline/Timeline");
const noop = () => undefined;
const container = {
display: 'flex',
flexDirection: 'column',
flex: 1,
height: 0,
};
const EditorContent = ({ readOnlyStudio, children }) => {
const isStill = (0, is_current_selected_still_1.useIsStill)();
const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
// Preventing multiple renders so the update check doesn't get rendered twice and needs to be aborted
const onlyTopPanel = canvasContent === null || isStill || canvasContent.type !== 'composition';
return ((0, jsx_runtime_1.jsxs)("div", { style: container, children: [(0, jsx_runtime_1.jsx)(InitialCompositionLoader_1.InitialCompositionLoader, {}), (0, jsx_runtime_1.jsx)(MenuToolbar_1.MenuToolbar, { readOnlyStudio: readOnlyStudio }), (0, jsx_runtime_1.jsxs)(SplitterContainer_1.SplitterContainer, { orientation: "horizontal", id: "top-to-bottom", maxFlex: 0.9, minFlex: 0.2, defaultFlex: 0.75, children: [(0, jsx_runtime_1.jsx)(SplitterElement_1.SplitterElement, { sticky: null, type: "flexer", children: children }), onlyTopPanel ? null : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(SplitterHandle_1.SplitterHandle, { allowToCollapse: "none", onCollapse: noop }), (0, jsx_runtime_1.jsx)(SplitterElement_1.SplitterElement, { sticky: null, type: "anti-flexer", children: (0, jsx_runtime_1.jsx)(Timeline_1.Timeline, {}) })] }))] })] }));
};
exports.EditorContent = EditorContent;
@@ -0,0 +1,5 @@
import React from 'react';
export declare const EditorContexts: React.FC<{
readonly children: React.ReactNode;
readonly readOnlyStudio: boolean;
}>;
@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EditorContexts = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const player_1 = require("@remotion/player");
const client_id_1 = require("../helpers/client-id");
const folders_1 = require("../state/folders");
const highest_z_index_1 = require("../state/highest-z-index");
const keybindings_1 = require("../state/keybindings");
const preview_size_1 = require("../state/preview-size");
const sidebar_1 = require("../state/sidebar");
const VisualControls_1 = require("../visual-controls/VisualControls");
const CheckerboardProvider_1 = require("./CheckerboardProvider");
const get_zod_if_possible_1 = require("./get-zod-if-possible");
const MediaVolumeProvider_1 = require("./MediaVolumeProvider");
const ModalsProvider_1 = require("./ModalsProvider");
const ClientRenderQueueProcessor_1 = require("./RenderQueue/ClientRenderQueueProcessor");
const context_1 = require("./RenderQueue/context");
const SetTimelineInOutProvider_1 = require("./SetTimelineInOutProvider");
const ShowGuidesProvider_1 = require("./ShowGuidesProvider");
const ShowRulersProvider_1 = require("./ShowRulersProvider");
const ZoomGesturesProvider_1 = require("./ZoomGesturesProvider");
const EditorContexts = ({ children, readOnlyStudio }) => {
return ((0, jsx_runtime_1.jsx)(get_zod_if_possible_1.ZodProvider, { children: (0, jsx_runtime_1.jsx)(VisualControls_1.VisualControlsProvider, { children: (0, jsx_runtime_1.jsx)(client_id_1.PreviewServerConnection, { readOnlyStudio: readOnlyStudio, children: (0, jsx_runtime_1.jsxs)(context_1.RenderQueueContextProvider, { children: [(0, jsx_runtime_1.jsx)(ClientRenderQueueProcessor_1.ClientRenderQueueProcessor, {}), (0, jsx_runtime_1.jsx)(keybindings_1.KeybindingContextProvider, { children: (0, jsx_runtime_1.jsx)(CheckerboardProvider_1.CheckerboardProvider, { children: (0, jsx_runtime_1.jsx)(ZoomGesturesProvider_1.ZoomGesturesProvider, { children: (0, jsx_runtime_1.jsx)(ShowRulersProvider_1.ShowRulersProvider, { children: (0, jsx_runtime_1.jsx)(ShowGuidesProvider_1.ShowGuidesProvider, { children: (0, jsx_runtime_1.jsx)(preview_size_1.PreviewSizeProvider, { children: (0, jsx_runtime_1.jsx)(ModalsProvider_1.ModalsProvider, { children: (0, jsx_runtime_1.jsx)(MediaVolumeProvider_1.MediaVolumeProvider, { children: (0, jsx_runtime_1.jsx)(player_1.PlayerInternals.PlayerEmitterProvider, { currentPlaybackRate: null, children: (0, jsx_runtime_1.jsx)(sidebar_1.SidebarContextProvider, { children: (0, jsx_runtime_1.jsx)(folders_1.FolderContextProvider, { children: (0, jsx_runtime_1.jsx)(highest_z_index_1.HighestZIndexProvider, { children: (0, jsx_runtime_1.jsx)(SetTimelineInOutProvider_1.SetTimelineInOutProvider, { children: children }) }) }) }) }) }) }) }) }) }) }) }) })] }) }) }) }));
};
exports.EditorContexts = EditorContexts;
@@ -0,0 +1,12 @@
import type { Guide } from '../../state/editor-guides';
declare const _default: import("react").NamedExoticComponent<{
guide: Guide;
canvasDimensions: {
left: number;
top: number;
width: number;
height: number;
};
scale: number;
}>;
export default _default;
@@ -0,0 +1,91 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const no_react_1 = require("remotion/no-react");
const colors_1 = require("../../helpers/colors");
const editor_guides_1 = require("../../state/editor-guides");
const editor_rulers_1 = require("../../state/editor-rulers");
const ContextMenu_1 = require("../ContextMenu");
const PADDING_FOR_EASY_DRAG = 4;
const GuideComp = ({ guide, canvasDimensions, scale }) => {
const { shouldCreateGuideRef, setGuidesList, setSelectedGuideId, selectedGuideId, setHoveredGuideId, hoveredGuideId, } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
const onPointerEnter = (0, react_1.useCallback)(() => {
setHoveredGuideId(() => guide.id);
}, [guide.id, setHoveredGuideId]);
const onPointerLeave = (0, react_1.useCallback)(() => {
setHoveredGuideId(() => null);
}, [setHoveredGuideId]);
const isVerticalGuide = guide.orientation === 'vertical';
const guideStyle = (0, react_1.useMemo)(() => {
const canvasPosition = isVerticalGuide
? canvasDimensions.left
: canvasDimensions.top;
const guidePosition = guide.position * scale + canvasPosition;
return {
position: 'absolute',
width: `${isVerticalGuide ? '1px' : '100%'}`,
height: `${isVerticalGuide ? '100%' : '1px'}`,
left: `${isVerticalGuide ? guidePosition - PADDING_FOR_EASY_DRAG : 0}px`,
top: `${isVerticalGuide ? 0 : guidePosition - PADDING_FOR_EASY_DRAG}px`,
cursor: `${isVerticalGuide ? 'ew-resize' : 'ns-resize'}`,
padding: isVerticalGuide
? `0 ${PADDING_FOR_EASY_DRAG}px`
: `${PADDING_FOR_EASY_DRAG}px 0`,
};
}, [guide, scale, canvasDimensions, isVerticalGuide]);
const guideContentStyle = (0, react_1.useMemo)(() => {
return {
position: 'relative',
minWidth: `${isVerticalGuide ? '1px' : `calc(100% + ${editor_rulers_1.RULER_WIDTH}px`}`,
minHeight: `${isVerticalGuide ? `calc(100% + ${editor_rulers_1.RULER_WIDTH}px` : '1px'}`,
top: `${isVerticalGuide ? `-${editor_rulers_1.RULER_WIDTH}px` : '0px'}`,
left: `${isVerticalGuide ? '0px' : `-${editor_rulers_1.RULER_WIDTH}px`}`,
display: guide.show ? 'block' : 'none',
backgroundColor: selectedGuideId === guide.id || hoveredGuideId === guide.id
? colors_1.SELECTED_GUIDE
: colors_1.UNSELECTED_GUIDE,
};
}, [isVerticalGuide, guide.show, guide.id, selectedGuideId, hoveredGuideId]);
const onMouseDown = (0, react_1.useCallback)((e) => {
e.preventDefault();
if (e.button !== 0) {
return;
}
shouldCreateGuideRef.current = true;
document.body.style.cursor = 'no-drop';
setSelectedGuideId(() => guide.id);
}, [shouldCreateGuideRef, setSelectedGuideId, guide.id]);
const values = (0, react_1.useMemo)(() => {
return [
{
id: '1',
keyHint: null,
label: 'Remove guide',
leftItem: null,
onClick: () => {
setGuidesList((prevState) => {
const newGuides = prevState.filter((selected) => {
return selected.id !== guide.id;
});
(0, editor_guides_1.persistGuidesList)(newGuides);
return newGuides;
});
},
quickSwitcherLabel: null,
subMenu: null,
type: 'item',
value: 'remove',
},
];
}, [guide.id, setGuidesList]);
return ((0, jsx_runtime_1.jsx)(ContextMenu_1.ContextMenu, { values: values, children: (0, jsx_runtime_1.jsx)("div", { style: guideStyle, onMouseDown: onMouseDown, className: "__remotion_editor_guide", onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, children: (0, jsx_runtime_1.jsx)("div", { style: guideContentStyle, className: [
'__remotion_editor_guide_content',
selectedGuideId === guide.id || hoveredGuideId === guide.id
? '__remotion_editor_guide_selected'
: null,
]
.filter(no_react_1.NoReactInternals.truthy)
.join(' ') }) }) }));
};
exports.default = (0, react_1.memo)(GuideComp);
@@ -0,0 +1,9 @@
import { type Size } from '@remotion/player';
import type { AssetMetadata } from '../../helpers/get-asset-metadata';
import type { Dimensions } from '../../helpers/is-current-selected-still';
declare const EditorGuides: React.FC<{
canvasSize: Size | null;
contentDimensions: Dimensions | 'none' | null;
assetMetadata: AssetMetadata | null;
}>;
export default EditorGuides;
@@ -0,0 +1,32 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const remotion_1 = require("remotion");
const use_studio_canvas_dimensions_1 = require("../../helpers/use-studio-canvas-dimensions");
const editor_guides_1 = require("../../state/editor-guides");
const Guide_1 = __importDefault(require("./Guide"));
const EditorGuides = ({ canvasSize, contentDimensions, assetMetadata }) => {
const { canvasPosition: canvasDimensions, scale } = (0, use_studio_canvas_dimensions_1.useStudioCanvasDimensions)({
canvasSize,
contentDimensions,
assetMetadata,
});
const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
if (canvasContent === null || canvasContent.type !== 'composition') {
throw new Error('Expected to be in a composition');
}
const { guidesList } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
const guidesForThisComposition = (0, react_1.useMemo)(() => {
return guidesList.filter((guide) => {
return guide.compositionId === canvasContent.compositionId;
});
}, [canvasContent.compositionId, guidesList]);
return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: guidesForThisComposition.map((guide) => {
return ((0, jsx_runtime_1.jsx)(Guide_1.default, { guide: guide, canvasDimensions: canvasDimensions, scale: scale }, guide.id));
}) }));
};
exports.default = EditorGuides;

Some files were not shown because too many files have changed in this diff Show More