@remotion/studio 4.0.470 → 4.0.471

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/components/ContextMenu.d.ts +7 -2
  2. package/dist/components/ContextMenu.js +50 -10
  3. package/dist/components/Preview.js +2 -1
  4. package/dist/components/SelectedOutlineOverlay.d.ts +31 -0
  5. package/dist/components/SelectedOutlineOverlay.js +100 -35
  6. package/dist/components/Timeline/Timeline.js +76 -1
  7. package/dist/components/Timeline/TimelineDeleteKeybindings.js +15 -0
  8. package/dist/components/Timeline/TimelineDragHandler.js +1 -0
  9. package/dist/components/Timeline/TimelineEffectItem.js +157 -4
  10. package/dist/components/Timeline/TimelineKeyframeControls.js +16 -11
  11. package/dist/components/Timeline/TimelineRowChrome.d.ts +3 -0
  12. package/dist/components/Timeline/TimelineRowChrome.js +3 -3
  13. package/dist/components/Timeline/TimelineSequenceItem.js +91 -1
  14. package/dist/components/Timeline/call-delete-keyframe.d.ts +16 -0
  15. package/dist/components/Timeline/call-delete-keyframe.js +86 -14
  16. package/dist/components/Timeline/delete-selected-keyframe.d.ts +10 -0
  17. package/dist/components/Timeline/delete-selected-keyframe.js +48 -7
  18. package/dist/components/Timeline/delete-selected-timeline-item.js +6 -11
  19. package/dist/components/Timeline/reset-selected-timeline-props.d.ts +38 -0
  20. package/dist/components/Timeline/reset-selected-timeline-props.js +143 -0
  21. package/dist/components/Timeline/sequence-props-subscription-store.d.ts +3 -2
  22. package/dist/components/Timeline/sequence-props-subscription-store.js +2 -1
  23. package/dist/components/Timeline/timeline-scroll-logic.js +3 -3
  24. package/dist/components/Timeline/use-sequence-props-subscription.js +2 -1
  25. package/dist/esm/{chunk-dny42qnq.js → chunk-z0z9d4r0.js} +1704 -962
  26. package/dist/esm/internals.mjs +1704 -962
  27. package/dist/esm/previewEntry.mjs +1711 -967
  28. package/dist/esm/renderEntry.mjs +1 -1
  29. package/dist/helpers/get-left-of-timeline-slider.js +1 -1
  30. package/dist/helpers/get-timeline-sequence-layout.js +10 -11
  31. package/dist/helpers/open-in-editor.d.ts +19 -1
  32. package/dist/helpers/open-in-editor.js +42 -4
  33. package/dist/helpers/use-menu-structure.js +0 -1
  34. package/dist/state/z-index.js +5 -2
  35. package/package.json +10 -10
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.deleteSelectedKeyframe = void 0;
3
+ exports.deleteSelectedKeyframes = exports.deleteSelectedKeyframe = void 0;
4
4
  const call_delete_keyframe_1 = require("./call-delete-keyframe");
5
5
  const find_track_for_node_path_info_1 = require("./find-track-for-node-path-info");
6
6
  const parse_keyframe_field_from_node_path_1 = require("./parse-keyframe-field-from-node-path");
