@unicitylabs/sphere-ui 0.1.25 → 0.1.27

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 (2) hide show
  1. package/dist/index.js +51 -8
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1422,6 +1422,48 @@ async function readImageSize(file) {
1422
1422
  return null;
1423
1423
  }
1424
1424
  }
1425
+ async function fitImage(file, limit) {
1426
+ if (file.type === "image/svg+xml") return file;
1427
+ if (typeof createImageBitmap !== "function" || typeof document === "undefined") return file;
1428
+ try {
1429
+ const bitmap = await createImageBitmap(file);
1430
+ const sw = bitmap.width;
1431
+ const sh = bitmap.height;
1432
+ let cropW = sw, cropH = sh, cropX = 0, cropY = 0;
1433
+ if (limit.aspectRatio) {
1434
+ if (sw / sh > limit.aspectRatio) {
1435
+ cropW = Math.round(sh * limit.aspectRatio);
1436
+ cropX = Math.round((sw - cropW) / 2);
1437
+ } else if (sw / sh < limit.aspectRatio) {
1438
+ cropH = Math.round(sw / limit.aspectRatio);
1439
+ cropY = Math.round((sh - cropH) / 2);
1440
+ }
1441
+ }
1442
+ const scale = Math.min(1, (limit.maxWidth ?? cropW) / cropW, (limit.maxHeight ?? cropH) / cropH);
1443
+ const outW = Math.max(1, Math.round(cropW * scale));
1444
+ const outH = Math.max(1, Math.round(cropH * scale));
1445
+ if (cropX === 0 && cropY === 0 && cropW === sw && cropH === sh && scale === 1) {
1446
+ bitmap.close?.();
1447
+ return file;
1448
+ }
1449
+ const canvas = document.createElement("canvas");
1450
+ canvas.width = outW;
1451
+ canvas.height = outH;
1452
+ const ctx = canvas.getContext("2d");
1453
+ if (!ctx) {
1454
+ bitmap.close?.();
1455
+ return file;
1456
+ }
1457
+ ctx.drawImage(bitmap, cropX, cropY, cropW, cropH, 0, 0, outW, outH);
1458
+ bitmap.close?.();
1459
+ const mime = file.type === "image/jpeg" || file.type === "image/webp" ? file.type : "image/png";
1460
+ const blob = await new Promise((resolve) => canvas.toBlob(resolve, mime, 0.92));
1461
+ if (!blob) return file;
1462
+ return new File([blob], file.name, { type: mime });
1463
+ } catch {
1464
+ return file;
1465
+ }
1466
+ }
1425
1467
  function MediaUploader({
1426
1468
  kind,
1427
1469
  ownerType,
@@ -1464,8 +1506,9 @@ function MediaUploader({
1464
1506
  });
1465
1507
  return;
1466
1508
  }
1467
- if (file.type !== "image/svg+xml") {
1468
- const size = await readImageSize(file);
1509
+ const fitted = await fitImage(file, limit);
1510
+ if (fitted.type !== "image/svg+xml") {
1511
+ const size = await readImageSize(fitted);
1469
1512
  if (size) {
1470
1513
  const { width, height } = size;
1471
1514
  if (limit.maxWidth && width > limit.maxWidth || limit.maxHeight && height > limit.maxHeight) {
@@ -1490,18 +1533,18 @@ function MediaUploader({
1490
1533
  }
1491
1534
  if (deferUpload) {
1492
1535
  if (previewRef.current) URL.revokeObjectURL(previewRef.current);
1493
- previewRef.current = URL.createObjectURL(file);
1494
- setState({ phase: "pending", file });
1495
- onFileSelected?.(file);
1536
+ previewRef.current = URL.createObjectURL(fitted);
1537
+ setState({ phase: "pending", file: fitted });
1538
+ onFileSelected?.(fitted);
1496
1539
  onChange(null);
1497
1540
  return;
1498
1541
  }
1499
1542
  const abort = new AbortController();
1500
- setState({ phase: "uploading", file, progress: 0, abort });
1543
+ setState({ phase: "uploading", file: fitted, progress: 0, abort });
1501
1544
  if (previewRef.current) URL.revokeObjectURL(previewRef.current);
1502
- previewRef.current = URL.createObjectURL(file);
1545
+ previewRef.current = URL.createObjectURL(fitted);
1503
1546
  try {
1504
- const result = await uploadFn(file, {
1547
+ const result = await uploadFn(fitted, {
1505
1548
  kind,
1506
1549
  ownerType,
1507
1550
  ownerId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unicitylabs/sphere-ui",
3
- "version": "0.1.25",
3
+ "version": "0.1.27",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",