@remotion/studio 4.0.463 → 4.0.465

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 (94) hide show
  1. package/dist/components/CanvasOrLoading.js +1 -1
  2. package/dist/components/ColorPicker/AlphaSlider.d.ts +9 -0
  3. package/dist/components/ColorPicker/AlphaSlider.js +88 -0
  4. package/dist/components/ColorPicker/ColorPicker.d.ts +18 -0
  5. package/dist/components/ColorPicker/ColorPicker.js +176 -0
  6. package/dist/components/ColorPicker/ColorPickerPopup.d.ts +8 -0
  7. package/dist/components/ColorPicker/ColorPickerPopup.js +276 -0
  8. package/dist/components/ColorPicker/HueSlider.d.ts +6 -0
  9. package/dist/components/ColorPicker/HueSlider.js +68 -0
  10. package/dist/components/ColorPicker/SaturationValueArea.d.ts +14 -0
  11. package/dist/components/ColorPicker/SaturationValueArea.js +93 -0
  12. package/dist/components/ColorPicker/checker.d.ts +4 -0
  13. package/dist/components/ColorPicker/checker.js +9 -0
  14. package/dist/components/ExpandedTracksProvider.d.ts +2 -0
  15. package/dist/components/ExpandedTracksProvider.js +18 -1
  16. package/dist/components/NewComposition/CodemodFooter.d.ts +1 -0
  17. package/dist/components/NewComposition/CodemodFooter.js +35 -23
  18. package/dist/components/NewComposition/DeleteComposition.js +3 -1
  19. package/dist/components/NewComposition/DiffPreview.js +1 -1
  20. package/dist/components/NewComposition/DuplicateComposition.js +3 -1
  21. package/dist/components/NewComposition/RenameComposition.js +4 -2
  22. package/dist/components/RenderModal/SchemaEditor/ZodColorEditor.js +8 -47
  23. package/dist/components/RenderQueue/actions.d.ts +2 -1
  24. package/dist/components/RenderQueue/actions.js +2 -1
  25. package/dist/components/Timeline/Padder.js +2 -2
  26. package/dist/components/Timeline/SubscribeToNodePaths.d.ts +1 -1
  27. package/dist/components/Timeline/SubscribeToNodePaths.js +9 -4
  28. package/dist/components/Timeline/Timeline.js +4 -7
  29. package/dist/components/Timeline/TimelineColorField.js +18 -156
  30. package/dist/components/Timeline/TimelineEffectFieldRow.d.ts +1 -2
  31. package/dist/components/Timeline/TimelineEffectFieldRow.js +22 -31
  32. package/dist/components/Timeline/TimelineEffectGroupRow.d.ts +1 -2
  33. package/dist/components/Timeline/TimelineEffectGroupRow.js +67 -12
  34. package/dist/components/Timeline/TimelineExpandedRow.js +15 -30
  35. package/dist/components/Timeline/TimelineFieldRow.d.ts +1 -2
  36. package/dist/components/Timeline/TimelineFieldRow.js +19 -16
  37. package/dist/components/Timeline/TimelineImageInfo.js +5 -17
  38. package/dist/components/Timeline/TimelineListItem.d.ts +0 -1
  39. package/dist/components/Timeline/TimelineListItem.js +12 -14
  40. package/dist/components/Timeline/TimelineRowChrome.d.ts +8 -0
  41. package/dist/components/Timeline/TimelineRowChrome.js +21 -0
  42. package/dist/components/Timeline/TimelineTimeIndicators.js +4 -11
  43. package/dist/components/Timeline/TimelineTracks.js +0 -4
  44. package/dist/components/Timeline/TimelineVideoInfo.js +25 -8
  45. package/dist/components/Timeline/get-timeline-video-info-widths.d.ts +9 -0
  46. package/dist/components/Timeline/get-timeline-video-info-widths.js +11 -0
  47. package/dist/components/Timeline/save-effect-prop.d.ts +2 -1
  48. package/dist/components/Timeline/save-effect-prop.js +2 -13
  49. package/dist/components/Timeline/save-prop-queue.d.ts +1 -2
  50. package/dist/components/Timeline/save-prop-queue.js +3 -12
  51. package/dist/components/Timeline/save-sequence-prop.d.ts +2 -1
  52. package/dist/components/Timeline/save-sequence-prop.js +2 -11
  53. package/dist/components/Timeline/should-show-track-in-timeline.d.ts +2 -0
  54. package/dist/components/Timeline/should-show-track-in-timeline.js +23 -0
  55. package/dist/components/Timeline/timeline-field-row-layout.d.ts +2 -0
  56. package/dist/components/Timeline/timeline-field-row-layout.js +14 -0
  57. package/dist/components/Timeline/timeline-indent.d.ts +1 -0
  58. package/dist/components/Timeline/timeline-indent.js +4 -0
  59. package/dist/components/Timeline/timeline-row-layout.d.ts +11 -0
  60. package/dist/components/Timeline/timeline-row-layout.js +27 -0
  61. package/dist/components/Timeline/use-resolved-stack-react-to-change.d.ts +2 -0
  62. package/dist/components/Timeline/use-resolved-stack-react-to-change.js +59 -0
  63. package/dist/components/Timeline/use-resolved-stack.d.ts +1 -0
  64. package/dist/components/Timeline/use-resolved-stack.js +10 -1
  65. package/dist/components/Timeline/use-sequence-props-subscription.js +27 -1
  66. package/dist/error-overlay/remotion-overlay/ShortcutHint.js +5 -3
  67. package/dist/esm/chunk-6jf1natv.js +25 -0
  68. package/dist/esm/{chunk-b0m62frw.js → chunk-pqk2qd0d.js} +4971 -4013
  69. package/dist/esm/index.mjs +16 -0
  70. package/dist/esm/internals.mjs +4984 -4011
  71. package/dist/esm/previewEntry.mjs +4995 -4023
  72. package/dist/esm/renderEntry.mjs +4 -3
  73. package/dist/helpers/client-id.d.ts +2 -9
  74. package/dist/helpers/client-id.js +15 -40
  75. package/dist/helpers/color-conversion.d.ts +36 -0
  76. package/dist/helpers/color-conversion.js +121 -0
  77. package/dist/helpers/inject-css.js +4 -7
  78. package/dist/helpers/migrate-expanded-tracks-for-subscription-key.d.ts +3 -0
  79. package/dist/helpers/migrate-expanded-tracks-for-subscription-key.js +26 -0
  80. package/dist/helpers/preview-server-events.d.ts +15 -0
  81. package/dist/helpers/preview-server-events.js +81 -0
  82. package/dist/helpers/resolved-stack-to-symbolicated.d.ts +3 -0
  83. package/dist/helpers/resolved-stack-to-symbolicated.js +16 -0
  84. package/dist/helpers/timeline-layout.d.ts +0 -1
  85. package/dist/helpers/timeline-layout.js +29 -25
  86. package/dist/hot-middleware-client/client.js +10 -16
  87. package/package.json +10 -10
  88. package/dist/components/NewComposition/RemInputTypeColor.d.ts +0 -8
  89. package/dist/components/NewComposition/RemInputTypeColor.js +0 -53
  90. package/dist/components/Timeline/is-collapsed.d.ts +0 -2
  91. package/dist/components/Timeline/is-collapsed.js +0 -10
  92. package/dist/esm/chunk-5gtx3pza.js +0 -9
  93. package/dist/helpers/color-math.d.ts +0 -1
  94. package/dist/helpers/color-math.js +0 -13
