@tradly/asset 1.0.20 → 1.0.22
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/dist/core/MediaApiService.js +158 -144
- package/dist/esm/core/MediaApiService.js +158 -144
- package/dist/esm/native/FileUpload.native.js +5 -1
- package/dist/esm/native/ImagesSkeleton.native.js +18 -11
- package/dist/native/FileUpload.native.js +5 -1
- package/dist/native/ImagesSkeleton.native.js +16 -9
- package/package.json +1 -1
|
@@ -164,26 +164,123 @@ var MediaApiService = /*#__PURE__*/function () {
|
|
|
164
164
|
return fetchMedia;
|
|
165
165
|
}()
|
|
166
166
|
/**
|
|
167
|
-
*
|
|
167
|
+
* Upload a single file to S3 using signed URL
|
|
168
|
+
* Handles both web File objects and React Native file URIs
|
|
168
169
|
*/
|
|
169
170
|
)
|
|
170
171
|
}, {
|
|
171
|
-
key: "
|
|
172
|
+
key: "uploadFileToS3",
|
|
172
173
|
value: (function () {
|
|
173
|
-
var
|
|
174
|
-
var
|
|
174
|
+
var _uploadFileToS = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(signedUrl, fileUriOrFile, mimeType) {
|
|
175
|
+
var blob, response, _response, uploadResponse, errorText, _t2;
|
|
175
176
|
return _regenerator().w(function (_context3) {
|
|
176
177
|
while (1) switch (_context3.p = _context3.n) {
|
|
178
|
+
case 0:
|
|
179
|
+
_context3.p = 0;
|
|
180
|
+
if (!(typeof fileUriOrFile === "string")) {
|
|
181
|
+
_context3.n = 4;
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
_context3.n = 1;
|
|
185
|
+
return fetch(fileUriOrFile);
|
|
186
|
+
case 1:
|
|
187
|
+
response = _context3.v;
|
|
188
|
+
if (response.ok) {
|
|
189
|
+
_context3.n = 2;
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
throw new Error("Failed to fetch file: ".concat(response.status, " ").concat(response.statusText));
|
|
193
|
+
case 2:
|
|
194
|
+
_context3.n = 3;
|
|
195
|
+
return response.blob();
|
|
196
|
+
case 3:
|
|
197
|
+
blob = _context3.v;
|
|
198
|
+
_context3.n = 9;
|
|
199
|
+
break;
|
|
200
|
+
case 4:
|
|
201
|
+
if (!(fileUriOrFile && fileUriOrFile.uri)) {
|
|
202
|
+
_context3.n = 8;
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
_context3.n = 5;
|
|
206
|
+
return fetch(fileUriOrFile.uri);
|
|
207
|
+
case 5:
|
|
208
|
+
_response = _context3.v;
|
|
209
|
+
if (_response.ok) {
|
|
210
|
+
_context3.n = 6;
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
throw new Error("Failed to fetch file: ".concat(_response.status, " ").concat(_response.statusText));
|
|
214
|
+
case 6:
|
|
215
|
+
_context3.n = 7;
|
|
216
|
+
return _response.blob();
|
|
217
|
+
case 7:
|
|
218
|
+
blob = _context3.v;
|
|
219
|
+
_context3.n = 9;
|
|
220
|
+
break;
|
|
221
|
+
case 8:
|
|
222
|
+
// Web: fileUriOrFile is already a File/Blob object
|
|
223
|
+
blob = fileUriOrFile;
|
|
224
|
+
case 9:
|
|
225
|
+
_context3.n = 10;
|
|
226
|
+
return fetch(signedUrl, {
|
|
227
|
+
method: "PUT",
|
|
228
|
+
body: blob,
|
|
229
|
+
headers: {
|
|
230
|
+
"Content-Type": mimeType
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
case 10:
|
|
234
|
+
uploadResponse = _context3.v;
|
|
235
|
+
if (uploadResponse.ok) {
|
|
236
|
+
_context3.n = 12;
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
_context3.n = 11;
|
|
240
|
+
return uploadResponse.text().catch(function () {
|
|
241
|
+
return "";
|
|
242
|
+
});
|
|
243
|
+
case 11:
|
|
244
|
+
errorText = _context3.v;
|
|
245
|
+
throw new Error("S3 upload failed: ".concat(uploadResponse.status, " ").concat(uploadResponse.statusText).concat(errorText ? " - ".concat(errorText) : ""));
|
|
246
|
+
case 12:
|
|
247
|
+
_context3.n = 14;
|
|
248
|
+
break;
|
|
249
|
+
case 13:
|
|
250
|
+
_context3.p = 13;
|
|
251
|
+
_t2 = _context3.v;
|
|
252
|
+
throw new Error(_t2.message || "Failed to upload file to S3");
|
|
253
|
+
case 14:
|
|
254
|
+
return _context3.a(2);
|
|
255
|
+
}
|
|
256
|
+
}, _callee3, null, [[0, 13]]);
|
|
257
|
+
}));
|
|
258
|
+
function uploadFileToS3(_x3, _x4, _x5) {
|
|
259
|
+
return _uploadFileToS.apply(this, arguments);
|
|
260
|
+
}
|
|
261
|
+
return uploadFileToS3;
|
|
262
|
+
}()
|
|
263
|
+
/**
|
|
264
|
+
* Get S3 signed upload URLs from API
|
|
265
|
+
*/
|
|
266
|
+
)
|
|
267
|
+
}, {
|
|
268
|
+
key: "getS3SignedUrls",
|
|
269
|
+
value: (function () {
|
|
270
|
+
var _getS3SignedUrls = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(files, authKey) {
|
|
271
|
+
var auth_key, fileData, headers, _response$data$data, response, _t3;
|
|
272
|
+
return _regenerator().w(function (_context4) {
|
|
273
|
+
while (1) switch (_context4.p = _context4.n) {
|
|
177
274
|
case 0:
|
|
178
275
|
auth_key = authKey || this.authKey;
|
|
179
276
|
if (auth_key) {
|
|
180
|
-
|
|
277
|
+
_context4.n = 1;
|
|
181
278
|
break;
|
|
182
279
|
}
|
|
183
280
|
throw new Error("Authentication key is required for upload");
|
|
184
281
|
case 1:
|
|
185
282
|
if (this.apiBaseUrl) {
|
|
186
|
-
|
|
283
|
+
_context4.n = 2;
|
|
187
284
|
break;
|
|
188
285
|
}
|
|
189
286
|
throw new Error('API base URL is required. The package automatically detects it from ENVIRONMENT, or you can set apiBaseUrl in config: new MediaApiService({ apiBaseUrl: "https://api.tradly.app" })');
|
|
@@ -203,8 +300,8 @@ var MediaApiService = /*#__PURE__*/function () {
|
|
|
203
300
|
if (this.bearerToken) {
|
|
204
301
|
headers["Authorization"] = "Bearer ".concat(this.bearerToken);
|
|
205
302
|
}
|
|
206
|
-
|
|
207
|
-
|
|
303
|
+
_context4.p = 3;
|
|
304
|
+
_context4.n = 4;
|
|
208
305
|
return (0, _axios.default)({
|
|
209
306
|
method: "POST",
|
|
210
307
|
url: "".concat(this.apiBaseUrl, "/v1/utils/S3signedUploadURL"),
|
|
@@ -214,28 +311,28 @@ var MediaApiService = /*#__PURE__*/function () {
|
|
|
214
311
|
}
|
|
215
312
|
});
|
|
216
313
|
case 4:
|
|
217
|
-
response =
|
|
314
|
+
response = _context4.v;
|
|
218
315
|
if (!response.data.error) {
|
|
219
|
-
|
|
316
|
+
_context4.n = 5;
|
|
220
317
|
break;
|
|
221
318
|
}
|
|
222
319
|
throw new Error(response.data.error);
|
|
223
320
|
case 5:
|
|
224
|
-
return
|
|
321
|
+
return _context4.a(2, response.data.result || ((_response$data$data = response.data.data) === null || _response$data$data === void 0 ? void 0 : _response$data$data.result) || response.data);
|
|
225
322
|
case 6:
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
console.error("Error getting S3 signed URLs:",
|
|
323
|
+
_context4.p = 6;
|
|
324
|
+
_t3 = _context4.v;
|
|
325
|
+
console.error("Error getting S3 signed URLs:", _t3);
|
|
229
326
|
if (this.onError) {
|
|
230
|
-
this.onError(
|
|
327
|
+
this.onError(_t3);
|
|
231
328
|
}
|
|
232
|
-
throw
|
|
329
|
+
throw _t3;
|
|
233
330
|
case 7:
|
|
234
|
-
return
|
|
331
|
+
return _context4.a(2);
|
|
235
332
|
}
|
|
236
|
-
},
|
|
333
|
+
}, _callee4, this, [[3, 6]]);
|
|
237
334
|
}));
|
|
238
|
-
function getS3SignedUrls(
|
|
335
|
+
function getS3SignedUrls(_x6, _x7) {
|
|
239
336
|
return _getS3SignedUrls.apply(this, arguments);
|
|
240
337
|
}
|
|
241
338
|
return getS3SignedUrls;
|
|
@@ -248,14 +345,14 @@ var MediaApiService = /*#__PURE__*/function () {
|
|
|
248
345
|
}, {
|
|
249
346
|
key: "uploadMedia",
|
|
250
347
|
value: (function () {
|
|
251
|
-
var _uploadMedia = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function
|
|
252
|
-
var auth_key, all_files_uri, upload_files, upload_full_files, i, element, cleanFileName, file_data, responseFiles, index, path, fileURI, originalFile,
|
|
253
|
-
return _regenerator().w(function (
|
|
254
|
-
while (1) switch (
|
|
348
|
+
var _uploadMedia = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5(files, authKey) {
|
|
349
|
+
var auth_key, all_files_uri, upload_files, upload_full_files, i, element, cleanFileName, file_data, responseFiles, index, path, fileURI, originalFile, mimeType, fileInput, mediaData, _t4, _t5;
|
|
350
|
+
return _regenerator().w(function (_context5) {
|
|
351
|
+
while (1) switch (_context5.p = _context5.n) {
|
|
255
352
|
case 0:
|
|
256
353
|
auth_key = authKey || this.authKey;
|
|
257
354
|
if (auth_key) {
|
|
258
|
-
|
|
355
|
+
_context5.n = 1;
|
|
259
356
|
break;
|
|
260
357
|
}
|
|
261
358
|
throw new Error("Authentication key is required for upload");
|
|
@@ -266,7 +363,7 @@ var MediaApiService = /*#__PURE__*/function () {
|
|
|
266
363
|
i = 0;
|
|
267
364
|
case 2:
|
|
268
365
|
if (!(i < files.length)) {
|
|
269
|
-
|
|
366
|
+
_context5.n = 14;
|
|
270
367
|
break;
|
|
271
368
|
}
|
|
272
369
|
element = files[i]; // Check if file already has a path (from previous upload)
|
|
@@ -286,133 +383,50 @@ var MediaApiService = /*#__PURE__*/function () {
|
|
|
286
383
|
|
|
287
384
|
// Upload files when we've processed all files
|
|
288
385
|
if (!(files.length === i + 1 && upload_files.length > 0)) {
|
|
289
|
-
|
|
386
|
+
_context5.n = 13;
|
|
290
387
|
break;
|
|
291
388
|
}
|
|
292
|
-
|
|
293
|
-
|
|
389
|
+
_context5.p = 3;
|
|
390
|
+
_context5.n = 4;
|
|
294
391
|
return this.getS3SignedUrls(upload_full_files, auth_key);
|
|
295
392
|
case 4:
|
|
296
|
-
responseFiles =
|
|
393
|
+
responseFiles = _context5.v;
|
|
394
|
+
console.log("responseFiles", responseFiles);
|
|
395
|
+
|
|
396
|
+
// Step 2: Upload each file to S3
|
|
297
397
|
index = 0;
|
|
298
398
|
case 5:
|
|
299
399
|
if (!(index < responseFiles.length)) {
|
|
300
|
-
|
|
400
|
+
_context5.n = 10;
|
|
301
401
|
break;
|
|
302
402
|
}
|
|
303
403
|
path = responseFiles[index].signedUrl;
|
|
304
404
|
fileURI = responseFiles[index].fileUri;
|
|
305
405
|
originalFile = upload_full_files[index];
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
//
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
uri = originalFile.uri;
|
|
315
|
-
_context4.p = 7;
|
|
316
|
-
_context4.n = 8;
|
|
317
|
-
return fetch(uri);
|
|
318
|
-
case 8:
|
|
319
|
-
fileResponse = _context4.v;
|
|
320
|
-
if (fileResponse.ok) {
|
|
321
|
-
_context4.n = 9;
|
|
322
|
-
break;
|
|
323
|
-
}
|
|
324
|
-
throw new Error("Failed to fetch file: ".concat(fileResponse.status, " ").concat(fileResponse.statusText));
|
|
325
|
-
case 9:
|
|
326
|
-
if (!fileResponse.blob) {
|
|
327
|
-
_context4.n = 11;
|
|
328
|
-
break;
|
|
329
|
-
}
|
|
330
|
-
_context4.n = 10;
|
|
331
|
-
return fileResponse.blob();
|
|
332
|
-
case 10:
|
|
333
|
-
fileBody = _context4.v;
|
|
334
|
-
_context4.n = 14;
|
|
335
|
-
break;
|
|
336
|
-
case 11:
|
|
337
|
-
if (!fileResponse.arrayBuffer) {
|
|
338
|
-
_context4.n = 13;
|
|
339
|
-
break;
|
|
340
|
-
}
|
|
341
|
-
_context4.n = 12;
|
|
342
|
-
return fileResponse.arrayBuffer();
|
|
343
|
-
case 12:
|
|
344
|
-
arrayBuffer = _context4.v;
|
|
345
|
-
// Check if Blob constructor is available
|
|
346
|
-
if (typeof Blob !== "undefined") {
|
|
347
|
-
fileBody = new Blob([arrayBuffer], {
|
|
348
|
-
type: upload_files[index].type
|
|
349
|
-
});
|
|
350
|
-
} else {
|
|
351
|
-
// If Blob is not available, use arrayBuffer directly
|
|
352
|
-
fileBody = arrayBuffer;
|
|
353
|
-
}
|
|
354
|
-
_context4.n = 14;
|
|
355
|
-
break;
|
|
356
|
-
case 13:
|
|
357
|
-
// Last resort: use response directly (might not work for all cases)
|
|
358
|
-
fileBody = fileResponse;
|
|
359
|
-
case 14:
|
|
360
|
-
_context4.n = 16;
|
|
361
|
-
break;
|
|
362
|
-
case 15:
|
|
363
|
-
_context4.p = 15;
|
|
364
|
-
_t3 = _context4.v;
|
|
365
|
-
console.error("Error fetching file from URI:", _t3);
|
|
366
|
-
console.error("URI was:", uri);
|
|
367
|
-
console.error("File details:", {
|
|
368
|
-
name: originalFile.name,
|
|
369
|
-
type: originalFile.type
|
|
370
|
-
});
|
|
371
|
-
throw new Error("Failed to read file from URI: ".concat(uri, ". Error: ").concat(_t3.message, ". Make sure the file URI is accessible."));
|
|
372
|
-
case 16:
|
|
373
|
-
_context4.n = 17;
|
|
374
|
-
return fetch(path, {
|
|
375
|
-
method: "PUT",
|
|
376
|
-
headers: {
|
|
377
|
-
"Content-Type": upload_files[index].type
|
|
378
|
-
},
|
|
379
|
-
body: fileBody
|
|
380
|
-
});
|
|
381
|
-
case 17:
|
|
382
|
-
res = _context4.v;
|
|
383
|
-
if (!res.ok) {
|
|
384
|
-
_context4.n = 18;
|
|
385
|
-
break;
|
|
386
|
-
}
|
|
406
|
+
mimeType = upload_files[index].type;
|
|
407
|
+
_context5.p = 6;
|
|
408
|
+
// Upload file to S3 using the signed URL
|
|
409
|
+
// uploadFileToS3 handles both web File objects and React Native URIs
|
|
410
|
+
fileInput = originalFile.uri || originalFile;
|
|
411
|
+
_context5.n = 7;
|
|
412
|
+
return this.uploadFileToS3(path, fileInput, mimeType);
|
|
413
|
+
case 7:
|
|
387
414
|
all_files_uri.push(fileURI);
|
|
388
|
-
|
|
415
|
+
_context5.n = 9;
|
|
389
416
|
break;
|
|
390
|
-
case
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
return "";
|
|
394
|
-
});
|
|
395
|
-
case 19:
|
|
396
|
-
errorText = _context4.v;
|
|
397
|
-
console.error("Failed to upload file ".concat(index + 1, ":"), res.status, res.statusText, errorText);
|
|
398
|
-
errorMsg = errorText ? "S3 upload failed: ".concat(res.status, " ").concat(res.statusText, " - ").concat(errorText) : "S3 upload failed: ".concat(res.status, " ").concat(res.statusText);
|
|
399
|
-
throw new Error(errorMsg);
|
|
400
|
-
case 20:
|
|
401
|
-
_context4.n = 22;
|
|
402
|
-
break;
|
|
403
|
-
case 21:
|
|
404
|
-
_context4.p = 21;
|
|
405
|
-
_t4 = _context4.v;
|
|
417
|
+
case 8:
|
|
418
|
+
_context5.p = 8;
|
|
419
|
+
_t4 = _context5.v;
|
|
406
420
|
console.error("Error uploading file ".concat(index + 1, ":"), _t4);
|
|
407
421
|
// Re-throw to stop the upload process
|
|
408
422
|
throw _t4;
|
|
409
|
-
case
|
|
423
|
+
case 9:
|
|
410
424
|
index++;
|
|
411
|
-
|
|
425
|
+
_context5.n = 5;
|
|
412
426
|
break;
|
|
413
|
-
case
|
|
427
|
+
case 10:
|
|
414
428
|
if (!(all_files_uri.length > 0)) {
|
|
415
|
-
|
|
429
|
+
_context5.n = 11;
|
|
416
430
|
break;
|
|
417
431
|
}
|
|
418
432
|
mediaData = all_files_uri.map(function (url, index) {
|
|
@@ -425,7 +439,7 @@ var MediaApiService = /*#__PURE__*/function () {
|
|
|
425
439
|
mime_type: originalFile.type
|
|
426
440
|
};
|
|
427
441
|
}); // Save to media API - POST /v1/media with { media: [...] }
|
|
428
|
-
|
|
442
|
+
_context5.n = 11;
|
|
429
443
|
return this.apiCall({
|
|
430
444
|
method: "POST",
|
|
431
445
|
path: "/v1/media",
|
|
@@ -433,27 +447,27 @@ var MediaApiService = /*#__PURE__*/function () {
|
|
|
433
447
|
media: mediaData
|
|
434
448
|
}
|
|
435
449
|
});
|
|
436
|
-
case
|
|
437
|
-
|
|
450
|
+
case 11:
|
|
451
|
+
_context5.n = 13;
|
|
438
452
|
break;
|
|
439
|
-
case
|
|
440
|
-
|
|
441
|
-
_t5 =
|
|
453
|
+
case 12:
|
|
454
|
+
_context5.p = 12;
|
|
455
|
+
_t5 = _context5.v;
|
|
442
456
|
console.error("Upload error:", _t5);
|
|
443
457
|
if (this.onError) {
|
|
444
458
|
this.onError(_t5);
|
|
445
459
|
}
|
|
446
460
|
throw _t5;
|
|
447
|
-
case
|
|
461
|
+
case 13:
|
|
448
462
|
i++;
|
|
449
|
-
|
|
463
|
+
_context5.n = 2;
|
|
450
464
|
break;
|
|
451
|
-
case
|
|
452
|
-
return
|
|
465
|
+
case 14:
|
|
466
|
+
return _context5.a(2, all_files_uri);
|
|
453
467
|
}
|
|
454
|
-
},
|
|
468
|
+
}, _callee5, this, [[6, 8], [3, 12]]);
|
|
455
469
|
}));
|
|
456
|
-
function uploadMedia(
|
|
470
|
+
function uploadMedia(_x8, _x9) {
|
|
457
471
|
return _uploadMedia.apply(this, arguments);
|
|
458
472
|
}
|
|
459
473
|
return uploadMedia;
|
|
@@ -158,26 +158,123 @@ var MediaApiService = /*#__PURE__*/function () {
|
|
|
158
158
|
return fetchMedia;
|
|
159
159
|
}()
|
|
160
160
|
/**
|
|
161
|
-
*
|
|
161
|
+
* Upload a single file to S3 using signed URL
|
|
162
|
+
* Handles both web File objects and React Native file URIs
|
|
162
163
|
*/
|
|
163
164
|
)
|
|
164
165
|
}, {
|
|
165
|
-
key: "
|
|
166
|
+
key: "uploadFileToS3",
|
|
166
167
|
value: (function () {
|
|
167
|
-
var
|
|
168
|
-
var
|
|
168
|
+
var _uploadFileToS = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(signedUrl, fileUriOrFile, mimeType) {
|
|
169
|
+
var blob, response, _response, uploadResponse, errorText, _t2;
|
|
169
170
|
return _regenerator().w(function (_context3) {
|
|
170
171
|
while (1) switch (_context3.p = _context3.n) {
|
|
172
|
+
case 0:
|
|
173
|
+
_context3.p = 0;
|
|
174
|
+
if (!(typeof fileUriOrFile === "string")) {
|
|
175
|
+
_context3.n = 4;
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
_context3.n = 1;
|
|
179
|
+
return fetch(fileUriOrFile);
|
|
180
|
+
case 1:
|
|
181
|
+
response = _context3.v;
|
|
182
|
+
if (response.ok) {
|
|
183
|
+
_context3.n = 2;
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
throw new Error("Failed to fetch file: ".concat(response.status, " ").concat(response.statusText));
|
|
187
|
+
case 2:
|
|
188
|
+
_context3.n = 3;
|
|
189
|
+
return response.blob();
|
|
190
|
+
case 3:
|
|
191
|
+
blob = _context3.v;
|
|
192
|
+
_context3.n = 9;
|
|
193
|
+
break;
|
|
194
|
+
case 4:
|
|
195
|
+
if (!(fileUriOrFile && fileUriOrFile.uri)) {
|
|
196
|
+
_context3.n = 8;
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
_context3.n = 5;
|
|
200
|
+
return fetch(fileUriOrFile.uri);
|
|
201
|
+
case 5:
|
|
202
|
+
_response = _context3.v;
|
|
203
|
+
if (_response.ok) {
|
|
204
|
+
_context3.n = 6;
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
throw new Error("Failed to fetch file: ".concat(_response.status, " ").concat(_response.statusText));
|
|
208
|
+
case 6:
|
|
209
|
+
_context3.n = 7;
|
|
210
|
+
return _response.blob();
|
|
211
|
+
case 7:
|
|
212
|
+
blob = _context3.v;
|
|
213
|
+
_context3.n = 9;
|
|
214
|
+
break;
|
|
215
|
+
case 8:
|
|
216
|
+
// Web: fileUriOrFile is already a File/Blob object
|
|
217
|
+
blob = fileUriOrFile;
|
|
218
|
+
case 9:
|
|
219
|
+
_context3.n = 10;
|
|
220
|
+
return fetch(signedUrl, {
|
|
221
|
+
method: "PUT",
|
|
222
|
+
body: blob,
|
|
223
|
+
headers: {
|
|
224
|
+
"Content-Type": mimeType
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
case 10:
|
|
228
|
+
uploadResponse = _context3.v;
|
|
229
|
+
if (uploadResponse.ok) {
|
|
230
|
+
_context3.n = 12;
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
_context3.n = 11;
|
|
234
|
+
return uploadResponse.text().catch(function () {
|
|
235
|
+
return "";
|
|
236
|
+
});
|
|
237
|
+
case 11:
|
|
238
|
+
errorText = _context3.v;
|
|
239
|
+
throw new Error("S3 upload failed: ".concat(uploadResponse.status, " ").concat(uploadResponse.statusText).concat(errorText ? " - ".concat(errorText) : ""));
|
|
240
|
+
case 12:
|
|
241
|
+
_context3.n = 14;
|
|
242
|
+
break;
|
|
243
|
+
case 13:
|
|
244
|
+
_context3.p = 13;
|
|
245
|
+
_t2 = _context3.v;
|
|
246
|
+
throw new Error(_t2.message || "Failed to upload file to S3");
|
|
247
|
+
case 14:
|
|
248
|
+
return _context3.a(2);
|
|
249
|
+
}
|
|
250
|
+
}, _callee3, null, [[0, 13]]);
|
|
251
|
+
}));
|
|
252
|
+
function uploadFileToS3(_x3, _x4, _x5) {
|
|
253
|
+
return _uploadFileToS.apply(this, arguments);
|
|
254
|
+
}
|
|
255
|
+
return uploadFileToS3;
|
|
256
|
+
}()
|
|
257
|
+
/**
|
|
258
|
+
* Get S3 signed upload URLs from API
|
|
259
|
+
*/
|
|
260
|
+
)
|
|
261
|
+
}, {
|
|
262
|
+
key: "getS3SignedUrls",
|
|
263
|
+
value: (function () {
|
|
264
|
+
var _getS3SignedUrls = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(files, authKey) {
|
|
265
|
+
var auth_key, fileData, headers, _response$data$data, response, _t3;
|
|
266
|
+
return _regenerator().w(function (_context4) {
|
|
267
|
+
while (1) switch (_context4.p = _context4.n) {
|
|
171
268
|
case 0:
|
|
172
269
|
auth_key = authKey || this.authKey;
|
|
173
270
|
if (auth_key) {
|
|
174
|
-
|
|
271
|
+
_context4.n = 1;
|
|
175
272
|
break;
|
|
176
273
|
}
|
|
177
274
|
throw new Error("Authentication key is required for upload");
|
|
178
275
|
case 1:
|
|
179
276
|
if (this.apiBaseUrl) {
|
|
180
|
-
|
|
277
|
+
_context4.n = 2;
|
|
181
278
|
break;
|
|
182
279
|
}
|
|
183
280
|
throw new Error('API base URL is required. The package automatically detects it from ENVIRONMENT, or you can set apiBaseUrl in config: new MediaApiService({ apiBaseUrl: "https://api.tradly.app" })');
|
|
@@ -197,8 +294,8 @@ var MediaApiService = /*#__PURE__*/function () {
|
|
|
197
294
|
if (this.bearerToken) {
|
|
198
295
|
headers["Authorization"] = "Bearer ".concat(this.bearerToken);
|
|
199
296
|
}
|
|
200
|
-
|
|
201
|
-
|
|
297
|
+
_context4.p = 3;
|
|
298
|
+
_context4.n = 4;
|
|
202
299
|
return axios({
|
|
203
300
|
method: "POST",
|
|
204
301
|
url: "".concat(this.apiBaseUrl, "/v1/utils/S3signedUploadURL"),
|
|
@@ -208,28 +305,28 @@ var MediaApiService = /*#__PURE__*/function () {
|
|
|
208
305
|
}
|
|
209
306
|
});
|
|
210
307
|
case 4:
|
|
211
|
-
response =
|
|
308
|
+
response = _context4.v;
|
|
212
309
|
if (!response.data.error) {
|
|
213
|
-
|
|
310
|
+
_context4.n = 5;
|
|
214
311
|
break;
|
|
215
312
|
}
|
|
216
313
|
throw new Error(response.data.error);
|
|
217
314
|
case 5:
|
|
218
|
-
return
|
|
315
|
+
return _context4.a(2, response.data.result || ((_response$data$data = response.data.data) === null || _response$data$data === void 0 ? void 0 : _response$data$data.result) || response.data);
|
|
219
316
|
case 6:
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
console.error("Error getting S3 signed URLs:",
|
|
317
|
+
_context4.p = 6;
|
|
318
|
+
_t3 = _context4.v;
|
|
319
|
+
console.error("Error getting S3 signed URLs:", _t3);
|
|
223
320
|
if (this.onError) {
|
|
224
|
-
this.onError(
|
|
321
|
+
this.onError(_t3);
|
|
225
322
|
}
|
|
226
|
-
throw
|
|
323
|
+
throw _t3;
|
|
227
324
|
case 7:
|
|
228
|
-
return
|
|
325
|
+
return _context4.a(2);
|
|
229
326
|
}
|
|
230
|
-
},
|
|
327
|
+
}, _callee4, this, [[3, 6]]);
|
|
231
328
|
}));
|
|
232
|
-
function getS3SignedUrls(
|
|
329
|
+
function getS3SignedUrls(_x6, _x7) {
|
|
233
330
|
return _getS3SignedUrls.apply(this, arguments);
|
|
234
331
|
}
|
|
235
332
|
return getS3SignedUrls;
|
|
@@ -242,14 +339,14 @@ var MediaApiService = /*#__PURE__*/function () {
|
|
|
242
339
|
}, {
|
|
243
340
|
key: "uploadMedia",
|
|
244
341
|
value: (function () {
|
|
245
|
-
var _uploadMedia = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function
|
|
246
|
-
var auth_key, all_files_uri, upload_files, upload_full_files, i, element, cleanFileName, file_data, responseFiles, index, path, fileURI, originalFile,
|
|
247
|
-
return _regenerator().w(function (
|
|
248
|
-
while (1) switch (
|
|
342
|
+
var _uploadMedia = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5(files, authKey) {
|
|
343
|
+
var auth_key, all_files_uri, upload_files, upload_full_files, i, element, cleanFileName, file_data, responseFiles, index, path, fileURI, originalFile, mimeType, fileInput, mediaData, _t4, _t5;
|
|
344
|
+
return _regenerator().w(function (_context5) {
|
|
345
|
+
while (1) switch (_context5.p = _context5.n) {
|
|
249
346
|
case 0:
|
|
250
347
|
auth_key = authKey || this.authKey;
|
|
251
348
|
if (auth_key) {
|
|
252
|
-
|
|
349
|
+
_context5.n = 1;
|
|
253
350
|
break;
|
|
254
351
|
}
|
|
255
352
|
throw new Error("Authentication key is required for upload");
|
|
@@ -260,7 +357,7 @@ var MediaApiService = /*#__PURE__*/function () {
|
|
|
260
357
|
i = 0;
|
|
261
358
|
case 2:
|
|
262
359
|
if (!(i < files.length)) {
|
|
263
|
-
|
|
360
|
+
_context5.n = 14;
|
|
264
361
|
break;
|
|
265
362
|
}
|
|
266
363
|
element = files[i]; // Check if file already has a path (from previous upload)
|
|
@@ -280,133 +377,50 @@ var MediaApiService = /*#__PURE__*/function () {
|
|
|
280
377
|
|
|
281
378
|
// Upload files when we've processed all files
|
|
282
379
|
if (!(files.length === i + 1 && upload_files.length > 0)) {
|
|
283
|
-
|
|
380
|
+
_context5.n = 13;
|
|
284
381
|
break;
|
|
285
382
|
}
|
|
286
|
-
|
|
287
|
-
|
|
383
|
+
_context5.p = 3;
|
|
384
|
+
_context5.n = 4;
|
|
288
385
|
return this.getS3SignedUrls(upload_full_files, auth_key);
|
|
289
386
|
case 4:
|
|
290
|
-
responseFiles =
|
|
387
|
+
responseFiles = _context5.v;
|
|
388
|
+
console.log("responseFiles", responseFiles);
|
|
389
|
+
|
|
390
|
+
// Step 2: Upload each file to S3
|
|
291
391
|
index = 0;
|
|
292
392
|
case 5:
|
|
293
393
|
if (!(index < responseFiles.length)) {
|
|
294
|
-
|
|
394
|
+
_context5.n = 10;
|
|
295
395
|
break;
|
|
296
396
|
}
|
|
297
397
|
path = responseFiles[index].signedUrl;
|
|
298
398
|
fileURI = responseFiles[index].fileUri;
|
|
299
399
|
originalFile = upload_full_files[index];
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
//
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
uri = originalFile.uri;
|
|
309
|
-
_context4.p = 7;
|
|
310
|
-
_context4.n = 8;
|
|
311
|
-
return fetch(uri);
|
|
312
|
-
case 8:
|
|
313
|
-
fileResponse = _context4.v;
|
|
314
|
-
if (fileResponse.ok) {
|
|
315
|
-
_context4.n = 9;
|
|
316
|
-
break;
|
|
317
|
-
}
|
|
318
|
-
throw new Error("Failed to fetch file: ".concat(fileResponse.status, " ").concat(fileResponse.statusText));
|
|
319
|
-
case 9:
|
|
320
|
-
if (!fileResponse.blob) {
|
|
321
|
-
_context4.n = 11;
|
|
322
|
-
break;
|
|
323
|
-
}
|
|
324
|
-
_context4.n = 10;
|
|
325
|
-
return fileResponse.blob();
|
|
326
|
-
case 10:
|
|
327
|
-
fileBody = _context4.v;
|
|
328
|
-
_context4.n = 14;
|
|
329
|
-
break;
|
|
330
|
-
case 11:
|
|
331
|
-
if (!fileResponse.arrayBuffer) {
|
|
332
|
-
_context4.n = 13;
|
|
333
|
-
break;
|
|
334
|
-
}
|
|
335
|
-
_context4.n = 12;
|
|
336
|
-
return fileResponse.arrayBuffer();
|
|
337
|
-
case 12:
|
|
338
|
-
arrayBuffer = _context4.v;
|
|
339
|
-
// Check if Blob constructor is available
|
|
340
|
-
if (typeof Blob !== "undefined") {
|
|
341
|
-
fileBody = new Blob([arrayBuffer], {
|
|
342
|
-
type: upload_files[index].type
|
|
343
|
-
});
|
|
344
|
-
} else {
|
|
345
|
-
// If Blob is not available, use arrayBuffer directly
|
|
346
|
-
fileBody = arrayBuffer;
|
|
347
|
-
}
|
|
348
|
-
_context4.n = 14;
|
|
349
|
-
break;
|
|
350
|
-
case 13:
|
|
351
|
-
// Last resort: use response directly (might not work for all cases)
|
|
352
|
-
fileBody = fileResponse;
|
|
353
|
-
case 14:
|
|
354
|
-
_context4.n = 16;
|
|
355
|
-
break;
|
|
356
|
-
case 15:
|
|
357
|
-
_context4.p = 15;
|
|
358
|
-
_t3 = _context4.v;
|
|
359
|
-
console.error("Error fetching file from URI:", _t3);
|
|
360
|
-
console.error("URI was:", uri);
|
|
361
|
-
console.error("File details:", {
|
|
362
|
-
name: originalFile.name,
|
|
363
|
-
type: originalFile.type
|
|
364
|
-
});
|
|
365
|
-
throw new Error("Failed to read file from URI: ".concat(uri, ". Error: ").concat(_t3.message, ". Make sure the file URI is accessible."));
|
|
366
|
-
case 16:
|
|
367
|
-
_context4.n = 17;
|
|
368
|
-
return fetch(path, {
|
|
369
|
-
method: "PUT",
|
|
370
|
-
headers: {
|
|
371
|
-
"Content-Type": upload_files[index].type
|
|
372
|
-
},
|
|
373
|
-
body: fileBody
|
|
374
|
-
});
|
|
375
|
-
case 17:
|
|
376
|
-
res = _context4.v;
|
|
377
|
-
if (!res.ok) {
|
|
378
|
-
_context4.n = 18;
|
|
379
|
-
break;
|
|
380
|
-
}
|
|
400
|
+
mimeType = upload_files[index].type;
|
|
401
|
+
_context5.p = 6;
|
|
402
|
+
// Upload file to S3 using the signed URL
|
|
403
|
+
// uploadFileToS3 handles both web File objects and React Native URIs
|
|
404
|
+
fileInput = originalFile.uri || originalFile;
|
|
405
|
+
_context5.n = 7;
|
|
406
|
+
return this.uploadFileToS3(path, fileInput, mimeType);
|
|
407
|
+
case 7:
|
|
381
408
|
all_files_uri.push(fileURI);
|
|
382
|
-
|
|
409
|
+
_context5.n = 9;
|
|
383
410
|
break;
|
|
384
|
-
case
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
return "";
|
|
388
|
-
});
|
|
389
|
-
case 19:
|
|
390
|
-
errorText = _context4.v;
|
|
391
|
-
console.error("Failed to upload file ".concat(index + 1, ":"), res.status, res.statusText, errorText);
|
|
392
|
-
errorMsg = errorText ? "S3 upload failed: ".concat(res.status, " ").concat(res.statusText, " - ").concat(errorText) : "S3 upload failed: ".concat(res.status, " ").concat(res.statusText);
|
|
393
|
-
throw new Error(errorMsg);
|
|
394
|
-
case 20:
|
|
395
|
-
_context4.n = 22;
|
|
396
|
-
break;
|
|
397
|
-
case 21:
|
|
398
|
-
_context4.p = 21;
|
|
399
|
-
_t4 = _context4.v;
|
|
411
|
+
case 8:
|
|
412
|
+
_context5.p = 8;
|
|
413
|
+
_t4 = _context5.v;
|
|
400
414
|
console.error("Error uploading file ".concat(index + 1, ":"), _t4);
|
|
401
415
|
// Re-throw to stop the upload process
|
|
402
416
|
throw _t4;
|
|
403
|
-
case
|
|
417
|
+
case 9:
|
|
404
418
|
index++;
|
|
405
|
-
|
|
419
|
+
_context5.n = 5;
|
|
406
420
|
break;
|
|
407
|
-
case
|
|
421
|
+
case 10:
|
|
408
422
|
if (!(all_files_uri.length > 0)) {
|
|
409
|
-
|
|
423
|
+
_context5.n = 11;
|
|
410
424
|
break;
|
|
411
425
|
}
|
|
412
426
|
mediaData = all_files_uri.map(function (url, index) {
|
|
@@ -419,7 +433,7 @@ var MediaApiService = /*#__PURE__*/function () {
|
|
|
419
433
|
mime_type: originalFile.type
|
|
420
434
|
};
|
|
421
435
|
}); // Save to media API - POST /v1/media with { media: [...] }
|
|
422
|
-
|
|
436
|
+
_context5.n = 11;
|
|
423
437
|
return this.apiCall({
|
|
424
438
|
method: "POST",
|
|
425
439
|
path: "/v1/media",
|
|
@@ -427,27 +441,27 @@ var MediaApiService = /*#__PURE__*/function () {
|
|
|
427
441
|
media: mediaData
|
|
428
442
|
}
|
|
429
443
|
});
|
|
430
|
-
case
|
|
431
|
-
|
|
444
|
+
case 11:
|
|
445
|
+
_context5.n = 13;
|
|
432
446
|
break;
|
|
433
|
-
case
|
|
434
|
-
|
|
435
|
-
_t5 =
|
|
447
|
+
case 12:
|
|
448
|
+
_context5.p = 12;
|
|
449
|
+
_t5 = _context5.v;
|
|
436
450
|
console.error("Upload error:", _t5);
|
|
437
451
|
if (this.onError) {
|
|
438
452
|
this.onError(_t5);
|
|
439
453
|
}
|
|
440
454
|
throw _t5;
|
|
441
|
-
case
|
|
455
|
+
case 13:
|
|
442
456
|
i++;
|
|
443
|
-
|
|
457
|
+
_context5.n = 2;
|
|
444
458
|
break;
|
|
445
|
-
case
|
|
446
|
-
return
|
|
459
|
+
case 14:
|
|
460
|
+
return _context5.a(2, all_files_uri);
|
|
447
461
|
}
|
|
448
|
-
},
|
|
462
|
+
}, _callee5, this, [[6, 8], [3, 12]]);
|
|
449
463
|
}));
|
|
450
|
-
function uploadMedia(
|
|
464
|
+
function uploadMedia(_x8, _x9) {
|
|
451
465
|
return _uploadMedia.apply(this, arguments);
|
|
452
466
|
}
|
|
453
467
|
return uploadMedia;
|
|
@@ -186,13 +186,17 @@ var FileUpload = function FileUpload(_ref) {
|
|
|
186
186
|
while (1) switch (_context.p = _context.n) {
|
|
187
187
|
case 0:
|
|
188
188
|
if (onUploadStart) {
|
|
189
|
+
console.log("onUploadStart", fileList);
|
|
189
190
|
onUploadStart(fileList);
|
|
190
191
|
}
|
|
191
192
|
setISLoading(true);
|
|
192
193
|
setUploadProgress(0);
|
|
193
194
|
_context.p = 1;
|
|
194
195
|
// Convert picker results to File-like objects
|
|
195
|
-
filesToUpload = fileList.map(convertToFile);
|
|
196
|
+
filesToUpload = fileList.map(convertToFile);
|
|
197
|
+
console.log("filesToUpload", filesToUpload);
|
|
198
|
+
|
|
199
|
+
// Use the API service to upload files
|
|
196
200
|
// Note: uploadMedia will need to handle React Native file URIs
|
|
197
201
|
_context.n = 2;
|
|
198
202
|
return apiService.uploadMedia(filesToUpload, apiService.authKey);
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { View, StyleSheet, Dimensions, ActivityIndicator } from
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { View, StyleSheet, Dimensions, ActivityIndicator } from "react-native";
|
|
3
3
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
4
|
-
var _Dimensions$get = Dimensions.get(
|
|
4
|
+
var _Dimensions$get = Dimensions.get("window"),
|
|
5
5
|
SCREEN_WIDTH = _Dimensions$get.width;
|
|
6
6
|
var NUM_COLUMNS = 3;
|
|
7
|
-
var ITEM_MARGIN =
|
|
8
|
-
|
|
7
|
+
var ITEM_MARGIN = 4; // Match MediaGallery margin
|
|
8
|
+
// Calculate item size accounting for:
|
|
9
|
+
// - Container padding (md = 12px on each side = 24px total)
|
|
10
|
+
// - Grid padding (2px on each side = 4px total)
|
|
11
|
+
// - Item margins between items (4px * 2 gaps = 8px total)
|
|
12
|
+
var CONTAINER_PADDING = 24; // paddingHorizontal md (12 * 2)
|
|
13
|
+
var GRID_PADDING = 4; // padding 2 on each side (2 * 2)
|
|
14
|
+
var TOTAL_MARGINS = ITEM_MARGIN * (NUM_COLUMNS - 1) * 2; // margins between items (4px * 2 gaps = 8px)
|
|
15
|
+
var ITEM_SIZE = (SCREEN_WIDTH - CONTAINER_PADDING - GRID_PADDING - TOTAL_MARGINS) / NUM_COLUMNS;
|
|
9
16
|
var ImagesSkeleton = function ImagesSkeleton(_ref) {
|
|
10
17
|
var _ref$per_page = _ref.per_page,
|
|
11
18
|
per_page = _ref$per_page === void 0 ? 30 : _ref$per_page;
|
|
@@ -30,15 +37,15 @@ var ImagesSkeleton = function ImagesSkeleton(_ref) {
|
|
|
30
37
|
};
|
|
31
38
|
var styles = StyleSheet.create({
|
|
32
39
|
container: {
|
|
33
|
-
flexDirection:
|
|
34
|
-
flexWrap:
|
|
35
|
-
padding:
|
|
40
|
+
flexDirection: "row",
|
|
41
|
+
flexWrap: "wrap",
|
|
42
|
+
padding: 2 // Match MediaGallery grid padding
|
|
36
43
|
},
|
|
37
44
|
skeletonItem: {
|
|
38
|
-
backgroundColor:
|
|
45
|
+
backgroundColor: "#E5E5E5",
|
|
39
46
|
borderRadius: 8,
|
|
40
|
-
justifyContent:
|
|
41
|
-
alignItems:
|
|
47
|
+
justifyContent: "center",
|
|
48
|
+
alignItems: "center",
|
|
42
49
|
opacity: 0.3
|
|
43
50
|
}
|
|
44
51
|
});
|
|
@@ -191,13 +191,17 @@ var FileUpload = function FileUpload(_ref) {
|
|
|
191
191
|
while (1) switch (_context.p = _context.n) {
|
|
192
192
|
case 0:
|
|
193
193
|
if (onUploadStart) {
|
|
194
|
+
console.log("onUploadStart", fileList);
|
|
194
195
|
onUploadStart(fileList);
|
|
195
196
|
}
|
|
196
197
|
setISLoading(true);
|
|
197
198
|
setUploadProgress(0);
|
|
198
199
|
_context.p = 1;
|
|
199
200
|
// Convert picker results to File-like objects
|
|
200
|
-
filesToUpload = fileList.map(convertToFile);
|
|
201
|
+
filesToUpload = fileList.map(convertToFile);
|
|
202
|
+
console.log("filesToUpload", filesToUpload);
|
|
203
|
+
|
|
204
|
+
// Use the API service to upload files
|
|
201
205
|
// Note: uploadMedia will need to handle React Native file URIs
|
|
202
206
|
_context.n = 2;
|
|
203
207
|
return apiService.uploadMedia(filesToUpload, apiService.authKey);
|
|
@@ -8,11 +8,18 @@ var _react = _interopRequireDefault(require("react"));
|
|
|
8
8
|
var _reactNative = require("react-native");
|
|
9
9
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
10
10
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
-
var _Dimensions$get = _reactNative.Dimensions.get(
|
|
11
|
+
var _Dimensions$get = _reactNative.Dimensions.get("window"),
|
|
12
12
|
SCREEN_WIDTH = _Dimensions$get.width;
|
|
13
13
|
var NUM_COLUMNS = 3;
|
|
14
|
-
var ITEM_MARGIN =
|
|
15
|
-
|
|
14
|
+
var ITEM_MARGIN = 4; // Match MediaGallery margin
|
|
15
|
+
// Calculate item size accounting for:
|
|
16
|
+
// - Container padding (md = 12px on each side = 24px total)
|
|
17
|
+
// - Grid padding (2px on each side = 4px total)
|
|
18
|
+
// - Item margins between items (4px * 2 gaps = 8px total)
|
|
19
|
+
var CONTAINER_PADDING = 24; // paddingHorizontal md (12 * 2)
|
|
20
|
+
var GRID_PADDING = 4; // padding 2 on each side (2 * 2)
|
|
21
|
+
var TOTAL_MARGINS = ITEM_MARGIN * (NUM_COLUMNS - 1) * 2; // margins between items (4px * 2 gaps = 8px)
|
|
22
|
+
var ITEM_SIZE = (SCREEN_WIDTH - CONTAINER_PADDING - GRID_PADDING - TOTAL_MARGINS) / NUM_COLUMNS;
|
|
16
23
|
var ImagesSkeleton = function ImagesSkeleton(_ref) {
|
|
17
24
|
var _ref$per_page = _ref.per_page,
|
|
18
25
|
per_page = _ref$per_page === void 0 ? 30 : _ref$per_page;
|
|
@@ -37,15 +44,15 @@ var ImagesSkeleton = function ImagesSkeleton(_ref) {
|
|
|
37
44
|
};
|
|
38
45
|
var styles = _reactNative.StyleSheet.create({
|
|
39
46
|
container: {
|
|
40
|
-
flexDirection:
|
|
41
|
-
flexWrap:
|
|
42
|
-
padding:
|
|
47
|
+
flexDirection: "row",
|
|
48
|
+
flexWrap: "wrap",
|
|
49
|
+
padding: 2 // Match MediaGallery grid padding
|
|
43
50
|
},
|
|
44
51
|
skeletonItem: {
|
|
45
|
-
backgroundColor:
|
|
52
|
+
backgroundColor: "#E5E5E5",
|
|
46
53
|
borderRadius: 8,
|
|
47
|
-
justifyContent:
|
|
48
|
-
alignItems:
|
|
54
|
+
justifyContent: "center",
|
|
55
|
+
alignItems: "center",
|
|
49
56
|
opacity: 0.3
|
|
50
57
|
}
|
|
51
58
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tradly/asset",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.22",
|
|
4
4
|
"description": "A reusable media gallery component for uploading and selecting images, videos, and files with Tradly authentication",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|