@atlaskit/media-card 77.2.3 → 77.4.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 (50) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/cjs/card/card.js +1 -1
  3. package/dist/cjs/card/getCardPreview/cache.js +1 -1
  4. package/dist/cjs/card/media-card-analytics-error-boundary.js +1 -1
  5. package/dist/cjs/card/ui/imageRenderer/imageRenderer.js +6 -3
  6. package/dist/cjs/card/v2/cardV2.js +18 -1037
  7. package/dist/cjs/card/v2/externalImageCard.js +299 -0
  8. package/dist/cjs/card/v2/fileCard.js +1001 -0
  9. package/dist/cjs/errors.js +33 -55
  10. package/dist/cjs/inline/loader.js +1 -1
  11. package/dist/cjs/utils/ufoExperiences.js +1 -1
  12. package/dist/cjs/utils/useCurrentValueRef.js +12 -0
  13. package/dist/cjs/utils/usePrevious.js +14 -0
  14. package/dist/es2019/card/card.js +1 -1
  15. package/dist/es2019/card/getCardPreview/cache.js +2 -0
  16. package/dist/es2019/card/media-card-analytics-error-boundary.js +1 -1
  17. package/dist/es2019/card/ui/imageRenderer/imageRenderer.js +6 -3
  18. package/dist/es2019/card/v2/cardV2.js +17 -1021
  19. package/dist/es2019/card/v2/externalImageCard.js +261 -0
  20. package/dist/es2019/card/v2/fileCard.js +881 -0
  21. package/dist/es2019/errors.js +1 -17
  22. package/dist/es2019/inline/loader.js +1 -1
  23. package/dist/es2019/utils/ufoExperiences.js +1 -1
  24. package/dist/es2019/utils/useCurrentValueRef.js +6 -0
  25. package/dist/es2019/utils/usePrevious.js +8 -0
  26. package/dist/esm/card/card.js +1 -1
  27. package/dist/esm/card/getCardPreview/cache.js +2 -0
  28. package/dist/esm/card/media-card-analytics-error-boundary.js +1 -1
  29. package/dist/esm/card/ui/imageRenderer/imageRenderer.js +6 -3
  30. package/dist/esm/card/v2/cardV2.js +19 -1036
  31. package/dist/esm/card/v2/externalImageCard.js +289 -0
  32. package/dist/esm/card/v2/fileCard.js +991 -0
  33. package/dist/esm/errors.js +31 -55
  34. package/dist/esm/inline/loader.js +1 -1
  35. package/dist/esm/utils/ufoExperiences.js +1 -1
  36. package/dist/esm/utils/useCurrentValueRef.js +6 -0
  37. package/dist/esm/utils/usePrevious.js +8 -0
  38. package/dist/types/card/v2/cardV2.d.ts +4 -60
  39. package/dist/types/card/v2/externalImageCard.d.ts +14 -0
  40. package/dist/types/card/v2/fileCard.d.ts +19 -0
  41. package/dist/types/errors.d.ts +1 -7
  42. package/dist/types/utils/useCurrentValueRef.d.ts +2 -0
  43. package/dist/types/utils/usePrevious.d.ts +1 -0
  44. package/dist/types-ts4.5/card/v2/cardV2.d.ts +4 -60
  45. package/dist/types-ts4.5/card/v2/externalImageCard.d.ts +14 -0
  46. package/dist/types-ts4.5/card/v2/fileCard.d.ts +19 -0
  47. package/dist/types-ts4.5/errors.d.ts +1 -7
  48. package/dist/types-ts4.5/utils/useCurrentValueRef.d.ts +2 -0
  49. package/dist/types-ts4.5/utils/usePrevious.d.ts +1 -0
  50. package/package.json +5 -5
@@ -1,1035 +1,31 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
- import React, { Component, Suspense, useEffect } from 'react';
4
- import ReactDOM from 'react-dom';
5
2
  import { withAnalyticsEvents } from '@atlaskit/analytics-next';
3
+ import { isFileIdentifier } from '@atlaskit/media-client';
6
4
  import { withMediaAnalyticsContext } from '@atlaskit/media-common';
7
- import DownloadIcon from '@atlaskit/icon/glyph/download';
8
- import { getRandomHex } from '@atlaskit/media-common';
9
- import { globalMediaEventEmitter, isDifferentIdentifier, isFileIdentifier, RECENTS_COLLECTION, isImageRepresentationReady, isExternalImageIdentifier, imageResizeModeToFileImageMode } from '@atlaskit/media-client';
10
- import { MediaViewer } from '@atlaskit/media-viewer';
11
- import { injectIntl, IntlProvider } from 'react-intl-next';
12
- import { CardViewV2 } from './cardViewV2';
13
- import { ViewportDetector } from '../../utils/viewportDetector';
14
- import { videoIsPlayable } from '../../utils/videoIsPlayable';
15
- import { getRequestedDimensions } from '../../utils/getDataURIDimension';
16
- import { getCardPreview, getCardPreviewFromCache, removeCardPreviewFromCache, getFilePreviewFromFileState, shouldResolvePreview, getSSRCardPreview, isLocalPreview, isSSRPreview, isSSRClientPreview, isSSRDataPreview, fetchAndCacheRemotePreview } from '../getCardPreview';
17
- import { getFileDetails } from '../../utils/metadata';
18
- import { InlinePlayerLazyV2 } from './inlinePlayerLazyV2';
19
- import { getFileAttributes, extractErrorInfo } from '../../utils/analytics';
20
- import { isLocalPreviewError, MediaCardError, MediaFileStateError, ensureMediaCardError, ImageLoadError } from '../../errors';
21
- import { fireOperationalEvent, fireCommencedEvent, fireCopiedEvent, fireScreenEvent, fireNonCriticalErrorEvent } from '../cardAnalytics';
22
- import getDocument from '../../utils/document';
23
- import { StoreSSRDataScript, getSSRData } from '../../utils/globalScope';
24
- import { getCardStateFromFileState, createStateUpdater } from '../cardState';
25
- import { isBigger } from '../../utils/dimensionComparer';
26
- import { getMediaCardCursor } from '../../utils/getMediaCardCursor';
27
- import { completeUfoExperience, startUfoExperience, abortUfoExperience } from '../../utils/ufoExperiences';
28
- import { generateUniqueId } from '../../utils/generateUniqueId';
29
- import { useFileState } from '@atlaskit/media-client-react';
5
+ import React from 'react';
6
+ import { IntlProvider, injectIntl } from 'react-intl-next';
7
+ import { ExternalImageCard } from './externalImageCard';
8
+ import { FileCard } from './fileCard';
30
9
  const packageName = "@atlaskit/media-card";
