@poolse/react-native 2.0.11 → 2.0.13

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/index.js CHANGED
@@ -5,6 +5,7 @@ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
5
  import { SvgXml, Svg, Path, Circle, G } from 'react-native-svg';
6
6
  import * as ImagePicker from 'expo-image-picker';
7
7
  import * as DocumentPicker from 'expo-document-picker';
8
+ import { manipulateAsync, SaveFormat } from 'expo-image-manipulator';
8
9
 
9
10
  // src/PoolseInbox.tsx
10
11
 
@@ -1160,24 +1161,84 @@ async function uriToBlob(uri) {
1160
1161
  }
1161
1162
  return res.blob();
1162
1163
  }
1164
+ var COMPRESSION_LONG_SIDE_PX = 1600;
1165
+ var COMPRESSION_QUALITY = 0.75;
1166
+ function getImageSize(uri) {
1167
+ return new Promise((resolve, reject) => {
1168
+ Image.getSize(uri, (width, height) => resolve({ width, height }), reject);
1169
+ });
1170
+ }
1171
+ async function compressImage({
1172
+ uri,
1173
+ width,
1174
+ height,
1175
+ filename
1176
+ }) {
1177
+ let w = width;
1178
+ let h = height;
1179
+ if (!w || !h) {
1180
+ try {
1181
+ const size = await getImageSize(uri);
1182
+ w = size.width;
1183
+ h = size.height;
1184
+ } catch {
1185
+ w = 0;
1186
+ h = 0;
1187
+ }
1188
+ }
1189
+ const longSide = Math.max(w ?? 0, h ?? 0);
1190
+ const scale = longSide > COMPRESSION_LONG_SIDE_PX ? COMPRESSION_LONG_SIDE_PX / longSide : 1;
1191
+ const actions = scale < 1 && w && h ? [{ resize: { width: Math.round(w * scale), height: Math.round(h * scale) } }] : [];
1192
+ const result = await manipulateAsync(uri, actions, {
1193
+ compress: COMPRESSION_QUALITY,
1194
+ format: SaveFormat.WEBP
1195
+ });
1196
+ const blob = await uriToBlob(result.uri);
1197
+ const base = (filename ?? `image-${Date.now()}`).replace(/\.[^.]+$/, "");
1198
+ return {
1199
+ blob,
1200
+ contentType: "image/webp",
1201
+ filename: `${base}.webp`
1202
+ };
1203
+ }
1163
1204
  async function defaultAdapter(kind) {
1164
1205
  if (kind === "image") {
1165
1206
  const res2 = await ImagePicker.launchImageLibraryAsync({
1166
1207
  mediaTypes: "images",
1167
- quality: 0.85
1208
+ // Quality 1 — picker hands back the source as-is and we do the
1209
+ // compression ourselves below. Letting the picker re-encode
1210
+ // first just chains two lossy passes.
1211
+ quality: 1
1168
1212
  });
1169
1213
  if (res2.canceled) return [];
1170
1214
  return Promise.all(
1171
1215
  res2.assets.map(async (asset) => {
1172
- const blob = await uriToBlob(asset.uri);
1173
- const contentType = asset.mimeType ?? blob.type ?? "image/jpeg";
1174
- return {
1175
- body: blob,
1176
- contentType,
1177
- byteSize: asset.fileSize ?? blob.size,
1178
- filename: asset.fileName ?? `image-${Date.now()}.jpg`,
1179
- _previewUri: asset.uri
1180
- };
1216
+ try {
1217
+ const compressed = await compressImage({
1218
+ uri: asset.uri,
1219
+ width: asset.width,
1220
+ height: asset.height,
1221
+ filename: asset.fileName ?? `image-${Date.now()}`
1222
+ });
1223
+ return {
1224
+ body: compressed.blob,
1225
+ contentType: compressed.contentType,
1226
+ byteSize: compressed.blob.size,
1227
+ filename: compressed.filename,
1228
+ _previewUri: asset.uri
1229
+ };
1230
+ } catch (err) {
1231
+ console.warn("[poolse/picker] image compression failed, sending original:", err);
1232
+ const blob = await uriToBlob(asset.uri);
1233
+ const contentType = asset.mimeType ?? blob.type ?? "image/jpeg";
1234
+ return {
1235
+ body: blob,
1236
+ contentType,
1237
+ byteSize: asset.fileSize ?? blob.size,
1238
+ filename: asset.fileName ?? `image-${Date.now()}.jpg`,
1239
+ _previewUri: asset.uri
1240
+ };
1241
+ }
1181
1242
  })
1182
1243
  );
1183
1244
  }
@@ -1188,6 +1249,24 @@ async function defaultAdapter(kind) {
1188
1249
  if (res.canceled) return [];
1189
1250
  return Promise.all(
1190
1251
  res.assets.map(async (asset) => {
1252
+ const isImage = (asset.mimeType ?? "").startsWith("image/");
1253
+ if (isImage) {
1254
+ try {
1255
+ const compressed = await compressImage({
1256
+ uri: asset.uri,
1257
+ filename: asset.name
1258
+ });
1259
+ return {
1260
+ body: compressed.blob,
1261
+ contentType: compressed.contentType,
1262
+ byteSize: compressed.blob.size,
1263
+ filename: compressed.filename,
1264
+ _previewUri: asset.uri
1265
+ };
1266
+ } catch (err) {
1267
+ console.warn("[poolse/picker] image compression failed, sending original:", err);
1268
+ }
1269
+ }
1191
1270
  const blob = await uriToBlob(asset.uri);
1192
1271
  const contentType = asset.mimeType ?? blob.type ?? "application/octet-stream";
1193
1272
  return {
@@ -1476,14 +1555,17 @@ var MessageComposer = forwardRef(
1476
1555
  const submitDisabled = disabled || sending || isUploading || value.trim().length === 0 && readyAttachmentIds.length === 0;
1477
1556
  const handleSend = async () => {
1478
1557
  if (submitDisabled) return;
1558
+ const body = value.trim();
1559
+ const replyId = replyingTo?.id;
1560
+ const attachmentIds = readyAttachmentIds;
1561
+ setValue("");
1562
+ upload.reset();
1479
1563
  setSending(true);
1480
1564
  try {
1481
- await onSend(value.trim(), {
1482
- ...replyingTo ? { quoted_message_id: replyingTo.id } : {},
1483
- ...readyAttachmentIds.length > 0 ? { attachment_ids: readyAttachmentIds } : {}
1565
+ await onSend(body, {
1566
+ ...replyId ? { quoted_message_id: replyId } : {},
1567
+ ...attachmentIds.length > 0 ? { attachment_ids: attachmentIds } : {}
1484
1568
  });
1485
- setValue("");
1486
- upload.reset();
1487
1569
  } finally {
1488
1570
  setSending(false);
1489
1571
  }