@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 +107 -123
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -2
- package/dist/index.d.ts +14 -2
- package/dist/index.js +104 -124
- package/dist/index.js.map +1 -1
- package/package.json +3 -9
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({
|
|
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: "
|
|
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
|
|
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
|
|
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(
|
|
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
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2785
|
+
body.length > 0 ? isDeleted ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2786
|
+
reactNative.Text,
|
|
2787
|
+
{
|
|
2788
|
+
style: [
|
|
2789
|
+
styles15.body,
|
|
2777
2790
|
{
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
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
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
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
|
|
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,
|