@atlaskit/media-card 77.6.1 → 77.6.3

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 (38) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/card/card.js +1 -1
  3. package/dist/cjs/card/media-card-analytics-error-boundary.js +1 -1
  4. package/dist/cjs/card/v2/cardV2.js +1 -1
  5. package/dist/cjs/card/v2/fileCard.js +8 -8
  6. package/dist/cjs/card/v2/useFilePreview/getPreview/getPreview.js +2 -2
  7. package/dist/cjs/card/v2/useFilePreview/getPreview/index.js +2 -2
  8. package/dist/cjs/card/v2/useFilePreview/useFilePreview.js +234 -235
  9. package/dist/cjs/inline/loader.js +1 -1
  10. package/dist/cjs/inline/mediaInlineCard.js +5 -7
  11. package/dist/cjs/utils/ufoExperiences.js +1 -1
  12. package/dist/es2019/card/card.js +1 -1
  13. package/dist/es2019/card/media-card-analytics-error-boundary.js +1 -1
  14. package/dist/es2019/card/v2/cardV2.js +1 -1
  15. package/dist/es2019/card/v2/fileCard.js +8 -8
  16. package/dist/es2019/card/v2/useFilePreview/getPreview/getPreview.js +1 -1
  17. package/dist/es2019/card/v2/useFilePreview/getPreview/index.js +1 -1
  18. package/dist/es2019/card/v2/useFilePreview/useFilePreview.js +194 -197
  19. package/dist/es2019/inline/loader.js +1 -1
  20. package/dist/es2019/inline/mediaInlineCard.js +5 -7
  21. package/dist/es2019/utils/ufoExperiences.js +1 -1
  22. package/dist/esm/card/card.js +1 -1
  23. package/dist/esm/card/media-card-analytics-error-boundary.js +1 -1
  24. package/dist/esm/card/v2/cardV2.js +1 -1
  25. package/dist/esm/card/v2/fileCard.js +8 -8
  26. package/dist/esm/card/v2/useFilePreview/getPreview/getPreview.js +1 -1
  27. package/dist/esm/card/v2/useFilePreview/getPreview/index.js +1 -1
  28. package/dist/esm/card/v2/useFilePreview/useFilePreview.js +236 -237
  29. package/dist/esm/inline/loader.js +1 -1
  30. package/dist/esm/inline/mediaInlineCard.js +5 -7
  31. package/dist/esm/utils/ufoExperiences.js +1 -1
  32. package/dist/types/card/v2/useFilePreview/getPreview/getPreview.d.ts +1 -1
  33. package/dist/types/card/v2/useFilePreview/getPreview/index.d.ts +1 -1
  34. package/dist/types/card/v2/useFilePreview/useFilePreview.d.ts +6 -6
  35. package/dist/types-ts4.5/card/v2/useFilePreview/getPreview/getPreview.d.ts +1 -1
  36. package/dist/types-ts4.5/card/v2/useFilePreview/getPreview/index.d.ts +1 -1
  37. package/dist/types-ts4.5/card/v2/useFilePreview/useFilePreview.d.ts +6 -6
  38. package/package.json +1 -1
@@ -14,7 +14,7 @@ var _mediaClient = require("@atlaskit/media-client");
14
14
  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; }
15
15
  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; }
16
16
  var packageName = "@atlaskit/media-card";
17
- var packageVersion = "77.6.1";
17
+ var packageVersion = "77.6.3";
18
18
  var concurrentExperience;
