@remotion/studio 4.0.441 → 4.0.443
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AudioWaveform.js +67 -61
- package/dist/components/Editor.js +7 -4
- package/dist/components/EditorGuides/Guide.js +2 -1
- package/dist/components/EditorRuler/Ruler.js +2 -1
- package/dist/components/EditorRuler/index.js +4 -7
- package/dist/components/ForceSpecificCursor.d.ts +3 -0
- package/dist/components/ForceSpecificCursor.js +68 -0
- package/dist/components/MenuBuildIndicator.js +58 -3
- package/dist/components/MenuCompositionName.d.ts +2 -0
- package/dist/components/MenuCompositionName.js +80 -0
- package/dist/components/NewComposition/InputDragger.js +3 -0
- package/dist/components/RenderModal/RenderModalJSONPropsEditor.js +10 -3
- package/dist/components/Splitter/SplitterHandle.js +3 -0
- package/dist/components/Timeline/Timeline.js +3 -3
- package/dist/components/Timeline/TimelineDragHandler.js +4 -0
- package/dist/components/Timeline/TimelineRotationField.js +11 -0
- package/dist/components/Timeline/TimelineSequence.js +1 -1
- package/dist/components/Timeline/TimelineStack/index.js +2 -1
- package/dist/components/Timeline/TimelineVideoInfo.d.ts +4 -0
- package/dist/components/Timeline/TimelineVideoInfo.js +31 -12
- package/dist/components/Timeline/TimelineWidthProvider.js +16 -1
- package/dist/components/draw-peaks.d.ts +1 -0
- package/dist/components/draw-peaks.js +61 -0
- package/dist/components/load-waveform-peaks.d.ts +3 -0
- package/dist/components/load-waveform-peaks.js +67 -0
- package/dist/components/parse-color.d.ts +1 -0
- package/dist/components/parse-color.js +17 -0
- package/dist/esm/{chunk-1x2ychmc.js → chunk-cpv44d93.js} +3613 -3340
- package/dist/esm/internals.mjs +3613 -3340
- package/dist/esm/previewEntry.mjs +3405 -3132
- package/dist/esm/renderEntry.mjs +1 -1
- package/dist/helpers/calculate-timeline.d.ts +1 -2
- package/dist/helpers/calculate-timeline.js +2 -23
- package/dist/helpers/timeline-layout.d.ts +4 -1
- package/dist/helpers/timeline-layout.js +10 -4
- package/package.json +9 -9
- package/dist/components/AudioWaveformBar.d.ts +0 -14
- package/dist/components/AudioWaveformBar.js +0 -33
- package/dist/components/OpenEditorButton.d.ts +0 -3
- package/dist/components/OpenEditorButton.js +0 -67
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AudioWaveform = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
-
const media_utils_1 = require("@remotion/media-utils");
|
|
6
5
|
const react_1 = require("react");
|
|
7
6
|
const remotion_1 = require("remotion");
|
|
8
7
|
const colors_1 = require("../helpers/colors");
|
|
9
8
|
const timeline_layout_1 = require("../helpers/timeline-layout");
|
|
10
|
-
const
|
|
9
|
+
const draw_peaks_1 = require("./draw-peaks");
|
|
10
|
+
const load_waveform_peaks_1 = require("./load-waveform-peaks");
|
|
11
11
|
const container = {
|
|
12
12
|
display: 'flex',
|
|
13
13
|
flexDirection: 'row',
|
|
14
|
-
alignItems: '
|
|
14
|
+
alignItems: 'center',
|
|
15
15
|
position: 'absolute',
|
|
16
|
-
|
|
16
|
+
inset: 0,
|
|
17
17
|
};
|
|
18
18
|
const errorMessage = {
|
|
19
19
|
fontSize: 13,
|
|
@@ -25,46 +25,87 @@ const errorMessage = {
|
|
|
25
25
|
maxWidth: 450,
|
|
26
26
|
opacity: 0.75,
|
|
27
27
|
};
|
|
28
|
-
const
|
|
28
|
+
const waveformCanvasStyle = {
|
|
29
|
+
pointerEvents: 'none',
|
|
30
|
+
};
|
|
31
|
+
const volumeCanvasStyle = {
|
|
29
32
|
position: 'absolute',
|
|
30
33
|
};
|
|
31
34
|
const AudioWaveform = ({ src, startFrom, durationInFrames, visualizationWidth, volume, doesVolumeChange, playbackRate, }) => {
|
|
32
|
-
const [
|
|
35
|
+
const [peaks, setPeaks] = (0, react_1.useState)(null);
|
|
33
36
|
const [error, setError] = (0, react_1.useState)(null);
|
|
34
|
-
const mountState = (0, react_1.useRef)({ isMounted: true });
|
|
35
37
|
const vidConf = remotion_1.Internals.useUnsafeVideoConfig();
|
|
36
38
|
if (vidConf === null) {
|
|
37
39
|
throw new Error('Expected video config');
|
|
38
40
|
}
|
|
39
|
-
const
|
|
41
|
+
const containerRef = (0, react_1.useRef)(null);
|
|
42
|
+
const waveformCanvas = (0, react_1.useRef)(null);
|
|
43
|
+
const volumeCanvas = (0, react_1.useRef)(null);
|
|
40
44
|
(0, react_1.useEffect)(() => {
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
const controller = new AbortController();
|
|
46
|
+
setError(null);
|
|
47
|
+
(0, load_waveform_peaks_1.loadWaveformPeaks)(src, controller.signal)
|
|
48
|
+
.then((p) => {
|
|
49
|
+
if (!controller.signal.aborted) {
|
|
50
|
+
setPeaks(p);
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
.catch((err) => {
|
|
54
|
+
if (!controller.signal.aborted) {
|
|
55
|
+
setError(err);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
return () => controller.abort();
|
|
59
|
+
}, [src]);
|
|
60
|
+
const portionPeaks = (0, react_1.useMemo)(() => {
|
|
61
|
+
if (!peaks || peaks.length === 0) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const startTimeInSeconds = startFrom / vidConf.fps;
|
|
65
|
+
const durationInSeconds = (durationInFrames / vidConf.fps) * playbackRate;
|
|
66
|
+
const startPeakIndex = Math.floor(startTimeInSeconds * load_waveform_peaks_1.TARGET_SAMPLE_RATE);
|
|
67
|
+
const endPeakIndex = Math.ceil((startTimeInSeconds + durationInSeconds) * load_waveform_peaks_1.TARGET_SAMPLE_RATE);
|
|
68
|
+
return peaks.slice(Math.max(0, startPeakIndex), Math.min(peaks.length, endPeakIndex));
|
|
69
|
+
}, [peaks, startFrom, durationInFrames, vidConf.fps, playbackRate]);
|
|
70
|
+
(0, react_1.useEffect)(() => {
|
|
71
|
+
const { current: canvasElement } = waveformCanvas;
|
|
72
|
+
const { current: containerElement } = containerRef;
|
|
73
|
+
if (!canvasElement ||
|
|
74
|
+
!containerElement ||
|
|
75
|
+
!portionPeaks ||
|
|
76
|
+
portionPeaks.length === 0) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const h = containerElement.clientHeight;
|
|
80
|
+
const w = Math.ceil(visualizationWidth);
|
|
81
|
+
canvasElement.width = w;
|
|
82
|
+
canvasElement.height = h;
|
|
83
|
+
const vol = typeof volume === 'number' ? volume : 1;
|
|
84
|
+
(0, draw_peaks_1.drawBars)(canvasElement, portionPeaks, 'rgba(255, 255, 255, 0.6)', vol, w);
|
|
85
|
+
}, [portionPeaks, visualizationWidth, volume]);
|
|
47
86
|
(0, react_1.useEffect)(() => {
|
|
48
|
-
|
|
87
|
+
const { current: volumeCanvasElement } = volumeCanvas;
|
|
88
|
+
const { current: containerElement } = containerRef;
|
|
89
|
+
if (!volumeCanvasElement || !containerElement) {
|
|
49
90
|
return;
|
|
50
91
|
}
|
|
51
|
-
const
|
|
92
|
+
const h = containerElement.clientHeight;
|
|
93
|
+
const context = volumeCanvasElement.getContext('2d');
|
|
52
94
|
if (!context) {
|
|
53
95
|
return;
|
|
54
96
|
}
|
|
55
|
-
|
|
97
|
+
volumeCanvasElement.width = Math.ceil(visualizationWidth);
|
|
98
|
+
volumeCanvasElement.height = h;
|
|
99
|
+
context.clearRect(0, 0, visualizationWidth, h);
|
|
56
100
|
if (!doesVolumeChange || typeof volume === 'number') {
|
|
57
|
-
// The volume is a number, meaning it could change on each frame-
|
|
58
|
-
// User did not use the (f: number) => number syntax, so we can't draw
|
|
59
|
-
// a visualization.
|
|
60
101
|
return;
|
|
61
102
|
}
|
|
62
103
|
const volumes = volume.split(',').map((v) => Number(v));
|
|
63
104
|
context.beginPath();
|
|
64
|
-
context.moveTo(0,
|
|
105
|
+
context.moveTo(0, h);
|
|
65
106
|
volumes.forEach((v, index) => {
|
|
66
107
|
const x = (index / (volumes.length - 1)) * visualizationWidth;
|
|
67
|
-
const y = (1 - v) * (
|
|
108
|
+
const y = (1 - v) * (h - timeline_layout_1.TIMELINE_BORDER * 2) + 1;
|
|
68
109
|
if (index === 0) {
|
|
69
110
|
context.moveTo(x, y);
|
|
70
111
|
}
|
|
@@ -74,50 +115,15 @@ const AudioWaveform = ({ src, startFrom, durationInFrames, visualizationWidth, v
|
|
|
74
115
|
});
|
|
75
116
|
context.strokeStyle = colors_1.LIGHT_TRANSPARENT;
|
|
76
117
|
context.stroke();
|
|
77
|
-
}, [visualizationWidth,
|
|
78
|
-
(0, react_1.useEffect)(() => {
|
|
79
|
-
setError(null);
|
|
80
|
-
(0, media_utils_1.getAudioData)(src)
|
|
81
|
-
.then((data) => {
|
|
82
|
-
if (mountState.current.isMounted) {
|
|
83
|
-
setMetadata(data);
|
|
84
|
-
}
|
|
85
|
-
})
|
|
86
|
-
.catch((err) => {
|
|
87
|
-
if (mountState.current.isMounted) {
|
|
88
|
-
setError(err);
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
}, [src, vidConf.fps]);
|
|
92
|
-
const normalized = (0, react_1.useMemo)(() => {
|
|
93
|
-
if (!metadata || metadata.numberOfChannels === 0) {
|
|
94
|
-
return [];
|
|
95
|
-
}
|
|
96
|
-
const numberOfSamples = Math.floor(visualizationWidth / (AudioWaveformBar_1.WAVEFORM_BAR_LENGTH + AudioWaveformBar_1.WAVEFORM_BAR_MARGIN));
|
|
97
|
-
return (0, media_utils_1.getWaveformPortion)({
|
|
98
|
-
audioData: metadata,
|
|
99
|
-
startTimeInSeconds: startFrom / vidConf.fps,
|
|
100
|
-
durationInSeconds: Math.min((durationInFrames / vidConf.fps) * playbackRate, metadata.durationInSeconds),
|
|
101
|
-
numberOfSamples,
|
|
102
|
-
normalize: false,
|
|
103
|
-
});
|
|
104
|
-
}, [
|
|
105
|
-
durationInFrames,
|
|
106
|
-
vidConf.fps,
|
|
107
|
-
metadata,
|
|
108
|
-
playbackRate,
|
|
109
|
-
startFrom,
|
|
110
|
-
visualizationWidth,
|
|
111
|
-
]);
|
|
118
|
+
}, [visualizationWidth, volume, doesVolumeChange]);
|
|
112
119
|
if (error) {
|
|
113
120
|
return (jsx_runtime_1.jsx("div", { style: container, children: jsx_runtime_1.jsx("div", { style: errorMessage, children: "No waveform available. Audio might not support CORS." }) }));
|
|
114
121
|
}
|
|
115
|
-
if (!
|
|
122
|
+
if (!peaks) {
|
|
116
123
|
return null;
|
|
117
124
|
}
|
|
118
|
-
return (jsx_runtime_1.jsxs("div", { style: container, children: [
|
|
119
|
-
|
|
120
|
-
}), jsx_runtime_1.jsx("canvas", { ref: canvas, style: canvasStyle, width: visualizationWidth, height: (0, timeline_layout_1.getTimelineLayerHeight)('other') })
|
|
125
|
+
return (jsx_runtime_1.jsxs("div", { ref: containerRef, style: container, children: [
|
|
126
|
+
jsx_runtime_1.jsx("canvas", { ref: waveformCanvas, style: waveformCanvasStyle }), jsx_runtime_1.jsx("canvas", { ref: volumeCanvas, style: volumeCanvasStyle })
|
|
121
127
|
] }));
|
|
122
128
|
};
|
|
123
129
|
exports.AudioWaveform = AudioWaveform;
|
|
@@ -44,6 +44,7 @@ const canvas_ref_1 = require("../state/canvas-ref");
|
|
|
44
44
|
const timeline_zoom_1 = require("../state/timeline-zoom");
|
|
45
45
|
const z_index_1 = require("../state/z-index");
|
|
46
46
|
const EditorContent_1 = require("./EditorContent");
|
|
47
|
+
const ForceSpecificCursor_1 = require("./ForceSpecificCursor");
|
|
47
48
|
const GlobalKeybindings_1 = require("./GlobalKeybindings");
|
|
48
49
|
const Modals_1 = require("./Modals");
|
|
49
50
|
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
|
|
@@ -83,10 +84,12 @@ const Editor = ({ Root, readOnlyStudio }) => {
|
|
|
83
84
|
return react_1.default.memo(Root);
|
|
84
85
|
}, [Root]);
|
|
85
86
|
return (jsx_runtime_1.jsx(z_index_1.HigherZIndex, { onEscape: noop_1.noop, onOutsideClick: noop_1.noop, children: jsx_runtime_1.jsxs(timeline_zoom_1.TimelineZoomContext, { children: [
|
|
86
|
-
jsx_runtime_1.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
jsx_runtime_1.jsxs(remotion_1.Internals.CurrentScaleContext.Provider, { value: value, children: [
|
|
88
|
+
jsx_runtime_1.jsx(ForceSpecificCursor_1.ForceSpecificCursor, {}), jsx_runtime_1.jsxs("div", { style: background, children: [canvasMounted ? jsx_runtime_1.jsx(MemoRoot, {}) : null, jsx_runtime_1.jsxs(remotion_1.Internals.CanUseRemotionHooksProvider, { children: [
|
|
89
|
+
jsx_runtime_1.jsx(EditorContent_1.EditorContent, { readOnlyStudio: readOnlyStudio, children: jsx_runtime_1.jsx(TopPanel_1.TopPanel, { drawRef: canvas_ref_1.drawRef, bufferStateDelayInMilliseconds: exports.BUFFER_STATE_DELAY_IN_MILLISECONDS, onMounted: onMounted, readOnlyStudio: readOnlyStudio }) }), jsx_runtime_1.jsx(GlobalKeybindings_1.GlobalKeybindings, {})
|
|
90
|
+
] })
|
|
91
|
+
] })
|
|
92
|
+
] }), jsx_runtime_1.jsx(Modals_1.Modals, { readOnlyStudio: readOnlyStudio }), jsx_runtime_1.jsx(NotificationCenter_1.NotificationCenter, {})
|
|
90
93
|
] }) }));
|
|
91
94
|
};
|
|
92
95
|
exports.Editor = Editor;
|
|
@@ -7,6 +7,7 @@ const colors_1 = require("../../helpers/colors");
|
|
|
7
7
|
const editor_guides_1 = require("../../state/editor-guides");
|
|
8
8
|
const editor_rulers_1 = require("../../state/editor-rulers");
|
|
9
9
|
const ContextMenu_1 = require("../ContextMenu");
|
|
10
|
+
const ForceSpecificCursor_1 = require("../ForceSpecificCursor");
|
|
10
11
|
const PADDING_FOR_EASY_DRAG = 4;
|
|
11
12
|
const GuideComp = ({ guide, canvasDimensions, scale }) => {
|
|
12
13
|
const { shouldCreateGuideRef, setGuidesList, setSelectedGuideId, selectedGuideId, setHoveredGuideId, hoveredGuideId, } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
|
|
@@ -53,7 +54,7 @@ const GuideComp = ({ guide, canvasDimensions, scale }) => {
|
|
|
53
54
|
return;
|
|
54
55
|
}
|
|
55
56
|
shouldCreateGuideRef.current = true;
|
|
56
|
-
|
|
57
|
+
(0, ForceSpecificCursor_1.forceSpecificCursor)('no-drop');
|
|
57
58
|
setSelectedGuideId(() => guide.id);
|
|
58
59
|
}, [shouldCreateGuideRef, setSelectedGuideId, guide.id]);
|
|
59
60
|
const values = (0, react_1.useMemo)(() => {
|
|
@@ -7,6 +7,7 @@ const colors_1 = require("../../helpers/colors");
|
|
|
7
7
|
const editor_ruler_1 = require("../../helpers/editor-ruler");
|
|
8
8
|
const editor_guides_1 = require("../../state/editor-guides");
|
|
9
9
|
const editor_rulers_1 = require("../../state/editor-rulers");
|
|
10
|
+
const ForceSpecificCursor_1 = require("../ForceSpecificCursor");
|
|
10
11
|
const makeGuideId = () => {
|
|
11
12
|
return Math.random().toString(36).substring(7);
|
|
12
13
|
};
|
|
@@ -67,7 +68,7 @@ const Ruler = ({ scale, points, originOffset, startMarking, size, markingGaps, o
|
|
|
67
68
|
}
|
|
68
69
|
e.preventDefault();
|
|
69
70
|
shouldCreateGuideRef.current = true;
|
|
70
|
-
|
|
71
|
+
(0, ForceSpecificCursor_1.forceSpecificCursor)('no-drop');
|
|
71
72
|
const guideId = makeGuideId();
|
|
72
73
|
setEditorShowGuides(() => true);
|
|
73
74
|
setSelectedGuideId(() => guideId);
|
|
@@ -11,6 +11,7 @@ const editor_ruler_1 = require("../../helpers/editor-ruler");
|
|
|
11
11
|
const use_studio_canvas_dimensions_1 = require("../../helpers/use-studio-canvas-dimensions");
|
|
12
12
|
const editor_guides_1 = require("../../state/editor-guides");
|
|
13
13
|
const editor_rulers_1 = require("../../state/editor-rulers");
|
|
14
|
+
const ForceSpecificCursor_1 = require("../ForceSpecificCursor");
|
|
14
15
|
const Ruler_1 = __importDefault(require("./Ruler"));
|
|
15
16
|
const originBlockStyles = {
|
|
16
17
|
position: 'absolute',
|
|
@@ -70,9 +71,7 @@ const EditorRulers = ({ contentDimensions, canvasSize, assetMetadata, containerR
|
|
|
70
71
|
if (!shouldDeleteGuideRef.current) {
|
|
71
72
|
shouldDeleteGuideRef.current = true;
|
|
72
73
|
}
|
|
73
|
-
|
|
74
|
-
document.body.style.cursor = 'no-drop';
|
|
75
|
-
}
|
|
74
|
+
(0, ForceSpecificCursor_1.forceSpecificCursor)('no-drop');
|
|
76
75
|
setGuidesList((prevState) => {
|
|
77
76
|
const newGuides = prevState.map((guide) => {
|
|
78
77
|
if (guide.id !== selectedGuideId) {
|
|
@@ -103,9 +102,7 @@ const EditorRulers = ({ contentDimensions, canvasSize, assetMetadata, containerR
|
|
|
103
102
|
: (mouseY - containerTop) / scale -
|
|
104
103
|
canvasPosition.top / scale;
|
|
105
104
|
const desiredCursor = guide.orientation === 'vertical' ? 'ew-resize' : 'ns-resize';
|
|
106
|
-
|
|
107
|
-
document.body.style.cursor = desiredCursor;
|
|
108
|
-
}
|
|
105
|
+
(0, ForceSpecificCursor_1.forceSpecificCursor)(desiredCursor);
|
|
109
106
|
return {
|
|
110
107
|
...guide,
|
|
111
108
|
position: Math.floor(position / 1.0),
|
|
@@ -136,7 +133,7 @@ const EditorRulers = ({ contentDimensions, canvasSize, assetMetadata, containerR
|
|
|
136
133
|
return newGuides;
|
|
137
134
|
});
|
|
138
135
|
shouldDeleteGuideRef.current = false;
|
|
139
|
-
|
|
136
|
+
(0, ForceSpecificCursor_1.stopForcingSpecificCursor)();
|
|
140
137
|
shouldCreateGuideRef.current = false;
|
|
141
138
|
setSelectedGuideId(() => null);
|
|
142
139
|
document.removeEventListener('pointerup', onMouseUp);
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.ForceSpecificCursor = exports.stopForcingSpecificCursor = exports.forceSpecificCursor = void 0;
|
|
37
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
38
|
+
const react_1 = __importStar(require("react"));
|
|
39
|
+
const ref = react_1.default.createRef();
|
|
40
|
+
const forceSpecificCursor = (cursor) => {
|
|
41
|
+
if (!ref.current) {
|
|
42
|
+
throw new Error('ForceSpecificCursor is not mounted');
|
|
43
|
+
}
|
|
44
|
+
ref.current.style.cursor = cursor;
|
|
45
|
+
ref.current.style.pointerEvents = 'auto';
|
|
46
|
+
};
|
|
47
|
+
exports.forceSpecificCursor = forceSpecificCursor;
|
|
48
|
+
const stopForcingSpecificCursor = () => {
|
|
49
|
+
if (!ref.current) {
|
|
50
|
+
throw new Error('ForceSpecificCursor is not mounted');
|
|
51
|
+
}
|
|
52
|
+
ref.current.style.cursor = '';
|
|
53
|
+
ref.current.style.pointerEvents = 'none';
|
|
54
|
+
};
|
|
55
|
+
exports.stopForcingSpecificCursor = stopForcingSpecificCursor;
|
|
56
|
+
const Z_INDEX_FORCE_SPECIFIC_CURSOR = 100;
|
|
57
|
+
const ForceSpecificCursor = () => {
|
|
58
|
+
const style = (0, react_1.useMemo)(() => {
|
|
59
|
+
return {
|
|
60
|
+
position: 'fixed',
|
|
61
|
+
inset: 0,
|
|
62
|
+
zIndex: Z_INDEX_FORCE_SPECIFIC_CURSOR,
|
|
63
|
+
pointerEvents: 'none',
|
|
64
|
+
};
|
|
65
|
+
}, []);
|
|
66
|
+
return jsx_runtime_1.jsx("div", { ref: ref, style: style });
|
|
67
|
+
};
|
|
68
|
+
exports.ForceSpecificCursor = ForceSpecificCursor;
|
|
@@ -4,8 +4,11 @@ exports.MenuBuildIndicator = void 0;
|
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const react_1 = require("react");
|
|
6
6
|
const client_id_1 = require("../helpers/client-id");
|
|
7
|
+
const get_git_menu_item_1 = require("../helpers/get-git-menu-item");
|
|
8
|
+
const open_in_editor_1 = require("../helpers/open-in-editor");
|
|
7
9
|
const layout_1 = require("./layout");
|
|
8
|
-
const
|
|
10
|
+
const MenuCompositionName_1 = require("./MenuCompositionName");
|
|
11
|
+
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
|
|
9
12
|
const Spinner_1 = require("./Spinner");
|
|
10
13
|
const cwd = {
|
|
11
14
|
fontSize: 13,
|
|
@@ -25,10 +28,61 @@ const noSpinner = {
|
|
|
25
28
|
position: 'relative',
|
|
26
29
|
width: spinnerSize,
|
|
27
30
|
};
|
|
31
|
+
const projectNameLinkBase = {
|
|
32
|
+
color: 'inherit',
|
|
33
|
+
textDecoration: 'none',
|
|
34
|
+
cursor: 'pointer',
|
|
35
|
+
fontSize: 'inherit',
|
|
36
|
+
textUnderlineOffset: 2,
|
|
37
|
+
};
|
|
38
|
+
const projectNameLink = {
|
|
39
|
+
...projectNameLinkBase,
|
|
40
|
+
};
|
|
41
|
+
const projectNameLinkHovered = {
|
|
42
|
+
...projectNameLinkBase,
|
|
43
|
+
textDecoration: 'underline',
|
|
44
|
+
};
|
|
28
45
|
const MenuBuildIndicator = () => {
|
|
29
46
|
const [isBuilding, setIsBuilding] = (0, react_1.useState)(false);
|
|
47
|
+
const [projectNameHovered, setProjectNameHovered] = (0, react_1.useState)(false);
|
|
30
48
|
const ctx = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx).previewServerState;
|
|
31
|
-
const
|
|
49
|
+
const showEditorLink = window.remotion_editorName && ctx.type === 'connected';
|
|
50
|
+
const showGitLink = !showEditorLink && Boolean(window.remotion_gitSource);
|
|
51
|
+
const handleProjectNameClick = (0, react_1.useCallback)(async () => {
|
|
52
|
+
if (showEditorLink) {
|
|
53
|
+
await (0, open_in_editor_1.openInEditor)({
|
|
54
|
+
originalFileName: `${window.remotion_cwd}`,
|
|
55
|
+
originalLineNumber: 1,
|
|
56
|
+
originalColumnNumber: 1,
|
|
57
|
+
originalFunctionName: null,
|
|
58
|
+
originalScriptCode: null,
|
|
59
|
+
})
|
|
60
|
+
.then((res) => res.json())
|
|
61
|
+
.then(({ success }) => {
|
|
62
|
+
if (!success) {
|
|
63
|
+
(0, NotificationCenter_1.showNotification)(`Could not open ${window.remotion_editorName}`, 2000);
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
.catch((err) => {
|
|
67
|
+
// eslint-disable-next-line no-console
|
|
68
|
+
console.error(err);
|
|
69
|
+
(0, NotificationCenter_1.showNotification)(`Could not open ${window.remotion_editorName}`, 2000);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
else if (showGitLink) {
|
|
73
|
+
window.open((0, get_git_menu_item_1.getGitSourceBranchUrl)(window.remotion_gitSource), '_blank');
|
|
74
|
+
}
|
|
75
|
+
}, [showEditorLink, showGitLink]);
|
|
76
|
+
const projectNameTitle = (0, react_1.useMemo)(() => {
|
|
77
|
+
if (showEditorLink) {
|
|
78
|
+
return `Open in ${window.remotion_editorName}`;
|
|
79
|
+
}
|
|
80
|
+
if (showGitLink) {
|
|
81
|
+
return `Open ${(0, get_git_menu_item_1.getGitSourceName)(window.remotion_gitSource)} Repo`;
|
|
82
|
+
}
|
|
83
|
+
return undefined;
|
|
84
|
+
}, [showEditorLink, showGitLink]);
|
|
85
|
+
const isClickable = showEditorLink || showGitLink;
|
|
32
86
|
(0, react_1.useEffect)(() => {
|
|
33
87
|
window.remotion_isBuilding = () => {
|
|
34
88
|
setIsBuilding(true);
|
|
@@ -41,6 +95,7 @@ const MenuBuildIndicator = () => {
|
|
|
41
95
|
window.remotion_finishedBuilding = undefined;
|
|
42
96
|
};
|
|
43
97
|
}, []);
|
|
44
|
-
return (jsx_runtime_1.jsxs("div", { style: cwd, title: window.remotion_cwd, children: [
|
|
98
|
+
return (jsx_runtime_1.jsxs("div", { style: cwd, title: window.remotion_cwd, children: [isClickable ? jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }) : null, isBuilding ? (jsx_runtime_1.jsx("div", { style: spinner, children: jsx_runtime_1.jsx(Spinner_1.Spinner, { duration: 0.5, size: spinnerSize }) })) : (jsx_runtime_1.jsx("div", { style: noSpinner })), isClickable ? jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }) : null, isClickable ? (jsx_runtime_1.jsx("a", { style: projectNameHovered ? projectNameLinkHovered : projectNameLink, title: projectNameTitle, onClick: handleProjectNameClick, onPointerEnter: () => setProjectNameHovered(true), onPointerLeave: () => setProjectNameHovered(false), children: window.remotion_projectName })) : (window.remotion_projectName), jsx_runtime_1.jsx(MenuCompositionName_1.MenuCompositionName, {})
|
|
99
|
+
] }));
|
|
45
100
|
};
|
|
46
101
|
exports.MenuBuildIndicator = MenuBuildIndicator;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MenuCompositionName = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const remotion_1 = require("remotion");
|
|
7
|
+
const client_id_1 = require("../helpers/client-id");
|
|
8
|
+
const colors_1 = require("../helpers/colors");
|
|
9
|
+
const open_in_editor_1 = require("../helpers/open-in-editor");
|
|
10
|
+
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
|
|
11
|
+
const use_resolved_stack_1 = require("./Timeline/use-resolved-stack");
|
|
12
|
+
const baseStyle = {
|
|
13
|
+
color: 'inherit',
|
|
14
|
+
textDecoration: 'none',
|
|
15
|
+
fontSize: 'inherit',
|
|
16
|
+
textUnderlineOffset: 2,
|
|
17
|
+
};
|
|
18
|
+
const compositionNameStyle = {
|
|
19
|
+
...baseStyle,
|
|
20
|
+
cursor: 'default',
|
|
21
|
+
};
|
|
22
|
+
const clickableStyle = {
|
|
23
|
+
...baseStyle,
|
|
24
|
+
cursor: 'pointer',
|
|
25
|
+
};
|
|
26
|
+
const clickableHoveredStyle = {
|
|
27
|
+
...clickableStyle,
|
|
28
|
+
textDecoration: 'underline',
|
|
29
|
+
};
|
|
30
|
+
const slashStyle = {
|
|
31
|
+
color: colors_1.LIGHT_TEXT,
|
|
32
|
+
marginInline: 4,
|
|
33
|
+
position: 'relative',
|
|
34
|
+
top: 1,
|
|
35
|
+
};
|
|
36
|
+
const MenuCompositionName = () => {
|
|
37
|
+
var _a;
|
|
38
|
+
const { canvasContent, compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
|
39
|
+
const connectionStatus = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx)
|
|
40
|
+
.previewServerState.type;
|
|
41
|
+
const [opening, setOpening] = (0, react_1.useState)(false);
|
|
42
|
+
const [hovered, setHovered] = (0, react_1.useState)(false);
|
|
43
|
+
const composition = (0, react_1.useMemo)(() => {
|
|
44
|
+
var _a;
|
|
45
|
+
if (canvasContent === null || canvasContent.type !== 'composition') {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
return ((_a = compositions.find((c) => c.id === canvasContent.compositionId)) !== null && _a !== void 0 ? _a : null);
|
|
49
|
+
}, [canvasContent, compositions]);
|
|
50
|
+
const resolvedLocation = (0, use_resolved_stack_1.useResolvedStack)((_a = composition === null || composition === void 0 ? void 0 : composition.stack) !== null && _a !== void 0 ? _a : null);
|
|
51
|
+
const canOpen = resolvedLocation &&
|
|
52
|
+
window.remotion_editorName &&
|
|
53
|
+
connectionStatus === 'connected';
|
|
54
|
+
const handleClick = (0, react_1.useCallback)(async () => {
|
|
55
|
+
if (!canOpen || !resolvedLocation) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
setOpening(true);
|
|
59
|
+
try {
|
|
60
|
+
await (0, open_in_editor_1.openOriginalPositionInEditor)(resolvedLocation);
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
(0, NotificationCenter_1.showNotification)(err.message, 2000);
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
setOpening(false);
|
|
67
|
+
}
|
|
68
|
+
}, [canOpen, resolvedLocation]);
|
|
69
|
+
if (!composition) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
|
|
73
|
+
jsx_runtime_1.jsx("span", { style: slashStyle, children: "/" }), jsx_runtime_1.jsx("a", { style: canOpen && !opening
|
|
74
|
+
? hovered
|
|
75
|
+
? clickableHoveredStyle
|
|
76
|
+
: clickableStyle
|
|
77
|
+
: compositionNameStyle, title: canOpen ? `Open in ${window.remotion_editorName}` : composition.id, onClick: handleClick, onPointerEnter: () => setHovered(true), onPointerLeave: () => setHovered(false), children: composition.id })
|
|
78
|
+
] }));
|
|
79
|
+
};
|
|
80
|
+
exports.MenuCompositionName = MenuCompositionName;
|
|
@@ -41,6 +41,7 @@ const colors_1 = require("../../helpers/colors");
|
|
|
41
41
|
const noop_1 = require("../../helpers/noop");
|
|
42
42
|
const input_dragger_click_lock_1 = require("../../state/input-dragger-click-lock");
|
|
43
43
|
const z_index_1 = require("../../state/z-index");
|
|
44
|
+
const ForceSpecificCursor_1 = require("../ForceSpecificCursor");
|
|
44
45
|
const RemInput_1 = require("./RemInput");
|
|
45
46
|
const isInt = (num) => {
|
|
46
47
|
return num % 1 === 0;
|
|
@@ -135,6 +136,7 @@ const InputDraggerForwardRefFn = ({ onValueChange, onValueChangeEnd, min: _min,
|
|
|
135
136
|
if (distanceFromStart > 4) {
|
|
136
137
|
(0, input_dragger_click_lock_1.setClickLock)(true);
|
|
137
138
|
setDragging(true);
|
|
139
|
+
(0, ForceSpecificCursor_1.forceSpecificCursor)('ew-resize');
|
|
138
140
|
target.blur();
|
|
139
141
|
}
|
|
140
142
|
const diff = (0, remotion_1.interpolate)(xDistance, [-5, -4, 0, 4, 5], [-step, 0, 0, 0, step]);
|
|
@@ -148,6 +150,7 @@ const InputDraggerForwardRefFn = ({ onValueChange, onValueChangeEnd, min: _min,
|
|
|
148
150
|
window.removeEventListener('mousemove', moveListener);
|
|
149
151
|
pointerDownRef.current = false;
|
|
150
152
|
setDragging(false);
|
|
153
|
+
(0, ForceSpecificCursor_1.stopForcingSpecificCursor)();
|
|
151
154
|
if (lastDragValue !== null && onValueChangeEnd) {
|
|
152
155
|
onValueChangeEnd(lastDragValue);
|
|
153
156
|
}
|
|
@@ -103,13 +103,20 @@ const RenderModalJSONPropsEditor = ({ setValue, value, defaultProps, onSave, ser
|
|
|
103
103
|
}
|
|
104
104
|
const { result } = e;
|
|
105
105
|
if (result.canUpdate) {
|
|
106
|
-
|
|
106
|
+
const nextState = parseJS(result.currentDefaultProps, schema);
|
|
107
|
+
setLocalValue(nextState);
|
|
107
108
|
}
|
|
108
109
|
});
|
|
109
110
|
return () => {
|
|
110
111
|
unsub();
|
|
111
112
|
};
|
|
112
113
|
}, [subscribeToEvent, compositionId, schema]);
|
|
114
|
+
(0, react_1.useEffect)(() => {
|
|
115
|
+
if (localValue.validJSON && (0, deep_equal_1.deepEqual)(value, localValue.value)) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
setLocalValue(parseJS(value, schema));
|
|
119
|
+
}, [value, schema, localValue]);
|
|
113
120
|
const onPretty = (0, react_1.useCallback)(() => {
|
|
114
121
|
if (!localValue.validJSON) {
|
|
115
122
|
return;
|
|
@@ -137,8 +144,8 @@ const RenderModalJSONPropsEditor = ({ setValue, value, defaultProps, onSave, ser
|
|
|
137
144
|
}, [hasChanged, hasError, onSave]);
|
|
138
145
|
// If schema is changed in code
|
|
139
146
|
(0, react_1.useEffect)(() => {
|
|
140
|
-
setLocalValue(parseJSON(
|
|
141
|
-
}, [
|
|
147
|
+
setLocalValue((v) => parseJSON(v.str, schema));
|
|
148
|
+
}, [schema]);
|
|
142
149
|
const reset = (0, react_1.useCallback)(() => {
|
|
143
150
|
setValue(defaultProps);
|
|
144
151
|
setLocalValue(parseJSON(JSON.stringify(defaultProps, null, 2), schema));
|
|
@@ -4,6 +4,7 @@ exports.SplitterHandle = exports.SPLITTER_HANDLE_SIZE = void 0;
|
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const player_1 = require("@remotion/player");
|
|
6
6
|
const react_1 = require("react");
|
|
7
|
+
const ForceSpecificCursor_1 = require("../ForceSpecificCursor");
|
|
7
8
|
const SplitterContext_1 = require("./SplitterContext");
|
|
8
9
|
exports.SPLITTER_HANDLE_SIZE = 3;
|
|
9
10
|
const containerRow = {
|
|
@@ -58,6 +59,7 @@ const SplitterHandle = ({ allowToCollapse, onCollapse }) => {
|
|
|
58
59
|
x: e.clientX,
|
|
59
60
|
y: e.clientY,
|
|
60
61
|
};
|
|
62
|
+
(0, ForceSpecificCursor_1.forceSpecificCursor)(context.orientation === 'horizontal' ? 'row-resize' : 'col-resize');
|
|
61
63
|
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.classList.add('remotion-splitter-active');
|
|
62
64
|
window.addEventListener('pointerup', (ev) => {
|
|
63
65
|
if (!context.isDragging.current) {
|
|
@@ -94,6 +96,7 @@ const SplitterHandle = ({ allowToCollapse, onCollapse }) => {
|
|
|
94
96
|
const cleanup = () => {
|
|
95
97
|
var _a;
|
|
96
98
|
context.isDragging.current = false;
|
|
99
|
+
(0, ForceSpecificCursor_1.stopForcingSpecificCursor)();
|
|
97
100
|
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.classList.remove('remotion-splitter-active');
|
|
98
101
|
current.removeEventListener('pointerdown', onPointerDown);
|
|
99
102
|
window.removeEventListener('pointermove', onPointerMove);
|
|
@@ -75,15 +75,15 @@ const TimelineInner = () => {
|
|
|
75
75
|
const visualModeEnabled = Boolean(process.env.EXPERIMENTAL_VISUAL_MODE_ENABLED) &&
|
|
76
76
|
previewServerState.type === 'connected';
|
|
77
77
|
const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
|
|
78
|
+
const videoConfigIsNull = videoConfig === null;
|
|
78
79
|
const timeline = (0, react_1.useMemo)(() => {
|
|
79
|
-
if (
|
|
80
|
+
if (videoConfigIsNull) {
|
|
80
81
|
return [];
|
|
81
82
|
}
|
|
82
83
|
return (0, calculate_timeline_1.calculateTimeline)({
|
|
83
84
|
sequences,
|
|
84
|
-
sequenceDuration: videoConfig.durationInFrames,
|
|
85
85
|
});
|
|
86
|
-
}, [sequences,
|
|
86
|
+
}, [sequences, videoConfigIsNull]);
|
|
87
87
|
const durationInFrames = (_a = videoConfig === null || videoConfig === void 0 ? void 0 : videoConfig.durationInFrames) !== null && _a !== void 0 ? _a : 0;
|
|
88
88
|
const filtered = (0, react_1.useMemo)(() => {
|
|
89
89
|
const withoutHidden = timeline.filter((t) => !(0, is_collapsed_1.isTrackHidden)(t));
|