@atlaskit/media-card 74.0.0 → 74.1.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.
Files changed (41) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/errors.js +4 -0
  3. package/dist/cjs/root/card/cardAnalytics.js +6 -2
  4. package/dist/cjs/root/card/getCardPreview/index.js +47 -20
  5. package/dist/cjs/root/card/imageRefetchingAnalytics.js +45 -0
  6. package/dist/cjs/root/card/index.js +13 -16
  7. package/dist/cjs/utils/analytics.js +29 -2
  8. package/dist/cjs/utils/document.js +9 -1
  9. package/dist/cjs/utils/ufoExperiences.js +7 -3
  10. package/dist/cjs/utils/viewportDetector.js +11 -36
  11. package/dist/cjs/version.json +1 -1
  12. package/dist/es2019/errors.js +4 -0
  13. package/dist/es2019/root/card/cardAnalytics.js +3 -2
  14. package/dist/es2019/root/card/getCardPreview/index.js +27 -2
  15. package/dist/es2019/root/card/imageRefetchingAnalytics.js +30 -0
  16. package/dist/es2019/root/card/index.js +15 -20
  17. package/dist/es2019/utils/analytics.js +18 -1
  18. package/dist/es2019/utils/document.js +11 -1
  19. package/dist/es2019/utils/ufoExperiences.js +4 -3
  20. package/dist/es2019/utils/viewportDetector.js +9 -36
  21. package/dist/es2019/version.json +1 -1
  22. package/dist/esm/errors.js +4 -0
  23. package/dist/esm/root/card/cardAnalytics.js +5 -2
  24. package/dist/esm/root/card/getCardPreview/index.js +47 -20
  25. package/dist/esm/root/card/imageRefetchingAnalytics.js +32 -0
  26. package/dist/esm/root/card/index.js +15 -20
  27. package/dist/esm/utils/analytics.js +22 -1
  28. package/dist/esm/utils/document.js +9 -1
  29. package/dist/esm/utils/ufoExperiences.js +6 -3
  30. package/dist/esm/utils/viewportDetector.js +9 -36
  31. package/dist/esm/version.json +1 -1
  32. package/dist/types/errors.d.ts +5 -1
  33. package/dist/types/root/card/cardAnalytics.d.ts +1 -1
  34. package/dist/types/root/card/getCardPreview/index.d.ts +4 -1
  35. package/dist/types/root/card/imageRefetchingAnalytics.d.ts +10 -0
  36. package/dist/types/root/card/index.d.ts +0 -2
  37. package/dist/types/utils/analytics.d.ts +17 -1
  38. package/dist/types/utils/document.d.ts +1 -1
  39. package/dist/types/utils/ufoExperiences.d.ts +1 -1
  40. package/dist/types/utils/viewportDetector.d.ts +0 -10
  41. package/package.json +6 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @atlaskit/media-card
2
2
 