19
19
  var getExperience = function getExperience(id) {
20
20
  if (!concurrentExperience) {
@@ -27,7 +27,7 @@ import { getMediaCardCursor } from '../utils/getMediaCardCursor';
27
27
  import { completeUfoExperience, startUfoExperience, abortUfoExperience } from '../utils/ufoExperiences';
28
28
  import { generateUniqueId } from '../utils/generateUniqueId';
29
29
  const packageName = "@atlaskit/media-card";
30
- const packageVersion = "77.6.1";
30
+ const packageVersion = "77.6.3";
31
31
  export class CardBase extends Component {
32
32
  constructor(props) {
33
33
  super(props);
@@ -66,7 +66,7 @@ class WrappedMediaCardAnalyticsErrorBoundary extends React.Component {
66
66
  }
67
67
  _defineProperty(WrappedMediaCardAnalyticsErrorBoundary, "displayName", 'MediaCardAnalyticsErrorBoundary');
68
68
  const packageName = "@atlaskit/media-card";
69
- const packageVersion = "77.6.1";
69
+ const packageVersion = "77.6.3";
70
70
  const MediaCardAnalyticsErrorBoundary = withMediaAnalyticsContext({
71
71
  packageVersion,
72
72
  packageName,
@@ -7,7 +7,7 @@ import { IntlProvider, injectIntl } from 'react-intl-next';
7
7
  import { ExternalImageCard } from './externalImageCard';
8
8
  import { FileCard } from './fileCard';
9
9
  const packageName = "@atlaskit/media-card";
10
- const packageVersion = "77.6.1";
10
+ const packageVersion = "77.6.3";
11
11
  export const CardV2Base = ({
12
12
  identifier,
13
13
  ...otherProps
@@ -133,7 +133,7 @@ export const FileCard = ({
133
133
  } : undefined;
134
134
  }, [alt, previewDimensions, contextId, fileStateValue, identifier, originalDimensions]);
135
135
  const {
136
- cardPreview,
136
+ preview,
137
137
  error: previewError,
138
138
  nonCriticalError,
139
139
  ssrReliabilityRef,
@@ -278,7 +278,7 @@ export const FileCard = ({
278
278
  return;
279
279
  }
280
280
  const isVideo = metadata && metadata.mediaType === 'video';
281
- if (useInlinePlayer && isVideo && !!cardPreview && finalStatus !== 'error') {
281
+ if (useInlinePlayer && isVideo && !!preview && finalStatus !== 'error') {
282
282
  setIsPlayingFile(true);
283
283
  setShouldAutoplay(true);
284
284
  } else if (shouldOpenMediaViewer) {
@@ -383,11 +383,11 @@ export const FileCard = ({
383
383
 
384
384
  useEffect(() => {
385
385
  if (prevStatus !== undefined && finalStatus !== prevStatus) {
386
- if (finalStatus === 'complete' || fileAttributes.fileMediatype === 'video' && !!cardPreview && finalStatus === 'processing') {
386
+ if (finalStatus === 'complete' || fileAttributes.fileMediatype === 'video' && !!preview && finalStatus === 'processing') {
387
387
  fireScreenEventRef.current();
388
388
  }
389
389
  }
390
- }, [finalStatus, prevStatus, fileAttributes, cardPreview, fireScreenEventRef]);
390
+ }, [finalStatus, prevStatus, fileAttributes, preview, fireScreenEventRef]);
391
391
 
392
392
  //----------------------------------------------------------------//
393
393
  //----------------- abort UFO experience -------------------------//
@@ -467,16 +467,16 @@ export const FileCard = ({
467
467
  // Side note: We should not lazy load if the cardPreview is available from local cache,
468
468
  // in order to avoid flickers during re-mount of the component
469
469
  // CXP-2723 TODO: Create test cases for the above scenarios
470
- const nativeLazyLoad = isLazyWithOverride && !isCardVisible && cardPreview && isSSRPreview(cardPreview);
470
+ const nativeLazyLoad = isLazyWithOverride && !isCardVisible && preview && isSSRPreview(preview);
471
471
  // Force Media Image to always display img for SSR
472
472
  const forceSyncDisplay = !!ssr;
473
- const mediaCardCursor = getMediaCardCursor(!!useInlinePlayer, !!shouldOpenMediaViewer, finalStatus === 'error' || finalStatus === 'failed-processing', !!cardPreview, metadata.mediaType);
473
+ const mediaCardCursor = getMediaCardCursor(!!useInlinePlayer, !!shouldOpenMediaViewer, finalStatus === 'error' || finalStatus === 'failed-processing', !!preview, metadata.mediaType);
474
474
  const card = /*#__PURE__*/React.createElement(LoadedCardView, {
475
475
  status: cardStatusOverride || finalStatus,
476
476
  error: finalError,
477
477
  mediaItemType: mediaItemType,
478
478
  metadata: metadata,
479
- cardPreview: cardPreview,
479
+ cardPreview: preview,
480
480
  alt: alt,
481
481
  resizeMode: resizeMode,
482
482
  dimensions: cardDimensions,
@@ -544,7 +544,7 @@ export const FileCard = ({
544
544
  selected: selected,
545
545
  ref: setCardElement,
546
546
  testId: testId,
547
- cardPreview: cardPreview
547
+ cardPreview: preview
548
548
  })) : renderCard(), mediaViewerSelectedItem ? /*#__PURE__*/ReactDOM.createPortal( /*#__PURE__*/React.createElement(MediaViewer, {
549
549
  collectionName: collectionName,
550
550
  items: mediaViewerItems || [],
@@ -33,7 +33,7 @@ const extendAndCachePreview = (id, mode, preview, mediaBlobUrlAttrs) => {
33
33
  dataURI
34
34
  };
35
35
  };
36
- export const getSSRCardPreview = (ssr, mediaClient, id, params, mediaBlobUrlAttrs) => {
36
+ export const getSSRPreview = (ssr, mediaClient, id, params, mediaBlobUrlAttrs) => {
37
37
  let dataURI;
38
38
  try {
39
39
  const rawDataURI = mediaClient.getImageUrlSync(id, params);
@@ -1,3 +1,3 @@
1
1
  export { mediaFilePreviewCache } from './cache';
2
2
  export { isPreviewableStatus, extractFilePreviewStatus } from './filePreviewStatus';
3
- export { getSSRCardPreview, isLocalPreview, isSSRClientPreview, isSSRDataPreview, getAndCacheRemotePreview, getAndCacheLocalPreview } from './getPreview';
3
+ export { getSSRPreview, isLocalPreview, isSSRClientPreview, isSSRDataPreview, getAndCacheRemotePreview, getAndCacheLocalPreview } from './getPreview';
@@ -1,12 +1,12 @@
1
1
  import { imageResizeModeToFileImageMode, isImageRepresentationReady } from '@atlaskit/media-client';
2
2
  import { MediaFileStateError, useFileState, useMediaClient } from '@atlaskit/media-client-react';
3
3
  import { isMimeTypeSupportedByBrowser } from '@atlaskit/media-common';
4
- import { useEffect, useMemo, useRef, useState } from 'react';
4
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
5
5
  import { ensureMediaFilePreviewError, ImageLoadError, isLocalPreviewError, isUnsupportedLocalPreviewError, MediaFilePreviewError } from './errors';
6
6
  import { extractErrorInfo } from './analytics';
7
7
  import { isBigger, createRequestDimensions, useCurrentValueRef, usePrevious } from './helpers';
8
8
  import { generateScriptProps, getSSRData } from './globalScope';
9
- import { getAndCacheRemotePreview, getSSRCardPreview, isLocalPreview, isSSRClientPreview, isSSRDataPreview, isPreviewableStatus, extractFilePreviewStatus, mediaFilePreviewCache, getAndCacheLocalPreview } from './getPreview';
9
+ import { getAndCacheRemotePreview, getSSRPreview, isLocalPreview, isSSRClientPreview, isSSRDataPreview, isPreviewableStatus, extractFilePreviewStatus, mediaFilePreviewCache, getAndCacheLocalPreview } from './getPreview';
10
10
  export const useFilePreview = ({
11
11
  resizeMode = 'crop',
12
12
  identifier,
@@ -25,54 +25,52 @@ export const useFilePreview = ({
25
25
  const wasResolvedUpfrontPreviewRef = useRef(false);
26
26
  const ssrReliabilityRef = useRef(initialSsrReliability);
27
27
  const requestDimensions = useMemo(() => dimensions ? createRequestDimensions(dimensions) : undefined, [dimensions]);
28
+ const requestDimensionsRef = useCurrentValueRef(requestDimensions);
29
+ const prevRequestDimensions = usePrevious(requestDimensions);
28
30
  const imageURLParams = useMemo(() => ({
29
31
  collection: identifier.collectionName,
30
32
  mode: resizeMode === 'stretchy-fit' ? 'full-fit' : resizeMode,
31
33
  ...requestDimensions,
32
34
  allowAnimated: true
33
35
  }), [requestDimensions, identifier.collectionName, resizeMode]);
34
- const getSSRPreview = (ssr, identifier, mediaClient) => {
35
- const ssrData = getSSRData(identifier);
36
- if (ssrData !== null && ssrData !== void 0 && ssrData.error) {
37
- ssrReliabilityRef.current.server = {
38
- status: 'fail',
39
- ...ssrData.error
40
- };
36
+ const previewInitializer = () => {
37
+ const fileImageMode = imageResizeModeToFileImageMode(resizeMode);
38
+ const preview = mediaFilePreviewCache.get(identifier.id, fileImageMode);
39
+ if (preview) {
40
+ return preview;
41
41
  }
42
- if (!(ssrData !== null && ssrData !== void 0 && ssrData.dataURI)) {
43
- try {
44
- return getSSRCardPreview(ssr, mediaClient, identifier.id, imageURLParams, mediaBlobUrlAttrs);
45
- } catch (e) {
46
- ssrReliabilityRef.current[ssr] = {
42
+ if (ssr) {
43
+ const ssrData = getSSRData(identifier);
44
+ if (ssrData !== null && ssrData !== void 0 && ssrData.error) {
45
+ ssrReliabilityRef.current.server = {
47
46
  status: 'fail',
48
- ...extractErrorInfo(e)
47
+ ...ssrData.error
48
+ };
49
+ }
50
+ if (!(ssrData !== null && ssrData !== void 0 && ssrData.dataURI)) {
51
+ try {
52
+ return getSSRPreview(ssr, mediaClient, identifier.id, imageURLParams, mediaBlobUrlAttrs);
53
+ } catch (e) {
54
+ ssrReliabilityRef.current[ssr] = {
55
+ status: 'fail',
56
+ ...extractErrorInfo(e)
57
+ };
58
+ }
59
+ } else {
60
+ const {
61
+ dimensions,
62
+ dataURI
63
+ } = ssrData;
64
+ return {
65
+ dataURI,
66
+ dimensions,
67
+ source: 'ssr-data'
49
68
  };
50
69
  }
51
- } else {
52
- const {
53
- dimensions,
54
- dataURI
55
- } = ssrData;
56
- return {
57
- dataURI,
58
- dimensions,
59
- source: 'ssr-data'
60
- };
61
- }
62
- };
63
- const cardPreviewInitializer = () => {
64
- let cardPreview;
65
- const {
66
- id
67
- } = identifier;
68
- const fileImageMode = imageResizeModeToFileImageMode(resizeMode);
69
- cardPreview = mediaFilePreviewCache.get(id, fileImageMode);
70
- if (!cardPreview && ssr) {
71
- cardPreview = getSSRPreview(ssr, identifier, mediaClient);
72
70
  }
73
- return cardPreview;
74
71
  };
75
- const [cardPreview, setCardPreview] = useState(cardPreviewInitializer);
72
+ const [preview, setPreview] = useState(previewInitializer);
73
+ const prevPreview = usePrevious(preview);
76
74
  const {
77
75
  fileState
78
76
  } = useFileState(identifier.id, {
@@ -80,17 +78,142 @@ export const useFilePreview = ({
80
78
  collectionName: identifier.collectionName,
81
79
  occurrenceKey: identifier.occurrenceKey
82
80
  });
81
+
82
+ //----------------------------------------------------------------
83
+ // Update status
84
+ //----------------------------------------------------------------
85
+
86
+ // TOOD: make a full hook reset (remount) on New identifier or client
83
87
  useEffect(() => {
84
88
  setStatus('loading');
85
89
  }, [identifier]);
90
+ const updateFileStateRef = useCurrentValueRef(() => {
91
+ if (fileState) {
92
+ // do not update the status if the status is final
93
+ if (['complete', 'error', 'failed-processing'].includes(status)) {
94
+ return;
95
+ }
96
+ if (fileState.status !== 'error') {
97
+ const mediaType = 'mediaType' in fileState ? fileState.mediaType : undefined;
98
+ const isPreviewable = !!mediaType && ['audio', 'video', 'image', 'doc'].indexOf(mediaType) > -1;
99
+ const isPreviewableFileState = !!fileState.preview;
100
+ const isSupportedLocalPreview = mediaType === 'image' || mediaType === 'video';
101
+ const hasLocalPreview = !isBannedLocalPreview && isPreviewableFileState && isSupportedLocalPreview && !!fileState.mimeType && isMimeTypeSupportedByBrowser(fileState.mimeType);
102
+ const hasRemotePreview = isImageRepresentationReady(fileState);
103
+ const hasPreview = hasLocalPreview || hasRemotePreview;
104
+ let newStatus;
105
+ switch (fileState.status) {
106
+ case 'uploading':
107
+ case 'failed-processing':
108
+ case 'processing':
109
+ newStatus = fileState.status;
110
+ break;
111
+ case 'processed':
112
+ if (!isPreviewable || !hasPreview) {
113
+ newStatus = 'complete';
114
+ break;
115
+ }
116
+ newStatus = 'loading-preview';
117
+ break;
118
+ default:
119
+ newStatus = 'loading';
120
+ }
121
+ setStatus(newStatus);
122
+ } else {
123
+ const e = new MediaFileStateError(fileState.id, fileState.reason, fileState.message, fileState.details);
124
+ const errorReason = status === 'uploading' ? 'upload' : 'metadata-fetch';
125
+ setError(new MediaFilePreviewError(errorReason, e));
126
+ setStatus('error');
127
+ }
128
+ }
129
+ });
130
+ useEffect(() => {
131
+ updateFileStateRef.current();
132
+ }, [fileState, updateFileStateRef]);
133
+ useEffect(() => {
134
+ if (previewDidRender &&
135
+ // We should't complete if status is uploading
136
+ ['loading-preview', 'processing'].includes(status)) {
137
+ setStatus('complete');
138
+ // TODO MEX-788: add test for "do not remove the preview when unsubscribing".
139
+ setIsBannedLocalPreview(false); // CXP-2723 TODO: we might be able to remove this??
140
+ }
141
+ }, [previewDidRender, status]);
86
142
 
87
- //----------------------------------------------------------------//
88
- //---------------------- Helper Functions -----------------------//
89
- //----------------------------------------------------------------//
143
+ // CXP-2723 TODO: Create test cases for banning local preview after status is complete
90
144
 
91
- const fetchRemotePreviewRef = useCurrentValueRef(identifier => {
145
+ //----------------------------------------------------------------
146
+ // Preview Fetch Helper
147
+ //----------------------------------------------------------------
148
+ const getAndCacheRemotePreviewRef = useCurrentValueRef(() => {
92
149
  return getAndCacheRemotePreview(mediaClient, identifier.id, requestDimensions || {}, imageURLParams, mediaBlobUrlAttrs, traceContext);
93
150
  });
151
+
152
+ //----------------------------------------------------------------
153
+ // Cache SSR Preview
154
+ //----------------------------------------------------------------
155
+ useEffect(() => {
156
+ if (!skipRemote && ssr && !!preview && isSSRClientPreview(preview)) {
157
+ // Since the SSR preview brings the token in the query params,
158
+ // We need to fetch the remote preview to be able to cache it,
159
+ getAndCacheRemotePreviewRef.current().catch(() => {
160
+ // No need to log this error.
161
+ // If preview fails, it will be refetched later
162
+ //TODO: test this catch
163
+ // https://product-fabric.atlassian.net/browse/MEX-1071
164
+ });
165
+ }
166
+ }, [preview, identifier, skipRemote, ssr, getAndCacheRemotePreviewRef]);
167
+
168
+ //----------------------------------------------------------------
169
+ // Refetch SRR Preview if dimensions from Server have changed and are bigger,
170
+ //----------------------------------------------------------------
171
+ useEffect(() => {
172
+ // CXP-2813 TODO: This is called too many times if the refetch failed. Should be called only once
173
+ if (preview && !skipRemote && isSSRDataPreview(preview) && isBigger(preview.dimensions, requestDimensions)) {
174
+ getAndCacheRemotePreviewRef.current().then(setPreview).catch(e => {
175
+ const wrappedError = ensureMediaFilePreviewError('remote-preview-fetch-ssr', e, true);
176
+ setNonCriticalError(wrappedError);
177
+ });
178
+ }
179
+ }, [getAndCacheRemotePreviewRef, identifier, preview, requestDimensions, skipRemote]);
180
+
181
+ //----------------------------------------------------------------
182
+ // Upfront Preview
183
+ //----------------------------------------------------------------
184
+ useEffect(() => {
185
+ const resolveUpfrontPreview = async () => {
186
+ // We block any possible future call to this method regardless of the outcome (success or fail)
187
+ // If it fails, the normal preview fetch should occur after the file state is fetched anyways
188
+ wasResolvedUpfrontPreviewRef.current = true;
189
+ try {
190
+ const fetchedDimensions = {
191
+ ...requestDimensions
192
+ };
193
+ const newPreview = await getAndCacheRemotePreviewRef.current();
194
+ const areValidFetchedDimensions = !isBigger(fetchedDimensions, requestDimensionsRef.current);
195
+
196
+ // If there are new and bigger dimensions in the props, and the upfront preview is still resolving,
197
+ // the fetched preview is no longer valid, and thus, we dismiss it
198
+ if (areValidFetchedDimensions) {
199
+ setPreview(newPreview);
200
+ }
201
+ } catch (e) {
202
+ // NO need to log error. If this call fails, a refetch will happen after
203
+ }
204
+ };
205
+
206
+ // CXP-2723 TODO: `hadSSRPreview` is most likely redundant
207
+ const hadSSRPreview = ssr === 'client' && !!prevPreview && isSSRClientPreview(prevPreview);
208
+ if (!preview && !wasResolvedUpfrontPreviewRef.current && (!skipRemote || hadSSRPreview)) {
209
+ resolveUpfrontPreview();
210
+ }
211
+ }, [preview, requestDimensions, requestDimensionsRef, getAndCacheRemotePreviewRef, identifier, skipRemote, prevPreview, ssr]);
212
+
213
+ //----------------------------------------------------------------
214
+ // Fetch Preview
215
+ //----------------------------------------------------------------
216
+
94
217
  const resolvePreviewRef = useCurrentValueRef(async (identifier, fileState) => {
95
218
  const filePreview = isBannedLocalPreview ? undefined : fileState.status !== 'error' && 'mimeType' in fileState && isMimeTypeSupportedByBrowser(fileState.mimeType) ? fileState.preview : undefined;
96
219
  const isRemotePreviewReady = isImageRepresentationReady(fileState);
@@ -104,7 +227,7 @@ export const useFilePreview = ({
104
227
  try {
105
228
  if (filePreview) {
106
229
  const localPreview = await getAndCacheLocalPreview(identifier.id, filePreview, requestDimensions || {}, mode, mediaBlobUrlAttrs);
107
- setCardPreview(localPreview);
230
+ setPreview(localPreview);
108
231
  return;
109
232
  }
110
233
  } catch (e) {
@@ -139,8 +262,8 @@ export const useFilePreview = ({
139
262
  */
140
263
  throw new MediaFilePreviewError('remote-preview-not-ready');
141
264
  }
142
- const remotePreview = await fetchRemotePreviewRef.current(identifier);
143
- setCardPreview(remotePreview);
265
+ const remotePreview = await getAndCacheRemotePreviewRef.current();
266
+ setPreview(remotePreview);
144
267
  return;
145
268
  } catch (e) {
146
269
  const wrappedError = ensureMediaFilePreviewError('preview-fetch', e);
@@ -159,165 +282,43 @@ export const useFilePreview = ({
159
282
  }
160
283
  }
161
284
  });
162
-
163
- //----------------------------------------------------------------//
164
- //------------ resolveUpfrontPreview useEffect -------------------//
165
- //----------------------------------------------------------------//
166
- const prevCardPreview = usePrevious(cardPreview);
167
- const requestDimensionsRef = useCurrentValueRef(requestDimensions);
168
- useEffect(() => {
169
- const resolveUpfrontPreview = async identifier => {
170
- // We block any possible future call to this method regardless of the outcome (success or fail)
171
- // If it fails, the normal preview fetch should occur after the file state is fetched anyways
172
- wasResolvedUpfrontPreviewRef.current = true;
173
- try {
174
- const fetchedDimensions = {
175
- ...requestDimensions
176
- };
177
- const newCardPreview = await fetchRemotePreviewRef.current(identifier);
178
- const areValidFetchedDimensions = !isBigger(fetchedDimensions, requestDimensionsRef.current);
179
-
180
- // If there are new and bigger dimensions in the props, and the upfront preview is still resolving,
181
- // the fetched preview is no longer valid, and thus, we dismiss it
182
- if (areValidFetchedDimensions) {
183
- setCardPreview(newCardPreview);
184
- }
185
- } catch (e) {
186
- // NO need to log error. If this call fails, a refetch will happen after
187
- }
188
- };
189
- const hadSSRCardPreview = ssr === 'client' && !!prevCardPreview && isSSRClientPreview(prevCardPreview);
190
-
191
- // CXP-2723 TODO: `hadSSRCardPreview` is most likely redundant
192
- if (!wasResolvedUpfrontPreviewRef.current && (!skipRemote || hadSSRCardPreview) && !cardPreview) {
193
- resolveUpfrontPreview(identifier);
194
- }
195
- }, [cardPreview, requestDimensions, requestDimensionsRef, fetchRemotePreviewRef, identifier, skipRemote, prevCardPreview, ssr]);
196
-
197
- //----------------------------------------------------------------//
198
- //---------------- fetch and resolve card preview ----------------//
199
- //----------------------------------------------------------------//
200
-
201
- const prevRequestDimensions = usePrevious(requestDimensions);
202
285
  useEffect(() => {
203
- // CXP-2813 TODO: This is called too many times if the refetch failed. Should be called only once
204
- if (cardPreview && !skipRemote && isSSRDataPreview(cardPreview) && isBigger(cardPreview.dimensions, requestDimensions)) {
205
- // refetchSRRPreview: If dimensions from Server have changed and are bigger,
206
- // we need to refetch
207
- fetchRemotePreviewRef.current(identifier).then(setCardPreview).catch(e => {
208
- const wrappedError = ensureMediaFilePreviewError('remote-preview-fetch-ssr', e, true);
209
- setNonCriticalError(wrappedError);
210
- });
211
- }
212
- // CXP-2723 TODO: The above and below preview fetch logic seem very similar and could be revisted
213
- // Both compare dimensions, but the above is only for SSR in order to refetchSRRPreview and
214
- // will swallow any errors. Below logic only applies when there is no card preview or the dimensions
215
- // are bigger.
216
- if (fileState && wasResolvedUpfrontPreviewRef.current && isPreviewableStatus(status, extractFilePreviewStatus(fileState, isBannedLocalPreview)) && (!cardPreview || isBigger(prevRequestDimensions, requestDimensions))) {
286
+ if (fileState && wasResolvedUpfrontPreviewRef.current && isPreviewableStatus(status, extractFilePreviewStatus(fileState, isBannedLocalPreview)) && (!preview || isBigger(prevRequestDimensions, requestDimensions))) {
217
287
  resolvePreviewRef.current(identifier, fileState);
218
288
  }
219
- if (!skipRemote && ssr && !!cardPreview && isSSRClientPreview(cardPreview)) {
220
- // Since the SSR preview brings the token in the query params,
221
- // We need to fetch the remote preview to be able to cache it,
222
- fetchRemotePreviewRef.current(identifier).catch(() => {
223
- // No need to log this error.
224
- // If preview fails, it will be refetched later
225
- //TODO: test this catch
226
- // https://product-fabric.atlassian.net/browse/MEX-1071
227
- });
228
- }
229
- }, [cardPreview, requestDimensions, fetchRemotePreviewRef, fileState, identifier, isBannedLocalPreview, prevRequestDimensions, resolvePreviewRef, skipRemote, ssr, status]);
230
-
231
- //----------------------------------------------------------------//
232
- //----------------- set complete status --------------------------//
233
- //----------------------------------------------------------------//
289
+ }, [fileState, identifier, isBannedLocalPreview, prevRequestDimensions, preview, requestDimensions, resolvePreviewRef, status]);
234
290
 
235
- useEffect(() => {
236
- if (previewDidRender &&
237
- // We should't complete if status is uploading
238
- ['loading-preview', 'processing'].includes(status)) {
239
- setStatus('complete');
240
- // TODO MEX-788: add test for "do not remove the card preview when unsubscribing".
241
- setIsBannedLocalPreview(false); // CXP-2723 TODO: we might be able to remove this??
242
- }
243
- }, [previewDidRender, status]);
244
-
245
- // CXP-2723 TODO: Create test cases for banning local preview after status is complete
246
-
247
- //----------------------------------------------------------------//
248
- //------------------ Subscribe to file state ---------------------//
249
- //----------------------------------------------------------------//
291
+ //----------------------------------------------------------------
292
+ // RETURN
293
+ //----------------------------------------------------------------
250
294
 
251
- const updateFileStateRef = useCurrentValueRef(() => {
252
- if (fileState) {
253
- // do not update the card status if the status is final
254
- if (['complete', 'error', 'failed-processing'].includes(status)) {
255
- return;
256
- }
257
- if (fileState.status !== 'error') {
258
- const mediaType = 'mediaType' in fileState ? fileState.mediaType : undefined;
259
- const isPreviewable = !!mediaType && ['audio', 'video', 'image', 'doc'].indexOf(mediaType) > -1;
260
- const isPreviewableFileState = !!fileState.preview;
261
- const isSupportedLocalPreview = mediaType === 'image' || mediaType === 'video';
262
- const hasLocalPreview = !isBannedLocalPreview && isPreviewableFileState && isSupportedLocalPreview && !!fileState.mimeType && isMimeTypeSupportedByBrowser(fileState.mimeType);
263
- const hasRemotePreview = isImageRepresentationReady(fileState);
264
- const hasPreview = hasLocalPreview || hasRemotePreview;
265
- let newStatus;
266
- switch (fileState.status) {
267
- case 'uploading':
268
- case 'failed-processing':
269
- case 'processing':
270
- newStatus = fileState.status;
271
- break;
272
- case 'processed':
273
- if (!isPreviewable || !hasPreview) {
274
- newStatus = 'complete';
275
- break;
276
- }
277
- newStatus = 'loading-preview';
278
- break;
279
- default:
280
- newStatus = 'loading';
281
- }
282
- setStatus(newStatus);
283
- } else {
284
- const e = new MediaFileStateError(fileState.id, fileState.reason, fileState.message, fileState.details);
285
- const errorReason = status === 'uploading' ? 'upload' : 'metadata-fetch';
286
- setError(new MediaFilePreviewError(errorReason, e));
287
- setStatus('error');
288
- }
289
- }
290
- });
291
- useEffect(() => {
292
- updateFileStateRef.current();
293
- }, [fileState, updateFileStateRef]);
294
- const onImageError = newCardPreview => {
295
- if (newCardPreview) {
295
+ const onImageError = useCallback(newPreview => {
296
+ if (newPreview) {
296
297
  const failedSSRObject = {
297
298
  status: 'fail',
298
- ...extractErrorInfo(new ImageLoadError(newCardPreview.source))
299
+ ...extractErrorInfo(new ImageLoadError(newPreview.source))
299
300
  };
300
- if (isSSRClientPreview(newCardPreview)) {
301
+ if (isSSRClientPreview(newPreview)) {
301
302
  ssrReliabilityRef.current.client = failedSSRObject;
302
303
  }
303
304
 
304
305
  /*
305
- If the cardPreview failed and it comes from server (global scope / ssrData), it means that we have reused it in client and the error counts for both: server & client.
306
+ If the preview failed and it comes from server (global scope / ssrData), it means that we have reused it in client and the error counts for both: server & client.
306
307
  */
307
308
 
308
- if (isSSRDataPreview(newCardPreview)) {
309
+ if (isSSRDataPreview(newPreview)) {
309
310
  ssrReliabilityRef.current.server = failedSSRObject;
310
311
  ssrReliabilityRef.current.client = failedSSRObject;
311
312
  }
312
313
  }
313
314
 
314
315
  // If the dataURI has been replaced, we can dismiss this error
315
- if ((newCardPreview === null || newCardPreview === void 0 ? void 0 : newCardPreview.dataURI) !== (cardPreview === null || cardPreview === void 0 ? void 0 : cardPreview.dataURI)) {
316
+ if ((newPreview === null || newPreview === void 0 ? void 0 : newPreview.dataURI) !== (preview === null || preview === void 0 ? void 0 : preview.dataURI)) {
316
317
  return;
317
318
  }
318
- const error = new ImageLoadError(newCardPreview === null || newCardPreview === void 0 ? void 0 : newCardPreview.source);
319
- const isLocal = newCardPreview && isLocalPreview(newCardPreview);
320
- const isSSR = newCardPreview && (isSSRClientPreview(newCardPreview) || isSSRDataPreview(newCardPreview));
319
+ const error = new ImageLoadError(newPreview === null || newPreview === void 0 ? void 0 : newPreview.source);
320
+ const isLocal = newPreview && isLocalPreview(newPreview);
321
+ const isSSR = newPreview && (isSSRClientPreview(newPreview) || isSSRDataPreview(newPreview));
321
322
  if (isLocal || isSSR) {
322
323
  if (isLocal) {
323
324
  setIsBannedLocalPreview(true);
@@ -325,27 +326,27 @@ export const useFilePreview = ({
325
326
  }
326
327
  const fileImageMode = imageResizeModeToFileImageMode(resizeMode);
327
328
  mediaFilePreviewCache.remove(identifier.id, fileImageMode);
328
- setCardPreview(undefined);
329
+ setPreview(undefined);
329
330
  } else {
330
331
  if (!['complete', 'error', 'failed-processing'].includes(status)) {
331
332
  setStatus('error');
332
333
  setError(error);
333
334
  }
334
335
  }
335
- };
336
- const onImageLoad = newCardPreview => {
337
- if (newCardPreview) {
338
- if (isSSRClientPreview(newCardPreview) && ssrReliabilityRef.current.client.status === 'unknown') {
336
+ }, [identifier.id, preview === null || preview === void 0 ? void 0 : preview.dataURI, resizeMode, status]);
337
+ const onImageLoad = useCallback(newPreview => {
338
+ if (newPreview) {
339
+ if (isSSRClientPreview(newPreview) && ssrReliabilityRef.current.client.status === 'unknown') {
339
340
  ssrReliabilityRef.current.client = {
340
341
  status: 'success'
341
342
  };
342
343
  }
343
344
 
344
345
  /*
345
- If the image loads successfully and it comes from server (global scope / ssrData), it means that we have reused it in client and the success counts for both: server & client.
346
+ If the image loads successfully and it comes from server (global scope / ssrData), it means that we have reused it in client and the success counts for both: server & client.
346
347
  */
347
348
 
348
- if (isSSRDataPreview(newCardPreview) && ssrReliabilityRef.current.server.status === 'unknown') {
349
+ if (isSSRDataPreview(newPreview) && ssrReliabilityRef.current.server.status === 'unknown') {
349
350
  ssrReliabilityRef.current.server = {
350
351
  status: 'success'
351
352
  };
@@ -356,25 +357,21 @@ export const useFilePreview = ({
356
357
  }
357
358
 
358
359
  // If the dataURI has been replaced, we can dismiss this callback
359
- if ((newCardPreview === null || newCardPreview === void 0 ? void 0 : newCardPreview.dataURI) !== (cardPreview === null || cardPreview === void 0 ? void 0 : cardPreview.dataURI)) {
360
+ if ((newPreview === null || newPreview === void 0 ? void 0 : newPreview.dataURI) !== (preview === null || preview === void 0 ? void 0 : preview.dataURI)) {
360
361
  return;
361
362
  }
362
- };
363
-
364
- //----------------------------------------------------------------//
365
- // RETURN
366
- //----------------------------------------------------------------//
363
+ }, [preview === null || preview === void 0 ? void 0 : preview.dataURI]);
367
364
 
368
365
  // FOR SSR
369
366
  const getScriptProps = () => {
370
367
  var _ssrReliabilityRef$cu;
371
- return generateScriptProps(identifier, cardPreview === null || cardPreview === void 0 ? void 0 : cardPreview.dataURI, requestDimensions, ((_ssrReliabilityRef$cu = ssrReliabilityRef.current.server) === null || _ssrReliabilityRef$cu === void 0 ? void 0 : _ssrReliabilityRef$cu.status) === 'fail' ? ssrReliabilityRef.current.server : undefined);
368
+ return generateScriptProps(identifier, preview === null || preview === void 0 ? void 0 : preview.dataURI, requestDimensions, ((_ssrReliabilityRef$cu = ssrReliabilityRef.current.server) === null || _ssrReliabilityRef$cu === void 0 ? void 0 : _ssrReliabilityRef$cu.status) === 'fail' ? ssrReliabilityRef.current.server : undefined);
372
369
  };
373
370
 
374
371
  // CXP-2723 TODO: should consider simplifying our analytics, and how
375
372
  // we might get rid of ssrReliabiltyRef from our hook
376
373
  return {
377
- cardPreview,
374
+ preview,
378
375
  error,
379
376
  nonCriticalError,
380
377
  ssrReliabilityRef,
@@ -37,7 +37,7 @@ export default class MediaInlineCardLoader extends React.PureComponent {
37
37
  } = this.state;
38
38
  const analyticsContext = {
39
39
  packageVersion: "@atlaskit/media-card",
40
- packageName: "77.6.1",
40
+ packageName: "77.6.3",
41
41
  componentName: 'mediaInlineCard',
42
42
  component: 'mediaInlineCard'
43
43
  };