@atlaskit/media-card 71.0.0 → 72.0.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 (110) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/cjs/errors.js +56 -5
  3. package/dist/cjs/files/cardImageView/index.js +53 -104
  4. package/dist/cjs/files/index.js +0 -6
  5. package/dist/cjs/root/card/cardAnalytics.js +3 -15
  6. package/dist/cjs/root/card/cardSSRView.js +4 -2
  7. package/dist/cjs/root/card/cardState.js +50 -0
  8. package/dist/cjs/root/card/getCardPreview/cache.js +5 -0
  9. package/dist/cjs/root/card/getCardPreview/filePreviewStatus.js +50 -0
  10. package/dist/cjs/root/card/getCardPreview/helpers.js +13 -21
  11. package/dist/cjs/root/card/getCardPreview/index.js +91 -94
  12. package/dist/cjs/root/card/getCardStatus.js +7 -1
  13. package/dist/cjs/root/card/index.js +271 -266
  14. package/dist/cjs/root/cardView.js +96 -60
  15. package/dist/cjs/root/inline/loader.js +2 -1
  16. package/dist/cjs/root/inline/mediaInlineCard.js +4 -3
  17. package/dist/cjs/root/ui/iconMessage/index.js +12 -5
  18. package/dist/cjs/root/ui/imageRenderer/imageRenderer.js +30 -124
  19. package/dist/cjs/root/ui/titleBox/failedTitleBox.js +7 -3
  20. package/dist/cjs/utils/analytics.js +6 -44
  21. package/dist/cjs/utils/dimensionComparer.js +1 -1
  22. package/dist/cjs/utils/metadata.js +11 -3
  23. package/dist/cjs/utils/objectURLCache.js +6 -0
  24. package/dist/cjs/utils/shouldDisplayImageThumbnail.js +1 -1
  25. package/dist/cjs/version.json +1 -1
  26. package/dist/es2019/errors.js +34 -2
  27. package/dist/es2019/files/cardImageView/index.js +8 -61
  28. package/dist/es2019/files/index.js +1 -1
  29. package/dist/es2019/root/card/cardAnalytics.js +3 -14
  30. package/dist/es2019/root/card/cardSSRView.js +3 -2
  31. package/dist/es2019/root/card/cardState.js +26 -0
  32. package/dist/es2019/root/card/getCardPreview/cache.js +5 -0
  33. package/dist/es2019/root/card/getCardPreview/filePreviewStatus.js +35 -0
  34. package/dist/es2019/root/card/getCardPreview/helpers.js +2 -12
  35. package/dist/es2019/root/card/getCardPreview/index.js +71 -74
  36. package/dist/es2019/root/card/getCardStatus.js +1 -0
  37. package/dist/es2019/root/card/index.js +193 -171
  38. package/dist/es2019/root/cardView.js +100 -61
  39. package/dist/es2019/root/inline/loader.js +2 -1
  40. package/dist/es2019/root/inline/mediaInlineCard.js +4 -3
  41. package/dist/es2019/root/ui/iconMessage/index.js +5 -3
  42. package/dist/es2019/root/ui/imageRenderer/imageRenderer.js +21 -88
  43. package/dist/es2019/root/ui/titleBox/failedTitleBox.js +5 -3
  44. package/dist/es2019/utils/analytics.js +5 -34
  45. package/dist/es2019/utils/dimensionComparer.js +1 -1
  46. package/dist/es2019/utils/metadata.js +12 -4
  47. package/dist/es2019/utils/objectURLCache.js +5 -0
  48. package/dist/es2019/utils/shouldDisplayImageThumbnail.js +1 -1
  49. package/dist/es2019/version.json +1 -1
  50. package/dist/esm/errors.js +42 -1
  51. package/dist/esm/files/cardImageView/index.js +51 -102
  52. package/dist/esm/files/index.js +1 -1
  53. package/dist/esm/root/card/cardAnalytics.js +3 -15
  54. package/dist/esm/root/card/cardSSRView.js +3 -2
  55. package/dist/esm/root/card/cardState.js +32 -0
  56. package/dist/esm/root/card/getCardPreview/cache.js +6 -0
  57. package/dist/esm/root/card/getCardPreview/filePreviewStatus.js +35 -0
  58. package/dist/esm/root/card/getCardPreview/helpers.js +13 -21
  59. package/dist/esm/root/card/getCardPreview/index.js +79 -88
  60. package/dist/esm/root/card/getCardStatus.js +3 -0
  61. package/dist/esm/root/card/index.js +278 -268
  62. package/dist/esm/root/cardView.js +98 -61
  63. package/dist/esm/root/inline/loader.js +2 -1
  64. package/dist/esm/root/inline/mediaInlineCard.js +4 -3
  65. package/dist/esm/root/ui/iconMessage/index.js +7 -3
  66. package/dist/esm/root/ui/imageRenderer/imageRenderer.js +23 -118
  67. package/dist/esm/root/ui/titleBox/failedTitleBox.js +6 -3
  68. package/dist/esm/utils/analytics.js +5 -36
  69. package/dist/esm/utils/dimensionComparer.js +1 -1
  70. package/dist/esm/utils/metadata.js +12 -4
  71. package/dist/esm/utils/objectURLCache.js +6 -0
  72. package/dist/esm/utils/shouldDisplayImageThumbnail.js +1 -1
  73. package/dist/esm/version.json +1 -1
  74. package/dist/types/errors.d.ts +9 -1
  75. package/dist/types/files/cardImageView/index.d.ts +4 -13
  76. package/dist/types/files/cardImageView/styled.d.ts +1 -1
  77. package/dist/types/files/index.d.ts +1 -1
  78. package/dist/types/index.d.ts +4 -3
  79. package/dist/types/root/card/cardAnalytics.d.ts +1 -6
  80. package/dist/types/root/card/cardSSRView.d.ts +1 -1
  81. package/dist/types/root/card/cardState.d.ts +5 -0
  82. package/dist/types/root/card/getCardPreview/cache.d.ts +3 -1
  83. package/dist/types/root/card/getCardPreview/filePreviewStatus.d.ts +5 -0
  84. package/dist/types/root/card/getCardPreview/helpers.d.ts +3 -4
  85. package/dist/types/root/card/getCardPreview/index.d.ts +17 -13
  86. package/dist/types/root/card/getCardStatus.d.ts +1 -0
  87. package/dist/types/root/card/index.d.ts +11 -10
  88. package/dist/types/root/cardView.d.ts +11 -8
  89. package/dist/types/root/inlinePlayer.d.ts +1 -1
  90. package/dist/types/root/ui/iconMessage/index.d.ts +2 -1
  91. package/dist/types/root/ui/imageRenderer/imageRenderer.d.ts +2 -13
  92. package/dist/types/root/ui/styledSSR.d.ts +1 -1
  93. package/dist/types/root/ui/titleBox/failedTitleBox.d.ts +2 -0
  94. package/dist/types/styles/mixins.d.ts +1 -1
  95. package/dist/types/types.d.ts +7 -1
  96. package/dist/types/utils/analytics.d.ts +6 -15
  97. package/dist/types/utils/cardDimensions.d.ts +4 -4
  98. package/dist/types/utils/dimensionComparer.d.ts +1 -1
  99. package/dist/types/utils/metadata.d.ts +2 -2
  100. package/dist/types/utils/objectURLCache.d.ts +2 -1
  101. package/example-helpers/index.tsx +21 -0
  102. package/package.json +6 -5
  103. package/dist/cjs/root/card/getCardPreview/types.js +0 -5
  104. package/dist/cjs/utils/fileAttributesContext.js +0 -40
  105. package/dist/es2019/root/card/getCardPreview/types.js +0 -1
  106. package/dist/es2019/utils/fileAttributesContext.js +0 -19
  107. package/dist/esm/root/card/getCardPreview/types.js +0 -1
  108. package/dist/esm/utils/fileAttributesContext.js +0 -18
  109. package/dist/types/root/card/getCardPreview/types.d.ts +0 -5
  110. package/dist/types/utils/fileAttributesContext.d.ts +0 -10
