@atlaskit/media-file-preview 0.16.2 → 0.16.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @atlaskit/media-file-preview
2
2
 
3
+ ## 0.16.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [`fa50dabb4be8f`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/fa50dabb4be8f) -
8
+ Retrieve clientId synchronously during Media SSR blob URL construction.
9
+ - Updated dependencies
10
+
3
11
  ## 0.16.2
4
12
 
5
13
  ### Patch Changes
@@ -6,9 +6,11 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.isSSRPreview = exports.isSSRDataPreview = exports.isSSRClientPreview = exports.isRemotePreview = exports.isLocalPreview = exports.getSSRPreview = exports.getAndCacheRemotePreview = exports.getAndCacheLocalPreview = void 0;
8
8
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
10
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
10
11
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
12
  var _mediaClient = require("@atlaskit/media-client");
13
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
12
14
  var _errors = require("../errors");
13
15
  var _cache = require("./cache");
14
16
  var _helpers = require("./helpers");
@@ -41,15 +43,41 @@ var getDataUri = function getDataUri(mediaClient, id, params, mediaBlobUrlAttrs)
41
43
  var rawDataURI = mediaClient.getImageUrlSync(id, params);
42
44
  return mediaBlobUrlAttrs ? (0, _mediaClient.addFileAttrsToUrl)(rawDataURI, mediaBlobUrlAttrs) : rawDataURI;
43
45
  };
46
+
47
+ /**
48
+ * Merges a clientId into mediaBlobUrlAttrs for cross-client copy support.
49
+ * Returns the original attrs unchanged if clientId is not available or the feature flag is off.
50
+ */
51
+ var mergeClientIdIntoAttrs = function mergeClientIdIntoAttrs(clientId, id, mediaBlobUrlAttrs, collectionName) {
52
+ if (!clientId) {
53
+ return mediaBlobUrlAttrs;
54
+ }
55
+ if (mediaBlobUrlAttrs) {
56
+ return _objectSpread(_objectSpread({}, mediaBlobUrlAttrs), {}, {
57
+ clientId: clientId
58
+ });
59
+ }
60
+
61
+ // Construct minimal attrs when none provided
62
+ return {
63
+ id: id,
64
+ clientId: clientId,
65
+ contextId: collectionName || '',
66
+ collection: collectionName
67
+ };
68
+ };
44
69
  var getSSRPreview = exports.getSSRPreview = function getSSRPreview(ssr, mediaClient, id, params, mediaBlobUrlAttrs) {
45
70
  try {
46
- var dataURI = getDataUri(mediaClient, id, params, mediaBlobUrlAttrs);
71
+ // Synchronously extract clientId from initialAuth and merge into blob URL attrs
72
+ var clientId = (0, _platformFeatureFlags.fg)('platform_media_cross_client_copy_with_auth') ? mediaClient.getClientIdSync() : undefined;
73
+ var attrsWithClientId = mergeClientIdIntoAttrs(clientId, id, mediaBlobUrlAttrs, params.collection);
74
+ var dataURI = getDataUri(mediaClient, id, params, attrsWithClientId);
47
75
  var srcSet = "".concat(dataURI, " 1x");
48
76
  if (params.width) {
49
77
  var doubleDataURI = getDataUri(mediaClient, id, _objectSpread(_objectSpread({}, params), {}, {
50
78
  width: params.width * 2,
51
79
  height: params.height && params.height * 2
52
- }), mediaBlobUrlAttrs);
80
+ }), attrsWithClientId);
53
81
  // We want to embed some meta context into dataURI for Copy/Paste to work.
54
82
  srcSet += ", ".concat(doubleDataURI, " 2x");
55
83
  }
@@ -83,49 +111,100 @@ var isSSRPreview = exports.isSSRPreview = function isSSRPreview(preview) {
83
111
  var ssrClientSources = ['ssr-client', 'ssr-server', 'ssr-data'];
84
112
  return ssrClientSources.includes(preview.source);
85
113
  };
86
- var getAndCacheRemotePreview = exports.getAndCacheRemotePreview = /*#__PURE__*/function () {
87
- var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(mediaClient, id, dimensions, params, mediaBlobUrlAttrs, traceContext) {
88
- var remotePreview;
114
+
115
+ /**
116
+ * Resolves clientId (sync first, async fallback) and enriches mediaBlobUrlAttrs
117
+ * with it for cross-client copy support.
118
+ */
119
+ var enrichAttrsWithClientId = /*#__PURE__*/function () {
120
+ var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(mediaClient, id, mediaBlobUrlAttrs, collectionName) {
121
+ var clientId;
89
122
  return _regenerator.default.wrap(function _callee$(_context) {
90
123
  while (1) switch (_context.prev = _context.next) {
91
124
  case 0:
92
- _context.next = 2;
93
- return (0, _helpers.getRemotePreview)(mediaClient, id, params, traceContext);
125
+ if ((0, _platformFeatureFlags.fg)('platform_media_cross_client_copy_with_auth')) {
126
+ _context.next = 2;
127
+ break;
128
+ }
129
+ return _context.abrupt("return", mediaBlobUrlAttrs);
94
130
  case 2:
95
- remotePreview = _context.sent;
96
- return _context.abrupt("return", extendAndCachePreview(id, params.mode, _objectSpread(_objectSpread({}, remotePreview), {}, {
97
- dimensions: dimensions
98
- }), mediaBlobUrlAttrs));
99
- case 4:
131
+ // Try sync first, then async fallback
132
+ clientId = mediaClient.getClientIdSync();
133
+ if (clientId) {
134
+ _context.next = 12;
135
+ break;
136
+ }
137
+ _context.prev = 4;
138
+ _context.next = 7;
139
+ return mediaClient.getClientId(collectionName);
140
+ case 7:
141
+ clientId = _context.sent;
142
+ _context.next = 12;
143
+ break;
144
+ case 10:
145
+ _context.prev = 10;
146
+ _context.t0 = _context["catch"](4);
147
+ case 12:
148
+ return _context.abrupt("return", mergeClientIdIntoAttrs(clientId, id, mediaBlobUrlAttrs, collectionName));
149
+ case 13:
100
150
  case "end":
101
151
  return _context.stop();
102
152
  }
103
- }, _callee);
153
+ }, _callee, null, [[4, 10]]);
104
154
  }));
105
- return function getAndCacheRemotePreview(_x, _x2, _x3, _x4, _x5, _x6) {
155
+ return function enrichAttrsWithClientId(_x, _x2, _x3, _x4) {
106
156
  return _ref.apply(this, arguments);
107
157
  };
108
158
  }();