3
+ ## 74.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`a332288b5ea`](https://bitbucket.org/atlassian/atlassian-frontend/commits/a332288b5ea) - Added analytics for media-card memoryCacheLogging and added relevant featureFlag keys for media-common package.
8
+
9
+ ### Patch Changes
10
+
11
+ - [`baece961cdd`](https://bitbucket.org/atlassian/atlassian-frontend/commits/baece961cdd) - Add media-card example for use by media-pollinator-test
12
+ - [`2285a60dc65`](https://bitbucket.org/atlassian/atlassian-frontend/commits/2285a60dc65) - Logs events when status is error, even if there is no error data
13
+ - [`196bfa84bfd`](https://bitbucket.org/atlassian/atlassian-frontend/commits/196bfa84bfd) - Removed custom anchors from ViewportObserver in favour of IntersectionObserver's rootMargin
14
+ - Updated dependencies
15
+
3
16
  ## 74.0.0
4
17
 
5
18
  ### Major Changes
@@ -29,6 +29,10 @@ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflec
29
29
 
30
30
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
31
31
 
32
+ /**
33
+ * Primary reason is logged through Data Portal.
34
+ * Make sure all the values are whitelisted in Measure -> Event Regitry -> "mediaCardRender failed" event
35
+ */
32
36
  var MediaCardError = /*#__PURE__*/function (_Error) {
33
37
  (0, _inherits2.default)(MediaCardError, _Error);
34
38
 
@@ -7,7 +7,11 @@ exports.fireScreenEvent = exports.fireOperationalEvent = exports.fireCopiedEvent
7
7
 
8
8
  var _analytics = require("../../utils/analytics");
9
9
 
10
- var fireOperationalEvent = function fireOperationalEvent(createAnalyticsEvent, status, fileAttributes, performanceAttributes, ssrReliability, error) {
10
+ var _errors = require("./../../errors");
11
+
12
+ var fireOperationalEvent = function fireOperationalEvent(createAnalyticsEvent, status, fileAttributes, performanceAttributes, ssrReliability) {
13
+ var error = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : new _errors.MediaCardError('missing-error-data');
14
+
11
15
  var fireEvent = function fireEvent(payload) {
12
16
  return (0, _analytics.fireMediaCardEvent)(payload, createAnalyticsEvent);
13
17
  };
@@ -22,7 +26,7 @@ var fireOperationalEvent = function fireOperationalEvent(createAnalyticsEvent, s
22
26
  break;
23
27
 
24
28
  case 'error':
25
- error && fireEvent((0, _analytics.getRenderErrorEventPayload)(fileAttributes, performanceAttributes, error, ssrReliability));
29
+ fireEvent((0, _analytics.getRenderErrorEventPayload)(fileAttributes, performanceAttributes, error, ssrReliability));
26
30
  break;
27
31
  }
28
32
  };
@@ -54,6 +54,8 @@ var _dimensionComparer = require("../../../utils/dimensionComparer");
54
54
 
55
55
  var _filePreviewStatus = require("./filePreviewStatus");
56
56
 
57
+ var _imageRefetchingAnalytics = require("../imageRefetchingAnalytics");
58
+
57
59
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
58
60
 
59
61
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
@@ -124,48 +126,57 @@ var extendAndCachePreview = function extendAndCachePreview(id, mode, preview, me
124
126
 
125
127
  var getCardPreview = /*#__PURE__*/function () {
126
128
  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref) {
127
- var mediaClient, id, _ref$dimensions, dimensions, filePreview, onLocalPreviewError, isRemotePreviewReady, imageUrlParams, mediaBlobUrlAttrs, mode, cachedPreview, dimensionsAreBigger, localPreview;
129
+ var mediaClient, id, _ref$dimensions, dimensions, filePreview, onLocalPreviewError, isRemotePreviewReady, imageUrlParams, mediaBlobUrlAttrs, createAnalyticsEvent, featureFlags, mode, cachedPreview, dimensionsAreBigger, localPreview, remotePreview;
128
130
 
129
131
  return _regenerator.default.wrap(function _callee$(_context) {
130
132
  while (1) {
131
133
  switch (_context.prev = _context.next) {
132
134
  case 0:
133
- mediaClient = _ref.mediaClient, id = _ref.id, _ref$dimensions = _ref.dimensions, dimensions = _ref$dimensions === void 0 ? {} : _ref$dimensions, filePreview = _ref.filePreview, onLocalPreviewError = _ref.onLocalPreviewError, isRemotePreviewReady = _ref.isRemotePreviewReady, imageUrlParams = _ref.imageUrlParams, mediaBlobUrlAttrs = _ref.mediaBlobUrlAttrs;
135
+ mediaClient = _ref.mediaClient, id = _ref.id, _ref$dimensions = _ref.dimensions, dimensions = _ref$dimensions === void 0 ? {} : _ref$dimensions, filePreview = _ref.filePreview, onLocalPreviewError = _ref.onLocalPreviewError, isRemotePreviewReady = _ref.isRemotePreviewReady, imageUrlParams = _ref.imageUrlParams, mediaBlobUrlAttrs = _ref.mediaBlobUrlAttrs, createAnalyticsEvent = _ref.createAnalyticsEvent, featureFlags = _ref.featureFlags;
134
136
  mode = imageUrlParams.mode;
135
137
  cachedPreview = _cache.default.get(id, mode);
136
138
  dimensionsAreBigger = (0, _dimensionComparer.isBigger)(cachedPreview === null || cachedPreview === void 0 ? void 0 : cachedPreview.dimensions, dimensions);
137
139
 
138
140
  if (!(cachedPreview && !dimensionsAreBigger)) {
139
- _context.next = 6;
141
+ _context.next = 7;
140
142
  break;
141
143
  }
142
144
 
145
+ if ((0, _mediaCommon.getMediaFeatureFlag)('memoryCacheLogging', featureFlags)) {
146
+ createAnalyticsEvent && (0, _imageRefetchingAnalytics.fireImageFetchingOperationalEvent)(createAnalyticsEvent, 'cache-hit', {
147
+ fileId: id,
148
+ prevDimensions: cachedPreview.dimensions,
149
+ currentDimensions: dimensions,
150
+ source: cachedPreview.source
151
+ });
152
+ }
153
+
143
154
  return _context.abrupt("return", cachedPreview);
144
155
 
145
- case 6:
146
- _context.prev = 6;
156
+ case 7:
157
+ _context.prev = 7;
147
158
 
148
159
  if (!filePreview) {
149
- _context.next = 12;
160
+ _context.next = 13;
150
161
  break;
151
162
  }
152
163
 
153
- _context.next = 10;
164
+ _context.next = 11;
154
165
  return (0, _helpers.getCardPreviewFromFilePreview)(filePreview);
155
166
 
156
- case 10:
167
+ case 11:
157
168
  localPreview = _context.sent;
158
169
  return _context.abrupt("return", extendAndCachePreview(id, mode, _objectSpread(_objectSpread({}, localPreview), {}, {
159
170
  dimensions: dimensions
160
171
  }), mediaBlobUrlAttrs));
161
172
 
162
- case 12:
163
- _context.next = 19;
173
+ case 13:
174
+ _context.next = 20;
164
175
  break;
165
176
 
166
- case 14:
167
- _context.prev = 14;
168
- _context.t0 = _context["catch"](6);
177
+ case 15:
178
+ _context.prev = 15;
179
+ _context.t0 = _context["catch"](7);
169
180
 
170
181
  /**
171
182
  * We report the error if:
@@ -187,29 +198,45 @@ var getCardPreview = /*#__PURE__*/function () {
187
198
 
188
199
 
189
200
  if (isRemotePreviewReady) {
190
- _context.next = 19;
201
+ _context.next = 20;
191
202
  break;
192
203
  }
193
204
 
194
205
  throw _context.t0;
195
206
 
196
- case 19:
207
+ case 20:
197
208
  if (isRemotePreviewReady) {
198
- _context.next = 21;
209
+ _context.next = 22;
199
210
  break;
200
211
  }
201
212
 
202
213
  throw new _errors.MediaCardError('remote-preview-not-ready');
203
214
 
204
- case 21:
205
- return _context.abrupt("return", fetchAndCacheRemotePreview(mediaClient, id, dimensions, imageUrlParams, mediaBlobUrlAttrs));
206
-
207
215
  case 22:
216
+ _context.next = 24;
217
+ return fetchAndCacheRemotePreview(mediaClient, id, dimensions, imageUrlParams, mediaBlobUrlAttrs);
218
+
219
+ case 24:
220
+ remotePreview = _context.sent;
221
+
222
+ if ((0, _mediaCommon.getMediaFeatureFlag)('memoryCacheLogging', featureFlags)) {
223
+ createAnalyticsEvent && (0, _imageRefetchingAnalytics.fireImageFetchingOperationalEvent)(createAnalyticsEvent, 'remote-success', {
224
+ fileId: id,
225
+ prevDimensions: cachedPreview === null || cachedPreview === void 0 ? void 0 : cachedPreview.dimensions,
226
+ currentDimensions: dimensions,
227
+ dimensionsPercentageDiff: (0, _imageRefetchingAnalytics.calculatePercentageDifference)(cachedPreview === null || cachedPreview === void 0 ? void 0 : cachedPreview.dimensions, dimensions),
228
+ source: remotePreview.source
229
+ });
230
+ }
231
+
232
+ return _context.abrupt("return", remotePreview);
233
+
234
+ case 27:
208
235
  case "end":
209
236
  return _context.stop();
210
237
  }
211
238
  }
212
- }, _callee, null, [[6, 14]]);
239
+ }, _callee, null, [[7, 15]]);
213
240
  }));
214
241
 
215
242
  return function getCardPreview(_x) {
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.fireImageFetchingOperationalEvent = exports.calculatePercentageDifference = void 0;
7
+
8
+ var _analytics = require("../../utils/analytics");
9
+
10
+ var fireImageFetchingOperationalEvent = function fireImageFetchingOperationalEvent(createAnalyticsEvent, action, cardPreviewAttributes) {
11
+ var fireEvent = function fireEvent(payload) {
12
+ return (0, _analytics.fireMediaCardEvent)(payload, createAnalyticsEvent);
13
+ };
14
+
15
+ switch (action) {
16
+ case 'cache-hit':
17
+ fireEvent((0, _analytics.getCacheHitEventPayload)(cardPreviewAttributes));
18
+ break;
19
+
20
+ case 'remote-success':
21
+ fireEvent((0, _analytics.getRemoteSuccessEventPayload)(cardPreviewAttributes));
22
+ break;
23
+ }
24
+ };
25
+
26
+ exports.fireImageFetchingOperationalEvent = fireImageFetchingOperationalEvent;
27
+
28
+ var calculatePercentageDifference = function calculatePercentageDifference(prevDimensions, currentDimensions) {
29
+ if (!prevDimensions) {
30
+ return undefined;
31
+ }
32
+
33
+ var prevWidth = parseInt("".concat(prevDimensions === null || prevDimensions === void 0 ? void 0 : prevDimensions.width), 10);
34
+ var currWidth = parseInt("".concat(currentDimensions === null || currentDimensions === void 0 ? void 0 : currentDimensions.width), 10);
35
+ var prevHeight = parseInt("".concat(prevDimensions === null || prevDimensions === void 0 ? void 0 : prevDimensions.height), 10);
36
+ var currHeight = parseInt("".concat(currentDimensions === null || currentDimensions === void 0 ? void 0 : currentDimensions.height), 10);
37
+ var percentageDiffInWidth = ((currWidth - prevWidth) / prevWidth * 100).toFixed(2);
38
+ var percentageDiffInHeight = ((currHeight - prevHeight) / prevHeight * 100).toFixed(2);
39
+ return {
40
+ width: percentageDiffInWidth,
41
+ height: percentageDiffInHeight
42
+ };
43
+ };
44
+
45
+ exports.calculatePercentageDifference = calculatePercentageDifference;
@@ -90,7 +90,7 @@ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflec
90
90
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
91
91
 
92
92
  var packageName = "@atlaskit/media-card";
93
- var packageVersion = "74.0.0";
93
+ var packageVersion = "74.1.0";
94
94
 
95
95
  var CardBase = /*#__PURE__*/function (_Component) {
96
96
  (0, _inherits2.default)(CardBase, _Component);
@@ -112,8 +112,6 @@ var CardBase = /*#__PURE__*/function (_Component) {
112
112
  wasStatusUploading: false,
113
113
  wasStatusProcessing: false
114
114
  });
115
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "viewportPreAnchorRef", /*#__PURE__*/(0, _react.createRef)());
116
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "viewportPostAnchorRef", /*#__PURE__*/(0, _react.createRef)());
117
115
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "ssrReliability", {
118
116
  server: {
119
117
  status: 'unknown'
@@ -162,7 +160,8 @@ var CardBase = /*#__PURE__*/function (_Component) {
162
160
  var _this$props2 = _this.props,
163
161
  _this$props2$dimensio = _this$props2.dimensions,
164
162
  dimensions = _this$props2$dimensio === void 0 ? {} : _this$props2$dimensio,
165
- mediaClient = _this$props2.mediaClient;
163
+ mediaClient = _this$props2.mediaClient,
164
+ createAnalyticsEvent = _this$props2.createAnalyticsEvent;
166
165
  return {
167
166
  mediaClient: mediaClient,
168
167
  id: id,
@@ -171,7 +170,9 @@ var CardBase = /*#__PURE__*/function (_Component) {
171
170
  filePreview: isBannedLocalPreview ? undefined : (0, _getCardPreview.getFilePreviewFromFileState)(fileState),
172
171
  isRemotePreviewReady: (0, _mediaClient2.isImageRepresentationReady)(fileState),
173
172
  imageUrlParams: _this.getImageURLParams(identifier),
174
- mediaBlobUrlAttrs: _this.getMediaBlobUrlAttrs(identifier, fileState)
173
+ mediaBlobUrlAttrs: _this.getMediaBlobUrlAttrs(identifier, fileState),
174
+ createAnalyticsEvent: createAnalyticsEvent,
175
+ featureFlags: _this.props.featureFlags
175
176
  };
176
177
  });
177
178
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "setCacheSSRPreview", function (identifier) {
@@ -624,16 +625,8 @@ var CardBase = /*#__PURE__*/function (_Component) {
624
625
 
625
626
  return isLazy ? /*#__PURE__*/_react.default.createElement(_viewportDetector.ViewportDetector, {
626
627
  cardEl: cardRef,
627
- preAnchorRef: _this.viewportPreAnchorRef,
628
- postAnchorRef: _this.viewportPostAnchorRef,
629
628
  onVisible: _this.onCardInViewport
630
- }, /*#__PURE__*/_react.default.createElement(_viewportDetector.ViewportAnchor, {
631
- ref: _this.viewportPreAnchorRef,
632
- offsetTop: -_viewportDetector.ABS_VIEWPORT_ANCHOR_OFFSET_TOP
633
- }), card, /*#__PURE__*/_react.default.createElement(_viewportDetector.ViewportAnchor, {
634
- ref: _this.viewportPostAnchorRef,
635
- offsetTop: _viewportDetector.ABS_VIEWPORT_ANCHOR_OFFSET_TOP
636
- })) : card;
629
+ }, card) : card;
637
630
  });
638
631
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "storeSSRData", function () {
639
632
  var _this$ssrReliability$;
@@ -762,6 +755,8 @@ var CardBase = /*#__PURE__*/function (_Component) {
762
755
  (0, _createClass2.default)(CardBase, [{
763
756
  key: "componentDidMount",
764
757
  value: function componentDidMount() {
758
+ var _getDocument;
759
+
765
760
  this.hasBeenMounted = true;
766
761
  var _this$state3 = this.state,
767
762
  isCardVisible = _this$state3.isCardVisible,
@@ -795,7 +790,7 @@ var CardBase = /*#__PURE__*/function (_Component) {
795
790
  // won't work in IE11
796
791
 
797
792
 
798
- (0, _document.default)().addEventListener('copy', this.fireCopiedEvent);
793
+ (_getDocument = (0, _document.default)()) === null || _getDocument === void 0 ? void 0 : _getDocument.addEventListener('copy', this.fireCopiedEvent);
799
794
  }
800
795
  }, {
801
796
  key: "componentDidUpdate",
@@ -890,9 +885,11 @@ var CardBase = /*#__PURE__*/function (_Component) {
890
885
  }, {
891
886
  key: "componentWillUnmount",
892
887
  value: function componentWillUnmount() {
888
+ var _getDocument2;
889
+
893
890
  this.hasBeenMounted = false;
894
891
  this.unsubscribe();
895
- (0, _document.default)().removeEventListener('copy', this.fireCopiedEvent);
892
+ (_getDocument2 = (0, _document.default)()) === null || _getDocument2 === void 0 ? void 0 : _getDocument2.removeEventListener('copy', this.fireCopiedEvent);
896
893
  }
897
894
  }, {
898
895
  key: "updateStateForIdentifier",
@@ -7,7 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  });
8
8
  exports.extractErrorInfo = exports.createAndFireMediaCardEvent = exports.LOGGED_FEATURE_FLAG_KEYS = exports.LOGGED_FEATURE_FLAGS = void 0;
9
9
  exports.fireMediaCardEvent = fireMediaCardEvent;
10
- exports.getRenderSucceededEventPayload = exports.getRenderPreviewableCardPayload = exports.getRenderFailedFileStatusPayload = exports.getRenderFailedExternalUriPayload = exports.getRenderErrorRequestMetadata = exports.getRenderErrorFailReason = exports.getRenderErrorEventPayload = exports.getRenderErrorErrorReason = exports.getRenderErrorErrorDetail = exports.getRenderCommencedEventPayload = exports.getFileAttributes = exports.getCopiedFilePayload = void 0;
10
+ exports.getRenderSucceededEventPayload = exports.getRenderPreviewableCardPayload = exports.getRenderFailedFileStatusPayload = exports.getRenderFailedExternalUriPayload = exports.getRenderErrorRequestMetadata = exports.getRenderErrorFailReason = exports.getRenderErrorEventPayload = exports.getRenderErrorErrorReason = exports.getRenderErrorErrorDetail = exports.getRenderCommencedEventPayload = exports.getRemoteSuccessEventPayload = exports.getFileAttributes = exports.getCopiedFilePayload = exports.getCacheHitEventPayload = void 0;
11
11
 
12
12
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
13
13
 
@@ -30,7 +30,8 @@ var relevantFlags = {
30
30
  observedWidth: true,
31
31
  mediaInline: false,
32
32
  folderUploads: false,
33
- mediaUploadApiV2: true
33
+ mediaUploadApiV2: true,
34
+ memoryCacheLogging: true
34
35
  };
35
36
  var LOGGED_FEATURE_FLAGS = (0, _mediaCommon.filterFeatureFlagNames)(relevantFlags);
36
37
  exports.LOGGED_FEATURE_FLAGS = LOGGED_FEATURE_FLAGS;
@@ -94,6 +95,32 @@ var getRenderSucceededEventPayload = function getRenderSucceededEventPayload(fil
94
95
 
95
96
  exports.getRenderSucceededEventPayload = getRenderSucceededEventPayload;
96
97
 
98
+ var getCacheHitEventPayload = function getCacheHitEventPayload(cardPreviewAttributes) {
99
+ return {
100
+ eventType: 'operational',
101
+ action: 'cache-hit',
102
+ actionSubject: 'mediaCardCache',
103
+ attributes: {
104
+ cardPreviewAttributes: cardPreviewAttributes
105
+ }
106
+ };
107
+ };
108
+
109
+ exports.getCacheHitEventPayload = getCacheHitEventPayload;
110
+
111
+ var getRemoteSuccessEventPayload = function getRemoteSuccessEventPayload(cardPreviewAttributes) {
112
+ return {
113
+ eventType: 'operational',
114
+ action: 'Remote-success',
115
+ actionSubject: 'mediaCardCache',
116
+ attributes: {
117
+ cardPreviewAttributes: cardPreviewAttributes
118
+ }
119
+ };
120
+ };
121
+
122
+ exports.getRemoteSuccessEventPayload = getRemoteSuccessEventPayload;
123
+
97
124
  var getRenderFailedExternalUriPayload = function getRenderFailedExternalUriPayload(fileAttributes, performanceAttributes) {
98
125
  return {
99
126
  eventType: 'operational',
@@ -6,7 +6,15 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
 
8
8
  var _default = function _default() {
9
- return document;
9
+ if (typeof window === 'undefined') {
10
+ return;
11
+ }
12
+
13
+ if (typeof window.document === 'undefined') {
14
+ return;
15
+ }
16
+
17
+ return window.document;
10
18
  };
11
19
 
12
20
  exports.default = _default;
@@ -13,6 +13,8 @@ var _ufo = require("@atlaskit/ufo");
13
13
 
14
14
  var _analytics = require("./analytics");
15
15
 
16
+ var _errors = require("../errors");
17
+
16
18
  var _mediaClient = require("@atlaskit/media-client");
17
19
 
18
20
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
@@ -20,7 +22,7 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
20
22
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
21
23
 
22
24
  var packageName = "@atlaskit/media-card";
23
- var packageVersion = "74.0.0";
25
+ var packageVersion = "74.1.0";
24
26
  var concurrentExperience;
25
27
 
26
28
  var getExperience = function getExperience(id) {
@@ -45,7 +47,9 @@ var startUfoExperience = function startUfoExperience(id) {
45
47
 
46
48
  exports.startUfoExperience = startUfoExperience;
47
49
 
48
- var completeUfoExperience = function completeUfoExperience(id, status, fileAttributes, fileStateFlags, ssrReliability, error) {
50
+ var completeUfoExperience = function completeUfoExperience(id, status, fileAttributes, fileStateFlags, ssrReliability) {
51
+ var error = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : new _errors.MediaCardError('missing-error-data');
52
+
49
53
  switch (status) {
50
54
  case 'complete':
51
55
  succeedUfoExperience(id, {
@@ -65,7 +69,7 @@ var completeUfoExperience = function completeUfoExperience(id, status, fileAttri
65
69
  break;
66
70
 
67
71
  case 'error':
68
- error && failUfoExperience(id, _objectSpread(_objectSpread({
72
+ failUfoExperience(id, _objectSpread(_objectSpread({
69
73
  fileAttributes: fileAttributes
70
74
  }, (0, _analytics.extractErrorInfo)(error)), {}, {
71
75
  request: (0, _analytics.getRenderErrorRequestMetadata)(error),
@@ -1,14 +1,18 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
3
5
  var _typeof = require("@babel/runtime/helpers/typeof");
4
6
 
5
7
  Object.defineProperty(exports, "__esModule", {
6
8
  value: true
7
9
  });
8
- exports.ViewportDetector = exports.ViewportAnchor = exports.ABS_VIEWPORT_ANCHOR_OFFSET_TOP = void 0;
10
+ exports.ViewportDetector = void 0;
9
11
 
10
12
  var _react = _interopRequireWildcard(require("react"));
11
13
 
14
+ var _document = _interopRequireDefault(require("./document"));
15
+
12
16
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
13
17
 
14
18
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
@@ -19,31 +23,8 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
19
23
 
20
24
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
21
25
 
22
- /**
23
- * As IntersectionObserver::rootMargin doesn't work within IFrames, we use an empty div + dynamic offsetTop to eagerly detect cards entering viewport.
24
- * Using this approach, we can lazy load cards ABS_VIEWPORT_ANCHOR_OFFSET_TOP px before they enter viewport.
25
- */
26
26
  var ABS_VIEWPORT_ANCHOR_OFFSET_TOP = 900; //px
27
27
 
28
- exports.ABS_VIEWPORT_ANCHOR_OFFSET_TOP = ABS_VIEWPORT_ANCHOR_OFFSET_TOP;
29
- var ViewportAnchor = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
30
- if (typeof IntersectionObserver === 'undefined') {
31
- return null;
32
- }
33
-
34
- return /*#__PURE__*/_react.default.createElement("div", {
35
- ref: ref,
36
- className: "media-card-viewport-anchor",
37
- style: {
38
- position: 'absolute',
39
- top: "".concat(props.offsetTop, "px"),
40
- maxHeight: 0,
41
- pointerEvents: 'none'
42
- }
43
- });
44
- });
45
- exports.ViewportAnchor = ViewportAnchor;
46
-
47
28
  var createIntersectionObserverCallback = function createIntersectionObserverCallback(onVisible) {
48
29
  return function (entries, observer) {
49
30
  var _iterator = _createForOfIteratorHelper(entries),
@@ -70,26 +51,22 @@ var createIntersectionObserverCallback = function createIntersectionObserverCall
70
51
  var ViewportObserver = function ViewportObserver(_ref) {
71
52
  var onVisible = _ref.onVisible,
72
53
  cardEl = _ref.cardEl,
73
- children = _ref.children,
74
- preAnchorRef = _ref.preAnchorRef,
75
- postAnchorRef = _ref.postAnchorRef;
54
+ children = _ref.children;
76
55
  (0, _react.useEffect)(function () {
77
- // IntersectionObserver uses root and target elements to detect intersections, defaulting root to the viewport
78
- var intersectionObserver = new IntersectionObserver(createIntersectionObserverCallback(onVisible));
79
- (preAnchorRef === null || preAnchorRef === void 0 ? void 0 : preAnchorRef.current) && intersectionObserver.observe(preAnchorRef.current);
80
- (postAnchorRef === null || postAnchorRef === void 0 ? void 0 : postAnchorRef.current) && intersectionObserver.observe(postAnchorRef.current);
56
+ var intersectionObserver = new IntersectionObserver(createIntersectionObserverCallback(onVisible), {
57
+ root: (0, _document.default)(),
58
+ rootMargin: "".concat(ABS_VIEWPORT_ANCHOR_OFFSET_TOP, "px")
59
+ });
81
60
  cardEl && intersectionObserver.observe(cardEl);
82
61
  return function () {
83
62
  intersectionObserver.disconnect();
84
63
  };
85
- }, [cardEl, preAnchorRef, postAnchorRef, onVisible]);
64
+ }, [cardEl, onVisible]);
86
65
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, children);
87
66
  };
88
67
 
89
68
  var ViewportDetector = function ViewportDetector(_ref2) {
90
69
  var cardEl = _ref2.cardEl,
91
- preAnchorRef = _ref2.preAnchorRef,
92
- postAnchorRef = _ref2.postAnchorRef,
93
70
  onVisible = _ref2.onVisible,
94
71
  children = _ref2.children;
95
72
 
@@ -99,8 +76,6 @@ var ViewportDetector = function ViewportDetector(_ref2) {
99
76
 
100
77
  return /*#__PURE__*/_react.default.createElement(ViewportObserver, {
101
78
  cardEl: cardEl,
102
- preAnchorRef: preAnchorRef,
103
- postAnchorRef: postAnchorRef,
104
79
  onVisible: onVisible
105
80
  }, children);
106
81
  };
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/media-card",
3
- "version": "74.0.0",
3
+ "version": "74.1.0",
4
4
  "sideEffects": false
5
5
  }
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Primary reason is logged through Data Portal.
3
+ * Make sure all the values are whitelisted in Measure -> Event Regitry -> "mediaCardRender failed" event
4
+ */
1
5
  export class MediaCardError extends Error {
2
6
  constructor(primaryReason, secondaryError) {
3
7
  super(primaryReason); // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#support-for-newtarget
@@ -1,5 +1,6 @@
1
1
  import { fireMediaCardEvent, getRenderSucceededEventPayload, getRenderErrorEventPayload, getRenderFailedFileStatusPayload, getCopiedFilePayload, getRenderCommencedEventPayload, getRenderPreviewableCardPayload } from '../../utils/analytics';
2
- export const fireOperationalEvent = (createAnalyticsEvent, status, fileAttributes, performanceAttributes, ssrReliability, error) => {
2
+ import { MediaCardError } from './../../errors';
3
+ export const fireOperationalEvent = (createAnalyticsEvent, status, fileAttributes, performanceAttributes, ssrReliability, error = new MediaCardError('missing-error-data')) => {
3
4
  const fireEvent = payload => fireMediaCardEvent(payload, createAnalyticsEvent);
4
5
 
5
6
  switch (status) {
@@ -12,7 +13,7 @@ export const fireOperationalEvent = (createAnalyticsEvent, status, fileAttribute
12
13
  break;
13
14
 
14
15
  case 'error':
15
- error && fireEvent(getRenderErrorEventPayload(fileAttributes, performanceAttributes, error, ssrReliability));
16
+ fireEvent(getRenderErrorEventPayload(fileAttributes, performanceAttributes, error, ssrReliability));
16
17
  break;
17
18
  }
18
19
  };
@@ -5,6 +5,8 @@ import { getCardPreviewFromFilePreview, getCardPreviewFromBackend } from './help
5
5
  import { MediaCardError, SsrPreviewError, isUnsupportedLocalPreviewError } from '../../../errors';
6
6
  import { isBigger } from '../../../utils/dimensionComparer';
7
7
  import { extractFilePreviewStatus, isPreviewableStatus } from './filePreviewStatus';
8
+ import { fireImageFetchingOperationalEvent, calculatePercentageDifference } from '../imageRefetchingAnalytics';
9
+ import { getMediaFeatureFlag } from '@atlaskit/media-common';
8
10
  export { getCardPreviewFromFilePreview, getCardPreviewFromBackend, isSupportedLocalPreview } from './helpers';
9
11
  export { extractFilePreviewStatus } from './filePreviewStatus';
10
12
  export const getCardPreviewFromCache = cardPreviewCache.get;
@@ -71,13 +73,24 @@ export const getCardPreview = async ({
71
73
  onLocalPreviewError,
72
74
  isRemotePreviewReady,
73
75
  imageUrlParams,
74
- mediaBlobUrlAttrs
76
+ mediaBlobUrlAttrs,
77
+ createAnalyticsEvent,
78
+ featureFlags
75
79
  }) => {
76
80
  const mode = imageUrlParams.mode;
77
81
  const cachedPreview = cardPreviewCache.get(id, mode);
78
82
  const dimensionsAreBigger = isBigger(cachedPreview === null || cachedPreview === void 0 ? void 0 : cachedPreview.dimensions, dimensions);
79
83
 
80
84
  if (cachedPreview && !dimensionsAreBigger) {
85
+ if (getMediaFeatureFlag('memoryCacheLogging', featureFlags)) {
86
+ createAnalyticsEvent && fireImageFetchingOperationalEvent(createAnalyticsEvent, 'cache-hit', {
87
+ fileId: id,
88
+ prevDimensions: cachedPreview.dimensions,
89
+ currentDimensions: dimensions,
90
+ source: cachedPreview.source
91
+ });
92
+ }
93
+
81
94
  return cachedPreview;
82
95
  }
83
96
 
@@ -123,7 +136,19 @@ export const getCardPreview = async ({
123
136
  throw new MediaCardError('remote-preview-not-ready');
124
137
  }
125
138
 
126
- return fetchAndCacheRemotePreview(mediaClient, id, dimensions, imageUrlParams, mediaBlobUrlAttrs);
139
+ const remotePreview = await fetchAndCacheRemotePreview(mediaClient, id, dimensions, imageUrlParams, mediaBlobUrlAttrs);
140
+
141
+ if (getMediaFeatureFlag('memoryCacheLogging', featureFlags)) {
142
+ createAnalyticsEvent && fireImageFetchingOperationalEvent(createAnalyticsEvent, 'remote-success', {
143
+ fileId: id,
144
+ prevDimensions: cachedPreview === null || cachedPreview === void 0 ? void 0 : cachedPreview.dimensions,
145
+ currentDimensions: dimensions,
146
+ dimensionsPercentageDiff: calculatePercentageDifference(cachedPreview === null || cachedPreview === void 0 ? void 0 : cachedPreview.dimensions, dimensions),
147
+ source: remotePreview.source
148
+ });
149
+ }
150
+
151
+ return remotePreview;
127
152
  };
128
153
  export const shouldResolvePreview = ({
129
154
  status,
@@ -0,0 +1,30 @@
1
+ import { fireMediaCardEvent, getCacheHitEventPayload, getRemoteSuccessEventPayload } from '../../utils/analytics';
2
+ export const fireImageFetchingOperationalEvent = (createAnalyticsEvent, action, cardPreviewAttributes) => {
3
+ const fireEvent = payload => fireMediaCardEvent(payload, createAnalyticsEvent);
4
+
5
+ switch (action) {
6
+ case 'cache-hit':
7
+ fireEvent(getCacheHitEventPayload(cardPreviewAttributes));
8
+ break;
9
+
10
+ case 'remote-success':
11
+ fireEvent(getRemoteSuccessEventPayload(cardPreviewAttributes));
12
+ break;
13
+ }
14
+ };
15
+ export const calculatePercentageDifference = (prevDimensions, currentDimensions) => {
16
+ if (!prevDimensions) {
17
+ return undefined;
18
+ }
19
+
20
+ const prevWidth = parseInt(`${prevDimensions === null || prevDimensions === void 0 ? void 0 : prevDimensions.width}`, 10);
21
+ const currWidth = parseInt(`${currentDimensions === null || currentDimensions === void 0 ? void 0 : currentDimensions.width}`, 10);
22
+ const prevHeight = parseInt(`${prevDimensions === null || prevDimensions === void 0 ? void 0 : prevDimensions.height}`, 10);
23
+ const currHeight = parseInt(`${currentDimensions === null || currentDimensions === void 0 ? void 0 : currentDimensions.height}`, 10);
24
+ const percentageDiffInWidth = ((currWidth - prevWidth) / prevWidth * 100).toFixed(2);
25
+ const percentageDiffInHeight = ((currHeight - prevHeight) / prevHeight * 100).toFixed(2);
26
+ return {
27
+ width: percentageDiffInWidth,
28
+ height: percentageDiffInHeight
29
+ };
30
+ };