@atlaskit/editor-plugin-media 19.1.8 → 19.2.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @atlaskit/editor-plugin-media
2
2
 
3
+ ## 19.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`d3a7f9016da28`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/d3a7f9016da28) -
8
+ Add media render lifecycle callbacks for Remix-generated media behind
9
+ cc-maui-add-mark-for-remix-generated-images.
10
+
11
+ ## 19.1.9
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies
16
+
3
17
  ## 19.1.8
4
18
 
5
19
  ### Patch Changes
@@ -32,6 +32,8 @@ var _editorExperiment = require("@atlaskit/tmp-editor-statsig/editor-experiment"
32
32
  var _pluginKey = require("../../pm-plugins/plugin-key");
33
33
  var _styles = require("../styles");
34
34
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t3 in e) "default" !== _t3 && {}.hasOwnProperty.call(e, _t3) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t3)) && (i.get || i.set) ? o(f, _t3, i) : f[_t3] = e[_t3]); return f; })(e, t); }
35
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
36
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
35
37
  function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
36
38
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
37
39
  // This is being used by DropPlaceholder now
@@ -43,6 +45,7 @@ var MediaNode = exports.MediaNode = /*#__PURE__*/function (_Component) {
43
45
  var _this;
44
46
  (0, _classCallCheck2.default)(this, MediaNode);
45
47
  _this = _callSuper(this, MediaNode, [_props]);
48
+ (0, _defineProperty2.default)(_this, "mediaInstance", {});
46
49
  (0, _defineProperty2.default)(_this, "state", {});
47
50
  (0, _defineProperty2.default)(_this, "videoControlsWrapperRef", /*#__PURE__*/_react.default.createRef());
48
51
  (0, _defineProperty2.default)(_this, "unbindKeyDown", null);
@@ -51,6 +54,22 @@ var MediaNode = exports.MediaNode = /*#__PURE__*/function (_Component) {
51
54
  return m.type.name === 'dataConsumer';
52
55
  }) : undefined;
53
56
  });
57
+ (0, _defineProperty2.default)(_this, "getDataConsumerSource", function () {
58
+ var _props$node$marks$fin;
59
+ var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this.props;
60
+ return (_props$node$marks$fin = props.node.marks.find(function (mark) {
61
+ return mark.type.name === 'dataConsumer';
62
+ })) === null || _props$node$marks$fin === void 0 || (_props$node$marks$fin = _props$node$marks$fin.attrs.sources) === null || _props$node$marks$fin === void 0 ? void 0 : _props$node$marks$fin[0];
63
+ });
64
+ (0, _defineProperty2.default)(_this, "emitMediaRenderEvent", function (event) {
65
+ var _props$mediaOptions, _props$mediaOptions$o;
66
+ var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _this.props;
67
+ (_props$mediaOptions = props.mediaOptions) === null || _props$mediaOptions === void 0 || (_props$mediaOptions$o = _props$mediaOptions.onMediaRenderEvent) === null || _props$mediaOptions$o === void 0 || _props$mediaOptions$o.call(_props$mediaOptions, _objectSpread(_objectSpread({}, event), {}, {
68
+ dataConsumerSource: _this.getDataConsumerSource(props),
69
+ mediaId: props.node.attrs.id,
70
+ mediaInstance: _this.mediaInstance
71
+ }));
72
+ });
54
73
  (0, _defineProperty2.default)(_this, "setViewMediaClientConfig", /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
55
74
  var mediaProvider, viewMediaClientConfig, viewAndUploadMediaClientConfig;
56
75
  return _regenerator.default.wrap(function (_context) {
@@ -120,6 +139,10 @@ var MediaNode = exports.MediaNode = /*#__PURE__*/function (_Component) {
120
139
  };
121
140
  }));
