@poolse/react-native 2.1.0 → 2.1.2

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,8 @@ 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
- }
2641
+ var markdownit = Markdown.MarkdownIt({ typographer: false, linkify: true });
2628
2642
  function renderMarkdown(body, args) {
2629
- const Markdown = loadMarkdown();
2630
- if (!Markdown) return null;
2631
2643
  const baseText = {
2632
2644
  color: args.textColor,
2633
2645
  fontFamily: args.fontFamily,
@@ -2672,7 +2684,7 @@ function renderMarkdown(body, args) {
2672
2684
  opacity: 0.85
2673
2685
  }
2674
2686
  };
2675
- return react.createElement(Markdown, { style, onLinkPress: args.onLinkPress }, body);
2687
+ return react.createElement(Markdown__default.default, { style, markdownit, onLinkPress: args.onLinkPress }, body);
2676
2688
  }
2677
2689
  function MessageBubble({
2678
2690
  message,
@@ -2770,53 +2782,46 @@ function MessageBubble({
2770
2782
  ) : null,
2771
2783
  renderAttachments && images.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(ImageMosaic, { images, maxWidth: contentMaxWidth }) : null,
2772
2784
  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,
2785
+ body.length > 0 ? isDeleted ? /* @__PURE__ */ jsxRuntime.jsx(
2786
+ reactNative.Text,
2787
+ {
2788
+ style: [
2789
+ styles15.body,
2777
2790
  {
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"
2791
+ color: theme.colors.ink3,
2792
+ fontFamily: theme.type.fontBody,
2793
+ fontSize: theme.type.bodySize,
2794
+ lineHeight: theme.type.lineHeight,
2795
+ fontStyle: "italic"
2789
2796
  }
2790
- );
2797
+ ],
2798
+ children: "Message deleted"
2791
2799
  }
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,
2800
+ ) : markdown ? renderMarkdown(truncated, {
2801
+ textColor,
2802
+ linkColor: isSelf ? theme.colors.onBrand : theme.colors.brand,
2803
+ fontFamily: theme.type.fontBody,
2804
+ fontSize: theme.type.bodySize,
2805
+ lineHeight: theme.type.lineHeight,
2806
+ onLinkPress: (url) => {
2807
+ void reactNative.Linking.openURL(url).catch(() => void 0);
2808
+ return false;
2809
+ }
2810
+ }) : /* @__PURE__ */ jsxRuntime.jsx(
2811
+ reactNative.Text,
2812
+ {
2813
+ style: [
2814
+ styles15.body,
2815
+ {
2816
+ color: textColor,
2817
+ fontFamily: theme.type.fontBody,
2818
+ fontSize: theme.type.bodySize,
2819
+ lineHeight: theme.type.lineHeight
2820
+ }
2821
+ ],
2822
+ children: truncated
2823
+ }
2824
+ ) : null,
2820
2825
  maxBodyLength > 0 && body.length > maxBodyLength ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: () => setExpanded((e) => !e), children: /* @__PURE__ */ jsxRuntime.jsx(
2821
2826
  reactNative.Text,
2822
2827
  {
@@ -3353,7 +3358,7 @@ function MessageRow({
3353
3358
  ...msg.body && !msg.deleted_at ? {
3354
3359
  onCopy: () => {
3355
3360
  setActionsOpen(false);
3356
- void copyToClipboard(msg.body ?? "");
3361
+ void Clipboard__namespace.setStringAsync(msg.body ?? "");
3357
3362
  }
3358
3363
  } : {},
3359
3364
  ...onStartEdit ? {
@@ -3445,27 +3450,6 @@ var styles17 = reactNative.StyleSheet.create({
3445
3450
  marginTop: 2
3446
3451
  }
3447
3452
  });
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
3453
  var SHEET_HEIGHT_FRACTION = 0.88;
3470
3454
  function ThreadView({
3471
3455
  visible,