@@ -23,22 +23,20 @@ import { version as packageVersion, name as packageName } from '../../version.js
23
23
  import { withAnalyticsEvents } from '@atlaskit/analytics-next';
24
24
  import { withMediaAnalyticsContext } from '@atlaskit/media-common';
25
25
  import DownloadIcon from '@atlaskit/icon/glyph/download';
26
- import { addFileAttrsToUrl, globalMediaEventEmitter, isDifferentIdentifier, isFileIdentifier, isErrorFileState, RECENTS_COLLECTION, isImageRepresentationReady, isExternalImageIdentifier } from '@atlaskit/media-client';
26
+ import { globalMediaEventEmitter, isDifferentIdentifier, isFileIdentifier, RECENTS_COLLECTION, isImageRepresentationReady, isExternalImageIdentifier, imageResizeModeToFileImageMode } from '@atlaskit/media-client';
27
27
  import { MediaViewer } from '@atlaskit/media-viewer';
28
28
  import { IntlProvider, intlShape } from 'react-intl';
29
29
  import { CardView } from '../cardView';
30
30
  import { ViewportDetector } from '../../utils/viewportDetector';
31
31
  import { getRequestedDimensions } from '../../utils/getDataURIDimension';
32
- import { shouldGetCardPreview, extractFilePreviewStatus, getCardPreview, getCardPreviewFromCache, getFilePreviewFromFileState } from './getCardPreview';
32
+ import { getCardPreview, getCardPreviewFromCache, removeCardPreviewFromCache, getFilePreviewFromFileState, shouldResolvePreview } from './getCardPreview';
33
33
  import { getFileDetails } from '../../utils/metadata';
34
- import { isBigger } from '../../utils/dimensionComparer';
35
- import { getCardStatus } from './getCardStatus';
36
34
  import { InlinePlayer } from '../inlinePlayer';
37
35
  import { getFileAttributes } from '../../utils/analytics';
38
- import { FileAttributesProvider } from '../../utils/fileAttributesContext';
39
- import { isRemotePreviewError, MediaCardError, ensureMediaCardError } from '../../errors';
36
+ import { isLocalPreviewError, MediaCardError, ensureMediaCardError, ImageLoadError } from '../../errors';
40
37
  import { fireOperationalEvent as _fireOperationalEvent, fireCommencedEvent as _fireCommencedEvent, relevantFeatureFlagNames, fireCopiedEvent, fireScreenEvent } from './cardAnalytics';
41
38
  import getDocument from '../../utils/document';
