@poolse/react-native 2.1.0 → 2.1.1

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.cjs CHANGED
@@ -8,6 +8,10 @@ var reactNativeSvg = require('react-native-svg');
8
8
  var ImagePicker = require('expo-image-picker');
9
9
  var DocumentPicker = require('expo-document-picker');
10
10
  var expoImageManipulator = require('expo-image-manipulator');
11
+ var Clipboard = require('expo-clipboard');
12
+ var Markdown = require('react-native-markdown-display');
13
+
14
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
11
15
 
12
16
  function _interopNamespace(e) {
13
17
  if (e && e.__esModule) return e;
@@ -29,6 +33,8 @@ function _interopNamespace(e) {
29
33
 
30
34
  var ImagePicker__namespace = /*#__PURE__*/_interopNamespace(ImagePicker);
31
35
  var DocumentPicker__namespace = /*#__PURE__*/_interopNamespace(DocumentPicker);
36
+ var Clipboard__namespace = /*#__PURE__*/_interopNamespace(Clipboard);
37
+ var Markdown__default = /*#__PURE__*/_interopDefault(Markdown);
32
38
 
33
39
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
34
40
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
@@ -316,6 +322,10 @@ var ICONS = {
316
322
  vb: "0 0 24 24",
317
323
  d: '<path d="M6 9.2a6 6 0 0 1 12 0c0 4.8 1.4 6.3 1.9 6.8H4.1C4.6 15.5 6 14 6 9.2Z"/><path d="M9.6 19.8a2.5 2.5 0 0 0 4.8 0"/>'
318
324
  },
325
+ camera: {
326
+ vb: "0 0 24 24",
327
+ d: '<path d="M3 8.5a2 2 0 0 1 2-2h2.4l1.4-2h6.4l1.4 2H19a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-9Z"/><circle cx="12" cy="13" r="3.5"/>'
328
+ },
319
329
  "check-double": {
320
330
  vb: "0 0 24 24",
321
331
  d: '<path d="M2.5 12.8 6.9 17 15.4 7.6"/><path d="M11.4 16.4 12.3 17.2 21 7.6"/>'
@@ -1135,7 +1145,12 @@ function useUploadPreview() {
1135
1145
  getPreview: ctx?.getPreview ?? (() => null)
1136
1146
  };
1137
1147
  }
1138
- function AttachmentPicker({ visible, onClose, onPickInputs }) {
1148
+ function AttachmentPicker({
1149
+ visible,
1150
+ onClose,
1151
+ onPickInputs,
1152
+ camera = true
1153
+ }) {
1139
1154
  const theme = usePoolseTheme();
1140
1155
  const upload = useSharedUpload();
1141
1156
  const { setPreview } = useUploadPreview();
@@ -1169,8 +1184,12 @@ function AttachmentPicker({ visible, onClose, onPickInputs }) {
1169
1184
  theme.shadows.lg
1170
1185
  ],
1171
1186
  children: [
1187
+ camera ? /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { style: styles6.item, onPress: () => pickFromKind("camera"), children: [
1188
+ /* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "camera", size: 20, color: theme.colors.ink2 }),
1189
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles6.itemText, { color: theme.colors.ink }], children: "Camera" })
1190
+ ] }) : null,
1172
1191
  /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { style: styles6.item, onPress: () => pickFromKind("image"), children: [
1173
- /* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "attachment", size: 20, color: theme.colors.ink2 }),
1192
+ /* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "image", size: 20, color: theme.colors.ink2 }),
1174
1193
  /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles6.itemText, { color: theme.colors.ink }], children: "Photo or video" })
1175
1194
  ] }),
1176
1195
  /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { style: styles6.item, onPress: () => pickFromKind("document"), children: [
@@ -1229,7 +1248,52 @@ async function compressImage({
1229
1248
  filename: `${base}.webp`
1230
1249
  };
1231
1250
  }
1251
+ async function assetsToInputs(assets) {
1252
+ return Promise.all(
1253
+ assets.map(async (asset) => {
1254
+ try {
1255
+ const compressed = await compressImage({
1256
+ uri: asset.uri,
1257
+ width: asset.width,
1258
+ height: asset.height,
1259
+ filename: asset.fileName ?? `image-${Date.now()}`
1260
+ });
1261
+ return {
1262
+ body: compressed.blob,
1263
+ contentType: compressed.contentType,
1264
+ byteSize: compressed.blob.size,
1265
+ filename: compressed.filename,
1266
+ _previewUri: asset.uri
1267
+ };
1268
+ } catch (err) {
1269
+ console.warn("[poolse/picker] image compression failed, sending original:", err);
1270
+ const blob = await uriToBlob(asset.uri);
1271
+ const contentType = asset.mimeType ?? blob.type ?? "image/jpeg";
1272
+ return {
1273
+ body: blob,
1274
+ contentType,
1275
+ byteSize: asset.fileSize ?? blob.size,
1276
+ filename: asset.fileName ?? `image-${Date.now()}.jpg`,
1277
+ _previewUri: asset.uri
1278
+ };
1279
+ }
1280
+ })
1281
+ );
1282
+ }
1232
1283
  async function defaultAdapter(kind) {
1284
+ if (kind === "camera") {
1285
+ const perm = await ImagePicker__namespace.requestCameraPermissionsAsync();
1286
+ if (!perm.granted) {
1287
+ console.warn("[poolse/picker] camera permission denied");
1288
+ return [];
1289
+ }
1290
+ const res2 = await ImagePicker__namespace.launchCameraAsync({
1291
+ mediaTypes: "images",
1292
+ quality: 1
1293
+ });
1294
+ if (res2.canceled) return [];
1295
+ return assetsToInputs(res2.assets);
1296
+ }
1233
1297
  if (kind === "image") {
1234
1298
  const res2 = await ImagePicker__namespace.launchImageLibraryAsync({
1235
1299
  mediaTypes: "images",
@@ -1239,36 +1303,7 @@ async function defaultAdapter(kind) {
1239
1303
  quality: 1
1240
1304
  });
1241
1305
  if (res2.canceled) return [];
1242
- return Promise.all(
1243
- res2.assets.map(async (asset) => {
1244
- try {
1245
- const compressed = await compressImage({
1246
- uri: asset.uri,
1247
- width: asset.width,
1248
- height: asset.height,
1249
- filename: asset.fileName ?? `image-${Date.now()}`
1250
- });
1251
- return {
1252
- body: compressed.blob,
1253
- contentType: compressed.contentType,
1254
- byteSize: compressed.blob.size,
1255
- filename: compressed.filename,
1256
- _previewUri: asset.uri
1257
- };
1258
- } catch (err) {
1259
- console.warn("[poolse/picker] image compression failed, sending original:", err);
1260
- const blob = await uriToBlob(asset.uri);
1261
- const contentType = asset.mimeType ?? blob.type ?? "image/jpeg";
1262
- return {
1263
- body: blob,
1264
- contentType,
1265
- byteSize: asset.fileSize ?? blob.size,
1266
- filename: asset.fileName ?? `image-${Date.now()}.jpg`,
1267
- _previewUri: asset.uri
1268
- };
1269
- }
1270
- })
1271
- );
1306
+ return assetsToInputs(res2.assets);
1272
1307
  }
1273
1308
  const res = await DocumentPicker__namespace.getDocumentAsync({
1274
1309
  copyToCacheDirectory: true,
@@ -2603,31 +2638,7 @@ var styles14 = reactNative.StyleSheet.create({
2603
2638
  borderRadius: 20
2604
2639
  }
2605
2640
  });
2606
- var MarkdownModule;
2607
- var warned = false;
2608
- function loadMarkdown() {
2609
- if (MarkdownModule === void 0) {
2610
- try {
2611
- MarkdownModule = __require("react-native-markdown-display");
2612
- } catch {
2613
- MarkdownModule = null;
2614
- }
2615
- }
2616
- const fn = MarkdownModule?.default;
2617
- if (!fn) {
2618
- if (!warned) {
2619
- warned = true;
2620
- console.warn(
2621
- "[@poolse/react-native] Markdown rendering requires `react-native-markdown-display`. Install it to enable bold/italic/code/links in message bubbles. Falling back to plain text."
2622
- );
2623
- }
2624
- return null;
2625
- }
2626
- return fn;
2627
- }
2628
2641
  function renderMarkdown(body, args) {
2629
- const Markdown = loadMarkdown();
2630
- if (!Markdown) return null;
2631
2642
  const baseText = {
2632
2643
  color: args.textColor,
2633
2644
  fontFamily: args.fontFamily,
@@ -2672,7 +2683,7 @@ function renderMarkdown(body, args) {
2672
2683
  opacity: 0.85
2673
2684
  }
2674
2685
  };
2675
- return react.createElement(Markdown, { style, onLinkPress: args.onLinkPress }, body);
2686
+ return react.createElement(Markdown__default.default, { style, onLinkPress: args.onLinkPress }, body);
2676
2687
  }
2677
2688
  function MessageBubble({
2678
2689
  message,
@@ -2770,53 +2781,46 @@ function MessageBubble({
2770
2781
  ) : null,
2771
2782
  renderAttachments && images.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(ImageMosaic, { images, maxWidth: contentMaxWidth }) : null,
2772
2783
  renderAttachments && files.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { gap: theme.spacing.xs, marginBottom: theme.spacing.xs }, children: files.map((att) => /* @__PURE__ */ jsxRuntime.jsx(AttachmentPreview, { attachment: att, maxWidth: contentMaxWidth }, att.id)) }) : null,
2773
- body.length > 0 ? (() => {
2774
- if (isDeleted) {
2775
- return /* @__PURE__ */ jsxRuntime.jsx(
2776
- reactNative.Text,
2784
+ body.length > 0 ? isDeleted ? /* @__PURE__ */ jsxRuntime.jsx(
2785
+ reactNative.Text,
2786
+ {
2787
+ style: [
2788
+ styles15.body,
2777
2789
  {
2778
- style: [
2779
- styles15.body,
2780
- {
2781
- color: theme.colors.ink3,
2782
- fontFamily: theme.type.fontBody,
2783
- fontSize: theme.type.bodySize,
2784
- lineHeight: theme.type.lineHeight,
2785
- fontStyle: "italic"
2786
- }
2787
- ],
2788
- children: "Message deleted"
2790
+ color: theme.colors.ink3,
2791
+ fontFamily: theme.type.fontBody,
2792
+ fontSize: theme.type.bodySize,
2793
+ lineHeight: theme.type.lineHeight,
2794
+ fontStyle: "italic"
2789
2795
  }
2790
- );
2796
+ ],
2797
+ children: "Message deleted"
2791
2798
  }
2792
- const md = markdown ? renderMarkdown(truncated, {
2793
- textColor,
2794
- linkColor: isSelf ? theme.colors.onBrand : theme.colors.brand,
2795
- fontFamily: theme.type.fontBody,
2796
- fontSize: theme.type.bodySize,
2797
- lineHeight: theme.type.lineHeight,
2798
- onLinkPress: (url) => {
2799
- void reactNative.Linking.openURL(url).catch(() => void 0);
2800
- return false;
2801
- }
2802
- }) : null;
2803
- if (md) return md;
2804
- return /* @__PURE__ */ jsxRuntime.jsx(
2805
- reactNative.Text,
2806
- {
2807
- style: [
2808
- styles15.body,
2809
- {
2810
- color: textColor,
2811
- fontFamily: theme.type.fontBody,
2812
- fontSize: theme.type.bodySize,
2813
- lineHeight: theme.type.lineHeight
2814
- }
2815
- ],
2816
- children: truncated
2817
- }
2818
- );
2819
- })() : null,
2799
+ ) : markdown ? renderMarkdown(truncated, {
2800
+ textColor,
2801
+ linkColor: isSelf ? theme.colors.onBrand : theme.colors.brand,
2802
+ fontFamily: theme.type.fontBody,
2803
+ fontSize: theme.type.bodySize,
2804
+ lineHeight: theme.type.lineHeight,
2805
+ onLinkPress: (url) => {
2806
+ void reactNative.Linking.openURL(url).catch(() => void 0);
2807
+ return false;
2808
+ }
2809
+ }) : /* @__PURE__ */ jsxRuntime.jsx(
2810
+ reactNative.Text,
2811
+ {
2812
+ style: [
2813
+ styles15.body,
2814
+ {
2815
+ color: textColor,
2816
+ fontFamily: theme.type.fontBody,
2817
+ fontSize: theme.type.bodySize,
2818
+ lineHeight: theme.type.lineHeight
2819
+ }
2820
+ ],
2821
+ children: truncated
2822
+ }
2823
+ ) : null,
2820
2824
  maxBodyLength > 0 && body.length > maxBodyLength ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: () => setExpanded((e) => !e), children: /* @__PURE__ */ jsxRuntime.jsx(
2821
2825
  reactNative.Text,
2822
2826
  {
@@ -3353,7 +3357,7 @@ function MessageRow({
3353
3357
  ...msg.body && !msg.deleted_at ? {
3354
3358
  onCopy: () => {
3355
3359
  setActionsOpen(false);
3356
- void copyToClipboard(msg.body ?? "");
3360
+ void Clipboard__namespace.setStringAsync(msg.body ?? "");
3357
3361
  }
3358
3362
  } : {},
3359
3363
  ...onStartEdit ? {
@@ -3445,27 +3449,6 @@ var styles17 = reactNative.StyleSheet.create({
3445
3449
  marginTop: 2
3446
3450
  }
3447
3451
  });
3448
- var clipboardModule;
3449
- var clipboardWarned = false;
3450
- async function copyToClipboard(text) {
3451
- if (clipboardModule === void 0) {
3452
- try {
3453
- clipboardModule = __require("expo-clipboard");
3454
- } catch {
3455
- clipboardModule = null;
3456
- }
3457
- }
3458
- if (!clipboardModule?.setStringAsync) {
3459
- if (!clipboardWarned) {
3460
- clipboardWarned = true;
3461
- console.warn(
3462
- "[@poolse/react-native] Copy action requires `expo-clipboard`. Install it to enable copy-to-clipboard."
3463
- );
3464
- }
3465
- return;
3466
- }
3467
- await clipboardModule.setStringAsync(text);
3468
- }
3469
3452
  var SHEET_HEIGHT_FRACTION = 0.88;
3470
3453
  function ThreadView({
3471
3454
  visible,