7
- const deleteSelectedKeyframe = ({ nodePathInfo, frame, sequences, overrideIdsToNodePaths, setCodeValues, clientId, }) => {
7
+ const getSelectedKeyframeDeletion = ({ nodePathInfo, frame, sequences, overrideIdsToNodePaths, }) => {
8
8
  var _a, _b;
9
9
  const field = (0, parse_keyframe_field_from_node_path_1.parseKeyframeFieldFromNodePath)(nodePathInfo.auxiliaryKeys);
10
10
  if (field === null) {
@@ -27,25 +27,66 @@ const deleteSelectedKeyframe = ({ nodePathInfo, frame, sequences, overrideIdsToN
27
27
  if (!effect) {
28
28
  return null;
29
29
  }
30
- return (0, call_delete_keyframe_1.callDeleteEffectKeyframe)({
30
+ return {
31
+ type: 'effect',
31
32
  fileName,
32
33
  nodePath,
33
34
  effectIndex: field.effectIndex,
34
35
  fieldKey: field.fieldKey,
35
36
  sourceFrame,
36
37
  schema: effect.schema,
37
- setCodeValues,
38
- clientId,
39
- });
38
+ };
40
39
  }
41
- return (0, call_delete_keyframe_1.callDeleteSequenceKeyframe)({
40
+ return {
41
+ type: 'sequence',
42
42
  fileName,
43
43
  nodePath,
44
44
  fieldKey: field.fieldKey,
45
45
  sourceFrame,
46
46
  schema: sequence.controls.schema,
47
+ };
48
+ };
49
+ const deleteSelectedKeyframe = ({ nodePathInfo, frame, sequences, overrideIdsToNodePaths, setCodeValues, clientId, }) => {
50
+ const deletion = getSelectedKeyframeDeletion({
51
+ nodePathInfo,
52
+ frame,
53
+ sequences,
54
+ overrideIdsToNodePaths,
55
+ });
56
+ if (deletion === null) {
57
+ return null;
58
+ }
59
+ if (deletion.type === 'effect') {
60
+ return (0, call_delete_keyframe_1.callDeleteEffectKeyframe)({
61
+ ...deletion,
62
+ setCodeValues,
63
+ clientId,
64
+ });
65
+ }
66
+ return (0, call_delete_keyframe_1.callDeleteSequenceKeyframe)({
67
+ ...deletion,
47
68
  setCodeValues,
48
69
  clientId,
49
70
  });
50
71
  };
51
72
  exports.deleteSelectedKeyframe = deleteSelectedKeyframe;
73
+ const deleteSelectedKeyframes = ({ keyframes, sequences, overrideIdsToNodePaths, setCodeValues, clientId, }) => {
74
+ const deletions = keyframes
75
+ .map((keyframe) => getSelectedKeyframeDeletion({
76
+ nodePathInfo: keyframe.nodePathInfo,
77
+ frame: keyframe.frame,
78
+ sequences,
79
+ overrideIdsToNodePaths,
80
+ }))
81
+ .filter((deletion) => deletion !== null);
82
+ if (deletions.length === 0) {
83
+ return null;
84
+ }
85
+ return (0, call_delete_keyframe_1.callDeleteKeyframes)({
86
+ sequenceKeyframes: deletions.filter((deletion) => deletion.type === 'sequence'),
87
+ effectKeyframes: deletions.filter((deletion) => deletion.type === 'effect'),
88
+ setCodeValues,
89
+ clientId,
90
+ });
91
+ };
92
+ exports.deleteSelectedKeyframes = deleteSelectedKeyframes;
@@ -152,21 +152,16 @@ const deleteSelectedTimelineItems = ({ selections, sequences, overrideIdsToNodeP
152
152
  effectIndex: selection.i,
153
153
  })));
154
154
  case 'keyframe': {
155
- const deletePromises = selections
156
- .filter(isKeyframeSelection)
157
- .map((selection) => (0, delete_selected_keyframe_1.deleteSelectedKeyframe)({
158
- nodePathInfo: selection.nodePathInfo,
159
- frame: selection.frame,
155
+ return (0, delete_selected_keyframe_1.deleteSelectedKeyframes)({
156
+ keyframes: selections.filter(isKeyframeSelection).map((selection) => ({
157
+ nodePathInfo: selection.nodePathInfo,
158
+ frame: selection.frame,
159
+ })),
160
160
  sequences,
161
161
  overrideIdsToNodePaths,
162
162
  setCodeValues,
163
163
  clientId,
164
- }))
165
- .filter((promise) => promise !== null);
166
- if (deletePromises.length === 0) {
167
- return null;
168
- }
169
- return Promise.all(deletePromises).then(() => undefined);
164
+ });
170
165
  }
171
166
  case 'sequence-prop':
172
167
  case 'sequence-effect-prop':
@@ -0,0 +1,38 @@
1
+ import type { CodeValues, OverrideIdToNodePaths, SequencePropsSubscriptionKey, SequenceSchema, TSequence } from 'remotion';
2
+ import type { SetCodeValues } from './save-sequence-prop';
3
+ import type { TimelineSelection } from './TimelineSelection';
4
+ type SequencePropResetTarget = {
5
+ readonly type: 'sequence-prop';
6
+ readonly fileName: string;
7
+ readonly nodePath: SequencePropsSubscriptionKey;
8
+ readonly fieldKey: string;
9
+ readonly value: unknown;
10
+ readonly defaultValue: string | null;
11
+ readonly schema: SequenceSchema;
12
+ };
13
+ type EffectPropResetTarget = {
14
+ readonly type: 'effect-prop';
15
+ readonly fileName: string;
16
+ readonly nodePath: SequencePropsSubscriptionKey;
17
+ readonly effectIndex: number;
18
+ readonly fieldKey: string;
19
+ readonly value: unknown;
20
+ readonly defaultValue: string | null;
21
+ readonly schema: SequenceSchema;
22
+ };
23
+ type TimelinePropResetTarget = SequencePropResetTarget | EffectPropResetTarget;
24
+ export declare const getTimelinePropResetTargets: ({ selections, sequences, overrideIdsToNodePaths, codeValues, }: {
25
+ readonly selections: readonly TimelineSelection[];
26
+ readonly sequences: TSequence[];
27
+ readonly overrideIdsToNodePaths: OverrideIdToNodePaths;
28
+ readonly codeValues: CodeValues;
29
+ }) => TimelinePropResetTarget[] | null;
30
+ export declare const resetSelectedTimelineProps: ({ selections, sequences, overrideIdsToNodePaths, codeValues, setCodeValues, clientId, }: {
31
+ readonly selections: readonly TimelineSelection[];
32
+ readonly sequences: TSequence[];
33
+ readonly overrideIdsToNodePaths: OverrideIdToNodePaths;
34
+ readonly codeValues: CodeValues;
35
+ readonly setCodeValues: SetCodeValues;
36
+ readonly clientId: string;
37
+ }) => Promise<void> | null;
38
+ export {};
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resetSelectedTimelineProps = exports.getTimelinePropResetTargets = void 0;
4
+ const remotion_1 = require("remotion");
5
+ const find_track_for_node_path_info_1 = require("./find-track-for-node-path-info");
6
+ const save_effect_prop_1 = require("./save-effect-prop");
7
+ const save_sequence_prop_1 = require("./save-sequence-prop");
8
+ const isPropResetSelection = (selection) => selection.type === 'sequence-prop' ||
9
+ selection.type === 'sequence-effect-prop';
10
+ const isVisibleFieldSchema = (fieldSchema) => fieldSchema !== undefined && fieldSchema.type !== 'hidden';
11
+ const isNonDefaultCodeValue = ({ codeValue, defaultValue, }) => JSON.stringify(codeValue !== null && codeValue !== void 0 ? codeValue : defaultValue) !== JSON.stringify(defaultValue);
12
+ const getDefaultValue = (fieldSchema) => fieldSchema.default !== undefined
13
+ ? JSON.stringify(fieldSchema.default)
14
+ : null;
15
+ const getTimelinePropResetTargets = ({ selections, sequences, overrideIdsToNodePaths, codeValues, }) => {
16
+ var _a;
17
+ var _b;
18
+ const firstSelection = selections[0];
19
+ if (!firstSelection || !isPropResetSelection(firstSelection)) {
20
+ return null;
21
+ }
22
+ const resetTargets = [];
23
+ for (const selection of selections) {
24
+ if (!isPropResetSelection(selection)) {
25
+ throw new Error(`Assertion failed: Cannot reset timeline selections of different types (${firstSelection.type}, ${selection.type})`);
26
+ }
27
+ const track = (0, find_track_for_node_path_info_1.findTrackForNodePathInfo)({
28
+ sequences,
29
+ overrideIdsToNodePaths,
30
+ nodePathInfo: selection.nodePathInfo,
31
+ });
32
+ const sequence = (_b = track === null || track === void 0 ? void 0 : track.sequence) !== null && _b !== void 0 ? _b : null;
33
+ if (!sequence) {
34
+ continue;
35
+ }
36
+ const nodePath = selection.nodePathInfo.sequenceSubscriptionKey;
37
+ if (selection.type === 'sequence-prop') {
38
+ if (!sequence.controls) {
39
+ continue;
40
+ }
41
+ const sequenceFieldSchema = sequence.controls.schema[selection.key];
42
+ const sequencePropStatus = (_a = remotion_1.Internals.getCodeValuesCtx(codeValues, nodePath)) === null || _a === void 0 ? void 0 : _a[selection.key];
43
+ if (!isVisibleFieldSchema(sequenceFieldSchema) ||
44
+ !(sequencePropStatus === null || sequencePropStatus === void 0 ? void 0 : sequencePropStatus.canUpdate) ||
45
+ !isNonDefaultCodeValue({
46
+ codeValue: sequencePropStatus.codeValue,
47
+ defaultValue: sequenceFieldSchema.default,
48
+ })) {
49
+ continue;
50
+ }
51
+ resetTargets.push({
52
+ type: 'sequence-prop',
53
+ fileName: nodePath.absolutePath,
54
+ nodePath,
55
+ fieldKey: selection.key,
56
+ value: sequenceFieldSchema.default,
57
+ defaultValue: getDefaultValue(sequenceFieldSchema),
58
+ schema: sequence.controls.schema,
59
+ });
60
+ continue;
61
+ }
62
+ const effect = sequence.effects[selection.i];
63
+ const fieldSchema = effect === null || effect === void 0 ? void 0 : effect.schema[selection.key];
64
+ const effectStatus = remotion_1.Internals.getEffectCodeValuesCtx({
65
+ codeValues,
66
+ nodePath,
67
+ effectIndex: selection.i,
68
+ });
69
+ const propStatus = effectStatus.type === 'can-update-effect'
70
+ ? effectStatus.props[selection.key]
71
+ : null;
72
+ if (!effect ||
73
+ !isVisibleFieldSchema(fieldSchema) ||
74
+ !(propStatus === null || propStatus === void 0 ? void 0 : propStatus.canUpdate) ||
75
+ !isNonDefaultCodeValue({
76
+ codeValue: propStatus.codeValue,
77
+ defaultValue: fieldSchema.default,
78
+ })) {
79
+ continue;
80
+ }
81
+ resetTargets.push({
82
+ type: 'effect-prop',
83
+ fileName: nodePath.absolutePath,
84
+ nodePath,
85
+ effectIndex: selection.i,
86
+ fieldKey: selection.key,
87
+ value: fieldSchema.default,
88
+ defaultValue: getDefaultValue(fieldSchema),
89
+ schema: effect.schema,
90
+ });
91
+ }
92
+ return resetTargets;
93
+ };
94
+ exports.getTimelinePropResetTargets = getTimelinePropResetTargets;
95
+ const resetSelectedTimelineProps = ({ selections, sequences, overrideIdsToNodePaths, codeValues, setCodeValues, clientId, }) => {
96
+ const resetTargets = (0, exports.getTimelinePropResetTargets)({
97
+ selections,
98
+ sequences,
99
+ overrideIdsToNodePaths,
100
+ codeValues,
101
+ });
102
+ if (resetTargets === null || resetTargets.length === 0) {
103
+ return null;
104
+ }
105
+ const sequencePropTargets = resetTargets.filter((target) => target.type === 'sequence-prop');
106
+ const effectPropTargets = resetTargets.filter((target) => target.type === 'effect-prop');
107
+ const resetPromises = [];
108
+ if (sequencePropTargets.length > 0) {
109
+ resetPromises.push((0, save_sequence_prop_1.saveSequenceProps)({
110
+ changes: sequencePropTargets.map((target) => ({
111
+ fileName: target.fileName,
112
+ nodePath: target.nodePath,
113
+ fieldKey: target.fieldKey,
114
+ value: target.value,
115
+ defaultValue: target.defaultValue,
116
+ schema: target.schema,
117
+ })),
118
+ setCodeValues,
119
+ clientId,
120
+ undoLabel: sequencePropTargets.length > 1
121
+ ? 'Reset selected sequence props'
122
+ : null,
123
+ redoLabel: sequencePropTargets.length > 1
124
+ ? 'Reapply selected sequence props'
125
+ : null,
126
+ }));
127
+ }
128
+ for (const target of effectPropTargets) {
129
+ resetPromises.push((0, save_effect_prop_1.saveEffectProp)({
130
+ fileName: target.fileName,
131
+ nodePath: target.nodePath,
132
+ effectIndex: target.effectIndex,
133
+ fieldKey: target.fieldKey,
134
+ value: target.value,
135
+ defaultValue: target.defaultValue,
136
+ schema: target.schema,
137
+ setCodeValues,
138
+ clientId,
139
+ }));
140
+ }
141
+ return Promise.all(resetPromises).then(() => undefined);
142
+ };
143
+ exports.resetSelectedTimelineProps = resetSelectedTimelineProps;
@@ -1,13 +1,14 @@
1
- import type { SequenceSchema } from 'remotion';
1
+ import type { SequenceNodePath, SequenceSchema } from 'remotion';
2
2
  import { callApi } from '../call-api';
3
3
  type SubscribeResult = Awaited<ReturnType<typeof callApi<'/api/subscribe-to-sequence-props'>>>;
4
4
  type ApplyResult = (result: SubscribeResult) => void;
5
- export declare const acquireSequencePropsSubscription: ({ fileName, line, column, schema, effects, clientId, applyOnce, applyEach, }: {
5
+ export declare const acquireSequencePropsSubscription: ({ fileName, line, column, schema, effects, nodePath, clientId, applyOnce, applyEach, }: {
6
6
  fileName: string;
7
7
  line: number;
8
8
  column: number;
9
9
  schema: SequenceSchema;
10
10
  effects: SequenceSchema[];
11
+ nodePath: SequenceNodePath | null;
11
12
  clientId: string;
12
13
  applyOnce: ApplyResult;
13
14
  applyEach: ApplyResult;
@@ -6,7 +6,7 @@ const remotion_1 = require("remotion");
6
6
  const call_api_1 = require("../call-api");
7
7
  const makeKey = (fileName, line, column, sequenceKeys, effectKeys) => `${fileName}\0${line}\0${column}\0${sequenceKeys.join('\0')}\0${effectKeys.map((keys) => keys.join('\0')).join('\0\0')}`;
8
8
  const entries = new Map();
9
- const acquireSequencePropsSubscription = ({ fileName, line, column, schema, effects, clientId, applyOnce, applyEach, }) => {
9
+ const acquireSequencePropsSubscription = ({ fileName, line, column, schema, effects, nodePath, clientId, applyOnce, applyEach, }) => {
10
10
  const sequenceKeys = (0, studio_shared_1.getAllSchemaKeys)(schema);
11
11
  const effectKeys = effects.map((effect) => (0, studio_shared_1.getAllSchemaKeys)(effect));
12
12
  const key = makeKey(fileName, line, column, sequenceKeys, effectKeys);
@@ -16,6 +16,7 @@ const acquireSequencePropsSubscription = ({ fileName, line, column, schema, effe
16
16
  fileName,
17
17
  line,
18
18
  column,
19
+ nodePath,
19
20
  keys: (0, studio_shared_1.getAllSchemaKeys)(schema),
20
21
  effects: effectKeys,
21
22
  clientId,
@@ -172,7 +172,7 @@ const getFrameIncrement = (durationInFrames) => {
172
172
  return (0, exports.getFrameIncrementFromWidth)(durationInFrames, width);
173
173
  };
174
174
  const getFrameIncrementFromWidth = (durationInFrames, width) => {
175
- return (width - timeline_layout_1.TIMELINE_PADDING * 2) / (durationInFrames - 1);
175
+ return (width - timeline_layout_1.TIMELINE_PADDING * 2) / durationInFrames;
176
176
  };
177
177
  exports.getFrameIncrementFromWidth = getFrameIncrementFromWidth;
178
178
  const getFrameWhileScrollingRight = ({ durationInFrames, width, }) => {
@@ -193,10 +193,10 @@ const getFrameWhileScrollingRight = ({ durationInFrames, width, }) => {
193
193
  exports.getFrameWhileScrollingRight = getFrameWhileScrollingRight;
194
194
  const getFrameFromX = ({ clientX, durationInFrames, width, extrapolate, }) => {
195
195
  const pos = clientX - timeline_layout_1.TIMELINE_PADDING;
196
- const frame = Math.round((0, remotion_1.interpolate)(pos, [0, width - timeline_layout_1.TIMELINE_PADDING * 2], [0, durationInFrames - 1], {
196
+ const frame = Math.min(durationInFrames - 1, Math.round((0, remotion_1.interpolate)(pos, [0, width - timeline_layout_1.TIMELINE_PADDING * 2], [0, durationInFrames], {
197
197
  extrapolateLeft: extrapolate,
198
198
  extrapolateRight: extrapolate,
199
- }));
199
+ })));
200
200
  return frame;
201
201
  };
202
202
  exports.getFrameFromX = getFrameFromX;
@@ -36,7 +36,7 @@ const useSequencePropsSubscription = ({ originalLocation, overrideId, schema, ef
36
36
  const locationLine = (_b = validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.line) !== null && _b !== void 0 ? _b : null;
37
37
  const locationColumn = (_c = validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.column) !== null && _c !== void 0 ? _c : null;
38
38
  (0, react_1.useEffect)(() => {
39
- var _a;
39
+ var _a, _b;
40
40
  if (!clientId ||
41
41
  !locationSource ||
42
42
  !locationLine ||
@@ -51,6 +51,7 @@ const useSequencePropsSubscription = ({ originalLocation, overrideId, schema, ef
51
51
  column: locationColumn,
52
52
  schema,
53
53
  effects,
54
+ nodePath: (_b = nodePathAtResubscribe === null || nodePathAtResubscribe === void 0 ? void 0 : nodePathAtResubscribe.nodePath) !== null && _b !== void 0 ? _b : null,
54
55
  clientId,
55
56
  applyOnce: (result) => {
56
57
  if (!result.success) {