39
+ import { getCardStateFromFileState, createStateUpdater } from './cardState';
42
40
  export var CardBase = /*#__PURE__*/function (_Component) {
43
41
  _inherits(CardBase, _Component);
44
42
 
@@ -57,75 +55,159 @@ export var CardBase = /*#__PURE__*/function (_Component) {
57
55
 
58
56
  _defineProperty(_assertThisInitialized(_this), "timeElapsedTillCommenced", performance.now());
59
57
 
60
- _defineProperty(_assertThisInitialized(_this), "shouldRefetchImage", function (current, next) {
61
- if (!current || !next) {
62
- return false;
63
- }
64
-
65
- return isBigger(current, next);
66
- });
67
-
68
- _defineProperty(_assertThisInitialized(_this), "isLatestCardStatusUpdate", function (cardStatusUpdateTimestamp) {
69
- return !_this.lastCardStatusUpdateTimestamp || _this.lastCardStatusUpdateTimestamp <= cardStatusUpdateTimestamp;
70
- });
71
-
72
- _defineProperty(_assertThisInitialized(_this), "onLocalPreviewError", function (error) {// TODO: track local preview success rate
73
- // https://product-fabric.atlassian.net/browse/MEX-774
58
+ _defineProperty(_assertThisInitialized(_this), "getImageURLParams", function (_ref) {
59
+ var collection = _ref.collectionName;
60
+ return _objectSpread(_objectSpread({
61
+ collection: collection,
62
+ mode: imageResizeModeToFileImageMode(_this.props.resizeMode)
63
+ }, _this.requestedDimensions), {}, {
64
+ allowAnimated: true
65
+ });
74
66
  });
75
67
 
76
- _defineProperty(_assertThisInitialized(_this), "createAddContextToDataURI", function (fileId, fileState, _ref, collectionName) {
77
- var width = _ref.width,
78
- height = _ref.height;
79
- return function (dataURI) {
80
- var _this$props = _this.props,
81
- contextId = _this$props.contextId,
82
- alt = _this$props.alt;
83
-
84
- if (!contextId) {
85
- return dataURI;
86
- }
87
-
88
- var metadata = getFileDetails(fileState);
89
- return addFileAttrsToUrl(dataURI, {
90
- id: fileId,
91
- collection: collectionName,
92
- contextId: contextId,
93
- mimeType: metadata.mimeType,
94
- name: metadata.name,
95
- size: metadata.size,
96
- width: width,
97
- height: height,
98
- alt: alt
99
- });
100
- };
68
+ _defineProperty(_assertThisInitialized(_this), "getMediaBlobUrlAttrs", function (identifier, fileState) {
69
+ var id = identifier.id,
70
+ collection = identifier.collectionName;
71
+ var _this$props = _this.props,
72
+ originalDimensions = _this$props.originalDimensions,
73
+ contextId = _this$props.contextId,
74
+ alt = _this$props.alt;
75
+
76
+ var _getFileDetails = getFileDetails(identifier, fileState),
77
+ mimeType = _getFileDetails.mimeType,
78
+ name = _getFileDetails.name,
79
+ size = _getFileDetails.size;
80
+
81
+ return contextId ? _objectSpread(_objectSpread({
82
+ id: id,
83
+ collection: collection,
84
+ contextId: contextId,
85
+ mimeType: mimeType,
86
+ name: name,
87
+ size: size
88
+ }, originalDimensions || _this.requestedDimensions), {}, {
89
+ alt: alt
90
+ }) : undefined;
101
91
  });
102
92
 
103
- _defineProperty(_assertThisInitialized(_this), "getCardPreviewParams", function (id, collectionName, fileState) {
93
+ _defineProperty(_assertThisInitialized(_this), "getCardPreviewParams", function (identifier, fileState) {
94
+ var isBannedLocalPreview = _this.state.isBannedLocalPreview;
95
+ var id = identifier.id;
104
96
  var _this$props2 = _this.props,
105
97
  _this$props2$dimensio = _this$props2.dimensions,
106
98
  dimensions = _this$props2$dimensio === void 0 ? {} : _this$props2$dimensio,
107
- originalDimensions = _this$props2.originalDimensions,
108
- resizeMode = _this$props2.resizeMode,
109
99
  mediaClient = _this$props2.mediaClient;
110
- var cardRef = _this.state.cardRef;
111
- var requestedDimensions = getRequestedDimensions({
112
- dimensions: dimensions,
113
- element: cardRef
114
- });
115
100
  return {
116
101
  mediaClient: mediaClient,
117
102
  id: id,
118
- collectionName: collectionName,
119
103
  dimensions: dimensions,
120
- resizeMode: resizeMode,
121
- requestedDimensions: requestedDimensions,
122
- onLocalPreviewError: _this.onLocalPreviewError,
123
- filePreview: getFilePreviewFromFileState(fileState),
104
+ onLocalPreviewError: _this.fireLocalPreviewErrorEvent,
105
+ filePreview: isBannedLocalPreview ? undefined : getFilePreviewFromFileState(fileState),
124
106
  isRemotePreviewReady: isImageRepresentationReady(fileState),
125
- addContextToDataURI: _this.createAddContextToDataURI(id, fileState, originalDimensions || requestedDimensions, collectionName)
107
+ imageUrlParams: _this.getImageURLParams(identifier),
108
+ mediaBlobUrlAttrs: _this.getMediaBlobUrlAttrs(identifier, fileState)
109
+ };
110
+ });
111
+
112
+ _defineProperty(_assertThisInitialized(_this), "resolvePreview", /*#__PURE__*/function () {
113
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(identifier, fileState) {
114
+ var params, cardPreview, wrappedError;
115
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
116
+ while (1) {
117
+ switch (_context.prev = _context.next) {
118
+ case 0:
119
+ _context.prev = 0;
120
+ params = _this.getCardPreviewParams(identifier, fileState);
121
+ _context.next = 4;
122
+ return getCardPreview(params);
123
+
124
+ case 4:
125
+ cardPreview = _context.sent;
126
+
127
+ _this.safeSetState({
128
+ cardPreview: cardPreview
129
+ });
130
+
131
+ _context.next = 12;
132
+ break;
133
+
134
+ case 8:
135
+ _context.prev = 8;
136
+ _context.t0 = _context["catch"](0);
137
+ wrappedError = ensureMediaCardError('preview-fetch', _context.t0); // If remote preview fails, we set status 'error'
138
+ // If local preview fails (i.e, no remote preview available),
139
+ // we can stay in the same status until there is a remote preview available
140
+ // If it's any other error we set status 'error'
141
+
142
+ if (isLocalPreviewError(wrappedError)) {
143
+ _this.safeSetState({
144
+ isBannedLocalPreview: true
145
+ });
146
+ } else {
147
+ _this.safeSetState({
148
+ status: 'error',
149
+ error: wrappedError
150
+ });
151
+ }
152
+
153
+ case 12:
154
+ case "end":
155
+ return _context.stop();
156
+ }
157
+ }
158
+ }, _callee, null, [[0, 8]]);
159
+ }));
160
+
161
+ return function (_x, _x2) {
162
+ return _ref2.apply(this, arguments);
163
+ };
164
+ }());
165
+
166
+ _defineProperty(_assertThisInitialized(_this), "getPerformanceAttributes", function () {
167
+ var _assertThisInitialize = _assertThisInitialized(_this),
168
+ timeElapsedTillCommenced = _assertThisInitialize.timeElapsedTillCommenced;
169
+
170
+ var timeElapsedTillEvent = performance.now();
171
+ var durationSinceCommenced = timeElapsedTillCommenced && timeElapsedTillEvent - timeElapsedTillCommenced;
172
+ return {
173
+ overall: {
174
+ durationSincePageStart: timeElapsedTillEvent,
175
+ durationSinceCommenced: durationSinceCommenced
176
+ }
126
177
  };
127
178
  });
128
179
 
180
+ _defineProperty(_assertThisInitialized(_this), "onImageError", function () {
181
+ var cardPreview = _this.state.cardPreview;
182
+ var error = new ImageLoadError(cardPreview === null || cardPreview === void 0 ? void 0 : cardPreview.source);
183
+
184
+ if (cardPreview !== null && cardPreview !== void 0 && cardPreview.source && ['local', 'cache-local'].includes(cardPreview.source)) {
185
+ var _this$props3 = _this.props,
186
+ identifier = _this$props3.identifier,
187
+ _this$props3$dimensio = _this$props3.dimensions,
188
+ dimensions = _this$props3$dimensio === void 0 ? {} : _this$props3$dimensio;
189
+ isFileIdentifier(identifier) && removeCardPreviewFromCache(identifier.id, dimensions);
190
+
191
+ _this.safeSetState({
192
+ cardPreview: undefined,
193
+ isBannedLocalPreview: true
194
+ });
195
+
196
+ _this.fireLocalPreviewErrorEvent(error);
197
+ } else {
198
+ _this.safeSetState({
199
+ status: 'error',
200
+ error: error
201
+ });
202
+ }
203
+ });
204
+
205
+ _defineProperty(_assertThisInitialized(_this), "onImageLoad", function () {
206
+ _this.safeSetState({
207
+ previewDidRender: true
208
+ });
209
+ });
210
+
129
211
  _defineProperty(_assertThisInitialized(_this), "fireCopiedEvent", function () {
130
212
  var createAnalyticsEvent = _this.props.createAnalyticsEvent;
131
213
  var cardRef = _this.state.cardRef;
@@ -137,9 +219,18 @@ export var CardBase = /*#__PURE__*/function (_Component) {
137
219
  createAnalyticsEvent && fireScreenEvent(createAnalyticsEvent, _this.fileAttributes);
138
220
  });
139
221
 
222
+ _defineProperty(_assertThisInitialized(_this), "fireLocalPreviewErrorEvent", function (error) {// TODO: track local preview success rate
223
+ // https://product-fabric.atlassian.net/browse/MEX-774
224
+ });
225
+
140
226
  _defineProperty(_assertThisInitialized(_this), "safeSetState", function (state) {
141
227
  if (_this.hasBeenMounted) {
142
- _this.setState(state);
228
+ // If it's setting the status, we need to use a state updater function,
229
+ // which ensures that no non-final status overrides a final status.
230
+ // If no status is set, we don't need a sate updater
231
+ var updater = !!state.status ? createStateUpdater(state) : state;
232
+
233
+ _this.setState(updater);
143
234
  }
144
235
  });
145
236
 
@@ -149,21 +240,22 @@ export var CardBase = /*#__PURE__*/function (_Component) {
149
240
  }
150
241
 
151
242
  if (_this.hasBeenMounted) {
243
+ // TODO MEX-788: add test for "do not remove the card preview when unsubscribing".
152
244
  _this.setState({
153
- cardPreview: undefined
245
+ isBannedLocalPreview: false
154
246
  });
155
247
  }
156
248
  });
157
249
 
158
250
  _defineProperty(_assertThisInitialized(_this), "onCardViewClick", function (event, analyticsEvent) {
159
- var _this$props3 = _this.props,
160
- identifier = _this$props3.identifier,
161
- useInlinePlayer = _this$props3.useInlinePlayer,
162
- shouldOpenMediaViewer = _this$props3.shouldOpenMediaViewer;
251
+ var _this$props4 = _this.props,
252
+ identifier = _this$props4.identifier,
253
+ useInlinePlayer = _this$props4.useInlinePlayer,
254
+ shouldOpenMediaViewer = _this$props4.shouldOpenMediaViewer;
163
255
  var cardPreview = _this.state.cardPreview;
164
256
 
165
- var _assertThisInitialize = _assertThisInitialized(_this),
166
- metadata = _assertThisInitialize.metadata;
257
+ var _assertThisInitialize2 = _assertThisInitialized(_this),
258
+ metadata = _assertThisInitialize2.metadata;
167
259
 
168
260
  _this.onClick(event, analyticsEvent);
169
261
 
@@ -214,13 +306,13 @@ export var CardBase = /*#__PURE__*/function (_Component) {
214
306
  });
215
307
 
216
308
  _defineProperty(_assertThisInitialized(_this), "renderInlinePlayer", function () {
217
- var _this$props4 = _this.props,
218
- identifier = _this$props4.identifier,
219
- mediaClient = _this$props4.mediaClient,
220
- dimensions = _this$props4.dimensions,
221
- selected = _this$props4.selected,
222
- testId = _this$props4.testId,
223
- originalDimensions = _this$props4.originalDimensions;
309
+ var _this$props5 = _this.props,
310
+ identifier = _this$props5.identifier,
311
+ mediaClient = _this$props5.mediaClient,
312
+ dimensions = _this$props5.dimensions,
313
+ selected = _this$props5.selected,
314
+ testId = _this$props5.testId,
315
+ originalDimensions = _this$props5.originalDimensions;
224
316
  return /*#__PURE__*/React.createElement(InlinePlayer, {
225
317
  mediaClient: mediaClient,
226
318
  dimensions: dimensions,
@@ -263,12 +355,12 @@ export var CardBase = /*#__PURE__*/function (_Component) {
263
355
 
264
356
  _defineProperty(_assertThisInitialized(_this), "renderMediaViewer", function () {
265
357
  var mediaViewerSelectedItem = _this.state.mediaViewerSelectedItem;
266
- var _this$props5 = _this.props,
267
- mediaClient = _this$props5.mediaClient,
268
- identifier = _this$props5.identifier,
269
- mediaViewerDataSource = _this$props5.mediaViewerDataSource,
270
- contextId = _this$props5.contextId,
271
- featureFlags = _this$props5.featureFlags;
358
+ var _this$props6 = _this.props,
359
+ mediaClient = _this$props6.mediaClient,
360
+ identifier = _this$props6.identifier,
361
+ mediaViewerDataSource = _this$props6.mediaViewerDataSource,
362
+ contextId = _this$props6.contextId,
363
+ featureFlags = _this$props6.featureFlags;
272
364
 
273
365
  if (!mediaViewerSelectedItem) {
274
366
  return;
@@ -290,20 +382,20 @@ export var CardBase = /*#__PURE__*/function (_Component) {
290
382
  });
291
383
 
292
384
  _defineProperty(_assertThisInitialized(_this), "renderCard", function () {
293
- var _this$props6 = _this.props,
294
- identifier = _this$props6.identifier,
295
- isLazy = _this$props6.isLazy,
296
- appearance = _this$props6.appearance,
297
- resizeMode = _this$props6.resizeMode,
298
- dimensions = _this$props6.dimensions,
299
- selectable = _this$props6.selectable,
300
- selected = _this$props6.selected,
301
- disableOverlay = _this$props6.disableOverlay,
302
- alt = _this$props6.alt,
303
- testId = _this$props6.testId,
304
- featureFlags = _this$props6.featureFlags,
305
- titleBoxBgColor = _this$props6.titleBoxBgColor,
306
- titleBoxIcon = _this$props6.titleBoxIcon;
385
+ var _this$props7 = _this.props,
386
+ identifier = _this$props7.identifier,
387
+ isLazy = _this$props7.isLazy,
388
+ appearance = _this$props7.appearance,
389
+ resizeMode = _this$props7.resizeMode,
390
+ dimensions = _this$props7.dimensions,
391
+ selectable = _this$props7.selectable,
392
+ selected = _this$props7.selected,
393
+ disableOverlay = _this$props7.disableOverlay,
394
+ alt = _this$props7.alt,
395
+ testId = _this$props7.testId,
396
+ featureFlags = _this$props7.featureFlags,
397
+ titleBoxBgColor = _this$props7.titleBoxBgColor,
398
+ titleBoxIcon = _this$props7.titleBoxIcon;
307
399
  var mediaItemType = identifier.mediaItemType;
308
400
  var _this$state = _this.state,
309
401
  status = _this$state.status,
@@ -318,19 +410,18 @@ export var CardBase = /*#__PURE__*/function (_Component) {
318
410
  error = _this$state.error,
319
411
  cardRef = _this$state.cardRef;
320
412
 
321
- var _assertThisInitialize2 = _assertThisInitialized(_this),
322
- metadata = _assertThisInitialize2.metadata,
323
- timeElapsedTillCommenced = _assertThisInitialize2.timeElapsedTillCommenced;
324
-
325
413
  var _assertThisInitialize3 = _assertThisInitialized(_this),
326
- onCardViewClick = _assertThisInitialize3.onCardViewClick,
327
- onDisplayImage = _assertThisInitialize3.onDisplayImage,
328
- actions = _assertThisInitialize3.actions,
329
- onMouseEnter = _assertThisInitialize3.onMouseEnter;
414
+ metadata = _assertThisInitialize3.metadata;
415
+
416
+ var _assertThisInitialize4 = _assertThisInitialized(_this),
417
+ onCardViewClick = _assertThisInitialize4.onCardViewClick,
418
+ onDisplayImage = _assertThisInitialize4.onDisplayImage,
419
+ actions = _assertThisInitialize4.actions,
420
+ onMouseEnter = _assertThisInitialize4.onMouseEnter;
330
421
 
331
422
  var card = /*#__PURE__*/React.createElement(CardView, {
332
423
  status: status,
333
- error: error && error.secondaryError,
424
+ error: error,
334
425
  mediaItemType: mediaItemType,
335
426
  metadata: metadata,
336
427
  dataURI: dataURI,
@@ -352,7 +443,8 @@ export var CardBase = /*#__PURE__*/function (_Component) {
352
443
  featureFlags: featureFlags,
353
444
  titleBoxBgColor: titleBoxBgColor,
354
445
  titleBoxIcon: titleBoxIcon,
355
- timeElapsedTillCommenced: timeElapsedTillCommenced
446
+ onImageError: _this.onImageError,
447
+ onImageLoad: _this.onImageLoad
356
448
  });
357
449
  return isLazy ? /*#__PURE__*/React.createElement(ViewportDetector, {
358
450
  targetRef: cardRef,
@@ -369,8 +461,8 @@ export var CardBase = /*#__PURE__*/function (_Component) {
369
461
  _defineProperty(_assertThisInitialized(_this), "onClick", function (event, analyticsEvent) {
370
462
  var onClick = _this.props.onClick;
371
463
 
372
- var _assertThisInitialize4 = _assertThisInitialized(_this),
373
- metadata = _assertThisInitialize4.metadata;
464
+ var _assertThisInitialize5 = _assertThisInitialized(_this),
465
+ metadata = _assertThisInitialize5.metadata;
374
466
 
375
467
  if (onClick) {
376
468
  var cardEvent = {
@@ -384,8 +476,8 @@ export var CardBase = /*#__PURE__*/function (_Component) {
384
476
  _defineProperty(_assertThisInitialized(_this), "onMouseEnter", function (event) {
385
477
  var onMouseEnter = _this.props.onMouseEnter;
386
478
 
387
- var _assertThisInitialize5 = _assertThisInitialized(_this),
388
- metadata = _assertThisInitialize5.metadata;
479
+ var _assertThisInitialize6 = _assertThisInitialized(_this),
480
+ metadata = _assertThisInitialize6.metadata;
389
481
 
390
482
  if (onMouseEnter) {
391
483
  var cardEvent = {
@@ -400,10 +492,10 @@ export var CardBase = /*#__PURE__*/function (_Component) {
400
492
 
401
493
  var _cardPreview;
402
494
 
403
- var _this$props7 = _this.props,
404
- _identifier = _this$props7.identifier,
405
- _this$props7$dimensio = _this$props7.dimensions,
406
- _dimensions = _this$props7$dimensio === void 0 ? {} : _this$props7$dimensio;
495
+ var _this$props8 = _this.props,
496
+ _identifier = _this$props8.identifier,
497
+ _this$props8$dimensio = _this$props8.dimensions,
498
+ _dimensions = _this$props8$dimensio === void 0 ? {} : _this$props8$dimensio;
407
499
 
408
500
  if (isFileIdentifier(_identifier)) {
409
501
  var id = _identifier.id;
@@ -411,18 +503,15 @@ export var CardBase = /*#__PURE__*/function (_Component) {
411
503
  } else if (isExternalImageIdentifier(_identifier)) {
412
504
  _this.fireCommencedEvent();
413
505
 
414
- _status = 'complete';
506
+ _status = 'loading-preview';
415
507
  var dataURI = _identifier.dataURI;
416
508
  _cardPreview = {
417
509
  dataURI: dataURI,
418
510
  orientation: 1,
419
511
  source: 'external'
420
512
  };
421
- }
422
- /**
423
- * If cardPreview is available from local cache, `isCardVisible`
424
- * should be true to avoid flickers during re-mount of the component
425
- */
513
+ } // If cardPreview is available from local cache, `isCardVisible`
514
+ // should be true to avoid flickers during re-mount of the component
426
515
 
427
516
 
428
517
  var isCardVisible = _cardPreview ? true : !_this.props.isLazy;
@@ -431,7 +520,9 @@ export var CardBase = /*#__PURE__*/function (_Component) {
431
520
  isCardVisible: isCardVisible,
432
521
  isPlayingFile: false,
433
522
  cardPreview: _cardPreview,
434
- cardRef: null
523
+ cardRef: null,
524
+ isBannedLocalPreview: false,
525
+ previewDidRender: false
435
526
  };
436
527
  return _this;
437
528
  }
@@ -460,21 +551,27 @@ export var CardBase = /*#__PURE__*/function (_Component) {
460
551
  prevIdentifier = prevProps.identifier,
461
552
  prevDimensions = prevProps.dimensions;
462
553
  var prevIsCardVisible = prevState.isCardVisible;
463
- var _this$props8 = this.props,
464
- mediaClient = _this$props8.mediaClient,
465
- identifier = _this$props8.identifier,
466
- dimensions = _this$props8.dimensions;
554
+ var _this$props9 = this.props,
555
+ mediaClient = _this$props9.mediaClient,
556
+ identifier = _this$props9.identifier,
557
+ dimensions = _this$props9.dimensions,
558
+ featureFlags = _this$props9.featureFlags;
467
559
  var _this$state2 = this.state,
468
560
  isCardVisible = _this$state2.isCardVisible,
469
- cardPreview = _this$state2.cardPreview;
561
+ cardPreview = _this$state2.cardPreview,
562
+ status = _this$state2.status,
563
+ fileState = _this$state2.fileState,
564
+ isBannedLocalPreview = _this$state2.isBannedLocalPreview,
565
+ previewDidRender = _this$state2.previewDidRender;
470
566
  var isDifferent = isDifferentIdentifier(prevIdentifier, identifier);
471
567
  var turnedVisible = !prevIsCardVisible && isCardVisible;
568
+ var isNewMediaClient = prevMediaClient !== mediaClient;
472
569
 
473
570
  if (isExternalImageIdentifier(identifier) && isDifferent) {
474
571
  this.fireCommencedEvent();
475
572
  var dataURI = identifier.dataURI;
476
573
  this.setState({
477
- status: 'complete',
574
+ status: 'loading-preview',
478
575
  cardPreview: {
479
576
  dataURI: dataURI,
480
577
  orientation: 1,
@@ -484,8 +581,7 @@ export var CardBase = /*#__PURE__*/function (_Component) {
484
581
  });
485
582
  }
486
583
 
487
- if (isFileIdentifier(identifier) && (turnedVisible || prevMediaClient !== mediaClient || isDifferent || // TODO: should not resubscribe on resize. Only refetch
488
- this.shouldRefetchImage(prevDimensions, dimensions))) {
584
+ if (isFileIdentifier(identifier) && (turnedVisible || !!this.subscription && (isNewMediaClient || isDifferent))) {
489
585
  this.updateStateForIdentifier(identifier);
490
586
  }
491
587
 
@@ -496,6 +592,26 @@ export var CardBase = /*#__PURE__*/function (_Component) {
496
592
  this.fireScreenEvent();
497
593
  }
498
594
  }
595
+
596
+ if (isFileIdentifier(identifier) && fileState && shouldResolvePreview({
597
+ status: status,
598
+ fileState: fileState,
599
+ dimensions: dimensions,
600
+ prevDimensions: prevDimensions,
601
+ featureFlags: featureFlags,
602
+ hasCardPreview: !!cardPreview,
603
+ isBannedLocalPreview: isBannedLocalPreview
604
+ })) {
605
+ this.resolvePreview(identifier, fileState);
606
+ }
607
+
608
+ if (previewDidRender && // We should't complete if status is uploading
609
+ ['loading', 'loading-preview', 'processing'].includes(status)) {
610
+ this.safeSetState({
611
+ status: 'complete'
612
+ });
613
+ this.unsubscribe();
614
+ }
499
615
  }
500
616
  }, {
501
617
  key: "componentWillUnmount",
@@ -516,6 +632,7 @@ export var CardBase = /*#__PURE__*/function (_Component) {
516
632
  var _this2 = this;
517
633
 
518
634
  var mediaClient = this.props.mediaClient;
635
+ var isBannedLocalPreview = this.state.isBannedLocalPreview;
519
636
  var id = identifier.id,
520
637
  collectionName = identifier.collectionName,
521
638
  occurrenceKey = identifier.occurrenceKey;
@@ -524,157 +641,55 @@ export var CardBase = /*#__PURE__*/function (_Component) {
524
641
  collectionName: collectionName,
525
642
  occurrenceKey: occurrenceKey
526
643
  }).subscribe({
527
- next: function () {
528
- var _next = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(fileState) {
529
- var thisCardStatusUpdateTimestamp, filePreviewStatus, status, cardPreview, error, wrappedError;
530
- return _regeneratorRuntime.wrap(function _callee$(_context) {
531
- while (1) {
532
- switch (_context.prev = _context.next) {
533
- case 0:
534
- _this2.lastFileState = fileState;
535
- thisCardStatusUpdateTimestamp = (performance || Date).now();
536
- filePreviewStatus = extractFilePreviewStatus(fileState, _this2.props.featureFlags);
537
- status = getCardStatus(fileState.status, filePreviewStatus);
538
-
539
- _this2.safeSetState({
540
- fileState: fileState
541
- });
542
-
543
- if (!shouldGetCardPreview(status, filePreviewStatus)) {
544
- _context.next = 17;
545
- break;
546
- }
547
-
548
- _context.prev = 6;
549
- _context.next = 9;
550
- return getCardPreview(_this2.getCardPreviewParams(id, collectionName, fileState));
551
-
552
- case 9:
553
- cardPreview = _context.sent;
554
-
555
- if (['loading-preview', 'processing'].includes(status)) {
556
- status = 'complete';
557
- }
558
-
559
- _context.next = 17;
560
- break;
561
-
562
- case 13:
563
- _context.prev = 13;
564
- _context.t0 = _context["catch"](6);
565
- wrappedError = ensureMediaCardError('preview-fetch', _context.t0); // If remote preview fails, we set status 'error'
566
- // If the local preview fails (i.e, no remote preview available),
567
- // we can stay in the same status until there is a remote preview available
568
-
569
- if (isRemotePreviewError(wrappedError)) {
570
- status = 'error';
571
- error = wrappedError;
572
- }
573
-
574
- case 17:
575
- if (_this2.isLatestCardStatusUpdate(thisCardStatusUpdateTimestamp)) {
576
- // These status and progress must not override values representing more recent FileState
577
-
578
- /* next() start some await() delay in next() status & progress update
579
- * ------- ------------------ ------------------------
580
- * |----[1]FileState:uploading------>| |
581
- * | | |
582
- * |----[2]FileState:uploading------>| |
583
- * | | |
584
- * | |----[2]FileState:uploading------>| Update status to `uploading`
585
- * |----[3]FileState:processing----->| |
586
- * | |----[3]FileState:processing----->| Update status to `complete`
587
- * | | |
588
- * | |----[1]FileState:uploading------>| We do not want to update status to `uploading` again!
589
- *
590
- */
591
- if (status === 'error' && isErrorFileState(fileState) && !error) {
592
- error = new MediaCardError('error-file-state', new Error(fileState.message));
593
- }
594
-
595
- _this2.safeSetState({
596
- status: status,
597
- cardPreview: cardPreview,
598
- progress: status === 'uploading' && fileState.status === 'uploading' ? fileState.progress : 1,
599
- error: status === 'error' && error ? error : undefined
600
- });
601
-
602
- _this2.lastCardStatusUpdateTimestamp = thisCardStatusUpdateTimestamp;
603
- }
604
-
605
- case 18:
606
- case "end":
607
- return _context.stop();
608
- }
609
- }
610
- }, _callee, null, [[6, 13]]);
611
- }));
644
+ next: function next(fileState) {
645
+ var featureFlags = _this2.props.featureFlags;
646
+ var newState = getCardStateFromFileState(fileState, isBannedLocalPreview, featureFlags);
612
647
 
613
- function next(_x) {
614
- return _next.apply(this, arguments);
615
- }
616
-
617
- return next;
618
- }(),
648
+ _this2.safeSetState(newState);
649
+ },
619
650
  error: function error(e) {
620
- // If file state subscription decides that the card is complete
621
- // and later there is an error, we won't change the card's status.
622
- if (_this2.state.status === 'complete') {
623
- return;
624
- }
625
-
626
- var errorReason = _this2.fileAttributes.fileStatus === 'uploading' ? 'upload' : 'metadata-fetch';
651
+ var errorReason = _this2.state.status === 'uploading' ? 'upload' : 'metadata-fetch';
627
652
  var error = new MediaCardError(errorReason, e);
628
653
 
629
654
  _this2.safeSetState({
630
655
  error: error,
631
656
  status: 'error'
632
657
  });
633
-
634
- _this2.lastCardStatusUpdateTimestamp = (performance || Date).now();
635
658
  }
636
659
  });
637
660
  }
661
+ }, {
662
+ key: "requestedDimensions",
663
+ get: function get() {
664
+ var dimensions = this.props.dimensions;
665
+ var element = this.state.cardRef;
666
+ return getRequestedDimensions({
667
+ dimensions: dimensions,
668
+ element: element
669
+ });
670
+ }
638
671
  }, {
639
672
  key: "metadata",
640
673
  get: function get() {
641
- var identifier = this.props.identifier;
642
- return isFileIdentifier(identifier) ? this.state.fileState ? getFileDetails(this.state.fileState) : {
643
- id: identifier.id
644
- } : {
645
- id: identifier.mediaItemType,
646
- name: identifier.name || identifier.dataURI,
647
- mediaType: 'image'
648
- };
674
+ var _this$state3;
675
+
676
+ return getFileDetails(this.props.identifier, (_this$state3 = this.state) === null || _this$state3 === void 0 ? void 0 : _this$state3.fileState);
649
677
  }
650
678
  }, {
651
679
  key: "fileAttributes",
652
680
  get: function get() {
653
- var _this$lastFileState;
681
+ var _this$state4, _this$state4$fileStat;
654
682
 
655
- return getFileAttributes(this.metadata, (_this$lastFileState = this.lastFileState) === null || _this$lastFileState === void 0 ? void 0 : _this$lastFileState.status);
683
+ return getFileAttributes(this.metadata, (_this$state4 = this.state) === null || _this$state4 === void 0 ? void 0 : (_this$state4$fileStat = _this$state4.fileState) === null || _this$state4$fileStat === void 0 ? void 0 : _this$state4$fileStat.status);
656
684
  }
657
685
  }, {
658
686
  key: "fireOperationalEvent",
659
687
  value: function fireOperationalEvent() {
660
- var timeElapsedTillCommenced = this.timeElapsedTillCommenced;
661
- var _this$state3 = this.state,
662
- status = _this$state3.status,
663
- cardPreview = _this$state3.cardPreview,
664
- error = _this$state3.error;
688
+ var _this$state5 = this.state,
689
+ status = _this$state5.status,
690
+ error = _this$state5.error;
665
691
  var createAnalyticsEvent = this.props.createAnalyticsEvent;
666
- var timeElapsedTillEvent = performance.now();
667
- var durationSinceCommenced = timeElapsedTillCommenced && timeElapsedTillEvent - timeElapsedTillCommenced;
668
- var performanceAttributes = {
669
- overall: {
670
- durationSincePageStart: timeElapsedTillEvent,
671
- durationSinceCommenced: durationSinceCommenced
672
- }
673
- };
674
- createAnalyticsEvent && _fireOperationalEvent(createAnalyticsEvent, status, this.fileAttributes, performanceAttributes, {
675
- cardPreview: cardPreview,
676
- error: error
677
- });
692
+ createAnalyticsEvent && _fireOperationalEvent(createAnalyticsEvent, status, this.fileAttributes, this.getPerformanceAttributes(), error);
678
693
  }
679
694
  }, {
680
695
  key: "fireCommencedEvent",
@@ -692,11 +707,11 @@ export var CardBase = /*#__PURE__*/function (_Component) {
692
707
  get: function get() {
693
708
  var _this3 = this;
694
709
 
695
- var _this$props9 = this.props,
696
- _this$props9$actions = _this$props9.actions,
697
- actions = _this$props9$actions === void 0 ? [] : _this$props9$actions,
698
- identifier = _this$props9.identifier,
699
- shouldEnableDownloadButton = _this$props9.shouldEnableDownloadButton;
710
+ var _this$props10 = this.props,
711
+ _this$props10$actions = _this$props10.actions,
712
+ actions = _this$props10$actions === void 0 ? [] : _this$props10$actions,
713
+ identifier = _this$props10.identifier,
714
+ shouldEnableDownloadButton = _this$props10.shouldEnableDownloadButton;
700
715
  var status = this.state.status;
701
716
  var metadata = this.metadata;
702
717
 
@@ -718,18 +733,13 @@ export var CardBase = /*#__PURE__*/function (_Component) {
718
733
  }, {
719
734
  key: "render",
720
735
  value: function render() {
721
- var _this$lastFileState2;
722
-
723
- var _this$state4 = this.state,
724
- isPlayingFile = _this$state4.isPlayingFile,
725
- mediaViewerSelectedItem = _this$state4.mediaViewerSelectedItem;
736
+ var _this$state6 = this.state,
737
+ isPlayingFile = _this$state6.isPlayingFile,
738
+ mediaViewerSelectedItem = _this$state6.mediaViewerSelectedItem;
726
739
  var innerContent = /*#__PURE__*/React.createElement(React.Fragment, null, isPlayingFile ? this.renderInlinePlayer() : this.renderCard(), mediaViewerSelectedItem ? this.renderMediaViewer() : null);
727
- var content = this.context.intl ? innerContent : /*#__PURE__*/React.createElement(IntlProvider, {
740
+ return this.context.intl ? innerContent : /*#__PURE__*/React.createElement(IntlProvider, {
728
741
  locale: "en"
729
742
  }, innerContent);
730
- return /*#__PURE__*/React.createElement(FileAttributesProvider, {
731
- data: getFileAttributes(this.metadata, (_this$lastFileState2 = this.lastFileState) === null || _this$lastFileState2 === void 0 ? void 0 : _this$lastFileState2.status)
732
- }, content);
733
743
  }
734
744
  }]);
735
745