109
- var getAndCacheLocalPreview = exports.getAndCacheLocalPreview = /*#__PURE__*/function () {
110
- var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(id, filePreview, dimensions, mode, mediaBlobUrlAttrs) {
111
- var localPreview;
159
+ var getAndCacheRemotePreview = exports.getAndCacheRemotePreview = /*#__PURE__*/function () {
160
+ var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(mediaClient, id, dimensions, params, mediaBlobUrlAttrs, traceContext) {
161
+ var _yield$Promise$all, _yield$Promise$all2, remotePreview, enrichedAttrs;
112
162
  return _regenerator.default.wrap(function _callee2$(_context2) {
113
163
  while (1) switch (_context2.prev = _context2.next) {
114
164
  case 0:
115
165
  _context2.next = 2;
116
- return (0, _helpers.getLocalPreview)(filePreview);
166
+ return Promise.all([(0, _helpers.getRemotePreview)(mediaClient, id, params, traceContext), enrichAttrsWithClientId(mediaClient, id, mediaBlobUrlAttrs, params.collection)]);
117
167
  case 2:
118
- localPreview = _context2.sent;
119
- return _context2.abrupt("return", extendAndCachePreview(id, mode, _objectSpread(_objectSpread({}, localPreview), {}, {
168
+ _yield$Promise$all = _context2.sent;
169
+ _yield$Promise$all2 = (0, _slicedToArray2.default)(_yield$Promise$all, 2);
170
+ remotePreview = _yield$Promise$all2[0];
171
+ enrichedAttrs = _yield$Promise$all2[1];
172
+ return _context2.abrupt("return", extendAndCachePreview(id, params.mode, _objectSpread(_objectSpread({}, remotePreview), {}, {
120
173
  dimensions: dimensions
121
- }), mediaBlobUrlAttrs));
122
- case 4:
174
+ }), enrichedAttrs));
175
+ case 7:
123
176
  case "end":
124
177
  return _context2.stop();
125
178
  }
126
179
  }, _callee2);
127
180
  }));
128
- return function getAndCacheLocalPreview(_x7, _x8, _x9, _x0, _x1) {
181
+ return function getAndCacheRemotePreview(_x5, _x6, _x7, _x8, _x9, _x0) {
129
182
  return _ref2.apply(this, arguments);
130
183
  };
184
+ }();
185
+ var getAndCacheLocalPreview = exports.getAndCacheLocalPreview = /*#__PURE__*/function () {
186
+ var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(mediaClient, id, filePreview, dimensions, mode, mediaBlobUrlAttrs, collectionName) {
187
+ var _yield$Promise$all3, _yield$Promise$all4, localPreview, enrichedAttrs;
188
+ return _regenerator.default.wrap(function _callee3$(_context3) {
189
+ while (1) switch (_context3.prev = _context3.next) {
190
+ case 0:
191
+ _context3.next = 2;
192
+ return Promise.all([(0, _helpers.getLocalPreview)(filePreview), enrichAttrsWithClientId(mediaClient, id, mediaBlobUrlAttrs, collectionName)]);
193
+ case 2:
194
+ _yield$Promise$all3 = _context3.sent;
195
+ _yield$Promise$all4 = (0, _slicedToArray2.default)(_yield$Promise$all3, 2);
196
+ localPreview = _yield$Promise$all4[0];
197
+ enrichedAttrs = _yield$Promise$all4[1];
198
+ return _context3.abrupt("return", extendAndCachePreview(id, mode, _objectSpread(_objectSpread({}, localPreview), {}, {
199
+ dimensions: dimensions
200
+ }), enrichedAttrs));
201
+ case 7:
202
+ case "end":
203
+ return _context3.stop();
204
+ }
205
+ }, _callee3);
206
+ }));
207
+ return function getAndCacheLocalPreview(_x1, _x10, _x11, _x12, _x13, _x14, _x15) {
208
+ return _ref3.apply(this, arguments);
209
+ };
131
210
  }();