122
141
  (0, _defineProperty2.default)(_this, "onPreviewRender", function (fileId) {
142
+ _this.emitMediaRenderEvent({
143
+ renderedMediaId: fileId,
144
+ type: 'preview-rendered'
145
+ });
123
146
  if ((0, _isExperimentEnabled.isExperimentEnabled)('aifc_page_create_with_rovo_include_infographics')) {
124
147
  var _this$props$pluginInj2;
125
148
  (_this$props$pluginInj2 = _this.props.pluginInjectionApi) === null || _this$props$pluginInj2 === void 0 || (_this$props$pluginInj2 = _this$props$pluginInj2.core) === null || _this$props$pluginInj2 === void 0 || _this$props$pluginInj2.actions.execute(function (_ref3) {
@@ -133,9 +156,26 @@ var MediaNode = exports.MediaNode = /*#__PURE__*/function (_Component) {
133
156
  });
134
157
  (0, _defineProperty2.default)(_this, "onError", function (reason) {
135
158
  var _this$props$api;
159
+ _this.emitMediaRenderEvent({
160
+ reason: reason,
161
+ type: 'error'
162
+ });
136
163
  var nestedUnder = _this.getNestedUnder();
137
164
  (_this$props$api = _this.props.api) === null || _this$props$api === void 0 || _this$props$api.media.actions.handleMediaNodeRenderError(_this.props.node, reason, nestedUnder);
138
165
  });
166
+ (0, _defineProperty2.default)(_this, "onRemixRenderError", function (reason) {
167
+ _this.emitMediaRenderEvent({
168
+ reason: reason,
169
+ type: 'error'
170
+ });
171
+ });
172
+ (0, _defineProperty2.default)(_this, "getMediaRenderErrorHandler", function () {
173
+ var _this$props$mediaOpti;
174
+ if ((0, _expValEquals.expValEquals)('platform_editor_media_error_analytics', 'isEnabled', true)) {
175
+ return _this.onError;
176
+ }
177
+ return (_this$props$mediaOpti = _this.props.mediaOptions) !== null && _this$props$mediaOpti !== void 0 && _this$props$mediaOpti.onMediaRenderEvent ? _this.onRemixRenderError : undefined;
178
+ });
139
179
  /**
140
180
  * This function checks if the media node is nested under a certain nodes, and if so,
141
181
  * returns the name of the parent node type. This is used for providing more context in media render errors.
@@ -190,9 +230,10 @@ var MediaNode = exports.MediaNode = /*#__PURE__*/function (_Component) {
190
230
  return (0, _createClass2.default)(MediaNode, [{
191
231
  key: "shouldComponentUpdate",
192
232
  value: function shouldComponentUpdate(nextProps, nextState) {
233
+ var _this$props$mediaOpti2, _nextProps$mediaOptio;
193
234
  var hasNewViewMediaClientConfig = !this.state.viewMediaClientConfig && nextState.viewMediaClientConfig;
194
235
  var hasNewViewAndUploadMediaClientConfig = !this.state.viewAndUploadMediaClientConfig && nextState.viewAndUploadMediaClientConfig;
195
- if (this.props.selected !== nextProps.selected || this.props.node.attrs.id !== nextProps.node.attrs.id || this.props.node.attrs.collection !== nextProps.node.attrs.collection || this.props.isAIGenerating !== nextProps.isAIGenerating || this.props.isCwrAIGenerating !== nextProps.isCwrAIGenerating || this.props.maxDimensions.height !== nextProps.maxDimensions.height || this.props.maxDimensions.width !== nextProps.maxDimensions.width || this.props.contextIdentifierProvider !== nextProps.contextIdentifierProvider || this.props.isLoading !== nextProps.isLoading || this.props.isViewOnly !== nextProps.isViewOnly || this.props.mediaProvider !== nextProps.mediaProvider || this.props.syncProvider !== nextProps.syncProvider || hasNewViewMediaClientConfig || hasNewViewAndUploadMediaClientConfig) {
236
+ if (this.props.selected !== nextProps.selected || this.props.node.attrs.id !== nextProps.node.attrs.id || this.props.node.attrs.collection !== nextProps.node.attrs.collection || this.props.isAIGenerating !== nextProps.isAIGenerating || this.props.isCwrAIGenerating !== nextProps.isCwrAIGenerating || this.props.maxDimensions.height !== nextProps.maxDimensions.height || this.props.maxDimensions.width !== nextProps.maxDimensions.width || this.props.contextIdentifierProvider !== nextProps.contextIdentifierProvider || this.props.isLoading !== nextProps.isLoading || this.props.isViewOnly !== nextProps.isViewOnly || this.props.mediaProvider !== nextProps.mediaProvider || this.props.syncProvider !== nextProps.syncProvider || this.getDataConsumerSource() !== this.getDataConsumerSource(nextProps) || ((_this$props$mediaOpti2 = this.props.mediaOptions) === null || _this$props$mediaOpti2 === void 0 ? void 0 : _this$props$mediaOpti2.onMediaRenderEvent) !== ((_nextProps$mediaOptio = nextProps.mediaOptions) === null || _nextProps$mediaOptio === void 0 ? void 0 : _nextProps$mediaOptio.onMediaRenderEvent) || hasNewViewMediaClientConfig || hasNewViewAndUploadMediaClientConfig) {
196
237
  return true;
197
238
  }
198
239
  return false;
@@ -207,6 +248,9 @@ var MediaNode = exports.MediaNode = /*#__PURE__*/function (_Component) {
207
248
  while (1) switch (_context2.prev = _context2.next) {
208
249
  case 0:
209
250
  this.handleNewNode(this.props);
251
+ this.emitMediaRenderEvent({
252
+ type: 'mounted'
253
+ });
210
254
  _this$props2 = this.props, node = _this$props2.node, pluginInjectionApi = _this$props2.pluginInjectionApi;
211
255
  dataConsumerMark = this.getDataConsumerMark();
212
256
  infographicType = dataConsumerMark === null || dataConsumerMark === void 0 || (_dataConsumerMark$att = dataConsumerMark.attrs.sources) === null || _dataConsumerMark$att === void 0 ? void 0 : _dataConsumerMark$att[0];
@@ -250,6 +294,9 @@ var MediaNode = exports.MediaNode = /*#__PURE__*/function (_Component) {
250
294
  value: function componentWillUnmount() {
251
295
  var _this$mediaPluginStat3;
252
296
  var node = this.props.node;
297
+ this.emitMediaRenderEvent({
298
+ type: 'unmounted'
299
+ });
253
300
  (_this$mediaPluginStat3 = this.mediaPluginState) === null || _this$mediaPluginStat3 === void 0 || _this$mediaPluginStat3.handleMediaNodeUnmount(node);
254
301
  if (this.unbindKeyDown && typeof this.unbindKeyDown === 'function') {
255
302
  this.unbindKeyDown();
@@ -258,7 +305,15 @@ var MediaNode = exports.MediaNode = /*#__PURE__*/function (_Component) {
258
305
  }, {
259
306
  key: "componentDidUpdate",
260
307
  value: function componentDidUpdate(prevProps) {
261
- var _this$mediaPluginStat5;
308
+ var _prevProps$mediaOptio, _this$props$mediaOpti3, _this$mediaPluginStat5;
309
+ if (prevProps.node.attrs.id !== this.props.node.attrs.id || this.getDataConsumerSource(prevProps) !== this.getDataConsumerSource() || ((_prevProps$mediaOptio = prevProps.mediaOptions) === null || _prevProps$mediaOptio === void 0 ? void 0 : _prevProps$mediaOptio.onMediaRenderEvent) !== ((_this$props$mediaOpti3 = this.props.mediaOptions) === null || _this$props$mediaOpti3 === void 0 ? void 0 : _this$props$mediaOpti3.onMediaRenderEvent)) {
310
+ this.emitMediaRenderEvent({
311
+ type: 'unmounted'
312
+ }, prevProps);
313
+ this.emitMediaRenderEvent({
314
+ type: 'mounted'
315
+ });
316
+ }
262
317
  if (prevProps.node.attrs.id !== this.props.node.attrs.id) {
263
318
  var _this$mediaPluginStat4;
264
319
  (_this$mediaPluginStat4 = this.mediaPluginState) === null || _this$mediaPluginStat4 === void 0 || _this$mediaPluginStat4.handleMediaNodeUnmount(prevProps.node);
@@ -371,7 +426,6 @@ var MediaNode = exports.MediaNode = /*#__PURE__*/function (_Component) {
371
426
  collectionName: collection
372
427
  };
373
428
  var resolvedViewAndUploadMediaClientConfig = (0, _fg.fg)('platform_media_video_captions') ? viewAndUploadMediaClientConfig : undefined;
374
-
375
429
  // mediaClientConfig is not needed for "external" case. So we have to cheat here.
376
430
  // there is a possibility mediaClientConfig will be part of a identifier,
377
431
  // so this might be not an issue
@@ -425,7 +479,7 @@ var MediaNode = exports.MediaNode = /*#__PURE__*/function (_Component) {
425
479
  isCWR: isCWR,
426
480
  onPreviewRender: this.onPreviewRender,
427
481
  fallbackMediaNameFetcher: mediaOptions === null || mediaOptions === void 0 ? void 0 : mediaOptions.fallbackMediaNameFetcher,
428
- onError: (0, _expValEquals.expValEquals)('platform_editor_media_error_analytics', 'isEnabled', true) ? this.onError : undefined
482
+ onError: this.getMediaRenderErrorHandler()
429
483
  })));
430
484
  }
431
485
  }]);
@@ -24,10 +24,24 @@ export const FILE_WIDTH = 156;
24
24
  export class MediaNode extends Component {
25
25
  constructor(_props) {
26
26
  super(_props);
27
+ _defineProperty(this, "mediaInstance", {});
27
28
  _defineProperty(this, "state", {});
28
29
  _defineProperty(this, "videoControlsWrapperRef", /*#__PURE__*/React.createRef());
29
30
  _defineProperty(this, "unbindKeyDown", null);
30
31
  _defineProperty(this, "getDataConsumerMark", () => fg('cc-maui-add-mark-for-remix-generated-images') ? this.props.node.marks.find(m => m.type.name === 'dataConsumer') : undefined);
32
+ _defineProperty(this, "getDataConsumerSource", (props = this.props) => {
33
+ var _props$node$marks$fin, _props$node$marks$fin2;
34
+ return (_props$node$marks$fin = props.node.marks.find(mark => mark.type.name === 'dataConsumer')) === null || _props$node$marks$fin === void 0 ? void 0 : (_props$node$marks$fin2 = _props$node$marks$fin.attrs.sources) === null || _props$node$marks$fin2 === void 0 ? void 0 : _props$node$marks$fin2[0];
35
+ });
36
+ _defineProperty(this, "emitMediaRenderEvent", (event, props = this.props) => {
37
+ var _props$mediaOptions, _props$mediaOptions$o;
38
+ (_props$mediaOptions = props.mediaOptions) === null || _props$mediaOptions === void 0 ? void 0 : (_props$mediaOptions$o = _props$mediaOptions.onMediaRenderEvent) === null || _props$mediaOptions$o === void 0 ? void 0 : _props$mediaOptions$o.call(_props$mediaOptions, {
39
+ ...event,
40
+ dataConsumerSource: this.getDataConsumerSource(props),
41
+ mediaId: props.node.attrs.id,
42
+ mediaInstance: this.mediaInstance
43
+ });
44
+ });
31
45
  _defineProperty(this, "setViewMediaClientConfig", async () => {
32
46
  // mediaProvider is Promise<MediaProvider>, so await it first to get the actual provider
33
47
  const mediaProvider = await this.props.mediaProvider;
@@ -90,6 +104,10 @@ export class MediaNode extends Component {
90
104
  };
91
105
  }));
92
106
  _defineProperty(this, "onPreviewRender", fileId => {
107
+ this.emitMediaRenderEvent({
108
+ renderedMediaId: fileId,
109
+ type: 'preview-rendered'
110
+ });
93
111
  if (isExperimentEnabled('aifc_page_create_with_rovo_include_infographics')) {
94
112
  var _this$props$pluginInj2, _this$props$pluginInj3;
95
113
  (_this$props$pluginInj2 = this.props.pluginInjectionApi) === null || _this$props$pluginInj2 === void 0 ? void 0 : (_this$props$pluginInj3 = _this$props$pluginInj2.core) === null || _this$props$pluginInj3 === void 0 ? void 0 : _this$props$pluginInj3.actions.execute(({
@@ -102,9 +120,26 @@ export class MediaNode extends Component {
102
120
  });
103
121
  _defineProperty(this, "onError", reason => {
104
122
  var _this$props$api;
123
+ this.emitMediaRenderEvent({
124
+ reason,
125
+ type: 'error'
126
+ });
105
127
  const nestedUnder = this.getNestedUnder();
106
128
  (_this$props$api = this.props.api) === null || _this$props$api === void 0 ? void 0 : _this$props$api.media.actions.handleMediaNodeRenderError(this.props.node, reason, nestedUnder);
107
129
  });
130
+ _defineProperty(this, "onRemixRenderError", reason => {
131
+ this.emitMediaRenderEvent({
132
+ reason,
133
+ type: 'error'
134
+ });
135
+ });
136
+ _defineProperty(this, "getMediaRenderErrorHandler", () => {
137
+ var _this$props$mediaOpti;
138
+ if (expValEquals('platform_editor_media_error_analytics', 'isEnabled', true)) {
139
+ return this.onError;
140
+ }
141
+ return (_this$props$mediaOpti = this.props.mediaOptions) !== null && _this$props$mediaOpti !== void 0 && _this$props$mediaOpti.onMediaRenderEvent ? this.onRemixRenderError : undefined;
142
+ });
108
143
  /**
109
144
  * This function checks if the media node is nested under a certain nodes, and if so,
110
145
  * returns the name of the parent node type. This is used for providing more context in media render errors.
@@ -157,9 +192,10 @@ export class MediaNode extends Component {
157
192
  }
158
193
  }
159
194
  shouldComponentUpdate(nextProps, nextState) {
195
+ var _this$props$mediaOpti2, _nextProps$mediaOptio;
160
196
  const hasNewViewMediaClientConfig = !this.state.viewMediaClientConfig && nextState.viewMediaClientConfig;
161
197
  const hasNewViewAndUploadMediaClientConfig = !this.state.viewAndUploadMediaClientConfig && nextState.viewAndUploadMediaClientConfig;
162
- if (this.props.selected !== nextProps.selected || this.props.node.attrs.id !== nextProps.node.attrs.id || this.props.node.attrs.collection !== nextProps.node.attrs.collection || this.props.isAIGenerating !== nextProps.isAIGenerating || this.props.isCwrAIGenerating !== nextProps.isCwrAIGenerating || this.props.maxDimensions.height !== nextProps.maxDimensions.height || this.props.maxDimensions.width !== nextProps.maxDimensions.width || this.props.contextIdentifierProvider !== nextProps.contextIdentifierProvider || this.props.isLoading !== nextProps.isLoading || this.props.isViewOnly !== nextProps.isViewOnly || this.props.mediaProvider !== nextProps.mediaProvider || this.props.syncProvider !== nextProps.syncProvider || hasNewViewMediaClientConfig || hasNewViewAndUploadMediaClientConfig) {
198
+ if (this.props.selected !== nextProps.selected || this.props.node.attrs.id !== nextProps.node.attrs.id || this.props.node.attrs.collection !== nextProps.node.attrs.collection || this.props.isAIGenerating !== nextProps.isAIGenerating || this.props.isCwrAIGenerating !== nextProps.isCwrAIGenerating || this.props.maxDimensions.height !== nextProps.maxDimensions.height || this.props.maxDimensions.width !== nextProps.maxDimensions.width || this.props.contextIdentifierProvider !== nextProps.contextIdentifierProvider || this.props.isLoading !== nextProps.isLoading || this.props.isViewOnly !== nextProps.isViewOnly || this.props.mediaProvider !== nextProps.mediaProvider || this.props.syncProvider !== nextProps.syncProvider || this.getDataConsumerSource() !== this.getDataConsumerSource(nextProps) || ((_this$props$mediaOpti2 = this.props.mediaOptions) === null || _this$props$mediaOpti2 === void 0 ? void 0 : _this$props$mediaOpti2.onMediaRenderEvent) !== ((_nextProps$mediaOptio = nextProps.mediaOptions) === null || _nextProps$mediaOptio === void 0 ? void 0 : _nextProps$mediaOptio.onMediaRenderEvent) || hasNewViewMediaClientConfig || hasNewViewAndUploadMediaClientConfig) {
163
199
  return true;
164
200
  }
165
201
  return false;
@@ -167,6 +203,9 @@ export class MediaNode extends Component {
167
203
  async componentDidMount() {
168
204
  var _dataConsumerMark$att;
169
205
  this.handleNewNode(this.props);
206
+ this.emitMediaRenderEvent({
207
+ type: 'mounted'
208
+ });
170
209
  const {
171
210
  node,
172
211
  pluginInjectionApi
@@ -200,13 +239,24 @@ export class MediaNode extends Component {
200
239
  const {
201
240
  node
202
241
  } = this.props;
242
+ this.emitMediaRenderEvent({
243
+ type: 'unmounted'
244
+ });
203
245
  (_this$mediaPluginStat3 = this.mediaPluginState) === null || _this$mediaPluginStat3 === void 0 ? void 0 : _this$mediaPluginStat3.handleMediaNodeUnmount(node);
204
246
  if (this.unbindKeyDown && typeof this.unbindKeyDown === 'function') {
205
247
  this.unbindKeyDown();
206
248
  }
207
249
  }
208
250
  componentDidUpdate(prevProps) {
209
- var _this$mediaPluginStat5;
251
+ var _prevProps$mediaOptio, _this$props$mediaOpti3, _this$mediaPluginStat5;
252
+ if (prevProps.node.attrs.id !== this.props.node.attrs.id || this.getDataConsumerSource(prevProps) !== this.getDataConsumerSource() || ((_prevProps$mediaOptio = prevProps.mediaOptions) === null || _prevProps$mediaOptio === void 0 ? void 0 : _prevProps$mediaOptio.onMediaRenderEvent) !== ((_this$props$mediaOpti3 = this.props.mediaOptions) === null || _this$props$mediaOpti3 === void 0 ? void 0 : _this$props$mediaOpti3.onMediaRenderEvent)) {
253
+ this.emitMediaRenderEvent({
254
+ type: 'unmounted'
255
+ }, prevProps);
256
+ this.emitMediaRenderEvent({
257
+ type: 'mounted'
258
+ });
259
+ }
210
260
  if (prevProps.node.attrs.id !== this.props.node.attrs.id) {
211
261
  var _this$mediaPluginStat4;
212
262
  (_this$mediaPluginStat4 = this.mediaPluginState) === null || _this$mediaPluginStat4 === void 0 ? void 0 : _this$mediaPluginStat4.handleMediaNodeUnmount(prevProps.node);
@@ -315,7 +365,6 @@ export class MediaNode extends Component {
315
365
  collectionName: collection
316
366
  };
317
367
  const resolvedViewAndUploadMediaClientConfig = fg('platform_media_video_captions') ? viewAndUploadMediaClientConfig : undefined;
318
-
319
368
  // mediaClientConfig is not needed for "external" case. So we have to cheat here.
320
369
  // there is a possibility mediaClientConfig will be part of a identifier,
321
370
  // so this might be not an issue
@@ -369,7 +418,7 @@ export class MediaNode extends Component {
369
418
  isCWR: isCWR,
370
419
  onPreviewRender: this.onPreviewRender,
371
420
  fallbackMediaNameFetcher: mediaOptions === null || mediaOptions === void 0 ? void 0 : mediaOptions.fallbackMediaNameFetcher,
372
- onError: expValEquals('platform_editor_media_error_analytics', 'isEnabled', true) ? this.onError : undefined
421
+ onError: this.getMediaRenderErrorHandler()
373
422
  })));
374
423
  }
375
424
  }
@@ -6,6 +6,8 @@ import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
6
6
  import _inherits from "@babel/runtime/helpers/inherits";
7
7
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
8
8
  import _regeneratorRuntime from "@babel/runtime/regenerator";
9
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
10
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
9
11
  function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
10
12
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
11
13
  import React, { Component } from 'react';
@@ -35,6 +37,7 @@ export var MediaNode = /*#__PURE__*/function (_Component) {
35
37
  var _this;
36
38
  _classCallCheck(this, MediaNode);
37
39
  _this = _callSuper(this, MediaNode, [_props]);
40
+ _defineProperty(_this, "mediaInstance", {});
38
41
  _defineProperty(_this, "state", {});
39
42
  _defineProperty(_this, "videoControlsWrapperRef", /*#__PURE__*/React.createRef());
40
43
  _defineProperty(_this, "unbindKeyDown", null);
@@ -43,6 +46,22 @@ export var MediaNode = /*#__PURE__*/function (_Component) {
43
46
  return m.type.name === 'dataConsumer';
44
47
  }) : undefined;
45
48
  });
49
+ _defineProperty(_this, "getDataConsumerSource", function () {
50
+ var _props$node$marks$fin;
51
+ var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this.props;
52
+ return (_props$node$marks$fin = props.node.marks.find(function (mark) {
53
+ return mark.type.name === 'dataConsumer';
54
+ })) === null || _props$node$marks$fin === void 0 || (_props$node$marks$fin = _props$node$marks$fin.attrs.sources) === null || _props$node$marks$fin === void 0 ? void 0 : _props$node$marks$fin[0];
55
+ });
56
+ _defineProperty(_this, "emitMediaRenderEvent", function (event) {
57
+ var _props$mediaOptions, _props$mediaOptions$o;
58
+ var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _this.props;
59
+ (_props$mediaOptions = props.mediaOptions) === null || _props$mediaOptions === void 0 || (_props$mediaOptions$o = _props$mediaOptions.onMediaRenderEvent) === null || _props$mediaOptions$o === void 0 || _props$mediaOptions$o.call(_props$mediaOptions, _objectSpread(_objectSpread({}, event), {}, {
60
+ dataConsumerSource: _this.getDataConsumerSource(props),
61
+ mediaId: props.node.attrs.id,
62
+ mediaInstance: _this.mediaInstance
63
+ }));
64
+ });
46
65
  _defineProperty(_this, "setViewMediaClientConfig", /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
47
66
  var mediaProvider, viewMediaClientConfig, viewAndUploadMediaClientConfig;
48
67
  return _regeneratorRuntime.wrap(function (_context) {
@@ -112,6 +131,10 @@ export var MediaNode = /*#__PURE__*/function (_Component) {
112
131
  };
113
132
  }));
114
133
  _defineProperty(_this, "onPreviewRender", function (fileId) {
134
+ _this.emitMediaRenderEvent({
135
+ renderedMediaId: fileId,
136
+ type: 'preview-rendered'
137
+ });
115
138
  if (isExperimentEnabled('aifc_page_create_with_rovo_include_infographics')) {
116
139
  var _this$props$pluginInj2;
117
140
  (_this$props$pluginInj2 = _this.props.pluginInjectionApi) === null || _this$props$pluginInj2 === void 0 || (_this$props$pluginInj2 = _this$props$pluginInj2.core) === null || _this$props$pluginInj2 === void 0 || _this$props$pluginInj2.actions.execute(function (_ref3) {
@@ -125,9 +148,26 @@ export var MediaNode = /*#__PURE__*/function (_Component) {
125
148
  });
126
149
  _defineProperty(_this, "onError", function (reason) {
127
150
  var _this$props$api;
151
+ _this.emitMediaRenderEvent({
152
+ reason: reason,
153
+ type: 'error'
154
+ });
128
155
  var nestedUnder = _this.getNestedUnder();
129
156
  (_this$props$api = _this.props.api) === null || _this$props$api === void 0 || _this$props$api.media.actions.handleMediaNodeRenderError(_this.props.node, reason, nestedUnder);
130
157
  });
158
+ _defineProperty(_this, "onRemixRenderError", function (reason) {
159
+ _this.emitMediaRenderEvent({
160
+ reason: reason,
161
+ type: 'error'
162
+ });
163
+ });
164
+ _defineProperty(_this, "getMediaRenderErrorHandler", function () {
165
+ var _this$props$mediaOpti;
166
+ if (expValEquals('platform_editor_media_error_analytics', 'isEnabled', true)) {
167
+ return _this.onError;
168
+ }
169
+ return (_this$props$mediaOpti = _this.props.mediaOptions) !== null && _this$props$mediaOpti !== void 0 && _this$props$mediaOpti.onMediaRenderEvent ? _this.onRemixRenderError : undefined;
170
+ });
131
171
  /**
132
172
  * This function checks if the media node is nested under a certain nodes, and if so,
133
173
  * returns the name of the parent node type. This is used for providing more context in media render errors.
@@ -182,9 +222,10 @@ export var MediaNode = /*#__PURE__*/function (_Component) {
182
222
  return _createClass(MediaNode, [{
183
223
  key: "shouldComponentUpdate",
184
224
  value: function shouldComponentUpdate(nextProps, nextState) {
225
+ var _this$props$mediaOpti2, _nextProps$mediaOptio;
185
226
  var hasNewViewMediaClientConfig = !this.state.viewMediaClientConfig && nextState.viewMediaClientConfig;
186
227
  var hasNewViewAndUploadMediaClientConfig = !this.state.viewAndUploadMediaClientConfig && nextState.viewAndUploadMediaClientConfig;
187
- if (this.props.selected !== nextProps.selected || this.props.node.attrs.id !== nextProps.node.attrs.id || this.props.node.attrs.collection !== nextProps.node.attrs.collection || this.props.isAIGenerating !== nextProps.isAIGenerating || this.props.isCwrAIGenerating !== nextProps.isCwrAIGenerating || this.props.maxDimensions.height !== nextProps.maxDimensions.height || this.props.maxDimensions.width !== nextProps.maxDimensions.width || this.props.contextIdentifierProvider !== nextProps.contextIdentifierProvider || this.props.isLoading !== nextProps.isLoading || this.props.isViewOnly !== nextProps.isViewOnly || this.props.mediaProvider !== nextProps.mediaProvider || this.props.syncProvider !== nextProps.syncProvider || hasNewViewMediaClientConfig || hasNewViewAndUploadMediaClientConfig) {
228
+ if (this.props.selected !== nextProps.selected || this.props.node.attrs.id !== nextProps.node.attrs.id || this.props.node.attrs.collection !== nextProps.node.attrs.collection || this.props.isAIGenerating !== nextProps.isAIGenerating || this.props.isCwrAIGenerating !== nextProps.isCwrAIGenerating || this.props.maxDimensions.height !== nextProps.maxDimensions.height || this.props.maxDimensions.width !== nextProps.maxDimensions.width || this.props.contextIdentifierProvider !== nextProps.contextIdentifierProvider || this.props.isLoading !== nextProps.isLoading || this.props.isViewOnly !== nextProps.isViewOnly || this.props.mediaProvider !== nextProps.mediaProvider || this.props.syncProvider !== nextProps.syncProvider || this.getDataConsumerSource() !== this.getDataConsumerSource(nextProps) || ((_this$props$mediaOpti2 = this.props.mediaOptions) === null || _this$props$mediaOpti2 === void 0 ? void 0 : _this$props$mediaOpti2.onMediaRenderEvent) !== ((_nextProps$mediaOptio = nextProps.mediaOptions) === null || _nextProps$mediaOptio === void 0 ? void 0 : _nextProps$mediaOptio.onMediaRenderEvent) || hasNewViewMediaClientConfig || hasNewViewAndUploadMediaClientConfig) {
188
229
  return true;
189
230
  }
190
231
  return false;
@@ -199,6 +240,9 @@ export var MediaNode = /*#__PURE__*/function (_Component) {
199
240
  while (1) switch (_context2.prev = _context2.next) {
200
241
  case 0:
201
242
  this.handleNewNode(this.props);
243
+ this.emitMediaRenderEvent({
244
+ type: 'mounted'
245
+ });
202
246
  _this$props2 = this.props, node = _this$props2.node, pluginInjectionApi = _this$props2.pluginInjectionApi;
203
247
  dataConsumerMark = this.getDataConsumerMark();
204
248
  infographicType = dataConsumerMark === null || dataConsumerMark === void 0 || (_dataConsumerMark$att = dataConsumerMark.attrs.sources) === null || _dataConsumerMark$att === void 0 ? void 0 : _dataConsumerMark$att[0];
@@ -242,6 +286,9 @@ export var MediaNode = /*#__PURE__*/function (_Component) {
242
286
  value: function componentWillUnmount() {
243
287
  var _this$mediaPluginStat3;
244
288
  var node = this.props.node;
289
+ this.emitMediaRenderEvent({
290
+ type: 'unmounted'
291
+ });
245
292
  (_this$mediaPluginStat3 = this.mediaPluginState) === null || _this$mediaPluginStat3 === void 0 || _this$mediaPluginStat3.handleMediaNodeUnmount(node);
246
293
  if (this.unbindKeyDown && typeof this.unbindKeyDown === 'function') {
247
294
  this.unbindKeyDown();
@@ -250,7 +297,15 @@ export var MediaNode = /*#__PURE__*/function (_Component) {
250
297
  }, {
251
298
  key: "componentDidUpdate",
252
299
  value: function componentDidUpdate(prevProps) {
253
- var _this$mediaPluginStat5;
300
+ var _prevProps$mediaOptio, _this$props$mediaOpti3, _this$mediaPluginStat5;
301
+ if (prevProps.node.attrs.id !== this.props.node.attrs.id || this.getDataConsumerSource(prevProps) !== this.getDataConsumerSource() || ((_prevProps$mediaOptio = prevProps.mediaOptions) === null || _prevProps$mediaOptio === void 0 ? void 0 : _prevProps$mediaOptio.onMediaRenderEvent) !== ((_this$props$mediaOpti3 = this.props.mediaOptions) === null || _this$props$mediaOpti3 === void 0 ? void 0 : _this$props$mediaOpti3.onMediaRenderEvent)) {
302
+ this.emitMediaRenderEvent({
303
+ type: 'unmounted'
304
+ }, prevProps);
305
+ this.emitMediaRenderEvent({
306
+ type: 'mounted'
307
+ });
308
+ }
254
309
  if (prevProps.node.attrs.id !== this.props.node.attrs.id) {
255
310
  var _this$mediaPluginStat4;
256
311
  (_this$mediaPluginStat4 = this.mediaPluginState) === null || _this$mediaPluginStat4 === void 0 || _this$mediaPluginStat4.handleMediaNodeUnmount(prevProps.node);
@@ -363,7 +418,6 @@ export var MediaNode = /*#__PURE__*/function (_Component) {
363
418
  collectionName: collection
364
419
  };
365
420
  var resolvedViewAndUploadMediaClientConfig = fg('platform_media_video_captions') ? viewAndUploadMediaClientConfig : undefined;
366
-
367
421
  // mediaClientConfig is not needed for "external" case. So we have to cheat here.
368
422
  // there is a possibility mediaClientConfig will be part of a identifier,
369
423
  // so this might be not an issue
@@ -417,7 +471,7 @@ export var MediaNode = /*#__PURE__*/function (_Component) {
417
471
  isCWR: isCWR,
418
472
  onPreviewRender: this.onPreviewRender,
419
473
  fallbackMediaNameFetcher: mediaOptions === null || mediaOptions === void 0 ? void 0 : mediaOptions.fallbackMediaNameFetcher,
420
- onError: expValEquals('platform_editor_media_error_analytics', 'isEnabled', true) ? this.onError : undefined
474
+ onError: this.getMediaRenderErrorHandler()
421
475
  })));
422
476
  }
423
477
  }]);
@@ -36,6 +36,7 @@ interface MediaNodeState {
36
36
  viewMediaClientConfig?: MediaClientConfig;
37
37
  }
38
38
  export declare class MediaNode extends Component<MediaNodeProps, MediaNodeState> {
39
+ private readonly mediaInstance;
39
40
  private mediaPluginState;
40
41
  state: MediaNodeState;
41
42
  videoControlsWrapperRef: React.RefObject<HTMLDivElement>;
@@ -43,6 +44,8 @@ export declare class MediaNode extends Component<MediaNodeProps, MediaNodeState>
43
44
  constructor(props: MediaNodeProps);
44
45
  shouldComponentUpdate(nextProps: MediaNodeProps, nextState: MediaNodeState): boolean;
45
46
  private getDataConsumerMark;
47
+ private getDataConsumerSource;
48
+ private emitMediaRenderEvent;
46
49
  componentDidMount(): Promise<void>;
47
50
  componentWillUnmount(): void;
48
51
  componentDidUpdate(prevProps: Readonly<MediaNodeProps>): void;
@@ -53,6 +56,8 @@ export declare class MediaNode extends Component<MediaNodeProps, MediaNodeState>
53
56
  private getMediaSettings;
54
57
  private onPreviewRender;
55
58
  private onError;
59
+ private onRemixRenderError;
60
+ private getMediaRenderErrorHandler;
56
61
  /**
57
62
  * This function checks if the media node is nested under a certain nodes, and if so,
58
63
  * returns the name of the parent node type. This is used for providing more context in media render errors.
@@ -17,6 +17,20 @@ interface PlaceholderTextOptions {
17
17
  export type MediaStateStatus = 'unknown' | 'ready' | 'cancelled' | 'preview' | 'error' | 'mobile-upload-end';
18
18
  export type MediaSingleWithType = 'pixel' | 'percentage';
19
19
  export type MediaCopyScope = 'editor' | 'context';
20
+ export type MediaRenderEventPayload = {
21
+ type: 'mounted' | 'unmounted';
22
+ } | {
23
+ renderedMediaId?: string;
24
+ type: 'preview-rendered';
25
+ } | {
26
+ reason: string;
27
+ type: 'error';
28
+ };
29
+ export type MediaRenderEvent = {
30
+ dataConsumerSource?: string;
31
+ mediaId?: string;
32
+ mediaInstance: object;
33
+ } & MediaRenderEventPayload;
20
34
  export interface MediaPluginOptions {
21
35
  alignLeftOnInsert?: boolean;
22
36
  allowAdvancedToolBarOptions?: boolean;
@@ -102,6 +116,8 @@ export interface MediaPluginOptions {
102
116
  /** Extensions for the media viewer header (e.g. comment navigation button). */
103
117
  mediaViewerExtensions?: MediaViewerExtensions;
104
118
  onCommentButtonMount?: () => void;
119
+ /** Receives lifecycle events for each rendered media node. */
120
+ onMediaRenderEvent?: (event: MediaRenderEvent) => void;
105
121
  /**
106
122
  * When enabled, prevents automatic focus/selection of media nodes after upload completion.
107
123
  * The existing focus will be preserved instead of switching to the uploaded media.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-media",
3
- "version": "19.1.8",
3
+ "version": "19.2.0",
4
4
  "description": "Media plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -60,7 +60,7 @@
60
60
  "@atlaskit/platform-feature-flags": "^2.2.0",
61
61
  "@atlaskit/primitives": "^22.5.0",
62
62
  "@atlaskit/textfield": "^10.2.0",
63
- "@atlaskit/tmp-editor-statsig": "^186.0.0",
63
+ "@atlaskit/tmp-editor-statsig": "^187.0.0",
64
64
  "@atlaskit/tokens": "^16.12.0",
65
65
  "@atlaskit/tooltip": "^24.3.0",
66
66
  "@babel/runtime": "^7.0.0",