31
- const packageVersion = "77.2.3";
32
- export class CardV2Base extends Component {
33
- constructor(props) {
34
- super(props);
35
- // An internalOccurrenceKey is a randomly generated value to differentiate various instances
36
- // of Cards regardless of whether it shares the same file (either internal or external)
37
- _defineProperty(this, "internalOccurrenceKey", generateUniqueId());
38
- _defineProperty(this, "hasBeenMounted", false);
39
- _defineProperty(this, "fileStateFlags", {
40
- wasStatusUploading: false,
41
- wasStatusProcessing: false
42
- });
43
- _defineProperty(this, "ssrReliability", {
44
- server: {
45
- status: 'unknown'
46
- },
47
- client: {
48
- status: 'unknown'
49
- }
50
- });
51
- // We initialise timeElapsedTillCommenced
52
- // to avoid extra branching on a possibly undefined value.
53
- _defineProperty(this, "timeElapsedTillCommenced", performance.now());
54
- // Generate unique traceId for file
55
- _defineProperty(this, "traceContext", {
56
- traceId: getRandomHex(8)
57
- });
58
- _defineProperty(this, "getImageURLParams", ({
59
- collectionName: collection
60
- }) => ({
61
- collection,
62
- mode: imageResizeModeToFileImageMode(this.props.resizeMode),
63
- ...this.requestedDimensions,
64
- allowAnimated: true
65
- }));
66
- _defineProperty(this, "getMediaBlobUrlAttrs", (identifier, fileState) => {
67
- const {
68
- id,
69
- collectionName: collection
70
- } = identifier;
71
- const {
72
- originalDimensions,
73
- contextId,
74
- alt
75
- } = this.props;
76
- const {
77
- mimeType,
78
- name,
79
- size
80
- } = getFileDetails(identifier, fileState);
81
- return contextId ? {
82
- id,
83
- collection,
84
- contextId,
85
- mimeType,
86
- name,
87
- size,
88
- ...(originalDimensions || this.requestedDimensions),
89
- alt
90
- } : undefined;
91
- });
92
- _defineProperty(this, "getCardPreviewParams", (identifier, fileState) => {
93
- const {
94
- isBannedLocalPreview
95
- } = this.state;
96
- const {
97
- id
98
- } = identifier;
99
- const {
100
- dimensions = {},
101
- mediaClient
102
- } = this.props;
103
- return {
104
- mediaClient,
105
- id,
106
- dimensions,
107
- onLocalPreviewError: this.fireNonCriticalErrorEvent,
108
- filePreview: isBannedLocalPreview ? undefined : getFilePreviewFromFileState(fileState),
109
- isRemotePreviewReady: isImageRepresentationReady(fileState),
110
- imageUrlParams: this.getImageURLParams(identifier),
111
- mediaBlobUrlAttrs: this.getMediaBlobUrlAttrs(identifier, fileState),
112
- traceContext: this.traceContext
113
- };
114
- });
115
- _defineProperty(this, "setCacheSSRPreview", identifier => {
116
- this.fetchAndCacheRemotePreview(identifier).catch(() => {
117
- // No need to log this error.
118
- // If preview fails, it will be refetched later
119
- //TODO: test this catch
120
- // https://product-fabric.atlassian.net/browse/MEX-1071
121
- });
122
- });
123
- _defineProperty(this, "refetchSSRPreview", async identifier => {
124
- try {
125
- const cardPreview = await this.fetchAndCacheRemotePreview(identifier);
126
- this.safeSetState({
127
- cardPreview
128
- });
129
- } catch (e) {
130
- const wrappedError = ensureMediaCardError('remote-preview-fetch-ssr', e, true);
131
- this.fireNonCriticalErrorEvent(wrappedError);
132
- }
133
- });
134
- _defineProperty(this, "resolveUpfrontPreview", async identifier => {
135
- const requestedDimensions = {
136
- ...this.props.dimensions
137
- };
138
- try {
139
- const cardPreview = await this.fetchAndCacheRemotePreview(identifier);
140
- const {
141
- dimensions: currentDimensions
142
- } = this.props;
143
- const areValidRequestedDimensions = !isBigger(requestedDimensions, currentDimensions);
144
-
145
- // If there are new and bigger dimensions in the props, and the upfront preview is still resolving,
146
- // the fetched preview is no longer valid, and thus, we dismiss it and set the flag wasResolvedUpfrontPreview = true
147
- // to trigger a normal preview fetch.
148
- if (areValidRequestedDimensions) {
149
- this.safeSetState({
150
- cardPreview,
151
- wasResolvedUpfrontPreview: true
152
- });
153
- } else {
154
- this.safeSetState({
155
- wasResolvedUpfrontPreview: true
156
- });
157
- }
158
- } catch (e) {
159
- this.safeSetState({
160
- wasResolvedUpfrontPreview: true
161
- });
162
- // NO need to log error. If this call fails, a refetch will happen after
163
- }
164
- });
165
- _defineProperty(this, "fetchAndCacheRemotePreview", identifier => {
166
- const {
167
- mediaClient,
168
- dimensions = {}
169
- } = this.props;
170
- return fetchAndCacheRemotePreview(mediaClient, identifier.id, dimensions, this.getImageURLParams(identifier), this.getMediaBlobUrlAttrs(identifier));
171
- });
172
- _defineProperty(this, "resolvePreview", async (identifier, fileState) => {
173
- try {
174
- const params = this.getCardPreviewParams(identifier, fileState);
175
- const cardPreview = await getCardPreview(params);
176
- this.safeSetState({
177
- cardPreview
178
- });
179
- } catch (e) {
180
- const wrappedError = ensureMediaCardError('preview-fetch', e);
181
- // If remote preview fails, we set status 'error'
182
- // If local preview fails (i.e, no remote preview available),
183
- // we can stay in the same status until there is a remote preview available
184
- // If it's any other error we set status 'error'
185
- if (isLocalPreviewError(wrappedError)) {
186
- // This error should already been logged inside the getCardPreview. No need to log it here.
187
- this.safeSetState({
188
- isBannedLocalPreview: true
189
- });
190
- } else {
191
- this.safeSetState({
192
- status: 'error',
193
- error: wrappedError
194
- });
195
- }
196
- }
197
- });
198
- _defineProperty(this, "subscribeFileState", fileState => {
199
- const {
200
- isBannedLocalPreview
201
- } = this.state;
202
- if (fileState.status !== 'error') {
203
- const newState = getCardStateFromFileState(fileState, isBannedLocalPreview);
204
- this.safeSetState(newState);
205
- } else {
206
- const e = new MediaFileStateError(fileState.id, fileState.reason, fileState.message, fileState.details);
207
- const errorReason = this.state.status === 'uploading' ? 'upload' : 'metadata-fetch';
208
- const error = new MediaCardError(errorReason, e);
209
- this.safeSetState({
210
- error,
211
- status: 'error'
212
- });
213
- }
214
- });
215
- _defineProperty(this, "getPerformanceAttributes", () => {
216
- const {
217
- timeElapsedTillCommenced
218
- } = this;
219
- const timeElapsedTillEvent = performance.now();
220
- const durationSinceCommenced = timeElapsedTillCommenced && timeElapsedTillEvent - timeElapsedTillCommenced;
221
- return {
222
- overall: {
223
- durationSincePageStart: timeElapsedTillEvent,
224
- durationSinceCommenced
225
- }
226
- };
227
- });
228
- _defineProperty(this, "logSSRImageError", cardPreview => {
229
- if (cardPreview) {
230
- const failedSSRObject = {
231
- status: 'fail',
232
- ...extractErrorInfo(new ImageLoadError(cardPreview.source))
233
- };
234
- if (isSSRClientPreview(cardPreview)) {
235
- this.ssrReliability.client = failedSSRObject;
236
- }
237
-
238
- /*
239
- 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.
240
- */
241
-
242
- if (isSSRDataPreview(cardPreview)) {
243
- this.ssrReliability.server = failedSSRObject;
244
- this.ssrReliability.client = failedSSRObject;
245
- }
246
- }
247
- });
248
- _defineProperty(this, "onImageError", cardPreview => {
249
- this.logSSRImageError(cardPreview);
250
- const {
251
- cardPreview: currentPreview
252
- } = this.state;
253
- // If the dataURI has been replaced, we can dismiss this error
254
- if ((cardPreview === null || cardPreview === void 0 ? void 0 : cardPreview.dataURI) !== (currentPreview === null || currentPreview === void 0 ? void 0 : currentPreview.dataURI)) {
255
- return;
256
- }
257
- const error = new ImageLoadError(cardPreview === null || cardPreview === void 0 ? void 0 : cardPreview.source);
258
- const isLocal = cardPreview && isLocalPreview(cardPreview);
259
- const isSSR = cardPreview && (isSSRClientPreview(cardPreview) || isSSRDataPreview(cardPreview));
260
- if (isLocal || isSSR) {
261
- const updateState = {
262
- cardPreview: undefined
263
- };
264
- if (isLocal) {
265
- updateState.isBannedLocalPreview = true;
266
- this.fireNonCriticalErrorEvent(error);
267
- }
268
- const {
269
- identifier,
270
- resizeMode
271
- } = this.props;
272
- const fileImageMode = imageResizeModeToFileImageMode(resizeMode);
273
- isFileIdentifier(identifier) && removeCardPreviewFromCache(identifier.id, fileImageMode);
274
- this.safeSetState(updateState);
275
- } else {
276
- this.safeSetState({
277
- status: 'error',
278
- error
279
- });
280
- }
281
- });
282
- _defineProperty(this, "onImageLoad", cardPreview => {
283
- if (cardPreview) {
284
- if (isSSRClientPreview(cardPreview) && this.ssrReliability.client.status === 'unknown') {
285
- this.ssrReliability.client = {
286
- status: 'success'
287
- };
288
- }
289
-
290
- /*
291
- 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.
292
- */
293
-
294
- if (isSSRDataPreview(cardPreview) && this.ssrReliability.server.status === 'unknown') {
295
- this.ssrReliability.server = {
296
- status: 'success'
297
- };
298
- this.ssrReliability.client = {
299
- status: 'success'
300
- };
301
- }
302
- }
303
- const {
304
- cardPreview: currentPreview
305
- } = this.state;
306
- // If the dataURI has been replaced, we can dismiss this callback
307
- if ((cardPreview === null || cardPreview === void 0 ? void 0 : cardPreview.dataURI) !== (currentPreview === null || currentPreview === void 0 ? void 0 : currentPreview.dataURI)) {
308
- return;
309
- }
310
- this.safeSetState({
311
- previewDidRender: true
312
- });
313
- });
314
- _defineProperty(this, "fireCopiedEvent", () => {
315
- const {
316
- createAnalyticsEvent
317
- } = this.props;
318
- const {
319
- cardRef
320
- } = this.state;
321
- cardRef && createAnalyticsEvent && fireCopiedEvent(createAnalyticsEvent, this.metadata.id, cardRef);
322
- });
323
- _defineProperty(this, "fireScreenEvent", () => {
324
- const {
325
- createAnalyticsEvent
326
- } = this.props;
327
- createAnalyticsEvent && fireScreenEvent(createAnalyticsEvent, this.fileAttributes);
328
- });
329
- _defineProperty(this, "fireNonCriticalErrorEvent", error => {
330
- const {
331
- createAnalyticsEvent
332
- } = this.props;
333
- const {
334
- fileState
335
- } = this.state;
336
- createAnalyticsEvent && fireNonCriticalErrorEvent(createAnalyticsEvent, this.state.status, this.fileAttributes, this.ssrReliability, error, this.traceContext, fileState === null || fileState === void 0 ? void 0 : fileState.metadataTraceContext);
337
- });
338
- _defineProperty(this, "safeSetState", newState => {
339
- if (this.hasBeenMounted) {
340
- /**
341
- * createStateUpdater helper returns a callback to be passed to setState.
342
- * It decides wether to update the 'status' depending on the current state vs the input state.
343
- * From docs: "Both state and props received by the updater function are guaranteed to be up-to-date."
344
- * If the input state brings an error and it won't be updating the state, the error will be logged as non-critical inside the helper.
345
- * If the error persists int the state, it means it is a critical error and should be logged as a failed event for Card
346
- */
347
- this.setState(createStateUpdater(newState, this.fireNonCriticalErrorEvent));
348
- }
349
- });
350
- _defineProperty(this, "onCardViewClick", (event, analyticsEvent) => {
351
- const {
352
- identifier,
353
- useInlinePlayer,
354
- shouldOpenMediaViewer
355
- } = this.props;
356
- const {
357
- cardPreview
358
- } = this.state;
359
- const {
360
- metadata
361
- } = this;
362
- this.onClick(event, analyticsEvent);
363
- if (!metadata) {
364
- return;
365
- }
366
- const isVideo = metadata && metadata.mediaType === 'video';
367
- if (useInlinePlayer && isVideo && !!cardPreview) {
368
- this.setState({
369
- isPlayingFile: true,
370
- shouldAutoplay: true
371
- });
372
- } else if (shouldOpenMediaViewer) {
373
- let mediaViewerSelectedItem;
374
- if (isFileIdentifier(identifier)) {
375
- mediaViewerSelectedItem = {
376
- id: identifier.id,
377
- mediaItemType: 'file',
378
- collectionName: identifier.collectionName,
379
- occurrenceKey: identifier.occurrenceKey
380
- };
381
- } else {
382
- mediaViewerSelectedItem = {
383
- mediaItemType: 'external-image',
384
- dataURI: identifier.dataURI,
385
- name: identifier.name
386
- };
387
- }
388
- this.setState({
389
- mediaViewerSelectedItem
390
- });
391
- }
392
- });
393
- _defineProperty(this, "onInlinePlayerError", () => {
394
- this.setState({
395
- isPlayingFile: false
396
- });
397
- });
398
- _defineProperty(this, "setRef", cardRef => {
399
- !!cardRef && this.setState({
400
- cardRef
401
- });
402
- });
403
- _defineProperty(this, "renderInlinePlayer", () => {
404
- const {
405
- identifier,
406
- dimensions,
407
- selected,
408
- testId,
409
- originalDimensions,
410
- onFullscreenChange
411
- } = this.props;
412
- const {
413
- shouldAutoplay,
414
- cardPreview
415
- } = this.state;
416
- const card = this.renderCard(false, 'loading', false);
417
- return /*#__PURE__*/React.createElement(Suspense, {
418
- fallback: card
419
- }, /*#__PURE__*/React.createElement(InlinePlayerLazyV2, {
420
- dimensions: dimensions,
421
- originalDimensions: originalDimensions,
422
- identifier: identifier,
423
- autoplay: !!shouldAutoplay,
424
- onFullscreenChange: onFullscreenChange,
425
- onError: this.onInlinePlayerError,
426
- onClick: this.onClick,
427
- selected: selected,
428
- ref: this.setRef,
429
- testId: testId,
430
- cardPreview: cardPreview
431
- }));
432
- });
433
- _defineProperty(this, "onMediaViewerClose", () => {
434
- this.setState({
435
- mediaViewerSelectedItem: undefined
436
- });
437
- });
438
- _defineProperty(this, "onDisplayImage", () => {
439
- const {
440
- identifier
441
- } = this.props;
442
- let payloadPart;
443
- if (isFileIdentifier(identifier)) {
444
- payloadPart = {
445
- fileId: identifier.id,
446
- isUserCollection: identifier.collectionName === RECENTS_COLLECTION
447
- };
448
- } else {
449
- payloadPart = {
450
- fileId: identifier.dataURI,
451
- isUserCollection: false
452
- };
453
- }
454
- globalMediaEventEmitter.emit('media-viewed', {
455
- viewingLevel: 'minimal',
456
- ...payloadPart
457
- });
458
- });
459
- _defineProperty(this, "renderMediaViewer", () => {
460
- const {
461
- mediaViewerSelectedItem
462
- } = this.state;
463
- const {
464
- mediaClient,
465
- identifier,
466
- mediaViewerItems,
467
- contextId,
468
- featureFlags
469
- } = this.props;
470
- if (!mediaViewerSelectedItem) {
471
- return;
472
- }
473
- const collectionName = isFileIdentifier(identifier) ? identifier.collectionName || '' : '';
474
- return /*#__PURE__*/ReactDOM.createPortal( /*#__PURE__*/React.createElement(MediaViewer, {
475
- collectionName: collectionName,
476
- items: mediaViewerItems || [],
477
- mediaClientConfig: mediaClient.config,
478
- selectedItem: mediaViewerSelectedItem,
479
- onClose: this.onMediaViewerClose,
480
- contextId: contextId,
481
- featureFlags: featureFlags
482
- }), document.body);
483
- });
484
- _defineProperty(this, "renderCard", (withCallbacks = true, cardStatusOverride, izLazyOverride) => {
485
- const {
486
- identifier,
487
- isLazy,
488
- appearance,
489
- resizeMode,
490
- dimensions,
491
- selectable,
492
- selected,
493
- disableOverlay,
494
- alt,
495
- testId,
496
- featureFlags,
497
- titleBoxBgColor,
498
- titleBoxIcon,
499
- ssr,
500
- useInlinePlayer,
501
- shouldOpenMediaViewer,
502
- shouldHideTooltip
503
- } = this.props;
504
- const {
505
- mediaItemType
506
- } = identifier;
507
- const {
508
- status,
509
- progress,
510
- cardPreview,
511
- error,
512
- cardRef,
513
- isCardVisible
514
- } = this.state;
515
- const {
516
- metadata
517
- } = this;
518
- const {
519
- onCardViewClick,
520
- onDisplayImage,
521
- actions,
522
- onMouseEnter
523
- } = this;
524
- const isLazyWithOverride = izLazyOverride === undefined ? isLazy : izLazyOverride;
525
-
526
- // Card can be artificially turned visible before entering the viewport
527
- // For example, when we have the image in cache
528
- const nativeLazyLoad = isLazyWithOverride && !isCardVisible;
529
- // Force Media Image to always display img for SSR
530
- const forceSyncDisplay = !!ssr;
531
- const mediaCardCursor = getMediaCardCursor(!!useInlinePlayer, !!shouldOpenMediaViewer, status === 'error' || status === 'failed-processing', !!this.state.cardPreview, metadata.mediaType);
532
- const card = /*#__PURE__*/React.createElement(CardViewV2, {
533
- status: cardStatusOverride || status,
534
- error: error,
535
- mediaItemType: mediaItemType,
536
- metadata: metadata,
537
- cardPreview: cardPreview,
538
- alt: alt,
539
- appearance: appearance,
540
- resizeMode: resizeMode,
541
- dimensions: dimensions,
542
- actions: actions,
543
- selectable: selectable,
544
- selected: selected,
545
- onClick: withCallbacks ? onCardViewClick : undefined,
546
- onMouseEnter: withCallbacks ? onMouseEnter : undefined,
547
- disableOverlay: disableOverlay,
548
- progress: progress,
549
- onDisplayImage: withCallbacks ? onDisplayImage : undefined,
550
- innerRef: this.setRef,
551
- testId: testId,
552
- featureFlags: featureFlags,
553
- titleBoxBgColor: titleBoxBgColor,
554
- titleBoxIcon: titleBoxIcon,
555
- onImageError: withCallbacks ? this.onImageError : undefined,
556
- onImageLoad: withCallbacks ? this.onImageLoad : undefined,
557
- nativeLazyLoad: nativeLazyLoad,
558
- forceSyncDisplay: forceSyncDisplay,
559
- mediaCardCursor: mediaCardCursor,
560
- shouldHideTooltip: shouldHideTooltip
561
- });
562
- return isLazyWithOverride ? /*#__PURE__*/React.createElement(ViewportDetector, {
563
- cardEl: cardRef,
564
- onVisible: this.onCardInViewport
565
- }, card) : card;
566
- });
567
- _defineProperty(this, "storeSSRData", () => {
568
- var _this$ssrReliability$;
569
- const {
570
- ssr,
571
- identifier
572
- } = this.props;
573
- const {
574
- cardPreview: {
575
- dataURI
576
- } = {}
577
- } = this.state;
578
- return isFileIdentifier(identifier) && ssr === 'server' && /*#__PURE__*/React.createElement(StoreSSRDataScript, {
579
- identifier: identifier,
580
- dataURI: dataURI,
581
- dimensions: this.requestedDimensions,
582
- error: ((_this$ssrReliability$ = this.ssrReliability.server) === null || _this$ssrReliability$ === void 0 ? void 0 : _this$ssrReliability$.status) === 'fail' ? this.ssrReliability.server : undefined
583
- });
584
- });
585
- _defineProperty(this, "onCardInViewport", () => {
586
- this.setState({
587
- isCardVisible: true
588
- });
589
- });
590
- _defineProperty(this, "onClick", (event, analyticsEvent) => {
591
- const {
592
- onClick
593
- } = this.props;
594
- const {
595
- metadata
596
- } = this;
597
- if (onClick) {
598
- const cardEvent = {
599
- event,
600
- mediaItemDetails: metadata
601
- };
602
- onClick(cardEvent, analyticsEvent);
603
- }
604
- });
605
- _defineProperty(this, "onMouseEnter", event => {
606
- const {
607
- onMouseEnter
608
- } = this.props;
609
- const {
610
- metadata
611
- } = this;
612
- if (onMouseEnter) {
613
- const cardEvent = {
614
- event,
615
- mediaItemDetails: metadata
616
- };
617
- onMouseEnter(cardEvent);
618
- }
619
- });
620
- let _status = 'loading';
621
- let _cardPreview;
622
- let _error;
623
- const {
624
- identifier: _identifier,
625
- resizeMode: _resizeMode,
626
- ssr: _ssr,
627
- mediaClient: _mediaClient
628
- } = this.props;
629
- if (isFileIdentifier(_identifier)) {
630
- const {
631
- id
632
- } = _identifier;
633
- const fileImageMode = imageResizeModeToFileImageMode(_resizeMode);
634
- _cardPreview = getCardPreviewFromCache(id, fileImageMode);
635
- if (!_cardPreview && _ssr) {
636
- _cardPreview = this.getSSRPreview(_ssr, _identifier, _mediaClient);
637
- }
638
- } else if (isExternalImageIdentifier(_identifier)) {
639
- this.fireCommencedEvent();
640
- _status = 'loading-preview';
641
- const {
642
- dataURI
643
- } = _identifier;
644
- _cardPreview = {
645
- dataURI,
646
- orientation: 1,
647
- source: 'external'
648
- };
649
- }
650
-
651
- // If cardPreview is available from local cache or external, `isCardVisible`
652
- // should be true to avoid flickers during re-mount of the component
653
- // should not be visible for SSR preview, otherwise we'll fire the metadata fetch from
654
- // outside the viewport
655
- const _isCardVisible = !this.props.isLazy || !!_cardPreview && !isSSRPreview(_cardPreview);
656
- this.state = {
657
- status: _status,
658
- isCardVisible: _isCardVisible,
659
- isPlayingFile: false,
660
- shouldAutoplay: false,
661
- cardPreview: _cardPreview,
662
- cardRef: null,
663
- isBannedLocalPreview: false,
664
- previewDidRender: false,
665
- error: _error,
666
- wasResolvedUpfrontPreview: false,
667
- shouldUpdateStateForIdentifier: _isCardVisible && isFileIdentifier(_identifier)
668
- };
669
- }
670
- getSSRPreview(ssr, identifier, mediaClient) {
671
- var _this$ssrData, _this$ssrData2;
672
- this.ssrData = getSSRData(identifier);
673
- if ((_this$ssrData = this.ssrData) !== null && _this$ssrData !== void 0 && _this$ssrData.error) {
674
- this.ssrReliability.server = {
675
- status: 'fail',
676
- ...this.ssrData.error
677
- };
678
- }
679
- if (!((_this$ssrData2 = this.ssrData) !== null && _this$ssrData2 !== void 0 && _this$ssrData2.dataURI)) {
680
- try {
681
- return getSSRCardPreview(ssr, mediaClient, identifier.id, this.getImageURLParams(identifier), this.getMediaBlobUrlAttrs(identifier));
682
- } catch (e) {
683
- this.ssrReliability[ssr] = {
684
- status: 'fail',
685
- ...extractErrorInfo(e)
686
- };
687
- }
688
- } else {
689
- return {
690
- dataURI: this.ssrData.dataURI,
691
- source: 'ssr-data'
692
- };
693
- }
694
- }
695
- componentDidMount() {
696
- var _getDocument;
697
- this.hasBeenMounted = true;
698
- const {
699
- isCardVisible,
700
- cardPreview
701
- } = this.state;
702
- const {
703
- identifier,
704
- ssr,
705
- dimensions
706
- } = this.props;
707
- if (isCardVisible && isFileIdentifier(identifier)) {
708
- this.updateStateForIdentifier();
709
- if (!cardPreview) {
710
- this.resolveUpfrontPreview(identifier);
711
- }
712
- }
713
- if (isCardVisible && !!ssr && !!cardPreview && isFileIdentifier(identifier)) {
714
- var _this$ssrData3;
715
- if (isSSRClientPreview(cardPreview)) {
716
- // Since the SSR preview brings the token in the query params,
717
- // We need to fetch the remote preview to be able to cache it,
718
- this.setCacheSSRPreview(identifier);
719
- }
720
- if (isSSRDataPreview(cardPreview) && isBigger((_this$ssrData3 = this.ssrData) === null || _this$ssrData3 === void 0 ? void 0 : _this$ssrData3.dimensions, dimensions)) {
721
- // If dimensions from Server have changed and are bigger,
722
- // we need to refetch
723
- this.refetchSSRPreview(identifier);
724
- }
725
- }
726
- // we add a listener for each of the cards on the page
727
- // and then check if the triggered listener is from the card
728
- // that contains a div in current window.getSelection()
729
- // won't work in IE11
730
- (_getDocument = getDocument()) === null || _getDocument === void 0 ? void 0 : _getDocument.addEventListener('copy', this.fireCopiedEvent);
731
- }
732
- componentDidUpdate(prevProps, prevState) {
733
- var _this$ssrData4;
734
- const {
735
- mediaClient: prevMediaClient,
736
- identifier: prevIdentifier,
737
- dimensions: prevDimensions
738
- } = prevProps;
739
- const {
740
- isCardVisible: prevIsCardVisible,
741
- cardPreview: prevCardPreview
742
- } = prevState;
743
- const {
744
- mediaClient,
745
- identifier,
746
- dimensions,
747
- useInlinePlayer,
748
- disableOverlay,
749
- ssr
750
- } = this.props;
751
- const {
752
- isCardVisible,
753
- cardPreview,
754
- status,
755
- fileState,
756
- isBannedLocalPreview,
757
- previewDidRender,
758
- isPlayingFile,
759
- wasResolvedUpfrontPreview
760
- } = this.state;
761
- const isDiffIdentifier = isDifferentIdentifier(prevIdentifier, identifier);
762
- /**
763
- * Variable turnedVisible should only be true when media card
764
- * was invisible in the previous state and is visible in the current one
765
- *
766
- * prevIsCardVisible | isCardVisible | turnedVisible
767
- * ----------------------------------------------------
768
- * false | false | false
769
- * false | true | true
770
- * true | true | false
771
- * true | false | false (unreachable case)
772
- * ----------------------------------------------------
773
- */
774
- const turnedVisible = !prevIsCardVisible && isCardVisible;
775
- const hadSSRCardPreview = !!prevCardPreview && isSSRClientPreview(prevCardPreview) && !cardPreview;
776
- const isNewMediaClient = prevMediaClient !== mediaClient;
777
- this.updateFileStateFlag(fileState);
778
- if (isExternalImageIdentifier(identifier) && isDiffIdentifier) {
779
- this.fireCommencedEvent();
780
- const {
781
- dataURI
782
- } = identifier;
783
- this.setState({
784
- status: 'loading-preview',
785
- cardPreview: {
786
- dataURI,
787
- orientation: 1,
788
- source: 'external'
789
- },
790
- isCardVisible: true
791
- });
792
- }
793
- if (cardPreview && turnedVisible && isFileIdentifier(identifier) && isSSRDataPreview(cardPreview) && isBigger((_this$ssrData4 = this.ssrData) === null || _this$ssrData4 === void 0 ? void 0 : _this$ssrData4.dimensions, dimensions)) {
794
- // If dimensions from Server have changed and are bigger,
795
- // we need to refetch
796
- this.refetchSSRPreview(identifier);
797
- }
798
- if (isFileIdentifier(identifier) && (turnedVisible || !!this.subscription && (isNewMediaClient || isDiffIdentifier))) {
799
- this.updateStateForIdentifier();
800
- }
801
- if (this.state.status !== prevState.status) {
802
- this.fireOperationalEvent();
803
- if (this.state.status === 'complete' || this.fileAttributes.fileMediatype === 'video' && !!cardPreview && this.state.status === 'processing') {
804
- this.fireScreenEvent();
805
- }
806
- }
807
- if (isFileIdentifier(identifier) && (turnedVisible || ssr === 'client' && hadSSRCardPreview) && !cardPreview && !wasResolvedUpfrontPreview) {
808
- // This is a one-off call, only meant to happen once in the component's lifecycle. Mainly when either:
809
- // - turnedVisible = true
810
- // - ssr = client and has no preview (the dataURI failed to load in the previous state, most likely because of an initial auth issue)
811
- this.resolveUpfrontPreview(identifier);
812
- } else if (isFileIdentifier(identifier) && fileState && shouldResolvePreview({
813
- status,
814
- fileState,
815
- prevDimensions,
816
- dimensions,
817
- hasCardPreview: !!cardPreview,
818
- isBannedLocalPreview,
819
- wasResolvedUpfrontPreview
820
- })) {
821
- this.resolvePreview(identifier, fileState);
822
- }
823
- if (turnedVisible && this.props.ssr && !!cardPreview && isSSRClientPreview(cardPreview) && isFileIdentifier(identifier)) {
824
- // Since the SSR preview brings the token in the query params,
825
- // We need to fetch the remote preview to be able to cache it,
826
- this.setCacheSSRPreview(identifier);
827
- }
828
- if (previewDidRender &&
829
- // We should't complete if status is uploading
830
- ['loading-preview', 'processing'].includes(status)) {
831
- this.safeSetState({
832
- status: 'complete',
833
- shouldUpdateStateForIdentifier: false
834
- });
835
- if (this.hasBeenMounted) {
836
- // TODO MEX-788: add test for "do not remove the card preview when unsubscribing".
837
- this.setState({
838
- isBannedLocalPreview: false
839
- });
840
- }
841
- }
842
- const isVideo = this.fileAttributes.fileMediatype === 'video';
843
- const {
844
- mimeType
845
- } = getFileDetails(identifier, fileState);
846
- const isVideoPlayable = videoIsPlayable(isBannedLocalPreview, fileState, mimeType);
847
- if (isVideo && !isPlayingFile && disableOverlay && useInlinePlayer && isVideoPlayable) {
848
- this.setState({
849
- isPlayingFile: true
850
- });
851
- }
852
- }
853
- componentWillUnmount() {
854
- var _getDocument2;
855
- this.fireAbortedEvent();
856
- this.hasBeenMounted = false;
857
- (_getDocument2 = getDocument()) === null || _getDocument2 === void 0 ? void 0 : _getDocument2.removeEventListener('copy', this.fireCopiedEvent);
858
- }
859
- updateStateForIdentifier() {
860
- this.fireCommencedEvent();
861
- this.setState({
862
- shouldUpdateStateForIdentifier: true
863
- });
864
- }
865
- updateFileStateFlag(fileState) {
866
- if (!fileState) {
867
- return;
868
- }
869
- const {
870
- status
871
- } = fileState;
872
- if (status === 'processing') {
873
- this.fileStateFlags.wasStatusProcessing = true;
874
- } else if (status === 'uploading') {
875
- this.fileStateFlags.wasStatusUploading = true;
876
- }
877
- }
878
- get requestedDimensions() {
879
- const {
880
- dimensions
881
- } = this.props;
882
- const {
883
- cardRef: element
884
- } = this.state || {};
885
- return getRequestedDimensions({
886
- dimensions,
887
- element
888
- });
889
- }
890
- get metadata() {
891
- var _this$state;
892
- return getFileDetails(this.props.identifier, (_this$state = this.state) === null || _this$state === void 0 ? void 0 : _this$state.fileState);
893
- }
894
- get fileAttributes() {
895
- var _this$state2, _this$state2$fileStat;
896
- return getFileAttributes(this.metadata, (_this$state2 = this.state) === null || _this$state2 === void 0 ? void 0 : (_this$state2$fileStat = _this$state2.fileState) === null || _this$state2$fileStat === void 0 ? void 0 : _this$state2$fileStat.status);
897
- }
898
- fireOperationalEvent() {
899
- const {
900
- status,
901
- error,
902
- fileState
903
- } = this.state;
904
- const {
905
- createAnalyticsEvent
906
- } = this.props;
907
- createAnalyticsEvent && fireOperationalEvent(createAnalyticsEvent, status, this.fileAttributes, this.getPerformanceAttributes(), this.ssrReliability, error, this.traceContext, fileState === null || fileState === void 0 ? void 0 : fileState.metadataTraceContext);
908
- completeUfoExperience(this.internalOccurrenceKey, status, this.fileAttributes, this.fileStateFlags, this.ssrReliability, error);
909
- }
910
- fireCommencedEvent() {
911
- this.timeElapsedTillCommenced = performance.now();
912
- const {
913
- createAnalyticsEvent
914
- } = this.props;
915
- createAnalyticsEvent && fireCommencedEvent(createAnalyticsEvent, this.fileAttributes, {
916
- overall: {
917
- durationSincePageStart: this.timeElapsedTillCommenced
918
- }
919
- }, this.traceContext);
920
- startUfoExperience(this.internalOccurrenceKey);
921
- }
922
- fireAbortedEvent() {
923
- const {
924
- fileAttributes,
925
- fileStateFlags,
926
- ssrReliability
927
- } = this;
928
- // UFO won't abort if it's already in a final state (succeeded, failed, aborted, etc)
929
- abortUfoExperience(this.internalOccurrenceKey, {
930
- fileAttributes,
931
- fileStateFlags,
932
- ssrReliability
933
- });
934
- }
935
- get actions() {
936
- const {
937
- actions = [],
938
- identifier,
939
- shouldEnableDownloadButton
940
- } = this.props;
941
- const {
942
- status
943
- } = this.state;
944
- const {
945
- metadata
946
- } = this;
947
- if (isFileIdentifier(identifier) && (status === 'failed-processing' || shouldEnableDownloadButton)) {
948
- const downloadAction = {
949
- label: 'Download',
950
- icon: /*#__PURE__*/React.createElement(DownloadIcon, {
951
- label: "Download"
952
- }),
953
- handler: () => this.props.mediaClient.file.downloadBinary(identifier.id, metadata.name, identifier.collectionName)
954
- };
955
- return [downloadAction, ...actions];
956
- } else {
957
- return actions;
958
- }
959
- }
960
- render() {
961
- const {
962
- isPlayingFile,
963
- mediaViewerSelectedItem,
964
- shouldUpdateStateForIdentifier
965
- } = this.state;
966
- const innerContent = /*#__PURE__*/React.createElement(React.Fragment, null, isPlayingFile ? this.renderInlinePlayer() : this.renderCard(), mediaViewerSelectedItem ? this.renderMediaViewer() : null, this.storeSSRData());
967
- let wrappedContent = innerContent;
968
- if (shouldUpdateStateForIdentifier) {
969
- const {
970
- id,
971
- collectionName,
972
- occurrenceKey
973
- } = this.props.identifier;
974
- wrappedContent = /*#__PURE__*/React.createElement(FileStateListener, {
975
- id: id,
976
- onChange: this.subscribeFileState,
977
- collectionName: collectionName,
978
- occurrenceKey: occurrenceKey
979
- }, innerContent);
980
- }
981
- return this.props.intl ? wrappedContent : /*#__PURE__*/React.createElement(IntlProvider, {
982
- locale: "en"
983
- }, wrappedContent);
984
- }
985
- }
986
- _defineProperty(CardV2Base, "defaultProps", {
987
- appearance: 'auto',
988
- resizeMode: 'crop',
989
- isLazy: true,
990
- disableOverlay: false,
991
- // Media Feature Flag defaults are defined in @atlaskit/media-common
992
- featureFlags: {}
993
- });
994
- const FileStateListener = ({
995
- children,
996
- onChange,
997
- id,
998
- collectionName,
999
- occurrenceKey
10
+ const packageVersion = "77.4.0";
11
+ export const CardV2Base = ({
12
+ identifier,
13
+ ...otherProps
1000
14
  }) => {
1001
- const {
1002
- fileState
1003
- } = useFileState(id, {
1004
- collectionName,
1005
- occurrenceKey
1006
- });
1007
- useEffect(() => {
1008
- if (fileState) {
1009
- onChange(fileState);
1010
- }
1011
- }, [fileState, onChange]);
1012
- return children;
1013
- };
1014
-
1015
- /**
1016
- * We require this wrapper in order to refresh media card state when the identifier is updated (via a key)
1017
- * TODO: remove the key when the cardV2 is no longer required
1018
- */
1019
- const CardWithKey = props => {
1020
- const {
1021
- identifier
1022
- } = props;
1023
- const key = isFileIdentifier(identifier) ? identifier.id : identifier.dataURI;
1024
- return /*#__PURE__*/React.createElement(CardV2Base, _extends({}, props, {
1025
- key: key
15
+ const innerContent = isFileIdentifier(identifier) ? /*#__PURE__*/React.createElement(FileCard, _extends({}, otherProps, {
16
+ identifier: identifier
17
+ })) : /*#__PURE__*/React.createElement(ExternalImageCard, _extends({}, otherProps, {
18
+ identifier: identifier
1026
19
  }));
20
+ return otherProps.intl ? innerContent : /*#__PURE__*/React.createElement(IntlProvider, {
21
+ locale: "en"
22
+ }, innerContent);
1027
23
  };
1028
24
  export const CardV2 = withMediaAnalyticsContext({
1029
25
  packageVersion,
1030
26
  packageName,
1031
27
  componentName: 'mediaCard',
1032
28
  component: 'mediaCard'
1033
- })(withAnalyticsEvents()(injectIntl(CardWithKey, {
29
+ })(withAnalyticsEvents()(injectIntl(CardV2Base, {
1034
30
  enforceContext: false
1035
31
  })));