@@ -3,179 +3,41 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TimelineColorField = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
- const no_react_1 = require("remotion/no-react");
7
- const colors_1 = require("../../helpers/colors");
8
- const eyedropper_1 = require("../../icons/eyedropper");
9
- const z_index_1 = require("../../state/z-index");
10
- const SWATCH_WIDTH = 20;
11
- const SWATCH_HEIGHT = 15;
6
+ const ColorPicker_1 = require("../ColorPicker/ColorPicker");
12
7
  const containerStyle = {
13
8
  display: 'flex',
14
9
  alignItems: 'center',
15
10
  gap: 3,
16
11
  };
17
- const swatchWrapperBase = {
18
- position: 'relative',
19
- width: SWATCH_WIDTH,
20
- height: SWATCH_HEIGHT,
21
- display: 'inline-block',
22
- borderRadius: 3,
23
- overflow: 'hidden',
24
- cursor: 'pointer',
25
- borderStyle: 'solid',
26
- borderWidth: 1,
27
- };
28
- const hiddenInputStyle = {
29
- position: 'absolute',
30
- inset: 0,
31
- width: '100%',
32
- height: '100%',
33
- opacity: 0,
34
- cursor: 'pointer',
35
- border: 'none',
36
- padding: 0,
37
- margin: 0,
38
- };
39
- const swatchFillStyle = {
40
- width: '100%',
41
- height: '100%',
42
- };
43
- const eyedropperButtonBase = {
44
- background: 'transparent',
45
- border: 'none',
46
- padding: 0,
47
- margin: 0,
48
- cursor: 'pointer',
49
- display: 'inline-flex',
50
- alignItems: 'center',
51
- justifyContent: 'center',
52
- width: 20,
53
- height: 20,
54
- color: 'rgba(255, 255, 255, 0.7)',
55
- };
56
- const eyedropperIconStyle = {
57
- width: 16,
58
- height: 16,
59
- };
60
- // Normalizes any color string the user provided (e.g. `red`, `rgb(...)`, `#fff`)
61
- // into a `#rrggbb` string that `<input type="color">` accepts.
62
- const toHex = (value) => {
63
- try {
64
- const argb = no_react_1.NoReactInternals.processColor(value);
65
- const r = (argb >>> 16) & 0xff;
66
- const g = (argb >>> 8) & 0xff;
67
- const b = argb & 0xff;
68
- return `#${r.toString(16).padStart(2, '0')}${g
69
- .toString(16)
70
- .padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
71
- }
72
- catch (_a) {
73
- return '#000000';
74
- }
75
- };
76
- const hasEyeDropper = () => typeof window !== 'undefined' && 'EyeDropper' in window;
12
+ const SWATCH_WIDTH = 20;
13
+ const SWATCH_HEIGHT = 15;
77
14
  const TimelineColorField = ({ field, effectiveValue, propStatus, onSave, onDragValueChange, onDragEnd, }) => {
78
- const inputRef = (0, react_1.useRef)(null);
79
- const [isHovered, setIsHovered] = (0, react_1.useState)(false);
80
- const [isFocused, setIsFocused] = (0, react_1.useState)(false);
81
- const { tabIndex } = (0, z_index_1.useZIndex)();
82
- const commitTimeoutRef = (0, react_1.useRef)(null);
83
- const pendingCommitRef = (0, react_1.useRef)(null);
84
- // `<input type="color">` doesn't fire an event when dismissed; debounce
85
- // commits and flush any pending commit on unmount so we never lose the
86
- // final value.
87
- (0, react_1.useEffect)(() => {
88
- return () => {
89
- if (commitTimeoutRef.current) {
90
- clearTimeout(commitTimeoutRef.current);
91
- }
92
- if (pendingCommitRef.current) {
93
- pendingCommitRef.current();
94
- }
95
- };
96
- }, []);
15
+ var _a;
97
16
  const currentValue = typeof effectiveValue === 'string'
98
17
  ? effectiveValue
99
18
  : field.fieldSchema.type === 'color'
100
- ? field.fieldSchema.default
19
+ ? ((_a = field.fieldSchema.default) !== null && _a !== void 0 ? _a : '#000')
101
20
  : '';
102
- const hexValue = (0, react_1.useMemo)(() => toHex(currentValue), [currentValue]);
103
- const onColorChange = (0, react_1.useCallback)((e) => {
104
- const newValue = e.target.value;
21
+ const onChange = (0, react_1.useCallback)((next) => {
105
22
  if (!propStatus.canUpdate) {
106
23
  return;
107
24
  }
108
- onDragValueChange(newValue);
109
- if (commitTimeoutRef.current) {
110
- clearTimeout(commitTimeoutRef.current);
111
- }
112
- const commit = () => {
113
- pendingCommitRef.current = null;
114
- if (propStatus.canUpdate && newValue !== propStatus.codeValue) {
115
- onSave(newValue);
116
- }
117
- onDragEnd();
118
- };
119
- pendingCommitRef.current = commit;
120
- commitTimeoutRef.current = setTimeout(() => {
121
- commitTimeoutRef.current = null;
122
- commit();
123
- }, 500);
124
- }, [onSave, onDragValueChange, onDragEnd, propStatus]);
125
- const onPickColor = (0, react_1.useCallback)(() => {
126
- // `EyeDropper` is a Chromium-only API; it's feature-detected at render
127
- // time so this only runs in supported browsers.
128
- const EyeDropperCtor = typeof window !== 'undefined'
129
- ? window.EyeDropper
130
- : undefined;
131
- if (!EyeDropperCtor) {
25
+ onDragValueChange(next);
26
+ }, [onDragValueChange, propStatus.canUpdate]);
27
+ const onChangeComplete = (0, react_1.useCallback)((next) => {
28
+ if (!propStatus.canUpdate) {
132
29
  return;
133
30
  }
134
- const eyeDropper = new EyeDropperCtor();
135
- eyeDropper
136
- .open()
137
- .then((result) => {
138
- if (propStatus.canUpdate && result.sRGBHex !== propStatus.codeValue) {
139
- onSave(result.sRGBHex);
140
- }
141
- })
142
- .catch(() => {
143
- // User aborted or picker failed; safe to ignore.
144
- });
145
- }, [onSave, propStatus]);
146
- const swatchWrapperStyle = (0, react_1.useMemo)(() => {
31
+ if (next !== propStatus.codeValue) {
32
+ onSave(next);
33
+ }
34
+ onDragEnd();
35
+ }, [onSave, onDragEnd, propStatus]);
36
+ const swatchStyle = (0, react_1.useMemo)(() => {
147
37
  return {
148
- ...swatchWrapperBase,
149
- borderColor: isHovered || isFocused
150
- ? colors_1.INPUT_BORDER_COLOR_HOVERED
151
- : colors_1.INPUT_BORDER_COLOR_UNHOVERED,
152
- cursor: propStatus.canUpdate ? 'pointer' : 'not-allowed',
153
38
  marginLeft: 5,
154
39
  };
155
- }, [isFocused, isHovered, propStatus.canUpdate]);
156
- const swatchFill = (0, react_1.useMemo)(() => {
157
- return {
158
- ...swatchFillStyle,
159
- backgroundColor: currentValue || hexValue,
160
- position: 'absolute',
161
- display: 'block',
162
- };
163
- }, [currentValue, hexValue]);
164
- const onMouseEnter = (0, react_1.useCallback)(() => setIsHovered(true), []);
165
- const onMouseLeave = (0, react_1.useCallback)(() => setIsHovered(false), []);
166
- const onFocus = (0, react_1.useCallback)(() => setIsFocused(true), []);
167
- const onBlur = (0, react_1.useCallback)(() => setIsFocused(false), []);
168
- const onSwatchClick = (0, react_1.useCallback)(() => {
169
- var _a;
170
- if (!propStatus.canUpdate) {
171
- return;
172
- }
173
- (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.click();
174
- }, [propStatus.canUpdate]);
175
- const showEyeDropper = hasEyeDropper();
176
- return (jsx_runtime_1.jsxs("span", { style: containerStyle, children: [
177
- jsx_runtime_1.jsxs("span", { style: swatchWrapperStyle, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onClick: onSwatchClick, title: currentValue, children: [
178
- jsx_runtime_1.jsx("span", { style: swatchFill }), jsx_runtime_1.jsx("input", { ref: inputRef, type: "color", value: hexValue, onChange: onColorChange, onFocus: onFocus, onBlur: onBlur, disabled: !propStatus.canUpdate, name: field.key, tabIndex: tabIndex, style: hiddenInputStyle })
179
- ] }), showEyeDropper ? (jsx_runtime_1.jsx("button", { type: "button", onClick: onPickColor, disabled: !propStatus.canUpdate, style: eyedropperButtonBase, tabIndex: tabIndex, title: "Pick color from screen", "aria-label": "Pick color from screen", children: jsx_runtime_1.jsx(eyedropper_1.EyedropperIcon, { style: eyedropperIconStyle, color: "rgba(255, 255, 255, 0.7)" }) })) : null] }));
40
+ }, []);
41
+ return (jsx_runtime_1.jsx("span", { style: containerStyle, children: jsx_runtime_1.jsx(ColorPicker_1.ColorPicker, { value: currentValue, status: "ok", onChange: onChange, onChangeComplete: onChangeComplete, width: SWATCH_WIDTH, height: SWATCH_HEIGHT, disabled: !propStatus.canUpdate, name: field.key, title: currentValue, style: swatchStyle }) }));
180
42
  };
181
43
  exports.TimelineColorField = TimelineColorField;
@@ -5,7 +5,6 @@ import type { EffectSchemaFieldInfo } from '../../helpers/timeline-layout';
5
5
  export declare const TimelineEffectFieldRow: React.FC<{
6
6
  readonly field: EffectSchemaFieldInfo;
7
7
  readonly validatedLocation: CodePosition;
8
- readonly paddingLeft: number;
9
- readonly nestedDepth: number;
8
+ readonly rowDepth: number;
10
9
  readonly nodePath: SequencePropsSubscriptionKey;
11
10
  }>;
@@ -5,15 +5,16 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const studio_shared_1 = require("@remotion/studio-shared");
6
6
  const react_1 = require("react");
7
7
  const remotion_1 = require("remotion");
8
+ const client_id_1 = require("../../helpers/client-id");
8
9
  const timeline_layout_1 = require("../../helpers/timeline-layout");
9
10
  const call_api_1 = require("../call-api");
10
- const Padder_1 = require("./Padder");
11
11
  const save_prop_queue_1 = require("./save-prop-queue");
12
+ const timeline_field_row_layout_1 = require("./timeline-field-row-layout");
13
+ const TimelineExpandArrowButton_1 = require("./TimelineExpandArrowButton");
14
+ const TimelineLayerEye_1 = require("./TimelineLayerEye");
15
+ const TimelineRowChrome_1 = require("./TimelineRowChrome");
12
16
  const TimelineSchemaField_1 = require("./TimelineSchemaField");
13
17
  const fieldRowBase = {
14
- display: 'flex',
15
- alignItems: 'center',
16
- gap: 8,
17
18
  paddingRight: timeline_layout_1.EXPANDED_SECTION_PADDING_RIGHT,
18
19
  };
19
20
  const fieldName = {
@@ -21,19 +22,16 @@ const fieldName = {
21
22
  color: 'rgba(255, 255, 255, 0.8)',
22
23
  userSelect: 'none',
23
24
  };
24
- const fieldLabelRow = {
25
- flex: '0 0 50%',
26
- display: 'flex',
27
- flexDirection: 'row',
28
- alignItems: 'center',
29
- gap: 6,
30
- };
31
25
  const Value = ({ field, nodePath, validatedLocation }) => {
32
26
  var _a;
33
27
  var _b;
34
28
  const { setEffectDragOverrides, clearEffectDragOverrides, setCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
35
29
  const { getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
36
30
  const { codeValues: visualModeCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeCodeValuesContext);
31
+ const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
32
+ const clientId = previewServerState.type === 'connected'
33
+ ? previewServerState.clientId
34
+ : null;
37
35
  const effectStatus = remotion_1.Internals.getEffectCodeValuesCtx({
38
36
  codeValues: visualModeCodeValues,
39
37
  nodePath,
@@ -62,6 +60,9 @@ const Value = ({ field, nodePath, validatedLocation }) => {
62
60
  if (!propStatus.canUpdate) {
63
61
  return Promise.reject(new Error('Cannot save'));
64
62
  }
63
+ if (!clientId) {
64
+ return Promise.reject(new Error('Not connected to studio server'));
65
+ }
65
66
  const defaultValue = field.fieldSchema.default !== undefined
66
67
  ? JSON.stringify(field.fieldSchema.default)
67
68
  : null;
@@ -91,25 +92,12 @@ const Value = ({ field, nodePath, validatedLocation }) => {
91
92
  value: stringifiedValue,
92
93
  defaultValue,
93
94
  schema: field.effectSchema,
95
+ clientId,
94
96
  }),
95
- mergeServerResponse: (prev, data) => {
96
- if (!prev.canUpdate) {
97
- return prev;
98
- }
99
- const idx = prev.effects.findIndex((e) => e.effectIndex === field.effectIndex);
100
- if (idx === -1) {
101
- return {
102
- ...prev,
103
- effects: [...prev.effects, data],
104
- };
105
- }
106
- const nextEffects = [...prev.effects];
107
- nextEffects[idx] = data;
108
- return { ...prev, effects: nextEffects };
109
- },
110
97
  errorLabel: 'Could not save effect prop',
111
98
  });
112
99
  }, [
100
+ clientId,
113
101
  field.effectIndex,
114
102
  field.effectSchema,
115
103
  field.fieldSchema.default,
@@ -141,6 +129,9 @@ const Value = ({ field, nodePath, validatedLocation }) => {
141
129
  throw new Error(`Unsupported effect status: ${effectStatus.reason}`);
142
130
  }
143
131
  if (propStatus === null || !propStatus.canUpdate) {
132
+ if ((propStatus === null || propStatus === void 0 ? void 0 : propStatus.reason) === 'computed') {
133
+ return jsx_runtime_1.jsx(TimelineSchemaField_1.UnsupportedStatus, { label: "computed" });
134
+ }
144
135
  return null;
145
136
  }
146
137
  const effectiveValue = remotion_1.Internals.getEffectiveVisualModeValue({
@@ -151,17 +142,17 @@ const Value = ({ field, nodePath, validatedLocation }) => {
151
142
  });
152
143
  return (jsx_runtime_1.jsx(TimelineSchemaField_1.TimelineFieldValue, { field: field, propStatus: propStatus, onSave: onSave, onDragValueChange: onDragValueChange, onDragEnd: onDragEnd, effectiveValue: effectiveValue }));
153
144
  };
154
- const TimelineEffectFieldRow = ({ field, validatedLocation, paddingLeft, nestedDepth, nodePath }) => {
145
+ const TimelineEffectFieldRow = ({ field, validatedLocation, rowDepth, nodePath }) => {
155
146
  var _a;
156
147
  const style = (0, react_1.useMemo)(() => {
157
148
  return {
158
149
  ...fieldRowBase,
159
150
  height: field.rowHeight,
160
- paddingLeft,
161
151
  };
162
- }, [field.rowHeight, paddingLeft]);
163
- return (jsx_runtime_1.jsxs("div", { style: style, children: [
164
- jsx_runtime_1.jsx(Padder_1.Padder, { depth: nestedDepth + 1 }), jsx_runtime_1.jsx("div", { style: fieldLabelRow, children: jsx_runtime_1.jsx("span", { style: fieldName, children: (_a = field.description) !== null && _a !== void 0 ? _a : field.key }) }), jsx_runtime_1.jsx(Value, { field: field, nodePath: nodePath, validatedLocation: validatedLocation })
152
+ }, [field.rowHeight]);
153
+ const labelRowStyle = (0, react_1.useMemo)(() => (0, timeline_field_row_layout_1.getTimelineFieldLabelRowStyle)(rowDepth), [rowDepth]);
154
+ return (jsx_runtime_1.jsxs(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {}), arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {}), style: style, children: [
155
+ jsx_runtime_1.jsx("div", { style: labelRowStyle, children: jsx_runtime_1.jsx("span", { style: fieldName, children: (_a = field.description) !== null && _a !== void 0 ? _a : field.key }) }), jsx_runtime_1.jsx(Value, { field: field, nodePath: nodePath, validatedLocation: validatedLocation })
165
156
  ] }));
166
157
  };
167
158
  exports.TimelineEffectFieldRow = TimelineEffectFieldRow;
@@ -10,8 +10,7 @@ export declare const TimelineEffectGroupRow: React.FC<{
10
10
  readonly effectSchema: SequenceSchema;
11
11
  readonly nodePath: SequencePropsSubscriptionKey;
12
12
  readonly validatedLocation: CodePosition;
13
- readonly nestedDepth: number;
14
- readonly style: React.CSSProperties;
13
+ readonly rowDepth: number;
15
14
  readonly getIsExpanded: GetIsExpanded;
16
15
  readonly toggleTrack: (nodePathInfo: SequenceNodePathInfo) => void;
17
16
  }>;
@@ -4,22 +4,25 @@ exports.TimelineEffectGroupRow = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
- const Padder_1 = require("./Padder");
7
+ const client_id_1 = require("../../helpers/client-id");
8
+ const timeline_layout_1 = require("../../helpers/timeline-layout");
9
+ const call_api_1 = require("../call-api");
10
+ const ContextMenu_1 = require("../ContextMenu");
11
+ const NotificationCenter_1 = require("../Notifications/NotificationCenter");
8
12
  const save_effect_prop_1 = require("./save-effect-prop");
9
13
  const TimelineExpandArrowButton_1 = require("./TimelineExpandArrowButton");
10
14
  const TimelineLayerEye_1 = require("./TimelineLayerEye");
11
- const groupRowBase = {
12
- display: 'flex',
13
- alignItems: 'center',
14
- };
15
+ const TimelineRowChrome_1 = require("./TimelineRowChrome");
15
16
  const rowLabel = {
16
17
  fontSize: 12,
17
18
  color: 'rgba(255, 255, 255, 0.8)',
18
19
  userSelect: 'none',
19
20
  };
20
- const TimelineEffectGroupRow = ({ label, nodePathInfo, effectIndex, effectSchema, nodePath, validatedLocation, nestedDepth, style, getIsExpanded, toggleTrack, }) => {
21
+ const TimelineEffectGroupRow = ({ label, nodePathInfo, effectIndex, effectSchema, nodePath, validatedLocation, rowDepth, getIsExpanded, toggleTrack, }) => {
21
22
  var _a;
22
23
  var _b;
24
+ const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
25
+ const previewConnected = previewServerState.type === 'connected';
23
26
  const { codeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeCodeValuesContext);
24
27
  const { setCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
25
28
  const effectStatus = (0, react_1.useMemo)(() => remotion_1.Internals.getEffectCodeValuesCtx({
@@ -36,9 +39,57 @@ const TimelineEffectGroupRow = ({ label, nodePathInfo, effectIndex, effectSchema
36
39
  }
37
40
  return false;
38
41
  }, [disabledStatus]);
39
- const canToggle = disabledStatus !== null && disabledStatus.canUpdate;
42
+ const canToggle = previewConnected && disabledStatus !== null && disabledStatus.canUpdate;
43
+ const deleteDisabled = !previewConnected ||
44
+ effectStatus.type !== 'can-update-effect' ||
45
+ !validatedLocation.source;
46
+ const onDeleteEffectFromSource = (0, react_1.useCallback)(async () => {
47
+ if (deleteDisabled) {
48
+ return;
49
+ }
50
+ try {
51
+ const result = await (0, call_api_1.callApi)('/api/delete-effect', {
52
+ fileName: validatedLocation.source,
53
+ sequenceNodePath: nodePath,
54
+ effectIndex,
55
+ });
56
+ if (result.success) {
57
+ (0, NotificationCenter_1.showNotification)('Removed effect from source file', 2000);
58
+ }
59
+ else {
60
+ (0, NotificationCenter_1.showNotification)(result.reason, 4000);
61
+ }
62
+ }
63
+ catch (err) {
64
+ (0, NotificationCenter_1.showNotification)(err.message, 4000);
65
+ }
66
+ }, [deleteDisabled, effectIndex, nodePath, validatedLocation.source]);
67
+ const contextMenuValues = (0, react_1.useMemo)(() => {
68
+ if (!previewConnected) {
69
+ return [];
70
+ }
71
+ return [
72
+ {
73
+ type: 'item',
74
+ id: 'delete-effect',
75
+ keyHint: null,
76
+ label: 'Delete',
77
+ leftItem: null,
78
+ disabled: deleteDisabled,
79
+ onClick: () => {
80
+ if (deleteDisabled) {
81
+ return;
82
+ }
83
+ onDeleteEffectFromSource();
84
+ },
85
+ quickSwitcherLabel: null,
86
+ subMenu: null,
87
+ value: 'delete-effect',
88
+ },
89
+ ];
90
+ }, [deleteDisabled, onDeleteEffectFromSource, previewConnected]);
40
91
  const onToggle = (0, react_1.useCallback)((type) => {
41
- if (!canToggle) {
92
+ if (!canToggle || previewServerState.type !== 'connected') {
42
93
  return;
43
94
  }
44
95
  const newValue = type !== 'enable';
@@ -55,19 +106,23 @@ const TimelineEffectGroupRow = ({ label, nodePathInfo, effectIndex, effectSchema
55
106
  defaultValue,
56
107
  schema: effectSchema,
57
108
  setCodeValues,
109
+ clientId: previewServerState.clientId,
58
110
  });
59
111
  }, [
60
112
  canToggle,
61
113
  effectIndex,
62
114
  effectSchema,
63
115
  nodePath,
116
+ previewServerState,
64
117
  setCodeValues,
65
118
  validatedLocation.source,
66
119
  ]);
67
120
  const isExpanded = getIsExpanded(nodePathInfo);
68
- const mergedStyle = (0, react_1.useMemo)(() => ({ ...groupRowBase, ...style }), [style]);
69
- return (jsx_runtime_1.jsxs("div", { style: mergedStyle, children: [
70
- jsx_runtime_1.jsx(Padder_1.Padder, { depth: nestedDepth + 1 }), canToggle ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: "effect", hidden: isDisabled, onInvoked: onToggle })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowButton, { isExpanded: isExpanded, onClick: () => toggleTrack(nodePathInfo), label: `${label} section`, disabled: false }), jsx_runtime_1.jsx("span", { style: rowLabel, children: label })
71
- ] }));
121
+ const rowStyle = (0, react_1.useMemo)(() => ({
122
+ height: timeline_layout_1.TREE_GROUP_ROW_HEIGHT,
123
+ paddingRight: timeline_layout_1.EXPANDED_SECTION_PADDING_RIGHT,
124
+ }), []);
125
+ const row = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: canToggle ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: "effect", hidden: isDisabled, onInvoked: onToggle })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowButton, { isExpanded: isExpanded, onClick: () => toggleTrack(nodePathInfo), label: `${label} section`, disabled: false }), style: rowStyle, children: jsx_runtime_1.jsx("span", { style: rowLabel, children: label }) }));
126
+ return previewConnected ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, children: row })) : (row);
72
127
  };
73
128
  exports.TimelineEffectGroupRow = TimelineEffectGroupRow;
@@ -2,58 +2,43 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TimelineExpandedRow = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
- const react_1 = require("react");
6
5
  const timeline_layout_1 = require("../../helpers/timeline-layout");
7
- const Padder_1 = require("./Padder");
6
+ const timeline_row_layout_1 = require("./timeline-row-layout");
8
7
  const TimelineEffectFieldRow_1 = require("./TimelineEffectFieldRow");
9
8
  const TimelineEffectGroupRow_1 = require("./TimelineEffectGroupRow");
10
9
  const TimelineExpandArrowButton_1 = require("./TimelineExpandArrowButton");
11
10
  const TimelineFieldRow_1 = require("./TimelineFieldRow");
12
- const TimelineListItem_1 = require("./TimelineListItem");
13
- const groupRowBase = {
14
- height: timeline_layout_1.TREE_GROUP_ROW_HEIGHT,
15
- display: 'flex',
16
- alignItems: 'center',
17
- paddingRight: timeline_layout_1.EXPANDED_SECTION_PADDING_RIGHT,
18
- };
11
+ const TimelineLayerEye_1 = require("./TimelineLayerEye");
12
+ const TimelineRowChrome_1 = require("./TimelineRowChrome");
19
13
  const rowLabel = {
20
14
  fontSize: 12,
21
15
  color: 'rgba(255, 255, 255, 0.8)',
22
16
  userSelect: 'none',
23
17
  };
24
- const labelOnlyRowBase = {
25
- display: 'flex',
26
- alignItems: 'center',
27
- paddingRight: timeline_layout_1.EXPANDED_SECTION_PADDING_RIGHT,
28
- };
29
18
  const TimelineExpandedRow = ({ node, depth, nestedDepth, getIsExpanded, toggleTrack, validatedLocation, nodePath, schema, }) => {
30
- const paddingLeft = timeline_layout_1.EXPANDED_SECTION_PADDING_LEFT + depth * TimelineListItem_1.INDENT;
31
- const groupStyle = (0, react_1.useMemo)(() => ({ ...groupRowBase, paddingLeft }), [paddingLeft]);
32
- const labelOnlyStyle = (0, react_1.useMemo)(() => ({
33
- ...labelOnlyRowBase,
34
- height: (0, timeline_layout_1.getTreeRowHeight)(node),
35
- paddingLeft,
36
- }), [node, paddingLeft]);
19
+ const rowDepth = (0, timeline_row_layout_1.getExpandedRowDepth)({ nestedDepth, treeDepth: depth });
37
20
  if (node.kind === 'group') {
38
21
  if (node.effectInfo) {
39
- return (jsx_runtime_1.jsx(TimelineEffectGroupRow_1.TimelineEffectGroupRow, { label: node.label, nodePathInfo: node.nodePathInfo, effectIndex: node.effectInfo.effectIndex, effectSchema: node.effectInfo.effectSchema, nodePath: nodePath, validatedLocation: validatedLocation, nestedDepth: nestedDepth, style: groupStyle, getIsExpanded: getIsExpanded, toggleTrack: toggleTrack }));
22
+ return (jsx_runtime_1.jsx(TimelineEffectGroupRow_1.TimelineEffectGroupRow, { label: node.label, nodePathInfo: node.nodePathInfo, effectIndex: node.effectInfo.effectIndex, effectSchema: node.effectInfo.effectSchema, nodePath: nodePath, validatedLocation: validatedLocation, rowDepth: rowDepth, getIsExpanded: getIsExpanded, toggleTrack: toggleTrack }));
40
23
  }
41
24
  const isExpanded = getIsExpanded(node.nodePathInfo);
42
- return (jsx_runtime_1.jsxs("div", { style: groupStyle, children: [
43
- jsx_runtime_1.jsx(Padder_1.Padder, { depth: nestedDepth + 1 }), jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowButton, { isExpanded: isExpanded, onClick: () => toggleTrack(node.nodePathInfo), label: `${node.label} section`, disabled: false }), jsx_runtime_1.jsx("span", { style: rowLabel, children: node.label })
44
- ] }));
25
+ return (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {}), arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowButton, { isExpanded: isExpanded, onClick: () => toggleTrack(node.nodePathInfo), label: `${node.label} section`, disabled: false }), style: {
26
+ height: timeline_layout_1.TREE_GROUP_ROW_HEIGHT,
27
+ paddingRight: timeline_layout_1.EXPANDED_SECTION_PADDING_RIGHT,
28
+ }, children: jsx_runtime_1.jsx("span", { style: rowLabel, children: node.label }) }));
45
29
  }
46
30
  if (node.field) {
47
31
  if (node.field.kind === 'effect-field') {
48
- return (jsx_runtime_1.jsx(TimelineEffectFieldRow_1.TimelineEffectFieldRow, { field: node.field, validatedLocation: validatedLocation, paddingLeft: paddingLeft, nestedDepth: nestedDepth, nodePath: nodePath }));
32
+ return (jsx_runtime_1.jsx(TimelineEffectFieldRow_1.TimelineEffectFieldRow, { field: node.field, validatedLocation: validatedLocation, rowDepth: rowDepth, nodePath: nodePath }));
49
33
  }
50
34
  if (node.field.kind === 'sequence-field') {
51
- return (jsx_runtime_1.jsx(TimelineFieldRow_1.TimelineFieldRow, { field: node.field, validatedLocation: validatedLocation, paddingLeft: paddingLeft, nestedDepth: nestedDepth, nodePath: nodePath, schema: schema }));
35
+ return (jsx_runtime_1.jsx(TimelineFieldRow_1.TimelineFieldRow, { field: node.field, validatedLocation: validatedLocation, rowDepth: rowDepth, nodePath: nodePath, schema: schema }));
52
36
  }
53
37
  throw new Error('Unexpected field kind: ' + JSON.stringify(node.field));
54
38
  }
55
- return (jsx_runtime_1.jsxs("div", { style: labelOnlyStyle, children: [
56
- jsx_runtime_1.jsx(Padder_1.Padder, { depth: nestedDepth + 1 }), jsx_runtime_1.jsx("span", { style: rowLabel, children: node.label })
57
- ] }));
39
+ return (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {}), arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {}), style: {
40
+ height: (0, timeline_layout_1.getTreeRowHeight)(node),
41
+ paddingRight: timeline_layout_1.EXPANDED_SECTION_PADDING_RIGHT,
42
+ }, children: jsx_runtime_1.jsx("span", { style: rowLabel, children: node.label }) }));
58
43
  };
59
44
  exports.TimelineExpandedRow = TimelineExpandedRow;
@@ -6,8 +6,7 @@ import type { SchemaFieldInfo } from '../../helpers/timeline-layout';
6
6
  export declare const TimelineFieldRow: React.FC<{
7
7
  readonly field: SchemaFieldInfo;
8
8
  readonly validatedLocation: CodePosition;
9
- readonly paddingLeft: number;
10
- readonly nestedDepth: number;
9
+ readonly rowDepth: number;
11
10
  readonly nodePath: SequencePropsSubscriptionKey;
12
11
  readonly schema: SequenceSchema;
13
12
  }>;
@@ -4,14 +4,15 @@ exports.TimelineFieldRow = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
+ const client_id_1 = require("../../helpers/client-id");
7
8
  const timeline_layout_1 = require("../../helpers/timeline-layout");
8
- const Padder_1 = require("./Padder");
9
9
  const save_sequence_prop_1 = require("./save-sequence-prop");
10
+ const timeline_field_row_layout_1 = require("./timeline-field-row-layout");
11
+ const TimelineExpandArrowButton_1 = require("./TimelineExpandArrowButton");
12
+ const TimelineLayerEye_1 = require("./TimelineLayerEye");
13
+ const TimelineRowChrome_1 = require("./TimelineRowChrome");
10
14
  const TimelineSchemaField_1 = require("./TimelineSchemaField");
11
15
  const fieldRowBase = {
12
- display: 'flex',
13
- alignItems: 'center',
14
- gap: 8,
15
16
  paddingRight: timeline_layout_1.EXPANDED_SECTION_PADDING_RIGHT,
16
17
  };
17
18
  const fieldName = {
@@ -19,13 +20,6 @@ const fieldName = {
19
20
  color: 'rgba(255, 255, 255, 0.8)',
20
21
  userSelect: 'none',
21
22
  };
22
- const fieldLabelRow = {
23
- flex: '0 0 50%',
24
- display: 'flex',
25
- flexDirection: 'row',
26
- alignItems: 'center',
27
- gap: 6,
28
- };
29
23
  const Value = ({ field, nodePath, validatedLocation, schema, codeValue }) => {
30
24
  const { getDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
31
25
  const { setDragOverrides, clearDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
@@ -42,10 +36,17 @@ const Value = ({ field, nodePath, validatedLocation, schema, codeValue }) => {
42
36
  shouldResortToDefaultValueIfUndefined: true,
43
37
  });
44
38
  const { setCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
39
+ const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
40
+ const clientId = previewServerState.type === 'connected'
41
+ ? previewServerState.clientId
42
+ : null;
45
43
  const onSave = (0, react_1.useCallback)((value) => {
46
44
  if (!codeValue || !codeValue.canUpdate) {
47
45
  return Promise.reject(new Error('Cannot save'));
48
46
  }
47
+ if (!clientId) {
48
+ return Promise.reject(new Error('Not connected to studio server'));
49
+ }
49
50
  const defaultValue = field.fieldSchema.default !== undefined
50
51
  ? JSON.stringify(field.fieldSchema.default)
51
52
  : null;
@@ -65,9 +66,11 @@ const Value = ({ field, nodePath, validatedLocation, schema, codeValue }) => {
65
66
  defaultValue,
66
67
  schema,
67
68
  setCodeValues,
69
+ clientId,
68
70
  });
69
71
  }, [
70
72
  codeValue,
73
+ clientId,
71
74
  field.fieldSchema.default,
72
75
  field.key,
73
76
  nodePath,
@@ -89,7 +92,7 @@ const Value = ({ field, nodePath, validatedLocation, schema, codeValue }) => {
89
92
  }, [clearDragOverrides, nodePath]);
90
93
  return (jsx_runtime_1.jsx(TimelineSchemaField_1.TimelineFieldValue, { field: field, propStatus: codeValue, onSave: onSave, onDragValueChange: onDragValueChange, onDragEnd: onDragEnd, effectiveValue: effectiveValue }));
91
94
  };
92
- const TimelineFieldRow = ({ field, validatedLocation, paddingLeft, nestedDepth, nodePath, schema, }) => {
95
+ const TimelineFieldRow = ({ field, validatedLocation, rowDepth, nodePath, schema }) => {
93
96
  var _a, _b;
94
97
  const { codeValues: visualModeCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeCodeValuesContext);
95
98
  const codeValuesForOverride = remotion_1.Internals.getCodeValuesCtx(visualModeCodeValues, nodePath);
@@ -98,13 +101,13 @@ const TimelineFieldRow = ({ field, validatedLocation, paddingLeft, nestedDepth,
98
101
  return {
99
102
  ...fieldRowBase,
100
103
  height: field.rowHeight,
101
- paddingLeft,
102
104
  };
103
- }, [field.rowHeight, paddingLeft]);
105
+ }, [field.rowHeight]);
106
+ const labelRowStyle = (0, react_1.useMemo)(() => (0, timeline_field_row_layout_1.getTimelineFieldLabelRowStyle)(rowDepth), [rowDepth]);
104
107
  if (codeValue === null) {
105
108
  return null;
106
109
  }
107
- return (jsx_runtime_1.jsxs("div", { style: style, children: [
108
- jsx_runtime_1.jsx(Padder_1.Padder, { depth: nestedDepth + 1 }), jsx_runtime_1.jsx("div", { style: fieldLabelRow, children: jsx_runtime_1.jsx("span", { style: fieldName, children: (_b = field.description) !== null && _b !== void 0 ? _b : field.key }) }), codeValue.canUpdate ? (jsx_runtime_1.jsx(Value, { field: field, nodePath: nodePath, validatedLocation: validatedLocation, schema: schema, codeValue: codeValue })) : (jsx_runtime_1.jsx(TimelineSchemaField_1.TimelineNonEditableStatus, { propStatus: codeValue }))] }));
110
+ return (jsx_runtime_1.jsxs(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {}), arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {}), style: style, children: [
111
+ jsx_runtime_1.jsx("div", { style: labelRowStyle, children: jsx_runtime_1.jsx("span", { style: fieldName, children: (_b = field.description) !== null && _b !== void 0 ? _b : field.key }) }), codeValue.canUpdate ? (jsx_runtime_1.jsx(Value, { field: field, nodePath: nodePath, validatedLocation: validatedLocation, schema: schema, codeValue: codeValue })) : (jsx_runtime_1.jsx(TimelineSchemaField_1.TimelineNonEditableStatus, { propStatus: codeValue }))] }));
109
112
  };
110
113
  exports.TimelineFieldRow = TimelineFieldRow;