@@ -53,54 +53,20 @@ var useFilePreview = exports.useFilePreview = function useFilePreview(_ref) {
53
53
  setStatus = _useState2[1];
54
54
  var _useState3 = (0, _react.useState)(),
55
55
  _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
56
- clientId = _useState4[0],
57
- setClientId = _useState4[1];
58
-
59
- // Fetch clientId on mount for cross-client copy
60
- (0, _react.useEffect)(function () {
61
- if ((0, _platformFeatureFlags.fg)('platform_media_cross_client_copy_with_auth')) {
62
- mediaClient.getClientId(identifier.collectionName).then(setClientId).catch(function () {
63
- // ClientId is optional, silently fail
64
- });
65
- }
66
- }, [mediaClient, identifier.collectionName]);
67
-
68
- // Merge clientId into mediaBlobUrlAttrs for embedding in blob URLs
69
- // If mediaBlobUrlAttrs is not provided, construct minimal attrs from identifier
70
- var mediaBlobUrlAttrsWithClientId = (0, _react.useMemo)(function () {
71
- if (!(0, _platformFeatureFlags.fg)('platform_media_cross_client_copy_with_auth') || !clientId) {
72
- return mediaBlobUrlAttrs;
73
- }
74
- if (mediaBlobUrlAttrs) {
75
- return _objectSpread(_objectSpread({}, mediaBlobUrlAttrs), {}, {
76
- clientId: clientId
77
- });
78
- }
79
-
80
- // Construct minimal attrs when none provided (e.g., MediaImage)
81
- return {
82
- id: identifier.id,
83
- clientId: clientId,
84
- contextId: identifier.collectionName || '',
85
- collection: identifier.collectionName
86
- };
87
- }, [mediaBlobUrlAttrs, clientId, identifier.id, identifier.collectionName]);
56
+ error = _useState4[0],
57
+ setError = _useState4[1];
88
58
  var _useState5 = (0, _react.useState)(),
89
59
  _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
90
- error = _useState6[0],
91
- setError = _useState6[1];
92
- var _useState7 = (0, _react.useState)(),
60
+ nonCriticalError = _useState6[0],
61
+ setNonCriticalError = _useState6[1];
62
+ var _useState7 = (0, _react.useState)(false),
93
63
  _useState8 = (0, _slicedToArray2.default)(_useState7, 2),
94
- nonCriticalError = _useState8[0],
95
- setNonCriticalError = _useState8[1];
96
- var _useState9 = (0, _react.useState)(false),
64
+ isBannedLocalPreview = _useState8[0],
65
+ setIsBannedLocalPreview = _useState8[1];
66
+ var _useState9 = (0, _react.useState)('not-resolved'),
97
67
  _useState0 = (0, _slicedToArray2.default)(_useState9, 2),
98
- isBannedLocalPreview = _useState0[0],
99
- setIsBannedLocalPreview = _useState0[1];
100
- var _useState1 = (0, _react.useState)('not-resolved'),
101
- _useState10 = (0, _slicedToArray2.default)(_useState1, 2),
102
- upfrontPreviewStatus = _useState10[0],
103
- setUpfrontPreviewStatus = _useState10[1];
68
+ upfrontPreviewStatus = _useState0[0],
69
+ setUpfrontPreviewStatus = _useState0[1];
104
70
  var ssrReliabilityRef = (0, _react.useRef)({
105
71
  server: {
106
72
  status: 'unknown'
@@ -110,10 +76,10 @@ var useFilePreview = exports.useFilePreview = function useFilePreview(_ref) {
110
76
  }
111
77
  });
112
78
  var ufoContext = (0, _interactionContext.useInteractionContext)();
113
- var _useState11 = (0, _react.useState)(false),
114
- _useState12 = (0, _slicedToArray2.default)(_useState11, 2),
115
- isLoading = _useState12[0],
116
- setIsLoading = _useState12[1];
79
+ var _useState1 = (0, _react.useState)(false),
80
+ _useState10 = (0, _slicedToArray2.default)(_useState1, 2),
81
+ isLoading = _useState10[0],
82
+ setIsLoading = _useState10[1];
117
83
  (0, _react.useLayoutEffect)(function () {
118
84
  if (isLoading && (0, _platformFeatureFlags.fg)('platform_close_image_blindspot_2')) {
119
85
  return ufoContext === null || ufoContext === void 0 ? void 0 : ufoContext.hold('img-loading');
@@ -156,7 +122,7 @@ var useFilePreview = exports.useFilePreview = function useFilePreview(_ref) {
156
122
  // where no SSR occurred, so we should skip SSR preview generation entirely.
157
123
  if (ssr === 'server' || ssrData) {
158
124
  try {
159
- return (0, _getPreview.getSSRPreview)(ssr, mediaClient, identifier.id, imageURLParams, mediaBlobUrlAttrsWithClientId);
125
+ return (0, _getPreview.getSSRPreview)(ssr, mediaClient, identifier.id, imageURLParams, mediaBlobUrlAttrs);
160
126
  } catch (e) {
161
127
  ssrReliabilityRef.current = _objectSpread(_objectSpread({}, ssrReliabilityRef.current), {}, (0, _defineProperty2.default)({}, ssr, _objectSpread({
162
128
  status: 'fail'
@@ -178,10 +144,10 @@ var useFilePreview = exports.useFilePreview = function useFilePreview(_ref) {
178
144
  }
179
145
  }
180
146
  };
181
- var _useState13 = (0, _react.useState)(previewInitializer),
182
- _useState14 = (0, _slicedToArray2.default)(_useState13, 2),
183
- preview = _useState14[0],
184
- setPreview = _useState14[1];
147
+ var _useState11 = (0, _react.useState)(previewInitializer),
148
+ _useState12 = (0, _slicedToArray2.default)(_useState11, 2),
149
+ preview = _useState12[0],
150
+ setPreview = _useState12[1];
185
151
 
186
152
  //----------------------------------------------------------------
187
153
  // FILE STATE
@@ -248,29 +214,11 @@ var useFilePreview = exports.useFilePreview = function useFilePreview(_ref) {
248
214
  }
249
215
  }, [preview, identifier, resizeMode]);
250
216
 
251
- //----------------------------------------------------------------
252
- // Update preview with clientId when it becomes available
253
- //----------------------------------------------------------------
254
- var previewUpdatedWithClientIdRef = (0, _react.useRef)(null);
255
- (0, _react.useEffect)(function () {
256
- // Only update if we have a preview, clientId is available, URL doesn't already have clientId, and feature flag is enabled.
257
- // Also skip if we've already updated this preview (prevents re-render loops)
258
- if (preview && clientId && mediaBlobUrlAttrsWithClientId && !preview.dataURI.includes('clientId=') && previewUpdatedWithClientIdRef.current !== identifier.id && (0, _platformFeatureFlags.fg)('platform_media_cross_client_copy_with_auth')) {
259
- // Mark this preview as updated
260
- previewUpdatedWithClientIdRef.current = identifier.id;
261
- var baseUrl = preview.dataURI.split('#')[0]; // Remove any existing hash
262
- var updatedDataURI = (0, _mediaClient.addFileAttrsToUrl)(baseUrl, mediaBlobUrlAttrsWithClientId);
263
- setPreview(_objectSpread(_objectSpread({}, preview), {}, {
264
- dataURI: updatedDataURI
265
- }));
266
- }
267
- }, [clientId, mediaBlobUrlAttrsWithClientId, preview, identifier.id]);
268
-
269
217
  //----------------------------------------------------------------
270
218
  // Preview Fetch Helper
271
219
  //----------------------------------------------------------------
272
220
  var getAndCacheRemotePreviewRef = (0, _helpers.useCurrentValueRef)(function () {
273
- return (0, _getPreview.getAndCacheRemotePreview)(mediaClient, identifier.id, requestDimensions || {}, imageURLParams, mediaBlobUrlAttrsWithClientId, traceContext);
221
+ return (0, _getPreview.getAndCacheRemotePreview)(mediaClient, identifier.id, requestDimensions || {}, imageURLParams, mediaBlobUrlAttrs, traceContext);
274
222
  });
275
223
 
276
224
  //----------------------------------------------------------------
@@ -305,7 +253,7 @@ var useFilePreview = exports.useFilePreview = function useFilePreview(_ref) {
305
253
  // Cache, Local & Remote Preview
306
254
  //----------------------------------------------------------------
307
255
 
308
- var mediaBlobUrlAttrsRef = (0, _helpers.useCurrentValueRef)(mediaBlobUrlAttrsWithClientId);
256
+ var mediaBlobUrlAttrsRef = (0, _helpers.useCurrentValueRef)(mediaBlobUrlAttrs);
309
257
  (0, _react.useEffect)(function () {
310
258
  var cachedPreview = _getPreview.mediaFilePreviewCache.get(identifier.id, resizeMode);
311
259
 
@@ -319,7 +267,7 @@ var useFilePreview = exports.useFilePreview = function useFilePreview(_ref) {
319
267
  // For example, SVGs are mime type NOT supported by browser but media type supported by Media Card (image)
320
268
  // Then, local Preview NOT available
321
269
  setIsLoading(true);
322
- (0, _getPreview.getAndCacheLocalPreview)(identifier.id, localBinary, requestDimensions || {}, resizeMode, mediaBlobUrlAttrsRef.current).then(setPreview).catch(function (e) {
270
+ (0, _getPreview.getAndCacheLocalPreview)(mediaClient, identifier.id, localBinary, requestDimensions || {}, resizeMode, mediaBlobUrlAttrsRef.current, identifier.collectionName).then(setPreview).catch(function (e) {
323
271
  setIsBannedLocalPreview(true);
324
272
  // CXP-2723 TODO: We might have to wrap this error in MediaCardError
325
273
  setNonCriticalError(e);
@@ -350,7 +298,7 @@ var useFilePreview = exports.useFilePreview = function useFilePreview(_ref) {
350
298
  setIsLoading(false);
351
299
  });
352
300
  }
353
- }, [error, nonCriticalError, getAndCacheRemotePreviewRef, identifier.id, resizeMode, isBannedLocalPreview, mediaBlobUrlAttrsRef, preview, requestDimensions, skipRemote, isBackendPreviewReady, localBinary, mediaType, mimeType, upfrontPreviewStatus, dimensions]);
301
+ }, [error, nonCriticalError, getAndCacheRemotePreviewRef, identifier.id, identifier.collectionName, resizeMode, isBannedLocalPreview, mediaBlobUrlAttrsRef, mediaClient, preview, requestDimensions, skipRemote, isBackendPreviewReady, localBinary, mediaType, mimeType, upfrontPreviewStatus, dimensions]);
354
302
 
355
303
  //----------------------------------------------------------------
356
304
  // RETURN
@@ -467,7 +415,6 @@ var useFilePreview = exports.useFilePreview = function useFilePreview(_ref) {
467
415
  onImageError: onImageError,
468
416
  onImageLoad: onImageLoad,
469
417
  getSsrScriptProps: getSsrScriptProps,
470
- copyNodeRef: copyNodeRef,
471
- clientId: clientId
418
+ copyNodeRef: copyNodeRef
472
419
  };
473
420
  };
@@ -1,4 +1,5 @@
1
1
  import { addFileAttrsToUrl } from '@atlaskit/media-client';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
2
3
  import { SsrPreviewError } from '../errors';
3
4
  import { mediaFilePreviewCache } from './cache';
4
5
  import { getLocalPreview, getRemotePreview } from './helpers';
@@ -31,16 +32,43 @@ const getDataUri = (mediaClient, id, params, mediaBlobUrlAttrs) => {
31
32
  const rawDataURI = mediaClient.getImageUrlSync(id, params);
32
33
  return mediaBlobUrlAttrs ? addFileAttrsToUrl(rawDataURI, mediaBlobUrlAttrs) : rawDataURI;
33
34
  };
35
+
36
+ /**
37
+ * Merges a clientId into mediaBlobUrlAttrs for cross-client copy support.
38
+ * Returns the original attrs unchanged if clientId is not available or the feature flag is off.
39
+ */
40
+ const mergeClientIdIntoAttrs = (clientId, id, mediaBlobUrlAttrs, collectionName) => {
41
+ if (!clientId) {
42
+ return mediaBlobUrlAttrs;
43
+ }
44
+ if (mediaBlobUrlAttrs) {
45
+ return {
46
+ ...mediaBlobUrlAttrs,
47
+ clientId
48
+ };
49
+ }
50
+
51
+ // Construct minimal attrs when none provided
52
+ return {
53
+ id,
54
+ clientId,
55
+ contextId: collectionName || '',
56
+ collection: collectionName
57
+ };
58
+ };
34
59
  export const getSSRPreview = (ssr, mediaClient, id, params, mediaBlobUrlAttrs) => {
35
60
  try {
36
- const dataURI = getDataUri(mediaClient, id, params, mediaBlobUrlAttrs);
61
+ // Synchronously extract clientId from initialAuth and merge into blob URL attrs
62
+ const clientId = fg('platform_media_cross_client_copy_with_auth') ? mediaClient.getClientIdSync() : undefined;
63
+ const attrsWithClientId = mergeClientIdIntoAttrs(clientId, id, mediaBlobUrlAttrs, params.collection);
64
+ const dataURI = getDataUri(mediaClient, id, params, attrsWithClientId);
37
65
  let srcSet = `${dataURI} 1x`;
38
66
  if (params.width) {
39
67
  const doubleDataURI = getDataUri(mediaClient, id, {
40
68
  ...params,
41
69
  width: params.width * 2,
42
70
  height: params.height && params.height * 2
43
- }, mediaBlobUrlAttrs);
71
+ }, attrsWithClientId);
44
72
  // We want to embed some meta context into dataURI for Copy/Paste to work.
45
73
  srcSet += `, ${doubleDataURI} 2x`;
46
74
  }
@@ -70,17 +98,38 @@ export const isSSRPreview = preview => {
70
98
  const ssrClientSources = ['ssr-client', 'ssr-server', 'ssr-data'];
71
99
  return ssrClientSources.includes(preview.source);
72
100
  };
101
+
102
+ /**
103
+ * Resolves clientId (sync first, async fallback) and enriches mediaBlobUrlAttrs
104
+ * with it for cross-client copy support.
105
+ */
106
+ const enrichAttrsWithClientId = async (mediaClient, id, mediaBlobUrlAttrs, collectionName) => {
107
+ if (!fg('platform_media_cross_client_copy_with_auth')) {
108
+ return mediaBlobUrlAttrs;
109
+ }
110
+
111
+ // Try sync first, then async fallback
112
+ let clientId = mediaClient.getClientIdSync();
113
+ if (!clientId) {
114
+ try {
115
+ clientId = await mediaClient.getClientId(collectionName);
116
+ } catch {
117
+ // clientId is optional, silently fail
118
+ }
119
+ }
120
+ return mergeClientIdIntoAttrs(clientId, id, mediaBlobUrlAttrs, collectionName);
121
+ };
73
122
  export const getAndCacheRemotePreview = async (mediaClient, id, dimensions, params, mediaBlobUrlAttrs, traceContext) => {
74
- const remotePreview = await getRemotePreview(mediaClient, id, params, traceContext);
123
+ const [remotePreview, enrichedAttrs] = await Promise.all([getRemotePreview(mediaClient, id, params, traceContext), enrichAttrsWithClientId(mediaClient, id, mediaBlobUrlAttrs, params.collection)]);
75
124
  return extendAndCachePreview(id, params.mode, {
76
125
  ...remotePreview,
77
126
  dimensions
78
- }, mediaBlobUrlAttrs);
127
+ }, enrichedAttrs);
79
128
  };
80
- export const getAndCacheLocalPreview = async (id, filePreview, dimensions, mode, mediaBlobUrlAttrs) => {
81
- const localPreview = await getLocalPreview(filePreview);
129
+ export const getAndCacheLocalPreview = async (mediaClient, id, filePreview, dimensions, mode, mediaBlobUrlAttrs, collectionName) => {
130
+ const [localPreview, enrichedAttrs] = await Promise.all([getLocalPreview(filePreview), enrichAttrsWithClientId(mediaClient, id, mediaBlobUrlAttrs, collectionName)]);
82
131
  return extendAndCachePreview(id, mode, {
83
132
  ...localPreview,
84
133
  dimensions
85
- }, mediaBlobUrlAttrs);
134
+ }, enrichedAttrs);
86
135
  };
@@ -1,5 +1,5 @@
1
1
  import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
2
- import { addFileAttrsToUrl, isImageRepresentationReady, toCommonMediaClientError } from '@atlaskit/media-client';
2
+ import { isImageRepresentationReady, toCommonMediaClientError } from '@atlaskit/media-client';
3
3
  import { useCopyIntent, useFileState, useMediaClient } from '@atlaskit/media-client-react';
4
4
  import { isMimeTypeSupportedByBrowser } from '@atlaskit/media-common';
5
5
  import { fg } from '@atlaskit/platform-feature-flags';
@@ -36,38 +36,6 @@ export const useFilePreview = ({
36
36
  }) => {
37
37
  const mediaClient = useMediaClient();
38
38
  const [status, setStatus] = useState('loading');
39
- const [clientId, setClientId] = useState();
40
-
41
- // Fetch clientId on mount for cross-client copy
42
- useEffect(() => {
43
- if (fg('platform_media_cross_client_copy_with_auth')) {
44
- mediaClient.getClientId(identifier.collectionName).then(setClientId).catch(() => {
45
- // ClientId is optional, silently fail
46
- });
47
- }
48
- }, [mediaClient, identifier.collectionName]);
49
-
50
- // Merge clientId into mediaBlobUrlAttrs for embedding in blob URLs
51
- // If mediaBlobUrlAttrs is not provided, construct minimal attrs from identifier
52
- const mediaBlobUrlAttrsWithClientId = useMemo(() => {
53
- if (!fg('platform_media_cross_client_copy_with_auth') || !clientId) {
54
- return mediaBlobUrlAttrs;
55
- }
56
- if (mediaBlobUrlAttrs) {
57
- return {
58
- ...mediaBlobUrlAttrs,
59
- clientId
60
- };
61
- }
62
-
63
- // Construct minimal attrs when none provided (e.g., MediaImage)
64
- return {
65
- id: identifier.id,
66
- clientId,
67
- contextId: identifier.collectionName || '',
68
- collection: identifier.collectionName
69
- };
70
- }, [mediaBlobUrlAttrs, clientId, identifier.id, identifier.collectionName]);
71
39
  const [error, setError] = useState();
72
40
  const [nonCriticalError, setNonCriticalError] = useState();
73
41
  const [isBannedLocalPreview, setIsBannedLocalPreview] = useState(false);
@@ -125,7 +93,7 @@ export const useFilePreview = ({
125
93
  // where no SSR occurred, so we should skip SSR preview generation entirely.
126
94
  if (ssr === 'server' || ssrData) {
127
95
  try {
128
- return getSSRPreview(ssr, mediaClient, identifier.id, imageURLParams, mediaBlobUrlAttrsWithClientId);
96
+ return getSSRPreview(ssr, mediaClient, identifier.id, imageURLParams, mediaBlobUrlAttrs);
129
97
  } catch (e) {
130
98
  ssrReliabilityRef.current = {
131
99
  ...ssrReliabilityRef.current,
@@ -219,30 +187,11 @@ export const useFilePreview = ({
219
187
  }
220
188
  }, [preview, identifier, resizeMode]);
221
189
 
222
- //----------------------------------------------------------------
223
- // Update preview with clientId when it becomes available
224
- //----------------------------------------------------------------
225
- const previewUpdatedWithClientIdRef = useRef(null);
226
- useEffect(() => {
227
- // Only update if we have a preview, clientId is available, URL doesn't already have clientId, and feature flag is enabled.
228
- // Also skip if we've already updated this preview (prevents re-render loops)
229
- if (preview && clientId && mediaBlobUrlAttrsWithClientId && !preview.dataURI.includes('clientId=') && previewUpdatedWithClientIdRef.current !== identifier.id && fg('platform_media_cross_client_copy_with_auth')) {
230
- // Mark this preview as updated
231
- previewUpdatedWithClientIdRef.current = identifier.id;
232
- const baseUrl = preview.dataURI.split('#')[0]; // Remove any existing hash
233
- const updatedDataURI = addFileAttrsToUrl(baseUrl, mediaBlobUrlAttrsWithClientId);
234
- setPreview({
235
- ...preview,
236
- dataURI: updatedDataURI
237
- });
238
- }
239
- }, [clientId, mediaBlobUrlAttrsWithClientId, preview, identifier.id]);
240
-
241
190
  //----------------------------------------------------------------
242
191
  // Preview Fetch Helper
243
192
  //----------------------------------------------------------------
244
193
  const getAndCacheRemotePreviewRef = useCurrentValueRef(() => {
245
- return getAndCacheRemotePreview(mediaClient, identifier.id, requestDimensions || {}, imageURLParams, mediaBlobUrlAttrsWithClientId, traceContext);
194
+ return getAndCacheRemotePreview(mediaClient, identifier.id, requestDimensions || {}, imageURLParams, mediaBlobUrlAttrs, traceContext);
246
195
  });
247
196
 
248
197
  //----------------------------------------------------------------
@@ -279,7 +228,7 @@ export const useFilePreview = ({
279
228
  // Cache, Local & Remote Preview
280
229
  //----------------------------------------------------------------
281
230
 
282
- const mediaBlobUrlAttrsRef = useCurrentValueRef(mediaBlobUrlAttrsWithClientId);
231
+ const mediaBlobUrlAttrsRef = useCurrentValueRef(mediaBlobUrlAttrs);
283
232
  useEffect(() => {
284
233
  const cachedPreview = mediaFilePreviewCache.get(identifier.id, resizeMode);
285
234
 
@@ -293,7 +242,7 @@ export const useFilePreview = ({
293
242
  // For example, SVGs are mime type NOT supported by browser but media type supported by Media Card (image)
294
243
  // Then, local Preview NOT available
295
244
  setIsLoading(true);
296
- getAndCacheLocalPreview(identifier.id, localBinary, requestDimensions || {}, resizeMode, mediaBlobUrlAttrsRef.current).then(setPreview).catch(e => {
245
+ getAndCacheLocalPreview(mediaClient, identifier.id, localBinary, requestDimensions || {}, resizeMode, mediaBlobUrlAttrsRef.current, identifier.collectionName).then(setPreview).catch(e => {
297
246
  setIsBannedLocalPreview(true);
298
247
  // CXP-2723 TODO: We might have to wrap this error in MediaCardError
299
248
  setNonCriticalError(e);
@@ -324,7 +273,7 @@ export const useFilePreview = ({
324
273
  setIsLoading(false);
325
274
  });
326
275
  }
327
- }, [error, nonCriticalError, getAndCacheRemotePreviewRef, identifier.id, resizeMode, isBannedLocalPreview, mediaBlobUrlAttrsRef, preview, requestDimensions, skipRemote, isBackendPreviewReady, localBinary, mediaType, mimeType, upfrontPreviewStatus, dimensions]);
276
+ }, [error, nonCriticalError, getAndCacheRemotePreviewRef, identifier.id, identifier.collectionName, resizeMode, isBannedLocalPreview, mediaBlobUrlAttrsRef, mediaClient, preview, requestDimensions, skipRemote, isBackendPreviewReady, localBinary, mediaType, mimeType, upfrontPreviewStatus, dimensions]);
328
277
 
329
278
  //----------------------------------------------------------------
330
279
  // RETURN
@@ -444,7 +393,6 @@ export const useFilePreview = ({
444
393
  onImageError,
445
394
  onImageLoad,
446
395
  getSsrScriptProps,
447
- copyNodeRef,
448
- clientId
396
+ copyNodeRef
449
397
  };
450
398
  };
@@ -1,9 +1,11 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
1
2
  import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
3
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
4
  import _regeneratorRuntime from "@babel/runtime/regenerator";
4
5
  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; }
5
6
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
6
7
  import { addFileAttrsToUrl } from '@atlaskit/media-client';
8
+ import { fg } from '@atlaskit/platform-feature-flags';
7
9
  import { SsrPreviewError } from '../errors';
8
10
  import { mediaFilePreviewCache } from './cache';
9
11
  import { getLocalPreview, getRemotePreview } from './helpers';
@@ -34,15 +36,41 @@ var getDataUri = function getDataUri(mediaClient, id, params, mediaBlobUrlAttrs)
34
36
  var rawDataURI = mediaClient.getImageUrlSync(id, params);
35
37
  return mediaBlobUrlAttrs ? addFileAttrsToUrl(rawDataURI, mediaBlobUrlAttrs) : rawDataURI;
36
38
  };
39
+
40
+ /**
41
+ * Merges a clientId into mediaBlobUrlAttrs for cross-client copy support.
42
+ * Returns the original attrs unchanged if clientId is not available or the feature flag is off.
43
+ */
44
+ var mergeClientIdIntoAttrs = function mergeClientIdIntoAttrs(clientId, id, mediaBlobUrlAttrs, collectionName) {
45
+ if (!clientId) {
46
+ return mediaBlobUrlAttrs;
47
+ }
48
+ if (mediaBlobUrlAttrs) {
49
+ return _objectSpread(_objectSpread({}, mediaBlobUrlAttrs), {}, {
50
+ clientId: clientId
51
+ });
52
+ }
53
+
54
+ // Construct minimal attrs when none provided
55
+ return {
56
+ id: id,
57
+ clientId: clientId,
58
+ contextId: collectionName || '',
59
+ collection: collectionName
60
+ };
61
+ };
37
62
  export var getSSRPreview = function getSSRPreview(ssr, mediaClient, id, params, mediaBlobUrlAttrs) {
38
63
  try {
39
- var dataURI = getDataUri(mediaClient, id, params, mediaBlobUrlAttrs);
64
+ // Synchronously extract clientId from initialAuth and merge into blob URL attrs
65
+ var clientId = fg('platform_media_cross_client_copy_with_auth') ? mediaClient.getClientIdSync() : undefined;
66
+ var attrsWithClientId = mergeClientIdIntoAttrs(clientId, id, mediaBlobUrlAttrs, params.collection);
67
+ var dataURI = getDataUri(mediaClient, id, params, attrsWithClientId);
40
68
  var srcSet = "".concat(dataURI, " 1x");
41
69
  if (params.width) {
42
70
  var doubleDataURI = getDataUri(mediaClient, id, _objectSpread(_objectSpread({}, params), {}, {
43
71
  width: params.width * 2,
44
72
  height: params.height && params.height * 2
45
- }), mediaBlobUrlAttrs);
73
+ }), attrsWithClientId);
46
74
  // We want to embed some meta context into dataURI for Copy/Paste to work.
47
75
  srcSet += ", ".concat(doubleDataURI, " 2x");
48
76
  }
@@ -76,49 +104,100 @@ export var isSSRPreview = function isSSRPreview(preview) {
76
104
  var ssrClientSources = ['ssr-client', 'ssr-server', 'ssr-data'];
77
105
  return ssrClientSources.includes(preview.source);
78
106
  };
79
- export var getAndCacheRemotePreview = /*#__PURE__*/function () {
80
- var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(mediaClient, id, dimensions, params, mediaBlobUrlAttrs, traceContext) {
81
- var remotePreview;
107
+
108
+ /**
109
+ * Resolves clientId (sync first, async fallback) and enriches mediaBlobUrlAttrs
110
+ * with it for cross-client copy support.
111
+ */
112
+ var enrichAttrsWithClientId = /*#__PURE__*/function () {
113
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(mediaClient, id, mediaBlobUrlAttrs, collectionName) {
114
+ var clientId;
82
115
  return _regeneratorRuntime.wrap(function _callee$(_context) {
83
116
  while (1) switch (_context.prev = _context.next) {
84
117
  case 0:
85
- _context.next = 2;
86
- return getRemotePreview(mediaClient, id, params, traceContext);
118
+ if (fg('platform_media_cross_client_copy_with_auth')) {
119
+ _context.next = 2;
120
+ break;
121
+ }
122
+ return _context.abrupt("return", mediaBlobUrlAttrs);
87
123
  case 2:
88
- remotePreview = _context.sent;
89
- return _context.abrupt("return", extendAndCachePreview(id, params.mode, _objectSpread(_objectSpread({}, remotePreview), {}, {
90
- dimensions: dimensions
91
- }), mediaBlobUrlAttrs));
92
- case 4:
124
+ // Try sync first, then async fallback
125
+ clientId = mediaClient.getClientIdSync();
126
+ if (clientId) {
127
+ _context.next = 12;
128
+ break;
129
+ }
130
+ _context.prev = 4;
131
+ _context.next = 7;
132
+ return mediaClient.getClientId(collectionName);
133
+ case 7:
134
+ clientId = _context.sent;
135
+ _context.next = 12;
136
+ break;
137
+ case 10:
138
+ _context.prev = 10;
139
+ _context.t0 = _context["catch"](4);
140
+ case 12:
141
+ return _context.abrupt("return", mergeClientIdIntoAttrs(clientId, id, mediaBlobUrlAttrs, collectionName));
142
+ case 13:
93
143
  case "end":
94
144
  return _context.stop();
95
145
  }
96
- }, _callee);
146
+ }, _callee, null, [[4, 10]]);
97
147
  }));
98
- return function getAndCacheRemotePreview(_x, _x2, _x3, _x4, _x5, _x6) {
148
+ return function enrichAttrsWithClientId(_x, _x2, _x3, _x4) {
99
149
  return _ref.apply(this, arguments);
100
150
  };
101
151
  }();
102
- export var getAndCacheLocalPreview = /*#__PURE__*/function () {
103
- var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(id, filePreview, dimensions, mode, mediaBlobUrlAttrs) {
104
- var localPreview;
152
+ export var getAndCacheRemotePreview = /*#__PURE__*/function () {
153
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(mediaClient, id, dimensions, params, mediaBlobUrlAttrs, traceContext) {
154
+ var _yield$Promise$all, _yield$Promise$all2, remotePreview, enrichedAttrs;
105
155
  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
106
156
  while (1) switch (_context2.prev = _context2.next) {
107
157
  case 0:
108
158
  _context2.next = 2;
109
- return getLocalPreview(filePreview);
159
+ return Promise.all([getRemotePreview(mediaClient, id, params, traceContext), enrichAttrsWithClientId(mediaClient, id, mediaBlobUrlAttrs, params.collection)]);
110
160
  case 2:
111
- localPreview = _context2.sent;
112
- return _context2.abrupt("return", extendAndCachePreview(id, mode, _objectSpread(_objectSpread({}, localPreview), {}, {
161
+ _yield$Promise$all = _context2.sent;
162
+ _yield$Promise$all2 = _slicedToArray(_yield$Promise$all, 2);
163
+ remotePreview = _yield$Promise$all2[0];
164
+ enrichedAttrs = _yield$Promise$all2[1];
165
+ return _context2.abrupt("return", extendAndCachePreview(id, params.mode, _objectSpread(_objectSpread({}, remotePreview), {}, {
113
166
  dimensions: dimensions
114
- }), mediaBlobUrlAttrs));
115
- case 4:
167
+ }), enrichedAttrs));
168
+ case 7:
116
169
  case "end":
117
170
  return _context2.stop();
118
171
  }
119
172
  }, _callee2);
120
173
  }));
121
- return function getAndCacheLocalPreview(_x7, _x8, _x9, _x0, _x1) {
174
+ return function getAndCacheRemotePreview(_x5, _x6, _x7, _x8, _x9, _x0) {
122
175
  return _ref2.apply(this, arguments);
123
176
  };
177
+ }();
178
+ export var getAndCacheLocalPreview = /*#__PURE__*/function () {
179
+ var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(mediaClient, id, filePreview, dimensions, mode, mediaBlobUrlAttrs, collectionName) {
180
+ var _yield$Promise$all3, _yield$Promise$all4, localPreview, enrichedAttrs;
181
+ return _regeneratorRuntime.wrap(function _callee3$(_context3) {
182
+ while (1) switch (_context3.prev = _context3.next) {
183
+ case 0:
184
+ _context3.next = 2;
185
+ return Promise.all([getLocalPreview(filePreview), enrichAttrsWithClientId(mediaClient, id, mediaBlobUrlAttrs, collectionName)]);
186
+ case 2:
187
+ _yield$Promise$all3 = _context3.sent;
188
+ _yield$Promise$all4 = _slicedToArray(_yield$Promise$all3, 2);
189
+ localPreview = _yield$Promise$all4[0];
190
+ enrichedAttrs = _yield$Promise$all4[1];
191
+ return _context3.abrupt("return", extendAndCachePreview(id, mode, _objectSpread(_objectSpread({}, localPreview), {}, {
192
+ dimensions: dimensions
193
+ }), enrichedAttrs));
194
+ case 7:
195
+ case "end":
196
+ return _context3.stop();
197
+ }
198
+ }, _callee3);
199
+ }));
200
+ return function getAndCacheLocalPreview(_x1, _x10, _x11, _x12, _x13, _x14, _x15) {
201
+ return _ref3.apply(this, arguments);
202
+ };
124
203
  }();
@@ -3,7 +3,7 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
3
  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; }
4
4
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5
5
  import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
6
- import { addFileAttrsToUrl, isImageRepresentationReady, toCommonMediaClientError } from '@atlaskit/media-client';
6
+ import { isImageRepresentationReady, toCommonMediaClientError } from '@atlaskit/media-client';
7
7
  import { useCopyIntent, useFileState, useMediaClient } from '@atlaskit/media-client-react';
8
8
  import { isMimeTypeSupportedByBrowser } from '@atlaskit/media-common';
9
9
  import { fg } from '@atlaskit/platform-feature-flags';
@@ -46,54 +46,20 @@ export var useFilePreview = function useFilePreview(_ref) {
46
46
  setStatus = _useState2[1];
47
47
  var _useState3 = useState(),
48
48
  _useState4 = _slicedToArray(_useState3, 2),
49
- clientId = _useState4[0],
50
- setClientId = _useState4[1];
51
-
52
- // Fetch clientId on mount for cross-client copy
53
- useEffect(function () {
54
- if (fg('platform_media_cross_client_copy_with_auth')) {
55
- mediaClient.getClientId(identifier.collectionName).then(setClientId).catch(function () {
56
- // ClientId is optional, silently fail
57
- });
58
- }
59
- }, [mediaClient, identifier.collectionName]);
60
-
61
- // Merge clientId into mediaBlobUrlAttrs for embedding in blob URLs
62
- // If mediaBlobUrlAttrs is not provided, construct minimal attrs from identifier
63
- var mediaBlobUrlAttrsWithClientId = useMemo(function () {
64
- if (!fg('platform_media_cross_client_copy_with_auth') || !clientId) {
65
- return mediaBlobUrlAttrs;
66
- }
67
- if (mediaBlobUrlAttrs) {
68
- return _objectSpread(_objectSpread({}, mediaBlobUrlAttrs), {}, {
69
- clientId: clientId
70
- });
71
- }
72
-
73
- // Construct minimal attrs when none provided (e.g., MediaImage)
74
- return {
75
- id: identifier.id,
76
- clientId: clientId,
77
- contextId: identifier.collectionName || '',
78
- collection: identifier.collectionName
79
- };
80
- }, [mediaBlobUrlAttrs, clientId, identifier.id, identifier.collectionName]);
49
+ error = _useState4[0],
50
+ setError = _useState4[1];
81
51
  var _useState5 = useState(),
82
52
  _useState6 = _slicedToArray(_useState5, 2),
83
- error = _useState6[0],
84
- setError = _useState6[1];
85
- var _useState7 = useState(),
53
+ nonCriticalError = _useState6[0],
54
+ setNonCriticalError = _useState6[1];
55
+ var _useState7 = useState(false),
86
56
  _useState8 = _slicedToArray(_useState7, 2),
87
- nonCriticalError = _useState8[0],
88
- setNonCriticalError = _useState8[1];
89
- var _useState9 = useState(false),
57
+ isBannedLocalPreview = _useState8[0],
58
+ setIsBannedLocalPreview = _useState8[1];
59
+ var _useState9 = useState('not-resolved'),
90
60
  _useState0 = _slicedToArray(_useState9, 2),
91
- isBannedLocalPreview = _useState0[0],
92
- setIsBannedLocalPreview = _useState0[1];
93
- var _useState1 = useState('not-resolved'),
94
- _useState10 = _slicedToArray(_useState1, 2),
95
- upfrontPreviewStatus = _useState10[0],
96
- setUpfrontPreviewStatus = _useState10[1];
61
+ upfrontPreviewStatus = _useState0[0],
62
+ setUpfrontPreviewStatus = _useState0[1];
97
63
  var ssrReliabilityRef = useRef({
98
64
  server: {
99
65
  status: 'unknown'
@@ -103,10 +69,10 @@ export var useFilePreview = function useFilePreview(_ref) {
103
69
  }
104
70
  });
105
71
  var ufoContext = useInteractionContext();
106
- var _useState11 = useState(false),
107
- _useState12 = _slicedToArray(_useState11, 2),
108
- isLoading = _useState12[0],
109
- setIsLoading = _useState12[1];
72
+ var _useState1 = useState(false),
73
+ _useState10 = _slicedToArray(_useState1, 2),
74
+ isLoading = _useState10[0],
75
+ setIsLoading = _useState10[1];
110
76
  useLayoutEffect(function () {
111
77
  if (isLoading && fg('platform_close_image_blindspot_2')) {
112
78
  return ufoContext === null || ufoContext === void 0 ? void 0 : ufoContext.hold('img-loading');
@@ -149,7 +115,7 @@ export var useFilePreview = function useFilePreview(_ref) {
149
115
  // where no SSR occurred, so we should skip SSR preview generation entirely.
150
116
  if (ssr === 'server' || ssrData) {
151
117
  try {
152
- return getSSRPreview(ssr, mediaClient, identifier.id, imageURLParams, mediaBlobUrlAttrsWithClientId);
118
+ return getSSRPreview(ssr, mediaClient, identifier.id, imageURLParams, mediaBlobUrlAttrs);
153
119
  } catch (e) {
154
120
  ssrReliabilityRef.current = _objectSpread(_objectSpread({}, ssrReliabilityRef.current), {}, _defineProperty({}, ssr, _objectSpread({
155
121
  status: 'fail'
@@ -171,10 +137,10 @@ export var useFilePreview = function useFilePreview(_ref) {
171
137
  }
172
138
  }
173
139
  };
174
- var _useState13 = useState(previewInitializer),
175
- _useState14 = _slicedToArray(_useState13, 2),
176
- preview = _useState14[0],
177
- setPreview = _useState14[1];
140
+ var _useState11 = useState(previewInitializer),
141
+ _useState12 = _slicedToArray(_useState11, 2),
142
+ preview = _useState12[0],
143
+ setPreview = _useState12[1];
178
144
 
179
145
  //----------------------------------------------------------------
180
146
  // FILE STATE
@@ -241,29 +207,11 @@ export var useFilePreview = function useFilePreview(_ref) {
241
207
  }
242
208
  }, [preview, identifier, resizeMode]);
243
209
 
244
- //----------------------------------------------------------------
245
- // Update preview with clientId when it becomes available
246
- //----------------------------------------------------------------
247
- var previewUpdatedWithClientIdRef = useRef(null);
248
- useEffect(function () {
249
- // Only update if we have a preview, clientId is available, URL doesn't already have clientId, and feature flag is enabled.
250
- // Also skip if we've already updated this preview (prevents re-render loops)
251
- if (preview && clientId && mediaBlobUrlAttrsWithClientId && !preview.dataURI.includes('clientId=') && previewUpdatedWithClientIdRef.current !== identifier.id && fg('platform_media_cross_client_copy_with_auth')) {
252
- // Mark this preview as updated
253
- previewUpdatedWithClientIdRef.current = identifier.id;
254
- var baseUrl = preview.dataURI.split('#')[0]; // Remove any existing hash
255
- var updatedDataURI = addFileAttrsToUrl(baseUrl, mediaBlobUrlAttrsWithClientId);
256
- setPreview(_objectSpread(_objectSpread({}, preview), {}, {
257
- dataURI: updatedDataURI
258
- }));
259
- }
260
- }, [clientId, mediaBlobUrlAttrsWithClientId, preview, identifier.id]);
261
-
262
210
  //----------------------------------------------------------------
263
211
  // Preview Fetch Helper
264
212
  //----------------------------------------------------------------
265
213
  var getAndCacheRemotePreviewRef = useCurrentValueRef(function () {
266
- return getAndCacheRemotePreview(mediaClient, identifier.id, requestDimensions || {}, imageURLParams, mediaBlobUrlAttrsWithClientId, traceContext);
214
+ return getAndCacheRemotePreview(mediaClient, identifier.id, requestDimensions || {}, imageURLParams, mediaBlobUrlAttrs, traceContext);
267
215
  });
268
216
 
269
217
  //----------------------------------------------------------------
@@ -298,7 +246,7 @@ export var useFilePreview = function useFilePreview(_ref) {
298
246
  // Cache, Local & Remote Preview
299
247
  //----------------------------------------------------------------
300
248
 
301
- var mediaBlobUrlAttrsRef = useCurrentValueRef(mediaBlobUrlAttrsWithClientId);
249
+ var mediaBlobUrlAttrsRef = useCurrentValueRef(mediaBlobUrlAttrs);
302
250
  useEffect(function () {
303
251
  var cachedPreview = mediaFilePreviewCache.get(identifier.id, resizeMode);
304
252
 
@@ -312,7 +260,7 @@ export var useFilePreview = function useFilePreview(_ref) {
312
260
  // For example, SVGs are mime type NOT supported by browser but media type supported by Media Card (image)
313
261
  // Then, local Preview NOT available
314
262
  setIsLoading(true);
315
- getAndCacheLocalPreview(identifier.id, localBinary, requestDimensions || {}, resizeMode, mediaBlobUrlAttrsRef.current).then(setPreview).catch(function (e) {
263
+ getAndCacheLocalPreview(mediaClient, identifier.id, localBinary, requestDimensions || {}, resizeMode, mediaBlobUrlAttrsRef.current, identifier.collectionName).then(setPreview).catch(function (e) {
316
264
  setIsBannedLocalPreview(true);
317
265
  // CXP-2723 TODO: We might have to wrap this error in MediaCardError
318
266
  setNonCriticalError(e);
@@ -343,7 +291,7 @@ export var useFilePreview = function useFilePreview(_ref) {
343
291
  setIsLoading(false);
344
292
  });
345
293
  }
346
- }, [error, nonCriticalError, getAndCacheRemotePreviewRef, identifier.id, resizeMode, isBannedLocalPreview, mediaBlobUrlAttrsRef, preview, requestDimensions, skipRemote, isBackendPreviewReady, localBinary, mediaType, mimeType, upfrontPreviewStatus, dimensions]);
294
+ }, [error, nonCriticalError, getAndCacheRemotePreviewRef, identifier.id, identifier.collectionName, resizeMode, isBannedLocalPreview, mediaBlobUrlAttrsRef, mediaClient, preview, requestDimensions, skipRemote, isBackendPreviewReady, localBinary, mediaType, mimeType, upfrontPreviewStatus, dimensions]);
347
295
 
348
296
  //----------------------------------------------------------------
349
297
  // RETURN
@@ -460,7 +408,6 @@ export var useFilePreview = function useFilePreview(_ref) {
460
408
  onImageError: onImageError,
461
409
  onImageLoad: onImageLoad,
462
410
  getSsrScriptProps: getSsrScriptProps,
463
- copyNodeRef: copyNodeRef,
464
- clientId: clientId
411
+ copyNodeRef: copyNodeRef
465
412
  };
466
413
  };
@@ -8,4 +8,4 @@ export declare const isSSRClientPreview: (preview: MediaFilePreview) => boolean;
8
8
  export declare const isSSRDataPreview: (preview: MediaFilePreview) => boolean;
9
9
  export declare const isSSRPreview: (preview: MediaFilePreview) => boolean;
10
10
  export declare const getAndCacheRemotePreview: (mediaClient: MediaClient, id: string, dimensions: MediaFilePreviewDimensions, params: MediaStoreGetFileImageParams, mediaBlobUrlAttrs?: MediaBlobUrlAttrs, traceContext?: MediaTraceContext) => Promise<MediaFilePreview>;
11
- export declare const getAndCacheLocalPreview: (id: string, filePreview: FilePreview | Promise<FilePreview>, dimensions: MediaFilePreviewDimensions, mode: MediaStoreGetFileImageParams["mode"], mediaBlobUrlAttrs?: MediaBlobUrlAttrs) => Promise<MediaFilePreview>;
11
+ export declare const getAndCacheLocalPreview: (mediaClient: MediaClient, id: string, filePreview: FilePreview | Promise<FilePreview>, dimensions: MediaFilePreviewDimensions, mode: MediaStoreGetFileImageParams["mode"], mediaBlobUrlAttrs?: MediaBlobUrlAttrs, collectionName?: string) => Promise<MediaFilePreview>;
@@ -40,5 +40,4 @@ export declare const useFilePreview: ({ resizeMode, identifier, ssr, dimensions,
40
40
  onImageLoad: (newPreview?: MediaFilePreview) => void;
41
41
  getSsrScriptProps: (() => import("react").ScriptHTMLAttributes<HTMLScriptElement>) | undefined;
42
42
  copyNodeRef: (instance: HTMLDivElement | HTMLImageElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES];
43
- clientId: string | undefined;
44
43
  };
@@ -8,4 +8,4 @@ export declare const isSSRClientPreview: (preview: MediaFilePreview) => boolean;
8
8
  export declare const isSSRDataPreview: (preview: MediaFilePreview) => boolean;
9
9
  export declare const isSSRPreview: (preview: MediaFilePreview) => boolean;
10
10
  export declare const getAndCacheRemotePreview: (mediaClient: MediaClient, id: string, dimensions: MediaFilePreviewDimensions, params: MediaStoreGetFileImageParams, mediaBlobUrlAttrs?: MediaBlobUrlAttrs, traceContext?: MediaTraceContext) => Promise<MediaFilePreview>;
11
- export declare const getAndCacheLocalPreview: (id: string, filePreview: FilePreview | Promise<FilePreview>, dimensions: MediaFilePreviewDimensions, mode: MediaStoreGetFileImageParams["mode"], mediaBlobUrlAttrs?: MediaBlobUrlAttrs) => Promise<MediaFilePreview>;
11
+ export declare const getAndCacheLocalPreview: (mediaClient: MediaClient, id: string, filePreview: FilePreview | Promise<FilePreview>, dimensions: MediaFilePreviewDimensions, mode: MediaStoreGetFileImageParams["mode"], mediaBlobUrlAttrs?: MediaBlobUrlAttrs, collectionName?: string) => Promise<MediaFilePreview>;
@@ -40,5 +40,4 @@ export declare const useFilePreview: ({ resizeMode, identifier, ssr, dimensions,
40
40
  onImageLoad: (newPreview?: MediaFilePreview) => void;
41
41
  getSsrScriptProps: (() => import("react").ScriptHTMLAttributes<HTMLScriptElement>) | undefined;
42
42
  copyNodeRef: (instance: HTMLDivElement | HTMLImageElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES];
43
- clientId: string | undefined;
44
43
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/media-file-preview",
3
- "version": "0.16.2",
3
+ "version": "0.16.3",
4
4
  "description": "A React Hook to fetch and render file previews. It's overloaded with fancy features like SSR, lazy loading, memory cache and local preview.",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",