@poolse/react-native 2.12.0 → 2.13.0
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/CHANGELOG.md +132 -89
- package/README.md +238 -238
- package/dist/index.cjs +1188 -400
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +469 -63
- package/dist/index.d.ts +469 -63
- package/dist/index.js +1180 -401
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var react$1 = require('@poolse/react');
|
|
4
4
|
var react = require('react');
|
|
5
|
+
var reactNative = require('react-native');
|
|
5
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
-
var react$1 = require('@poolse/react');
|
|
7
7
|
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
11
|
var Clipboard = require('expo-clipboard');
|
|
12
12
|
var Markdown = require('react-native-markdown-display');
|
|
13
|
+
var reactNativeSafeAreaContext = require('react-native-safe-area-context');
|
|
13
14
|
|
|
14
15
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
15
16
|
|
|
@@ -206,79 +207,6 @@ function PoolseTheme({ mode, theme, children }) {
|
|
|
206
207
|
function usePoolseTheme() {
|
|
207
208
|
return react.useContext(ThemeContext) ?? defaultLightTheme;
|
|
208
209
|
}
|
|
209
|
-
function CallVideoGrid({ participants, livekitReactNative, labelFor }) {
|
|
210
|
-
const theme = usePoolseTheme();
|
|
211
|
-
const label = labelFor ?? ((id) => `User ${id.slice(0, 6)}`);
|
|
212
|
-
const VideoTrack = livekitReactNative?.VideoTrack;
|
|
213
|
-
if (participants.length === 0) return null;
|
|
214
|
-
const columns = participants.length <= 1 ? 1 : 2;
|
|
215
|
-
const basis = columns === 1 ? "100%" : "48%";
|
|
216
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles.grid, children: participants.map((participant) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
217
|
-
reactNative.View,
|
|
218
|
-
{
|
|
219
|
-
style: [
|
|
220
|
-
styles.tile,
|
|
221
|
-
{
|
|
222
|
-
flexBasis: basis,
|
|
223
|
-
backgroundColor: theme.colors.surface,
|
|
224
|
-
// A ring rather than a badge: it reads at a glance in a
|
|
225
|
-
// grid, and doesn't cover a face.
|
|
226
|
-
borderColor: participant.speaking ? theme.colors.brand : "transparent"
|
|
227
|
-
}
|
|
228
|
-
],
|
|
229
|
-
children: [
|
|
230
|
-
participant.videoTrackRef && VideoTrack ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
231
|
-
VideoTrack,
|
|
232
|
-
{
|
|
233
|
-
trackRef: participant.videoTrackRef,
|
|
234
|
-
style: styles.video,
|
|
235
|
-
objectFit: "cover",
|
|
236
|
-
mirror: participant.isSelf,
|
|
237
|
-
zOrder: participant.isSelf ? 1 : 0
|
|
238
|
-
}
|
|
239
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles.placeholder, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles.initial, { color: theme.colors.ink3 }], children: label(participant.userId).slice(0, 1).toUpperCase() }) }),
|
|
240
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles.caption, children: [
|
|
241
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { numberOfLines: 1, style: [styles.name, { color: theme.colors.onBrand }], children: participant.isSelf ? "You" : participant.name ?? label(participant.userId) }),
|
|
242
|
-
!participant.micEnabled && // Muted is worth showing even for yourself — it is the
|
|
243
|
-
// answer to "why can nobody hear me".
|
|
244
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles.muted, { color: theme.colors.onBrand }], children: "muted" })
|
|
245
|
-
] })
|
|
246
|
-
]
|
|
247
|
-
},
|
|
248
|
-
participant.userId
|
|
249
|
-
)) });
|
|
250
|
-
}
|
|
251
|
-
var styles = reactNative.StyleSheet.create({
|
|
252
|
-
grid: {
|
|
253
|
-
flex: 1,
|
|
254
|
-
flexDirection: "row",
|
|
255
|
-
flexWrap: "wrap",
|
|
256
|
-
justifyContent: "center",
|
|
257
|
-
alignContent: "center",
|
|
258
|
-
gap: 8
|
|
259
|
-
},
|
|
260
|
-
tile: {
|
|
261
|
-
aspectRatio: 3 / 4,
|
|
262
|
-
borderRadius: 16,
|
|
263
|
-
borderWidth: 2,
|
|
264
|
-
overflow: "hidden",
|
|
265
|
-
justifyContent: "flex-end"
|
|
266
|
-
},
|
|
267
|
-
video: { ...reactNative.StyleSheet.absoluteFillObject },
|
|
268
|
-
placeholder: { ...reactNative.StyleSheet.absoluteFillObject, alignItems: "center", justifyContent: "center" },
|
|
269
|
-
initial: { fontSize: 48, fontWeight: "600" },
|
|
270
|
-
caption: {
|
|
271
|
-
flexDirection: "row",
|
|
272
|
-
alignItems: "center",
|
|
273
|
-
gap: 6,
|
|
274
|
-
paddingHorizontal: 10,
|
|
275
|
-
paddingVertical: 6,
|
|
276
|
-
// Legible over both a bright video frame and a flat placeholder.
|
|
277
|
-
backgroundColor: "rgba(0,0,0,0.45)"
|
|
278
|
-
},
|
|
279
|
-
name: { flexShrink: 1, fontSize: 13, fontWeight: "600" },
|
|
280
|
-
muted: { fontSize: 11, opacity: 0.85 }
|
|
281
|
-
});
|
|
282
210
|
|
|
283
211
|
// src/primitives/userColor.ts
|
|
284
212
|
var PALETTE = [
|
|
@@ -317,7 +245,7 @@ function Avatar({ src, name, seed, online, size = "md" }) {
|
|
|
317
245
|
reactNative.View,
|
|
318
246
|
{
|
|
319
247
|
style: [
|
|
320
|
-
|
|
248
|
+
styles.root,
|
|
321
249
|
{
|
|
322
250
|
width: dim,
|
|
323
251
|
height: dim,
|
|
@@ -351,7 +279,7 @@ function Avatar({ src, name, seed, online, size = "md" }) {
|
|
|
351
279
|
reactNative.View,
|
|
352
280
|
{
|
|
353
281
|
style: [
|
|
354
|
-
|
|
282
|
+
styles.presence,
|
|
355
283
|
{
|
|
356
284
|
backgroundColor: theme.colors.presence,
|
|
357
285
|
borderColor: theme.colors.surface,
|
|
@@ -371,7 +299,7 @@ function computeInitials(name) {
|
|
|
371
299
|
const parts = name.trim().split(/\s+/).slice(0, 2);
|
|
372
300
|
return parts.map((p) => p.charAt(0).toUpperCase()).join("").slice(0, 2) || "?";
|
|
373
301
|
}
|
|
374
|
-
var
|
|
302
|
+
var styles = reactNative.StyleSheet.create({
|
|
375
303
|
root: {
|
|
376
304
|
alignItems: "center",
|
|
377
305
|
justifyContent: "center",
|
|
@@ -395,10 +323,18 @@ var ICONS = {
|
|
|
395
323
|
vb: "0 0 24 24",
|
|
396
324
|
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"/>'
|
|
397
325
|
},
|
|
326
|
+
bluetooth: {
|
|
327
|
+
vb: "0 0 24 24",
|
|
328
|
+
d: '<path d="M7.5 7.5 16.5 16.5 12 21V3l4.5 4.5L7.5 16.5"/>'
|
|
329
|
+
},
|
|
398
330
|
camera: {
|
|
399
331
|
vb: "0 0 24 24",
|
|
400
332
|
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"/>'
|
|
401
333
|
},
|
|
334
|
+
"camera-flip": {
|
|
335
|
+
vb: "0 0 24 24",
|
|
336
|
+
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"/><path d="M14.6 13a2.6 2.6 0 0 1-4.5 1.8"/><path d="M9.4 13a2.6 2.6 0 0 1 4.5-1.8"/><path d="M13.9 9.6v1.7h-1.7"/><path d="M10.1 16.4v-1.7h1.7"/>'
|
|
337
|
+
},
|
|
402
338
|
"check-double": {
|
|
403
339
|
vb: "0 0 24 24",
|
|
404
340
|
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"/>'
|
|
@@ -415,6 +351,10 @@ var ICONS = {
|
|
|
415
351
|
vb: "0 0 24 24",
|
|
416
352
|
d: '<path d="M9 5 16 12 9 19"/>'
|
|
417
353
|
},
|
|
354
|
+
"chevron-up": {
|
|
355
|
+
vb: "0 0 24 24",
|
|
356
|
+
d: '<path d="M6 14.5 12 8.5 18 14.5"/>'
|
|
357
|
+
},
|
|
418
358
|
close: {
|
|
419
359
|
vb: "0 0 24 24",
|
|
420
360
|
d: '<path d="M6 6 18 18M18 6 6 18"/>'
|
|
@@ -443,6 +383,10 @@ var ICONS = {
|
|
|
443
383
|
vb: "0 0 24 24",
|
|
444
384
|
d: '<circle cx="12" cy="12" r="8.6"/><circle cx="9" cy="10" r="1" fill="currentColor" stroke="none"/><circle cx="15" cy="10" r="1" fill="currentColor" stroke="none"/><path d="M8.4 14.2a4.6 4.6 0 0 0 7.2 0"/>'
|
|
445
385
|
},
|
|
386
|
+
headphones: {
|
|
387
|
+
vb: "0 0 24 24",
|
|
388
|
+
d: '<path d="M4 14v-2a8 8 0 0 1 16 0v2"/><path d="M4 14h2.6a1.4 1.4 0 0 1 1.4 1.4v3.2A1.4 1.4 0 0 1 6.6 20H5.4A1.4 1.4 0 0 1 4 18.6Z"/><path d="M20 14h-2.6a1.4 1.4 0 0 0-1.4 1.4v3.2A1.4 1.4 0 0 0 17.4 20h1.2A1.4 1.4 0 0 0 20 18.6Z"/>'
|
|
389
|
+
},
|
|
446
390
|
heart: {
|
|
447
391
|
vb: "0 0 24 24",
|
|
448
392
|
d: '<path d="M12 20.3 4.4 12.9a4.6 4.6 0 1 1 6.5-6.5l1.1 1.1 1.1-1.1a4.6 4.6 0 1 1 6.5 6.5L12 20.3Z"/>'
|
|
@@ -479,6 +423,10 @@ var ICONS = {
|
|
|
479
423
|
vb: "0 0 24 24",
|
|
480
424
|
d: '<rect x="9" y="2.6" width="6" height="11.2" rx="3"/><path d="M5.6 11.2a6.4 6.4 0 0 0 12.8 0"/><path d="M12 17.6v3.4"/><path d="M8.6 21h6.8"/>'
|
|
481
425
|
},
|
|
426
|
+
"mic-off": {
|
|
427
|
+
vb: "0 0 24 24",
|
|
428
|
+
d: '<rect x="9" y="2.6" width="6" height="11.2" rx="3"/><path d="M5.6 11.2a6.4 6.4 0 0 0 12.8 0"/><path d="M12 17.6v3.4"/><path d="M8.6 21h6.8"/><path d="M3.6 3.2 20.4 20.8"/>'
|
|
429
|
+
},
|
|
482
430
|
"more-h": {
|
|
483
431
|
vb: "0 0 24 24",
|
|
484
432
|
d: '<circle cx="5.4" cy="12" r="1.6" fill="currentColor" stroke="none"/><circle cx="12" cy="12" r="1.6" fill="currentColor" stroke="none"/><circle cx="18.6" cy="12" r="1.6" fill="currentColor" stroke="none"/>'
|
|
@@ -487,6 +435,14 @@ var ICONS = {
|
|
|
487
435
|
vb: "0 0 24 24",
|
|
488
436
|
d: '<circle cx="12" cy="5.4" r="1.6" fill="currentColor" stroke="none"/><circle cx="12" cy="12" r="1.6" fill="currentColor" stroke="none"/><circle cx="12" cy="18.6" r="1.6" fill="currentColor" stroke="none"/>'
|
|
489
437
|
},
|
|
438
|
+
phone: {
|
|
439
|
+
vb: "0 0 24 24",
|
|
440
|
+
d: '<path d="M6.6 3.5h3l1.5 3.7-1.9 1.4a12.5 12.5 0 0 0 6.2 6.2l1.4-1.9 3.7 1.5v3a2 2 0 0 1-2.2 2A16.8 16.8 0 0 1 4.6 5.7a2 2 0 0 1 2-2.2Z"/>'
|
|
441
|
+
},
|
|
442
|
+
"phone-off": {
|
|
443
|
+
vb: "0 0 24 24",
|
|
444
|
+
d: '<g transform="rotate(135 12 12)"><path d="M6.6 3.5h3l1.5 3.7-1.9 1.4a12.5 12.5 0 0 0 6.2 6.2l1.4-1.9 3.7 1.5v3a2 2 0 0 1-2.2 2A16.8 16.8 0 0 1 4.6 5.7a2 2 0 0 1 2-2.2Z"/></g>'
|
|
445
|
+
},
|
|
490
446
|
pin: {
|
|
491
447
|
vb: "0 0 24 24",
|
|
492
448
|
d: '<path d="M9 3.4h6v1.8l-1 5.6 3 3.2H7l3-3.2-1-5.6V3.4Z"/><path d="M12 17v3.6"/>'
|
|
@@ -527,6 +483,14 @@ var ICONS = {
|
|
|
527
483
|
vb: "0 0 24 24",
|
|
528
484
|
d: '<path d="M4 7h9M17 7h3"/><circle cx="15" cy="7" r="2.1"/><path d="M4 17h3M11 17h9"/><circle cx="9" cy="17" r="2.1"/>'
|
|
529
485
|
},
|
|
486
|
+
speaker: {
|
|
487
|
+
vb: "0 0 24 24",
|
|
488
|
+
d: '<path d="M4 9.5h3.2L12 5.4v13.2L7.2 14.5H4a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1Z"/><path d="M15.6 9.2a4 4 0 0 1 0 5.6"/><path d="M18.2 6.6a7.7 7.7 0 0 1 0 10.8"/>'
|
|
489
|
+
},
|
|
490
|
+
"speaker-off": {
|
|
491
|
+
vb: "0 0 24 24",
|
|
492
|
+
d: '<path d="M4 9.5h3.2L12 5.4v13.2L7.2 14.5H4a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1Z"/><path d="M16.4 9.6 21.4 14.4"/><path d="M21.4 9.6 16.4 14.4"/>'
|
|
493
|
+
},
|
|
530
494
|
"thumbs-up": {
|
|
531
495
|
vb: "0 0 24 24",
|
|
532
496
|
d: '<path d="M7 10.4V20H4.2V10.4Z"/><path d="M7 10.4 11 3.2a2 2 0 0 1 1.9 2.2L12.4 9H18a2 2 0 0 1 2 2.4l-1.1 6A2 2 0 0 1 16.9 20H7"/>'
|
|
@@ -551,6 +515,14 @@ var ICONS = {
|
|
|
551
515
|
vb: "0 0 24 24",
|
|
552
516
|
d: '<circle cx="9" cy="8" r="3.6"/><path d="M2.6 20a6.4 6.4 0 0 1 12.8 0"/><path d="M15.8 4.7a3.6 3.6 0 0 1 0 6.6"/><path d="M17.6 20a6.4 6.4 0 0 0-3.1-5.5"/>'
|
|
553
517
|
},
|
|
518
|
+
video: {
|
|
519
|
+
vb: "0 0 24 24",
|
|
520
|
+
d: '<rect x="2.6" y="6" width="13" height="12" rx="2.4"/><path d="M15.6 11.2 21.4 8v8l-5.8-3.2Z"/>'
|
|
521
|
+
},
|
|
522
|
+
"video-off": {
|
|
523
|
+
vb: "0 0 24 24",
|
|
524
|
+
d: '<rect x="2.6" y="6" width="13" height="12" rx="2.4"/><path d="M15.6 11.2 21.4 8v8l-5.8-3.2Z"/><path d="M3.6 3.2 20.4 20.8"/>'
|
|
525
|
+
},
|
|
554
526
|
webhook: {
|
|
555
527
|
vb: "0 0 24 24",
|
|
556
528
|
d: '<circle cx="6" cy="6" r="2.6"/><circle cx="18" cy="9" r="2.6"/><circle cx="9.5" cy="18" r="2.6"/><path d="M7.9 7.9 12 12l3.7-1.5"/><path d="M11.6 12.7 9.8 16"/>'
|
|
@@ -581,16 +553,16 @@ function MemberList({
|
|
|
581
553
|
);
|
|
582
554
|
const effectiveOnline = onlineExternalIds ?? presenceOnline;
|
|
583
555
|
if (loading && members.length === 0) {
|
|
584
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [
|
|
556
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles2.placeholder, { backgroundColor: theme.colors.paper }], children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.ActivityIndicator, { color: theme.colors.brand }) });
|
|
585
557
|
}
|
|
586
558
|
if (error) {
|
|
587
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [
|
|
559
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles2.placeholder, { backgroundColor: theme.colors.paper }], children: [
|
|
588
560
|
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: { color: theme.colors.error, fontFamily: theme.type.fontBody }, children: "Failed to load members." }),
|
|
589
|
-
error.message ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
561
|
+
error.message ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles2.errorDetail, { color: theme.colors.ink3 }], children: error.message }) : null
|
|
590
562
|
] });
|
|
591
563
|
}
|
|
592
564
|
if (members.length === 0) {
|
|
593
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [
|
|
565
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles2.placeholder, { backgroundColor: theme.colors.paper }], children: typeof emptyState === "string" || emptyState == null ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: { color: theme.colors.ink3, fontFamily: theme.type.fontBody }, children: emptyState ?? "No members." }) : emptyState });
|
|
594
566
|
}
|
|
595
567
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
596
568
|
reactNative.FlatList,
|
|
@@ -629,23 +601,23 @@ function MemberRow({
|
|
|
629
601
|
const resolved = react$1.useUser(externalId);
|
|
630
602
|
const name = labelFor?.(externalId) ?? resolved.profile?.displayName ?? externalId;
|
|
631
603
|
const avatarUrl = avatarFor?.(externalId) ?? resolved.profile?.avatarUrl ?? null;
|
|
632
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
604
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles2.row, children: [
|
|
633
605
|
/* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: avatarUrl, name, seed: externalId, online, size: "md" }),
|
|
634
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
606
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles2.body, children: [
|
|
635
607
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
636
608
|
reactNative.Text,
|
|
637
609
|
{
|
|
638
|
-
style: [
|
|
610
|
+
style: [styles2.name, { color: theme.colors.ink, fontFamily: theme.type.fontBody }],
|
|
639
611
|
numberOfLines: 1,
|
|
640
612
|
children: name
|
|
641
613
|
}
|
|
642
614
|
),
|
|
643
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
615
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles2.role, { color: theme.colors.ink3 }], children: role })
|
|
644
616
|
] }),
|
|
645
|
-
onRemove ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: onRemove, hitSlop: 8, style:
|
|
617
|
+
onRemove ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: onRemove, hitSlop: 8, style: styles2.removeBtn, children: /* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "close", size: 16, color: theme.colors.ink2 }) }) : null
|
|
646
618
|
] });
|
|
647
619
|
}
|
|
648
|
-
var
|
|
620
|
+
var styles2 = reactNative.StyleSheet.create({
|
|
649
621
|
placeholder: {
|
|
650
622
|
flex: 1,
|
|
651
623
|
alignItems: "center",
|
|
@@ -748,11 +720,11 @@ function GroupDetailsSheet({
|
|
|
748
720
|
animationType: "slide",
|
|
749
721
|
onRequestClose: onClose,
|
|
750
722
|
statusBarTranslucent: true,
|
|
751
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
723
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles3.modalRoot, children: [
|
|
752
724
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
753
725
|
reactNative.Pressable,
|
|
754
726
|
{
|
|
755
|
-
style:
|
|
727
|
+
style: styles3.backdrop,
|
|
756
728
|
onPress: onClose,
|
|
757
729
|
accessibilityLabel: "Close group details"
|
|
758
730
|
}
|
|
@@ -761,7 +733,7 @@ function GroupDetailsSheet({
|
|
|
761
733
|
reactNative.Animated.View,
|
|
762
734
|
{
|
|
763
735
|
style: [
|
|
764
|
-
|
|
736
|
+
styles3.sheet,
|
|
765
737
|
{
|
|
766
738
|
backgroundColor: theme.colors.paper,
|
|
767
739
|
borderTopLeftRadius: theme.radii.xl,
|
|
@@ -771,14 +743,14 @@ function GroupDetailsSheet({
|
|
|
771
743
|
theme.shadows.lg
|
|
772
744
|
],
|
|
773
745
|
children: [
|
|
774
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { ...panHandlers, style:
|
|
775
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
746
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { ...panHandlers, style: styles3.dragHandle, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles3.dragPill, { backgroundColor: theme.colors.ink3 }] }) }),
|
|
747
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles3.headerRow, children: [
|
|
776
748
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
777
749
|
reactNative.Pressable,
|
|
778
750
|
{
|
|
779
751
|
onPress: onClose,
|
|
780
752
|
hitSlop: 16,
|
|
781
|
-
style: [
|
|
753
|
+
style: [styles3.closeBtn, { backgroundColor: theme.colors.surface2 }],
|
|
782
754
|
accessibilityLabel: "Close",
|
|
783
755
|
children: /* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "close", size: 18, color: theme.colors.ink })
|
|
784
756
|
}
|
|
@@ -787,34 +759,34 @@ function GroupDetailsSheet({
|
|
|
787
759
|
reactNative.Text,
|
|
788
760
|
{
|
|
789
761
|
style: [
|
|
790
|
-
|
|
762
|
+
styles3.headerTitle,
|
|
791
763
|
{ color: theme.colors.ink, fontFamily: theme.type.fontDisplay }
|
|
792
764
|
],
|
|
793
765
|
children: "Group details"
|
|
794
766
|
}
|
|
795
767
|
)
|
|
796
768
|
] }),
|
|
797
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
769
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles3.summary, children: [
|
|
798
770
|
/* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: null, name: title, seed: conversationId, size: "lg" }),
|
|
799
771
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
800
772
|
reactNative.Text,
|
|
801
773
|
{
|
|
802
774
|
style: [
|
|
803
|
-
|
|
775
|
+
styles3.title,
|
|
804
776
|
{ color: theme.colors.ink, fontFamily: theme.type.fontDisplay }
|
|
805
777
|
],
|
|
806
778
|
numberOfLines: 1,
|
|
807
779
|
children: title
|
|
808
780
|
}
|
|
809
781
|
),
|
|
810
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
782
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles3.subtitle, { color: theme.colors.ink3 }], children: subtitle })
|
|
811
783
|
] }),
|
|
812
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [
|
|
813
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style:
|
|
784
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles3.divider, { backgroundColor: theme.colors.border }] }),
|
|
785
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles3.sectionLabelRow, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
814
786
|
reactNative.Text,
|
|
815
787
|
{
|
|
816
788
|
style: [
|
|
817
|
-
|
|
789
|
+
styles3.sectionLabel,
|
|
818
790
|
{ color: theme.colors.ink2, fontFamily: theme.type.fontBody }
|
|
819
791
|
],
|
|
820
792
|
children: "Members"
|
|
@@ -837,7 +809,7 @@ function GroupDetailsSheet({
|
|
|
837
809
|
}
|
|
838
810
|
);
|
|
839
811
|
}
|
|
840
|
-
var
|
|
812
|
+
var styles3 = reactNative.StyleSheet.create({
|
|
841
813
|
modalRoot: {
|
|
842
814
|
flex: 1,
|
|
843
815
|
justifyContent: "flex-end"
|
|
@@ -931,7 +903,7 @@ function ChatHeader({
|
|
|
931
903
|
reactNative.View,
|
|
932
904
|
{
|
|
933
905
|
style: [
|
|
934
|
-
|
|
906
|
+
styles4.root,
|
|
935
907
|
{
|
|
936
908
|
backgroundColor: theme.colors.surface,
|
|
937
909
|
borderBottomColor: theme.colors.border
|
|
@@ -956,32 +928,32 @@ function ChatHeader({
|
|
|
956
928
|
{
|
|
957
929
|
...headerOnPress ? { onPress: headerOnPress } : {},
|
|
958
930
|
style: [
|
|
959
|
-
|
|
931
|
+
styles4.root,
|
|
960
932
|
{
|
|
961
933
|
backgroundColor: theme.colors.surface,
|
|
962
934
|
borderBottomColor: theme.colors.border
|
|
963
935
|
}
|
|
964
936
|
],
|
|
965
937
|
children: [
|
|
966
|
-
onBack ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: onBack, hitSlop: 12, style:
|
|
938
|
+
onBack ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: onBack, hitSlop: 12, style: styles4.backBtn, accessibilityLabel: "Back", children: /* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "reply", size: 20, color: theme.colors.ink }) }) : null,
|
|
967
939
|
/* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: avatarUrl, name: title, seed: avatarSeed, online: isOnline, size: "md" }),
|
|
968
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
940
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles4.titleCol, children: [
|
|
969
941
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
970
942
|
reactNative.Text,
|
|
971
943
|
{
|
|
972
|
-
style: [
|
|
944
|
+
style: [styles4.title, { color: theme.colors.ink, fontFamily: theme.type.fontDisplay }],
|
|
973
945
|
numberOfLines: 1,
|
|
974
946
|
children: title
|
|
975
947
|
}
|
|
976
948
|
),
|
|
977
|
-
subtitle ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
949
|
+
subtitle ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles4.subtitle, { color: theme.colors.ink3 }], numberOfLines: 1, children: subtitle }) : null
|
|
978
950
|
] }),
|
|
979
951
|
onMembersPress ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
980
952
|
reactNative.Pressable,
|
|
981
953
|
{
|
|
982
954
|
onPress: onMembersPress,
|
|
983
955
|
hitSlop: 12,
|
|
984
|
-
style:
|
|
956
|
+
style: styles4.actionBtn,
|
|
985
957
|
accessibilityLabel: "Show members",
|
|
986
958
|
children: /* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "users", size: 20, color: theme.colors.ink2 })
|
|
987
959
|
}
|
|
@@ -1001,7 +973,7 @@ function ChatHeader({
|
|
|
1001
973
|
) : null
|
|
1002
974
|
] });
|
|
1003
975
|
}
|
|
1004
|
-
var
|
|
976
|
+
var styles4 = reactNative.StyleSheet.create({
|
|
1005
977
|
root: {
|
|
1006
978
|
flexDirection: "row",
|
|
1007
979
|
alignItems: "center",
|
|
@@ -1059,13 +1031,13 @@ function ConversationList({
|
|
|
1059
1031
|
const error = isControlled ? controlledError ?? null : auto.error;
|
|
1060
1032
|
const counts = unreadCounts ?? (isControlled ? void 0 : auto.unreadCounts);
|
|
1061
1033
|
if (loading && conversations.length === 0) {
|
|
1062
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [
|
|
1034
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles5.placeholder, { backgroundColor: theme.colors.paper }], children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.ActivityIndicator, { color: theme.colors.brand }) });
|
|
1063
1035
|
}
|
|
1064
1036
|
if (error) {
|
|
1065
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [
|
|
1037
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles5.placeholder, { backgroundColor: theme.colors.paper }], children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: { color: theme.colors.error, fontFamily: theme.type.fontBody }, children: "Failed to load conversations." }) });
|
|
1066
1038
|
}
|
|
1067
1039
|
if (conversations.length === 0) {
|
|
1068
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [
|
|
1040
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles5.placeholder, { backgroundColor: theme.colors.paper }], children: typeof emptyState === "string" || emptyState == null ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: { color: theme.colors.ink3, fontFamily: theme.type.fontBody }, children: emptyState ?? "No conversations yet." }) : emptyState });
|
|
1069
1041
|
}
|
|
1070
1042
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1071
1043
|
reactNative.FlatList,
|
|
@@ -1115,25 +1087,25 @@ function ConversationRow({
|
|
|
1115
1087
|
{
|
|
1116
1088
|
onPress: () => onSelect?.(conv),
|
|
1117
1089
|
style: [
|
|
1118
|
-
|
|
1090
|
+
styles5.row,
|
|
1119
1091
|
{
|
|
1120
1092
|
backgroundColor: selected ? theme.colors.surface2 : "transparent"
|
|
1121
1093
|
}
|
|
1122
1094
|
],
|
|
1123
1095
|
children: [
|
|
1124
|
-
avatarUrl ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Image, { source: { uri: avatarUrl }, style:
|
|
1125
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
1096
|
+
avatarUrl ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Image, { source: { uri: avatarUrl }, style: styles5.rowAvatar }) : /* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: null, name: title, seed: avatarSeed, size: "md" }),
|
|
1097
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles5.body, children: [
|
|
1126
1098
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1127
1099
|
reactNative.Text,
|
|
1128
1100
|
{
|
|
1129
|
-
style: [
|
|
1101
|
+
style: [styles5.name, { color: theme.colors.ink, fontFamily: theme.type.fontBody }],
|
|
1130
1102
|
numberOfLines: 1,
|
|
1131
1103
|
children: title
|
|
1132
1104
|
}
|
|
1133
1105
|
),
|
|
1134
|
-
conv.last_message_preview ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
1106
|
+
conv.last_message_preview ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles5.preview, { color: theme.colors.ink3 }], numberOfLines: 1, children: conv.last_message_preview }) : conv.last_message_at ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles5.preview, { color: theme.colors.ink3 }], numberOfLines: 1, children: formatRelative(conv.last_message_at) }) : null
|
|
1135
1107
|
] }),
|
|
1136
|
-
unread > 0 ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [
|
|
1108
|
+
unread > 0 ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles5.unreadPill, { backgroundColor: theme.colors.unreadPill }], children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles5.unreadText, { color: theme.colors.unreadPillText }], children: unread > 99 ? "99+" : String(unread) }) }) : null
|
|
1137
1109
|
]
|
|
1138
1110
|
}
|
|
1139
1111
|
);
|
|
@@ -1151,7 +1123,7 @@ function formatRelative(iso) {
|
|
|
1151
1123
|
return "";
|
|
1152
1124
|
}
|
|
1153
1125
|
}
|
|
1154
|
-
var
|
|
1126
|
+
var styles5 = reactNative.StyleSheet.create({
|
|
1155
1127
|
placeholder: {
|
|
1156
1128
|
flex: 1,
|
|
1157
1129
|
alignItems: "center",
|
|
@@ -1244,11 +1216,11 @@ function AttachmentPicker({
|
|
|
1244
1216
|
onClose();
|
|
1245
1217
|
}
|
|
1246
1218
|
};
|
|
1247
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.Modal, { visible, transparent: true, animationType: "slide", onRequestClose: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { style:
|
|
1219
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.Modal, { visible, transparent: true, animationType: "slide", onRequestClose: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { style: styles6.backdrop, onPress: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1248
1220
|
reactNative.View,
|
|
1249
1221
|
{
|
|
1250
1222
|
style: [
|
|
1251
|
-
|
|
1223
|
+
styles6.sheet,
|
|
1252
1224
|
{
|
|
1253
1225
|
backgroundColor: theme.colors.surface,
|
|
1254
1226
|
borderTopLeftRadius: theme.radii.lg,
|
|
@@ -1257,19 +1229,19 @@ function AttachmentPicker({
|
|
|
1257
1229
|
theme.shadows.lg
|
|
1258
1230
|
],
|
|
1259
1231
|
children: [
|
|
1260
|
-
camera ? /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { style:
|
|
1232
|
+
camera ? /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { style: styles6.item, onPress: () => pickFromKind("camera"), children: [
|
|
1261
1233
|
/* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "camera", size: 20, color: theme.colors.ink2 }),
|
|
1262
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
1234
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles6.itemText, { color: theme.colors.ink }], children: "Camera" })
|
|
1263
1235
|
] }) : null,
|
|
1264
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { style:
|
|
1236
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { style: styles6.item, onPress: () => pickFromKind("image"), children: [
|
|
1265
1237
|
/* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "image", size: 20, color: theme.colors.ink2 }),
|
|
1266
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
1238
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles6.itemText, { color: theme.colors.ink }], children: "Photo or video" })
|
|
1267
1239
|
] }),
|
|
1268
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { style:
|
|
1240
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { style: styles6.item, onPress: () => pickFromKind("document"), children: [
|
|
1269
1241
|
/* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "attachment", size: 20, color: theme.colors.ink2 }),
|
|
1270
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
1242
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles6.itemText, { color: theme.colors.ink }], children: "File" })
|
|
1271
1243
|
] }),
|
|
1272
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { style:
|
|
1244
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { style: styles6.cancel, onPress: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles6.itemText, { color: theme.colors.brand }], children: "Cancel" }) })
|
|
1273
1245
|
]
|
|
1274
1246
|
}
|
|
1275
1247
|
) }) });
|
|
@@ -1415,7 +1387,7 @@ async function defaultAdapter(kind) {
|
|
|
1415
1387
|
})
|
|
1416
1388
|
);
|
|
1417
1389
|
}
|
|
1418
|
-
var
|
|
1390
|
+
var styles6 = reactNative.StyleSheet.create({
|
|
1419
1391
|
backdrop: {
|
|
1420
1392
|
flex: 1,
|
|
1421
1393
|
backgroundColor: "rgba(0,0,0,0.35)",
|
|
@@ -1445,11 +1417,11 @@ var styles7 = reactNative.StyleSheet.create({
|
|
|
1445
1417
|
});
|
|
1446
1418
|
function DaySeparator({ label }) {
|
|
1447
1419
|
const theme = usePoolseTheme();
|
|
1448
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style:
|
|
1420
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles7.wrap, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1449
1421
|
reactNative.View,
|
|
1450
1422
|
{
|
|
1451
1423
|
style: [
|
|
1452
|
-
|
|
1424
|
+
styles7.chip,
|
|
1453
1425
|
{
|
|
1454
1426
|
backgroundColor: theme.colors.surface2,
|
|
1455
1427
|
borderColor: theme.colors.border
|
|
@@ -1459,7 +1431,7 @@ function DaySeparator({ label }) {
|
|
|
1459
1431
|
reactNative.Text,
|
|
1460
1432
|
{
|
|
1461
1433
|
style: [
|
|
1462
|
-
|
|
1434
|
+
styles7.label,
|
|
1463
1435
|
{
|
|
1464
1436
|
color: theme.colors.ink2,
|
|
1465
1437
|
fontFamily: theme.type.fontBody
|
|
@@ -1471,7 +1443,7 @@ function DaySeparator({ label }) {
|
|
|
1471
1443
|
}
|
|
1472
1444
|
) });
|
|
1473
1445
|
}
|
|
1474
|
-
var
|
|
1446
|
+
var styles7 = reactNative.StyleSheet.create({
|
|
1475
1447
|
wrap: {
|
|
1476
1448
|
alignItems: "center",
|
|
1477
1449
|
marginVertical: 8
|
|
@@ -1498,8 +1470,8 @@ function UploadQueueStrip() {
|
|
|
1498
1470
|
{
|
|
1499
1471
|
horizontal: true,
|
|
1500
1472
|
showsHorizontalScrollIndicator: false,
|
|
1501
|
-
contentContainerStyle:
|
|
1502
|
-
style: [
|
|
1473
|
+
contentContainerStyle: styles8.scroll,
|
|
1474
|
+
style: [styles8.scrollStyle, { marginBottom: 8 }],
|
|
1503
1475
|
children: upload.queue.map((item) => {
|
|
1504
1476
|
const isError = item.status === "error";
|
|
1505
1477
|
const isUploading = item.status === "uploading" || item.status === "pending";
|
|
@@ -1510,7 +1482,7 @@ function UploadQueueStrip() {
|
|
|
1510
1482
|
if (item.status === "ready" || isError) upload.remove(item.localId);
|
|
1511
1483
|
else upload.cancel(item.localId);
|
|
1512
1484
|
};
|
|
1513
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
1485
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles8.tileWrap, children: [
|
|
1514
1486
|
isImage && previewUri ? /* @__PURE__ */ jsxRuntime.jsx(ImageTile, { uri: previewUri, uploading: isUploading, error: isError }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1515
1487
|
FileTile,
|
|
1516
1488
|
{
|
|
@@ -1525,13 +1497,13 @@ function UploadQueueStrip() {
|
|
|
1525
1497
|
{
|
|
1526
1498
|
onPress: handleClose,
|
|
1527
1499
|
hitSlop: 8,
|
|
1528
|
-
style:
|
|
1500
|
+
style: styles8.closeBtn,
|
|
1529
1501
|
accessibilityLabel: isError ? "Remove failed upload" : "Cancel upload",
|
|
1530
1502
|
children: /* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "close", size: 11, color: "#fff" })
|
|
1531
1503
|
}
|
|
1532
1504
|
) : null,
|
|
1533
|
-
isUploading ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style:
|
|
1534
|
-
isError ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [
|
|
1505
|
+
isUploading ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles8.progressOverlay, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles8.spinner, { borderColor: theme.colors.onBrand }] }) }) : null,
|
|
1506
|
+
isError ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles8.errorOverlay, { backgroundColor: "rgba(229,72,77,0.85)" }], children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles8.errorText, { color: "#fff" }], children: "Failed" }) }) : null
|
|
1535
1507
|
] }, item.localId);
|
|
1536
1508
|
})
|
|
1537
1509
|
}
|
|
@@ -1544,7 +1516,7 @@ function ImageTile({ uri, uploading, error }) {
|
|
|
1544
1516
|
{
|
|
1545
1517
|
source: { uri },
|
|
1546
1518
|
style: [
|
|
1547
|
-
|
|
1519
|
+
styles8.imageTile,
|
|
1548
1520
|
{
|
|
1549
1521
|
backgroundColor: theme.colors.surface2,
|
|
1550
1522
|
borderColor: error ? theme.colors.error : "transparent",
|
|
@@ -1566,24 +1538,24 @@ function FileTile({
|
|
|
1566
1538
|
reactNative.View,
|
|
1567
1539
|
{
|
|
1568
1540
|
style: [
|
|
1569
|
-
|
|
1541
|
+
styles8.fileTile,
|
|
1570
1542
|
{
|
|
1571
1543
|
backgroundColor: theme.colors.surface2,
|
|
1572
1544
|
borderColor: error ? theme.colors.error : uploading ? theme.colors.brand : theme.colors.border
|
|
1573
1545
|
}
|
|
1574
1546
|
],
|
|
1575
1547
|
children: [
|
|
1576
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [
|
|
1577
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
1548
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles8.fileIconBox, { backgroundColor: theme.colors.brandSoft }], children: /* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "attachment", size: 18, color: theme.colors.brand }) }),
|
|
1549
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles8.fileInfo, children: [
|
|
1578
1550
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1579
1551
|
reactNative.Text,
|
|
1580
1552
|
{
|
|
1581
|
-
style: [
|
|
1553
|
+
style: [styles8.fileName, { color: theme.colors.ink, fontFamily: theme.type.fontBody }],
|
|
1582
1554
|
numberOfLines: 1,
|
|
1583
1555
|
children: filename
|
|
1584
1556
|
}
|
|
1585
1557
|
),
|
|
1586
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
1558
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles8.fileSize, { color: theme.colors.ink3 }], children: formatBytes(size) })
|
|
1587
1559
|
] })
|
|
1588
1560
|
]
|
|
1589
1561
|
}
|
|
@@ -1597,7 +1569,7 @@ function formatBytes(n) {
|
|
|
1597
1569
|
return `${(n / 1024 / 1024 / 1024).toFixed(1)} GB`;
|
|
1598
1570
|
}
|
|
1599
1571
|
var TILE = 64;
|
|
1600
|
-
var
|
|
1572
|
+
var styles8 = reactNative.StyleSheet.create({
|
|
1601
1573
|
scrollStyle: {
|
|
1602
1574
|
overflow: "visible"
|
|
1603
1575
|
},
|
|
@@ -1813,7 +1785,7 @@ var MessageComposer = react.forwardRef(
|
|
|
1813
1785
|
reactNative.View,
|
|
1814
1786
|
{
|
|
1815
1787
|
style: [
|
|
1816
|
-
|
|
1788
|
+
styles9.wrap,
|
|
1817
1789
|
{
|
|
1818
1790
|
backgroundColor: theme.colors.surface,
|
|
1819
1791
|
borderTopColor: theme.colors.border,
|
|
@@ -1836,13 +1808,13 @@ var MessageComposer = react.forwardRef(
|
|
|
1836
1808
|
}
|
|
1837
1809
|
) : null,
|
|
1838
1810
|
attachments && !isEditing ? /* @__PURE__ */ jsxRuntime.jsx(UploadQueueStrip, {}) : null,
|
|
1839
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
1811
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles9.row, children: [
|
|
1840
1812
|
attachments && onAttachPress ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1841
1813
|
reactNative.Pressable,
|
|
1842
1814
|
{
|
|
1843
1815
|
onPress: onAttachPress,
|
|
1844
1816
|
hitSlop: 8,
|
|
1845
|
-
style:
|
|
1817
|
+
style: styles9.iconBtn,
|
|
1846
1818
|
accessibilityLabel: "Attach file",
|
|
1847
1819
|
children: /* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "attachment", size: 22, color: theme.colors.ink2 })
|
|
1848
1820
|
}
|
|
@@ -1861,7 +1833,7 @@ var MessageComposer = react.forwardRef(
|
|
|
1861
1833
|
multiline: true,
|
|
1862
1834
|
editable: !disabled,
|
|
1863
1835
|
style: [
|
|
1864
|
-
|
|
1836
|
+
styles9.input,
|
|
1865
1837
|
{
|
|
1866
1838
|
color: theme.colors.ink,
|
|
1867
1839
|
backgroundColor: theme.colors.surface2,
|
|
@@ -1878,7 +1850,7 @@ var MessageComposer = react.forwardRef(
|
|
|
1878
1850
|
onPress: handleSend,
|
|
1879
1851
|
disabled: submitDisabled,
|
|
1880
1852
|
style: [
|
|
1881
|
-
|
|
1853
|
+
styles9.sendBtn,
|
|
1882
1854
|
{
|
|
1883
1855
|
backgroundColor: submitDisabled ? theme.colors.ink3 : theme.colors.brand,
|
|
1884
1856
|
opacity: submitDisabled ? 0.6 : 1
|
|
@@ -1900,7 +1872,7 @@ function EditChip({ message, onCancel }) {
|
|
|
1900
1872
|
reactNative.View,
|
|
1901
1873
|
{
|
|
1902
1874
|
style: [
|
|
1903
|
-
|
|
1875
|
+
styles9.replyChip,
|
|
1904
1876
|
{
|
|
1905
1877
|
backgroundColor: theme.colors.surface2,
|
|
1906
1878
|
borderLeftColor: theme.colors.brand
|
|
@@ -1908,10 +1880,10 @@ function EditChip({ message, onCancel }) {
|
|
|
1908
1880
|
],
|
|
1909
1881
|
children: [
|
|
1910
1882
|
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: { flex: 1 }, children: [
|
|
1911
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
1912
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
1883
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles9.replyName, { color: theme.colors.brand }], children: "Editing message" }),
|
|
1884
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles9.replyBody, { color: theme.colors.ink2 }], numberOfLines: 1, children: message.body ?? "\u2026" })
|
|
1913
1885
|
] }),
|
|
1914
|
-
onCancel ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: onCancel, hitSlop: 8, style:
|
|
1886
|
+
onCancel ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: onCancel, hitSlop: 8, style: styles9.replyCancel, children: /* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "close", size: 16, color: theme.colors.ink2 }) }) : null
|
|
1915
1887
|
]
|
|
1916
1888
|
}
|
|
1917
1889
|
);
|
|
@@ -1928,7 +1900,7 @@ function ReplyChip({
|
|
|
1928
1900
|
reactNative.View,
|
|
1929
1901
|
{
|
|
1930
1902
|
style: [
|
|
1931
|
-
|
|
1903
|
+
styles9.replyChip,
|
|
1932
1904
|
{
|
|
1933
1905
|
backgroundColor: theme.colors.surface2,
|
|
1934
1906
|
borderLeftColor: theme.colors.brand
|
|
@@ -1936,18 +1908,18 @@ function ReplyChip({
|
|
|
1936
1908
|
],
|
|
1937
1909
|
children: [
|
|
1938
1910
|
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: { flex: 1 }, children: [
|
|
1939
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.Text, { style: [
|
|
1911
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.Text, { style: [styles9.replyName, { color: theme.colors.brand }], children: [
|
|
1940
1912
|
"Replying to ",
|
|
1941
1913
|
senderName
|
|
1942
1914
|
] }),
|
|
1943
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
1915
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles9.replyBody, { color: theme.colors.ink2 }], numberOfLines: 1, children: message.body ?? "\u2026" })
|
|
1944
1916
|
] }),
|
|
1945
|
-
onCancel ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: onCancel, hitSlop: 8, style:
|
|
1917
|
+
onCancel ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: onCancel, hitSlop: 8, style: styles9.replyCancel, children: /* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "close", size: 16, color: theme.colors.ink2 }) }) : null
|
|
1946
1918
|
]
|
|
1947
1919
|
}
|
|
1948
1920
|
);
|
|
1949
1921
|
}
|
|
1950
|
-
var
|
|
1922
|
+
var styles9 = reactNative.StyleSheet.create({
|
|
1951
1923
|
wrap: {
|
|
1952
1924
|
borderTopWidth: reactNative.StyleSheet.hairlineWidth,
|
|
1953
1925
|
paddingTop: 8,
|
|
@@ -2044,11 +2016,11 @@ function MentionInput({ conversationId, onSend, ...composerProps }) {
|
|
|
2044
2016
|
transparent: true,
|
|
2045
2017
|
animationType: "slide",
|
|
2046
2018
|
onRequestClose: () => setPickerOpen(false),
|
|
2047
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { style:
|
|
2019
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { style: styles10.backdrop, onPress: () => setPickerOpen(false), children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2048
2020
|
reactNative.View,
|
|
2049
2021
|
{
|
|
2050
2022
|
style: [
|
|
2051
|
-
|
|
2023
|
+
styles10.sheet,
|
|
2052
2024
|
{
|
|
2053
2025
|
backgroundColor: theme.colors.surface,
|
|
2054
2026
|
borderTopLeftRadius: theme.radii.lg,
|
|
@@ -2059,7 +2031,7 @@ function MentionInput({ conversationId, onSend, ...composerProps }) {
|
|
|
2059
2031
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2060
2032
|
reactNative.Text,
|
|
2061
2033
|
{
|
|
2062
|
-
style: [
|
|
2034
|
+
style: [styles10.title, { color: theme.colors.ink, fontFamily: theme.type.fontBody }],
|
|
2063
2035
|
children: "Mention a member"
|
|
2064
2036
|
}
|
|
2065
2037
|
),
|
|
@@ -2090,12 +2062,12 @@ function MentionInput({ conversationId, onSend, ...composerProps }) {
|
|
|
2090
2062
|
}
|
|
2091
2063
|
function MentionRow({ member, onPress }) {
|
|
2092
2064
|
const theme = usePoolseTheme();
|
|
2093
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { onPress, style:
|
|
2065
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { onPress, style: styles10.row, children: [
|
|
2094
2066
|
/* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: null, name: member.external_id, seed: member.external_id, size: "sm" }),
|
|
2095
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
2067
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles10.rowText, { color: theme.colors.ink, fontFamily: theme.type.fontBody }], children: member.external_id })
|
|
2096
2068
|
] });
|
|
2097
2069
|
}
|
|
2098
|
-
var
|
|
2070
|
+
var styles10 = reactNative.StyleSheet.create({
|
|
2099
2071
|
backdrop: {
|
|
2100
2072
|
flex: 1,
|
|
2101
2073
|
backgroundColor: "rgba(0,0,0,0.35)",
|
|
@@ -2175,12 +2147,12 @@ function MessageList({
|
|
|
2175
2147
|
[renderItem, data.length]
|
|
2176
2148
|
);
|
|
2177
2149
|
if (loading && messages.length === 0) {
|
|
2178
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [
|
|
2150
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles11.placeholder, { backgroundColor: theme.colors.paper }], children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.ActivityIndicator, { color: theme.colors.brand }) });
|
|
2179
2151
|
}
|
|
2180
2152
|
if (messages.length === 0) {
|
|
2181
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [
|
|
2153
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles11.placeholder, { backgroundColor: theme.colors.paper }], children: typeof emptyState === "string" ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: { color: theme.colors.ink3, fontFamily: theme.type.fontBody }, children: emptyState }) : emptyState ?? null });
|
|
2182
2154
|
}
|
|
2183
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
2155
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles11.root, children: [
|
|
2184
2156
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2185
2157
|
reactNative.FlatList,
|
|
2186
2158
|
{
|
|
@@ -2207,7 +2179,7 @@ function MessageList({
|
|
|
2207
2179
|
{
|
|
2208
2180
|
onPress: scrollToBottom,
|
|
2209
2181
|
style: [
|
|
2210
|
-
|
|
2182
|
+
styles11.jumpButton,
|
|
2211
2183
|
{
|
|
2212
2184
|
backgroundColor: theme.colors.brand
|
|
2213
2185
|
},
|
|
@@ -2216,7 +2188,7 @@ function MessageList({
|
|
|
2216
2188
|
accessibilityLabel: `${newCount} new ${newCount === 1 ? "message" : "messages"}, jump to latest`,
|
|
2217
2189
|
children: [
|
|
2218
2190
|
/* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "chevron-down", size: 14, color: theme.colors.onBrand }),
|
|
2219
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.Text, { style: [
|
|
2191
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.Text, { style: [styles11.jumpText, { color: theme.colors.onBrand }], children: [
|
|
2220
2192
|
newCount,
|
|
2221
2193
|
" new ",
|
|
2222
2194
|
newCount === 1 ? "message" : "messages"
|
|
@@ -2226,7 +2198,7 @@ function MessageList({
|
|
|
2226
2198
|
) : null
|
|
2227
2199
|
] });
|
|
2228
2200
|
}
|
|
2229
|
-
var
|
|
2201
|
+
var styles11 = reactNative.StyleSheet.create({
|
|
2230
2202
|
root: {
|
|
2231
2203
|
flex: 1
|
|
2232
2204
|
},
|
|
@@ -2277,11 +2249,11 @@ function MessageActions({
|
|
|
2277
2249
|
if (isSelf && onDelete)
|
|
2278
2250
|
items.push({ label: "Delete", icon: "trash", onPress: onDelete, danger: true });
|
|
2279
2251
|
const showEmojiRow = !!onPickReaction && emojis.length > 0;
|
|
2280
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.Modal, { visible, transparent: true, animationType: "fade", onRequestClose: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { style:
|
|
2252
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.Modal, { visible, transparent: true, animationType: "fade", onRequestClose: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { style: styles12.backdrop, onPress: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2281
2253
|
reactNative.View,
|
|
2282
2254
|
{
|
|
2283
2255
|
style: [
|
|
2284
|
-
|
|
2256
|
+
styles12.sheet,
|
|
2285
2257
|
{
|
|
2286
2258
|
backgroundColor: theme.colors.surface,
|
|
2287
2259
|
borderTopLeftRadius: theme.radii.lg,
|
|
@@ -2290,21 +2262,21 @@ function MessageActions({
|
|
|
2290
2262
|
theme.shadows.lg
|
|
2291
2263
|
],
|
|
2292
2264
|
children: [
|
|
2293
|
-
showEmojiRow ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [
|
|
2265
|
+
showEmojiRow ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles12.emojiRow, { borderBottomColor: theme.colors.border }], children: emojis.map((emoji) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2294
2266
|
reactNative.Pressable,
|
|
2295
2267
|
{
|
|
2296
2268
|
onPress: () => {
|
|
2297
2269
|
onPickReaction(emoji);
|
|
2298
2270
|
onClose();
|
|
2299
2271
|
},
|
|
2300
|
-
style:
|
|
2272
|
+
style: styles12.emojiBtn,
|
|
2301
2273
|
hitSlop: 6,
|
|
2302
2274
|
accessibilityLabel: `React with ${emoji}`,
|
|
2303
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style:
|
|
2275
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles12.emoji, children: emoji })
|
|
2304
2276
|
},
|
|
2305
2277
|
emoji
|
|
2306
2278
|
)) }) : null,
|
|
2307
|
-
items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { onPress: item.onPress, style:
|
|
2279
|
+
items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { onPress: item.onPress, style: styles12.item, children: [
|
|
2308
2280
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2309
2281
|
PoolseIcon,
|
|
2310
2282
|
{
|
|
@@ -2317,7 +2289,7 @@ function MessageActions({
|
|
|
2317
2289
|
reactNative.Text,
|
|
2318
2290
|
{
|
|
2319
2291
|
style: [
|
|
2320
|
-
|
|
2292
|
+
styles12.itemText,
|
|
2321
2293
|
{
|
|
2322
2294
|
color: item.danger ? theme.colors.error : theme.colors.ink,
|
|
2323
2295
|
fontFamily: theme.type.fontBody
|
|
@@ -2331,7 +2303,7 @@ function MessageActions({
|
|
|
2331
2303
|
}
|
|
2332
2304
|
) }) });
|
|
2333
2305
|
}
|
|
2334
|
-
var
|
|
2306
|
+
var styles12 = reactNative.StyleSheet.create({
|
|
2335
2307
|
backdrop: {
|
|
2336
2308
|
flex: 1,
|
|
2337
2309
|
backgroundColor: "rgba(0,0,0,0.35)",
|
|
@@ -2396,7 +2368,7 @@ function AttachmentPreview({ attachment, onPress, maxWidth = 280 }) {
|
|
|
2396
2368
|
reactNative.View,
|
|
2397
2369
|
{
|
|
2398
2370
|
style: [
|
|
2399
|
-
|
|
2371
|
+
styles13.imagePlaceholder,
|
|
2400
2372
|
{
|
|
2401
2373
|
width: maxWidth,
|
|
2402
2374
|
height: 200,
|
|
@@ -2413,7 +2385,7 @@ function AttachmentPreview({ attachment, onPress, maxWidth = 280 }) {
|
|
|
2413
2385
|
onPress,
|
|
2414
2386
|
disabled: !onPress,
|
|
2415
2387
|
style: [
|
|
2416
|
-
|
|
2388
|
+
styles13.fileCard,
|
|
2417
2389
|
{
|
|
2418
2390
|
backgroundColor: theme.colors.surface2,
|
|
2419
2391
|
borderColor: theme.colors.border,
|
|
@@ -2426,12 +2398,12 @@ function AttachmentPreview({ attachment, onPress, maxWidth = 280 }) {
|
|
|
2426
2398
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2427
2399
|
reactNative.Text,
|
|
2428
2400
|
{
|
|
2429
|
-
style: [
|
|
2401
|
+
style: [styles13.fileName, { color: theme.colors.ink, fontFamily: theme.type.fontBody }],
|
|
2430
2402
|
numberOfLines: 1,
|
|
2431
2403
|
children: attachment.original_filename ?? "file"
|
|
2432
2404
|
}
|
|
2433
2405
|
),
|
|
2434
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
2406
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles13.fileSize, { color: theme.colors.ink3 }], children: formatBytes2(attachment.byte_size) })
|
|
2435
2407
|
] })
|
|
2436
2408
|
]
|
|
2437
2409
|
}
|
|
@@ -2443,7 +2415,7 @@ function formatBytes2(n) {
|
|
|
2443
2415
|
if (n < 1024 * 1024 * 1024) return `${(n / 1024 / 1024).toFixed(1)} MB`;
|
|
2444
2416
|
return `${(n / 1024 / 1024 / 1024).toFixed(1)} GB`;
|
|
2445
2417
|
}
|
|
2446
|
-
var
|
|
2418
|
+
var styles13 = reactNative.StyleSheet.create({
|
|
2447
2419
|
imagePlaceholder: {},
|
|
2448
2420
|
fileCard: {
|
|
2449
2421
|
flexDirection: "row",
|
|
@@ -2472,7 +2444,7 @@ function ImageMosaic({ images, maxWidth, radius }) {
|
|
|
2472
2444
|
reactNative.View,
|
|
2473
2445
|
{
|
|
2474
2446
|
style: [
|
|
2475
|
-
|
|
2447
|
+
styles14.root,
|
|
2476
2448
|
{
|
|
2477
2449
|
borderRadius: r,
|
|
2478
2450
|
...maxWidth ? { maxWidth } : {}
|
|
@@ -2483,17 +2455,17 @@ function ImageMosaic({ images, maxWidth, radius }) {
|
|
|
2483
2455
|
Tile,
|
|
2484
2456
|
{
|
|
2485
2457
|
attachment: visible[0],
|
|
2486
|
-
style:
|
|
2458
|
+
style: styles14.tileFull,
|
|
2487
2459
|
onPress: () => setViewerIndex(0),
|
|
2488
2460
|
overlay: null
|
|
2489
2461
|
}
|
|
2490
2462
|
) : null,
|
|
2491
|
-
n === 2 ? /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
2463
|
+
n === 2 ? /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles14.rowEven, children: [
|
|
2492
2464
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2493
2465
|
Tile,
|
|
2494
2466
|
{
|
|
2495
2467
|
attachment: visible[0],
|
|
2496
|
-
style:
|
|
2468
|
+
style: styles14.tileHalfSquare,
|
|
2497
2469
|
onPress: () => setViewerIndex(0),
|
|
2498
2470
|
overlay: null
|
|
2499
2471
|
}
|
|
@@ -2502,7 +2474,7 @@ function ImageMosaic({ images, maxWidth, radius }) {
|
|
|
2502
2474
|
Tile,
|
|
2503
2475
|
{
|
|
2504
2476
|
attachment: visible[1],
|
|
2505
|
-
style:
|
|
2477
|
+
style: styles14.tileHalfSquare,
|
|
2506
2478
|
onPress: () => setViewerIndex(1),
|
|
2507
2479
|
overlay: null
|
|
2508
2480
|
}
|
|
@@ -2513,17 +2485,17 @@ function ImageMosaic({ images, maxWidth, radius }) {
|
|
|
2513
2485
|
Tile,
|
|
2514
2486
|
{
|
|
2515
2487
|
attachment: visible[0],
|
|
2516
|
-
style:
|
|
2488
|
+
style: styles14.tileHero,
|
|
2517
2489
|
onPress: () => setViewerIndex(0),
|
|
2518
2490
|
overlay: null
|
|
2519
2491
|
}
|
|
2520
2492
|
),
|
|
2521
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [
|
|
2493
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles14.rowEven, { marginTop: 2 }], children: [
|
|
2522
2494
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2523
2495
|
Tile,
|
|
2524
2496
|
{
|
|
2525
2497
|
attachment: visible[1],
|
|
2526
|
-
style:
|
|
2498
|
+
style: styles14.tileHalfSquare,
|
|
2527
2499
|
onPress: () => setViewerIndex(1),
|
|
2528
2500
|
overlay: null
|
|
2529
2501
|
}
|
|
@@ -2532,7 +2504,7 @@ function ImageMosaic({ images, maxWidth, radius }) {
|
|
|
2532
2504
|
Tile,
|
|
2533
2505
|
{
|
|
2534
2506
|
attachment: visible[2],
|
|
2535
|
-
style:
|
|
2507
|
+
style: styles14.tileHalfSquare,
|
|
2536
2508
|
onPress: () => setViewerIndex(2),
|
|
2537
2509
|
overlay: null
|
|
2538
2510
|
}
|
|
@@ -2540,12 +2512,12 @@ function ImageMosaic({ images, maxWidth, radius }) {
|
|
|
2540
2512
|
] })
|
|
2541
2513
|
] }) : null,
|
|
2542
2514
|
n === 4 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2543
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
2515
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles14.rowEven, children: [
|
|
2544
2516
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2545
2517
|
Tile,
|
|
2546
2518
|
{
|
|
2547
2519
|
attachment: visible[0],
|
|
2548
|
-
style:
|
|
2520
|
+
style: styles14.tileHalfSquare,
|
|
2549
2521
|
onPress: () => setViewerIndex(0),
|
|
2550
2522
|
overlay: null
|
|
2551
2523
|
}
|
|
@@ -2554,18 +2526,18 @@ function ImageMosaic({ images, maxWidth, radius }) {
|
|
|
2554
2526
|
Tile,
|
|
2555
2527
|
{
|
|
2556
2528
|
attachment: visible[1],
|
|
2557
|
-
style:
|
|
2529
|
+
style: styles14.tileHalfSquare,
|
|
2558
2530
|
onPress: () => setViewerIndex(1),
|
|
2559
2531
|
overlay: null
|
|
2560
2532
|
}
|
|
2561
2533
|
)
|
|
2562
2534
|
] }),
|
|
2563
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [
|
|
2535
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles14.rowEven, { marginTop: 2 }], children: [
|
|
2564
2536
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2565
2537
|
Tile,
|
|
2566
2538
|
{
|
|
2567
2539
|
attachment: visible[2],
|
|
2568
|
-
style:
|
|
2540
|
+
style: styles14.tileHalfSquare,
|
|
2569
2541
|
onPress: () => setViewerIndex(2),
|
|
2570
2542
|
overlay: null
|
|
2571
2543
|
}
|
|
@@ -2574,7 +2546,7 @@ function ImageMosaic({ images, maxWidth, radius }) {
|
|
|
2574
2546
|
Tile,
|
|
2575
2547
|
{
|
|
2576
2548
|
attachment: visible[3],
|
|
2577
|
-
style:
|
|
2549
|
+
style: styles14.tileHalfSquare,
|
|
2578
2550
|
onPress: () => setViewerIndex(3),
|
|
2579
2551
|
overlay: overflow > 0 ? `+${overflow}` : null
|
|
2580
2552
|
}
|
|
@@ -2610,18 +2582,18 @@ function Tile({
|
|
|
2610
2582
|
}) {
|
|
2611
2583
|
const theme = usePoolseTheme();
|
|
2612
2584
|
const { url } = react$1.useAttachmentUrl(attachment.id);
|
|
2613
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { onPress, style: [
|
|
2585
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { onPress, style: [styles14.tileBase, style], children: [
|
|
2614
2586
|
url ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2615
2587
|
reactNative.Image,
|
|
2616
2588
|
{
|
|
2617
2589
|
source: { uri: url },
|
|
2618
|
-
style: [
|
|
2590
|
+
style: [styles14.tileImage, { backgroundColor: theme.colors.surface2 }],
|
|
2619
2591
|
resizeMode: "cover",
|
|
2620
2592
|
accessible: true,
|
|
2621
2593
|
accessibilityLabel: attachment.original_filename ?? "image"
|
|
2622
2594
|
}
|
|
2623
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [
|
|
2624
|
-
overlay ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style:
|
|
2595
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles14.tileImage, { backgroundColor: theme.colors.surface2 }] }),
|
|
2596
|
+
overlay ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles14.overflow, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles14.overflowText, children: overlay }) }) : null
|
|
2625
2597
|
] });
|
|
2626
2598
|
}
|
|
2627
2599
|
function FullScreenViewer({
|
|
@@ -2630,7 +2602,7 @@ function FullScreenViewer({
|
|
|
2630
2602
|
}) {
|
|
2631
2603
|
const { url } = react$1.useAttachmentUrl(attachment.id);
|
|
2632
2604
|
const { width, height } = reactNative.Dimensions.get("window");
|
|
2633
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { style:
|
|
2605
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { style: styles14.viewer, onPress: onClose, children: [
|
|
2634
2606
|
url ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2635
2607
|
reactNative.Image,
|
|
2636
2608
|
{
|
|
@@ -2646,14 +2618,14 @@ function FullScreenViewer({
|
|
|
2646
2618
|
{
|
|
2647
2619
|
onPress: onClose,
|
|
2648
2620
|
hitSlop: 12,
|
|
2649
|
-
style:
|
|
2621
|
+
style: styles14.closeBtn,
|
|
2650
2622
|
accessibilityLabel: "Close viewer",
|
|
2651
2623
|
children: /* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "close", size: 20, color: "#ffffff" })
|
|
2652
2624
|
}
|
|
2653
2625
|
)
|
|
2654
2626
|
] });
|
|
2655
2627
|
}
|
|
2656
|
-
var
|
|
2628
|
+
var styles14 = reactNative.StyleSheet.create({
|
|
2657
2629
|
root: {
|
|
2658
2630
|
width: "100%",
|
|
2659
2631
|
overflow: "hidden",
|
|
@@ -2808,7 +2780,7 @@ function MessageBubble({
|
|
|
2808
2780
|
reactNative.View,
|
|
2809
2781
|
{
|
|
2810
2782
|
style: [
|
|
2811
|
-
|
|
2783
|
+
styles15.wrap,
|
|
2812
2784
|
{
|
|
2813
2785
|
alignSelf: isSelf ? "flex-end" : "flex-start",
|
|
2814
2786
|
// Pixel maxWidth (not percentage) so single-line and
|
|
@@ -2822,7 +2794,7 @@ function MessageBubble({
|
|
|
2822
2794
|
reactNative.View,
|
|
2823
2795
|
{
|
|
2824
2796
|
style: [
|
|
2825
|
-
|
|
2797
|
+
styles15.bubble,
|
|
2826
2798
|
{
|
|
2827
2799
|
backgroundColor: bubbleColor,
|
|
2828
2800
|
borderColor: isSelf ? "transparent" : theme.colors.border,
|
|
@@ -2844,7 +2816,7 @@ function MessageBubble({
|
|
|
2844
2816
|
theme.shadows.sm
|
|
2845
2817
|
],
|
|
2846
2818
|
children: [
|
|
2847
|
-
showSenderName && !isSelf && (groupPosition === "first" || groupPosition === "standalone") ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
2819
|
+
showSenderName && !isSelf && (groupPosition === "first" || groupPosition === "standalone") ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles15.senderName, { color: senderTint, fontFamily: theme.type.fontBody }], children: senderLabel }) : null,
|
|
2848
2820
|
message.quoted_message ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2849
2821
|
QuotedCard,
|
|
2850
2822
|
{
|
|
@@ -2860,7 +2832,7 @@ function MessageBubble({
|
|
|
2860
2832
|
reactNative.Text,
|
|
2861
2833
|
{
|
|
2862
2834
|
style: [
|
|
2863
|
-
|
|
2835
|
+
styles15.body,
|
|
2864
2836
|
{
|
|
2865
2837
|
color: theme.colors.ink3,
|
|
2866
2838
|
fontFamily: theme.type.fontBody,
|
|
@@ -2885,7 +2857,7 @@ function MessageBubble({
|
|
|
2885
2857
|
reactNative.Text,
|
|
2886
2858
|
{
|
|
2887
2859
|
style: [
|
|
2888
|
-
|
|
2860
|
+
styles15.body,
|
|
2889
2861
|
{
|
|
2890
2862
|
color: textColor,
|
|
2891
2863
|
fontFamily: theme.type.fontBody,
|
|
@@ -2900,18 +2872,18 @@ function MessageBubble({
|
|
|
2900
2872
|
reactNative.Text,
|
|
2901
2873
|
{
|
|
2902
2874
|
style: [
|
|
2903
|
-
|
|
2875
|
+
styles15.readMore,
|
|
2904
2876
|
{ color: isSelf ? theme.colors.onBrand : theme.colors.brand }
|
|
2905
2877
|
],
|
|
2906
2878
|
children: expanded ? "Show less" : "Read more"
|
|
2907
2879
|
}
|
|
2908
2880
|
) }) : null,
|
|
2909
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
2881
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles15.metaRow, children: [
|
|
2910
2882
|
isEdited ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2911
2883
|
reactNative.Text,
|
|
2912
2884
|
{
|
|
2913
2885
|
style: [
|
|
2914
|
-
|
|
2886
|
+
styles15.editedTag,
|
|
2915
2887
|
{
|
|
2916
2888
|
color: isSelf ? theme.colors.onBrand : theme.colors.ink3,
|
|
2917
2889
|
opacity: 0.7
|
|
@@ -2924,7 +2896,7 @@ function MessageBubble({
|
|
|
2924
2896
|
reactNative.Text,
|
|
2925
2897
|
{
|
|
2926
2898
|
style: [
|
|
2927
|
-
|
|
2899
|
+
styles15.meta,
|
|
2928
2900
|
{
|
|
2929
2901
|
color: isSelf ? theme.colors.onBrand : theme.colors.ink3,
|
|
2930
2902
|
opacity: isSelf ? 0.85 : 1
|
|
@@ -2933,7 +2905,7 @@ function MessageBubble({
|
|
|
2933
2905
|
children: time
|
|
2934
2906
|
}
|
|
2935
2907
|
),
|
|
2936
|
-
isSelf && readState ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style:
|
|
2908
|
+
isSelf && readState ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles15.readTick, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2937
2909
|
PoolseIcon,
|
|
2938
2910
|
{
|
|
2939
2911
|
name: readState === "read" ? "check-double" : "check",
|
|
@@ -2942,7 +2914,7 @@ function MessageBubble({
|
|
|
2942
2914
|
}
|
|
2943
2915
|
) }) : null
|
|
2944
2916
|
] }),
|
|
2945
|
-
actionsTrigger ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style:
|
|
2917
|
+
actionsTrigger ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles15.actionsSlot, children: actionsTrigger }) : null
|
|
2946
2918
|
]
|
|
2947
2919
|
}
|
|
2948
2920
|
)
|
|
@@ -2967,15 +2939,15 @@ function QuotedCard({
|
|
|
2967
2939
|
onPress,
|
|
2968
2940
|
disabled: !onPress,
|
|
2969
2941
|
style: [
|
|
2970
|
-
|
|
2942
|
+
styles15.quoted,
|
|
2971
2943
|
{
|
|
2972
2944
|
backgroundColor: bg,
|
|
2973
2945
|
borderLeftColor: accent
|
|
2974
2946
|
}
|
|
2975
2947
|
],
|
|
2976
2948
|
children: [
|
|
2977
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
2978
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
2949
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles15.quotedSender, { color: accent }], children: senderName }),
|
|
2950
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles15.quotedBody, { color: txt }], numberOfLines: 2, children: quoted.body ?? "\u2026" })
|
|
2979
2951
|
]
|
|
2980
2952
|
}
|
|
2981
2953
|
);
|
|
@@ -3007,7 +2979,7 @@ function formatTime(iso) {
|
|
|
3007
2979
|
function isSameDay(a, b) {
|
|
3008
2980
|
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
3009
2981
|
}
|
|
3010
|
-
var
|
|
2982
|
+
var styles15 = reactNative.StyleSheet.create({
|
|
3011
2983
|
wrap: {
|
|
3012
2984
|
marginBottom: 2
|
|
3013
2985
|
},
|
|
@@ -3087,7 +3059,7 @@ function ReactionStrip({
|
|
|
3087
3059
|
});
|
|
3088
3060
|
const entries = Object.entries(reactions);
|
|
3089
3061
|
if (entries.length === 0) return null;
|
|
3090
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style:
|
|
3062
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles16.strip, children: entries.map(([emoji, userIds]) => {
|
|
3091
3063
|
const userArr = Array.isArray(userIds) ? userIds : [];
|
|
3092
3064
|
const meReacted = meId !== null && userArr.includes(meId);
|
|
3093
3065
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -3095,7 +3067,7 @@ function ReactionStrip({
|
|
|
3095
3067
|
{
|
|
3096
3068
|
onPress: () => meReacted ? removeReaction(emoji) : addReaction(emoji),
|
|
3097
3069
|
style: [
|
|
3098
|
-
|
|
3070
|
+
styles16.chip,
|
|
3099
3071
|
{
|
|
3100
3072
|
backgroundColor: meReacted ? theme.colors.brandSoft : theme.colors.surface2,
|
|
3101
3073
|
borderColor: meReacted ? theme.colors.brand : theme.colors.border,
|
|
@@ -3104,12 +3076,12 @@ function ReactionStrip({
|
|
|
3104
3076
|
}
|
|
3105
3077
|
],
|
|
3106
3078
|
children: [
|
|
3107
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style:
|
|
3079
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles16.emoji, children: emoji }),
|
|
3108
3080
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3109
3081
|
reactNative.Text,
|
|
3110
3082
|
{
|
|
3111
3083
|
style: [
|
|
3112
|
-
|
|
3084
|
+
styles16.count,
|
|
3113
3085
|
{
|
|
3114
3086
|
color: meReacted ? theme.colors.brand : theme.colors.ink2,
|
|
3115
3087
|
fontWeight: meReacted ? "700" : "600"
|
|
@@ -3131,11 +3103,11 @@ function ReactionPicker({
|
|
|
3131
3103
|
emojis = DEFAULT_EMOJIS
|
|
3132
3104
|
}) {
|
|
3133
3105
|
const theme = usePoolseTheme();
|
|
3134
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.Modal, { visible, transparent: true, animationType: "fade", onRequestClose: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { style:
|
|
3106
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.Modal, { visible, transparent: true, animationType: "fade", onRequestClose: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { style: styles16.backdrop, onPress: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3135
3107
|
reactNative.View,
|
|
3136
3108
|
{
|
|
3137
3109
|
style: [
|
|
3138
|
-
|
|
3110
|
+
styles16.sheet,
|
|
3139
3111
|
{
|
|
3140
3112
|
backgroundColor: theme.colors.surface,
|
|
3141
3113
|
borderRadius: theme.radii.lg
|
|
@@ -3145,19 +3117,19 @@ function ReactionPicker({
|
|
|
3145
3117
|
children: emojis.map((emoji) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3146
3118
|
reactNative.Pressable,
|
|
3147
3119
|
{
|
|
3148
|
-
style:
|
|
3120
|
+
style: styles16.emojiBtn,
|
|
3149
3121
|
onPress: () => {
|
|
3150
3122
|
onPick(emoji);
|
|
3151
3123
|
onClose();
|
|
3152
3124
|
},
|
|
3153
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style:
|
|
3125
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles16.bigEmoji, children: emoji })
|
|
3154
3126
|
},
|
|
3155
3127
|
emoji
|
|
3156
3128
|
))
|
|
3157
3129
|
}
|
|
3158
3130
|
) }) });
|
|
3159
3131
|
}
|
|
3160
|
-
var
|
|
3132
|
+
var styles16 = reactNative.StyleSheet.create({
|
|
3161
3133
|
strip: {
|
|
3162
3134
|
flexDirection: "row",
|
|
3163
3135
|
flexWrap: "wrap",
|
|
@@ -3325,15 +3297,15 @@ function MessageRow({
|
|
|
3325
3297
|
reactNative.View,
|
|
3326
3298
|
{
|
|
3327
3299
|
style: [
|
|
3328
|
-
|
|
3300
|
+
styles17.row,
|
|
3329
3301
|
{ alignSelf: isSelf ? "flex-end" : "flex-start" },
|
|
3330
3302
|
// Lift this row above the dim backdrop the parent renders
|
|
3331
3303
|
// during edit mode. zIndex covers iOS / web; elevation does
|
|
3332
3304
|
// the equivalent on Android.
|
|
3333
|
-
isEditing ?
|
|
3305
|
+
isEditing ? styles17.rowEditing : null
|
|
3334
3306
|
],
|
|
3335
3307
|
children: [
|
|
3336
|
-
showAvatarSlot ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style:
|
|
3308
|
+
showAvatarSlot ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles17.avatarSlot, children: showAvatarRender ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3337
3309
|
Avatar,
|
|
3338
3310
|
{
|
|
3339
3311
|
src: avatarUrl ?? null,
|
|
@@ -3342,14 +3314,14 @@ function MessageRow({
|
|
|
3342
3314
|
size: "sm"
|
|
3343
3315
|
}
|
|
3344
3316
|
) : null }) : null,
|
|
3345
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
3317
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles17.bubbleCol, children: [
|
|
3346
3318
|
swipeEnabled ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3347
3319
|
reactNative.Animated.View,
|
|
3348
3320
|
{
|
|
3349
3321
|
pointerEvents: "none",
|
|
3350
3322
|
style: [
|
|
3351
|
-
|
|
3352
|
-
isSelf ?
|
|
3323
|
+
styles17.replyHint,
|
|
3324
|
+
isSelf ? styles17.replyHintRight : styles17.replyHintLeft,
|
|
3353
3325
|
{
|
|
3354
3326
|
opacity: replyIconOpacity,
|
|
3355
3327
|
transform: [{ scale: replyIconScale }],
|
|
@@ -3400,13 +3372,13 @@ function MessageRow({
|
|
|
3400
3372
|
)
|
|
3401
3373
|
}
|
|
3402
3374
|
),
|
|
3403
|
-
threads && (msg.reply_count ?? 0) > 0 && onOpenThread ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: onOpenThread, style:
|
|
3375
|
+
threads && (msg.reply_count ?? 0) > 0 && onOpenThread ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: onOpenThread, style: styles17.threadPill, children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Text, { style: [styles17.threadPillText, { color: theme.colors.brand }], children: [
|
|
3404
3376
|
"\u{1F4AC} ",
|
|
3405
3377
|
msg.reply_count,
|
|
3406
3378
|
" ",
|
|
3407
3379
|
msg.reply_count === 1 ? "reply" : "replies"
|
|
3408
3380
|
] }) }) : null,
|
|
3409
|
-
reactions ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [
|
|
3381
|
+
reactions ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles17.reactionsRow, { alignSelf: isSelf ? "flex-end" : "flex-start" }], children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3410
3382
|
ReactionStrip,
|
|
3411
3383
|
{
|
|
3412
3384
|
messageId: msg.id,
|
|
@@ -3465,7 +3437,7 @@ function MessageRow({
|
|
|
3465
3437
|
}
|
|
3466
3438
|
);
|
|
3467
3439
|
}
|
|
3468
|
-
var
|
|
3440
|
+
var styles17 = reactNative.StyleSheet.create({
|
|
3469
3441
|
row: {
|
|
3470
3442
|
flexDirection: "row",
|
|
3471
3443
|
alignItems: "flex-end",
|
|
@@ -3625,13 +3597,13 @@ function ThreadSheet({
|
|
|
3625
3597
|
),
|
|
3626
3598
|
[rootMessage, meId, labelFor, avatarFor]
|
|
3627
3599
|
);
|
|
3628
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
3629
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { style:
|
|
3600
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles18.modalRoot, children: [
|
|
3601
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { style: styles18.backdrop, onPress: onClose, accessibilityLabel: "Close thread" }),
|
|
3630
3602
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3631
3603
|
reactNative.Animated.View,
|
|
3632
3604
|
{
|
|
3633
3605
|
style: [
|
|
3634
|
-
|
|
3606
|
+
styles18.sheet,
|
|
3635
3607
|
{
|
|
3636
3608
|
height: sheetHeight,
|
|
3637
3609
|
backgroundColor: theme.colors.paper,
|
|
@@ -3643,14 +3615,14 @@ function ThreadSheet({
|
|
|
3643
3615
|
],
|
|
3644
3616
|
children: [
|
|
3645
3617
|
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { ...panHandlers, children: [
|
|
3646
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style:
|
|
3647
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [
|
|
3618
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles18.dragHandle, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles18.dragPill, { backgroundColor: theme.colors.ink3 }] }) }),
|
|
3619
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles18.header, { borderBottomColor: theme.colors.border }], children: [
|
|
3648
3620
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3649
3621
|
reactNative.Pressable,
|
|
3650
3622
|
{
|
|
3651
3623
|
onPress: onClose,
|
|
3652
3624
|
hitSlop: 16,
|
|
3653
|
-
style: [
|
|
3625
|
+
style: [styles18.closeBtn, { backgroundColor: theme.colors.surface2 }],
|
|
3654
3626
|
accessibilityLabel: "Close thread",
|
|
3655
3627
|
children: /* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "close", size: 18, color: theme.colors.ink })
|
|
3656
3628
|
}
|
|
@@ -3659,7 +3631,7 @@ function ThreadSheet({
|
|
|
3659
3631
|
reactNative.Text,
|
|
3660
3632
|
{
|
|
3661
3633
|
style: [
|
|
3662
|
-
|
|
3634
|
+
styles18.title,
|
|
3663
3635
|
{ color: theme.colors.ink, fontFamily: theme.type.fontDisplay }
|
|
3664
3636
|
],
|
|
3665
3637
|
children: "Thread"
|
|
@@ -3670,12 +3642,12 @@ function ThreadSheet({
|
|
|
3670
3642
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3671
3643
|
reactNative.KeyboardAvoidingView,
|
|
3672
3644
|
{
|
|
3673
|
-
style:
|
|
3645
|
+
style: styles18.kavBody,
|
|
3674
3646
|
behavior: reactNative.Platform.OS === "ios" ? "padding" : "height",
|
|
3675
3647
|
keyboardVerticalOffset: reactNative.Platform.OS === "ios" ? gutter : 0,
|
|
3676
3648
|
children: [
|
|
3677
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [
|
|
3678
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style:
|
|
3649
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles18.rootPreview, { backgroundColor: theme.colors.surface2 }], children: rootRow }),
|
|
3650
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles18.listWrap, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3679
3651
|
MessageList,
|
|
3680
3652
|
{
|
|
3681
3653
|
messages: replies,
|
|
@@ -3711,7 +3683,7 @@ function ThreadSheet({
|
|
|
3711
3683
|
)
|
|
3712
3684
|
] });
|
|
3713
3685
|
}
|
|
3714
|
-
var
|
|
3686
|
+
var styles18 = reactNative.StyleSheet.create({
|
|
3715
3687
|
modalRoot: {
|
|
3716
3688
|
flex: 1,
|
|
3717
3689
|
justifyContent: "flex-end"
|
|
@@ -3783,7 +3755,7 @@ function TypingIndicator({ typing, labelFor }) {
|
|
|
3783
3755
|
const ids = Array.from(typing);
|
|
3784
3756
|
const isTyping = ids.length > 0;
|
|
3785
3757
|
if (!isTyping) return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { height: 0 } });
|
|
3786
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
3758
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles19.row, children: [
|
|
3787
3759
|
/* @__PURE__ */ jsxRuntime.jsx(TypingDots, {}),
|
|
3788
3760
|
/* @__PURE__ */ jsxRuntime.jsx(TypingLabel, { ids, ...labelFor ? { labelFor } : {} })
|
|
3789
3761
|
] });
|
|
@@ -3828,7 +3800,7 @@ function TypingDots() {
|
|
|
3828
3800
|
],
|
|
3829
3801
|
opacity: val.interpolate({ inputRange: [0, 1], outputRange: [0.5, 1] })
|
|
3830
3802
|
});
|
|
3831
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
3803
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles19.dotsWrap, children: [
|
|
3832
3804
|
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Animated.View, { style: dot(a) }),
|
|
3833
3805
|
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Animated.View, { style: dot(b) }),
|
|
3834
3806
|
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Animated.View, { style: dot(c) })
|
|
@@ -3844,9 +3816,9 @@ function TypingLabel({
|
|
|
3844
3816
|
const name1 = useDisplayName(id1, labelFor);
|
|
3845
3817
|
const name2 = useDisplayName(id2, labelFor);
|
|
3846
3818
|
const text = ids.length === 1 ? `${name1} is typing` : ids.length === 2 ? `${name1} and ${name2} are typing` : `${ids.length} people are typing`;
|
|
3847
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
3819
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles19.label, { color: theme.colors.ink2, fontFamily: theme.type.fontBody }], children: text });
|
|
3848
3820
|
}
|
|
3849
|
-
var
|
|
3821
|
+
var styles19 = reactNative.StyleSheet.create({
|
|
3850
3822
|
row: {
|
|
3851
3823
|
flexDirection: "row",
|
|
3852
3824
|
alignItems: "center",
|
|
@@ -4084,12 +4056,12 @@ function ConversationView({
|
|
|
4084
4056
|
return /* @__PURE__ */ jsxRuntime.jsx(UploadProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4085
4057
|
reactNative.KeyboardAvoidingView,
|
|
4086
4058
|
{
|
|
4087
|
-
style: [
|
|
4059
|
+
style: [styles20.root, { backgroundColor: theme.colors.paper }],
|
|
4088
4060
|
behavior: reactNative.Platform.OS === "ios" ? "padding" : "height",
|
|
4089
4061
|
keyboardVerticalOffset: keyboardOffset,
|
|
4090
4062
|
children: [
|
|
4091
4063
|
headerNode,
|
|
4092
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
4064
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles20.listWrap, children: [
|
|
4093
4065
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4094
4066
|
MessageList,
|
|
4095
4067
|
{
|
|
@@ -4107,7 +4079,7 @@ function ConversationView({
|
|
|
4107
4079
|
editingId ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4108
4080
|
reactNative.Pressable,
|
|
4109
4081
|
{
|
|
4110
|
-
style:
|
|
4082
|
+
style: styles20.editBackdrop,
|
|
4111
4083
|
onPress: () => setEditingId(null),
|
|
4112
4084
|
accessibilityLabel: "Cancel editing"
|
|
4113
4085
|
}
|
|
@@ -4142,7 +4114,7 @@ function readStateForMessage(msg, members, meId, sequenceByMessageId) {
|
|
|
4142
4114
|
});
|
|
4143
4115
|
return anyRead ? "read" : "sent";
|
|
4144
4116
|
}
|
|
4145
|
-
var
|
|
4117
|
+
var styles20 = reactNative.StyleSheet.create({
|
|
4146
4118
|
root: {
|
|
4147
4119
|
flex: 1
|
|
4148
4120
|
},
|
|
@@ -4224,13 +4196,13 @@ function UserPickerSheet({
|
|
|
4224
4196
|
animationType: "slide",
|
|
4225
4197
|
onRequestClose: handleClose,
|
|
4226
4198
|
statusBarTranslucent: true,
|
|
4227
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
4228
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { style:
|
|
4199
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles21.modalRoot, children: [
|
|
4200
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { style: styles21.backdrop, onPress: handleClose }),
|
|
4229
4201
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4230
4202
|
reactNative.Animated.View,
|
|
4231
4203
|
{
|
|
4232
4204
|
style: [
|
|
4233
|
-
|
|
4205
|
+
styles21.sheet,
|
|
4234
4206
|
{
|
|
4235
4207
|
backgroundColor: theme.colors.paper,
|
|
4236
4208
|
borderTopLeftRadius: theme.radii.xl,
|
|
@@ -4240,14 +4212,14 @@ function UserPickerSheet({
|
|
|
4240
4212
|
theme.shadows.lg
|
|
4241
4213
|
],
|
|
4242
4214
|
children: [
|
|
4243
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { ...panHandlers, style:
|
|
4244
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
4215
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { ...panHandlers, style: styles21.dragHandle, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles21.dragPill, { backgroundColor: theme.colors.ink3 }] }) }),
|
|
4216
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles21.header, children: [
|
|
4245
4217
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4246
4218
|
reactNative.Pressable,
|
|
4247
4219
|
{
|
|
4248
4220
|
onPress: handleClose,
|
|
4249
4221
|
hitSlop: 16,
|
|
4250
|
-
style: [
|
|
4222
|
+
style: [styles21.closeBtn, { backgroundColor: theme.colors.surface2 }],
|
|
4251
4223
|
accessibilityLabel: "Close picker",
|
|
4252
4224
|
children: /* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "close", size: 18, color: theme.colors.ink })
|
|
4253
4225
|
}
|
|
@@ -4256,7 +4228,7 @@ function UserPickerSheet({
|
|
|
4256
4228
|
reactNative.Text,
|
|
4257
4229
|
{
|
|
4258
4230
|
style: [
|
|
4259
|
-
|
|
4231
|
+
styles21.title,
|
|
4260
4232
|
{ color: theme.colors.ink, fontFamily: theme.type.fontDisplay }
|
|
4261
4233
|
],
|
|
4262
4234
|
numberOfLines: 1,
|
|
@@ -4270,7 +4242,7 @@ function UserPickerSheet({
|
|
|
4270
4242
|
disabled: !canCreate,
|
|
4271
4243
|
hitSlop: 6,
|
|
4272
4244
|
style: [
|
|
4273
|
-
|
|
4245
|
+
styles21.createBtn,
|
|
4274
4246
|
{
|
|
4275
4247
|
backgroundColor: canCreate ? theme.colors.brand : theme.colors.surface2,
|
|
4276
4248
|
opacity: canCreate ? 1 : 0.6
|
|
@@ -4301,7 +4273,7 @@ function UserPickerSheet({
|
|
|
4301
4273
|
value: groupName,
|
|
4302
4274
|
onChangeText: setGroupName,
|
|
4303
4275
|
style: [
|
|
4304
|
-
|
|
4276
|
+
styles21.groupNameInput,
|
|
4305
4277
|
{
|
|
4306
4278
|
color: theme.colors.ink,
|
|
4307
4279
|
backgroundColor: theme.colors.surface2,
|
|
@@ -4320,7 +4292,7 @@ function UserPickerSheet({
|
|
|
4320
4292
|
value: query,
|
|
4321
4293
|
onChangeText: setQuery,
|
|
4322
4294
|
style: [
|
|
4323
|
-
|
|
4295
|
+
styles21.searchInput,
|
|
4324
4296
|
{
|
|
4325
4297
|
color: theme.colors.ink,
|
|
4326
4298
|
backgroundColor: theme.colors.surface2,
|
|
@@ -4336,7 +4308,7 @@ function UserPickerSheet({
|
|
|
4336
4308
|
{
|
|
4337
4309
|
data: filtered,
|
|
4338
4310
|
keyExtractor: (u) => u.externalId,
|
|
4339
|
-
ListEmptyComponent: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style:
|
|
4311
|
+
ListEmptyComponent: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles21.empty, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles21.emptyText, { color: theme.colors.ink3 }], children: query ? "No matches." : "No users to show." }) }),
|
|
4340
4312
|
renderItem: ({ item }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4341
4313
|
UserRow,
|
|
4342
4314
|
{
|
|
@@ -4374,29 +4346,29 @@ function UserRow({
|
|
|
4374
4346
|
{
|
|
4375
4347
|
onPress,
|
|
4376
4348
|
style: [
|
|
4377
|
-
|
|
4349
|
+
styles21.row,
|
|
4378
4350
|
{
|
|
4379
4351
|
backgroundColor: selected ? theme.colors.brandSoft : "transparent"
|
|
4380
4352
|
}
|
|
4381
4353
|
],
|
|
4382
4354
|
children: [
|
|
4383
|
-
user.avatarUrl ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Image, { source: { uri: user.avatarUrl }, style:
|
|
4384
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
4355
|
+
user.avatarUrl ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Image, { source: { uri: user.avatarUrl }, style: styles21.avatarImg }) : /* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: null, name: user.name, seed: user.externalId, size: "md" }),
|
|
4356
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles21.body, children: [
|
|
4385
4357
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4386
4358
|
reactNative.Text,
|
|
4387
4359
|
{
|
|
4388
|
-
style: [
|
|
4360
|
+
style: [styles21.name, { color: theme.colors.ink, fontFamily: theme.type.fontBody }],
|
|
4389
4361
|
numberOfLines: 1,
|
|
4390
4362
|
children: user.name
|
|
4391
4363
|
}
|
|
4392
4364
|
),
|
|
4393
|
-
user.subtitle ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
4365
|
+
user.subtitle ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles21.subtitle, { color: theme.colors.ink3 }], numberOfLines: 1, children: user.subtitle }) : null
|
|
4394
4366
|
] }),
|
|
4395
4367
|
isGroup ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4396
4368
|
reactNative.View,
|
|
4397
4369
|
{
|
|
4398
4370
|
style: [
|
|
4399
|
-
|
|
4371
|
+
styles21.checkbox,
|
|
4400
4372
|
{
|
|
4401
4373
|
borderColor: selected ? theme.colors.brand : theme.colors.border,
|
|
4402
4374
|
backgroundColor: selected ? theme.colors.brand : "transparent"
|
|
@@ -4409,7 +4381,7 @@ function UserRow({
|
|
|
4409
4381
|
}
|
|
4410
4382
|
);
|
|
4411
4383
|
}
|
|
4412
|
-
var
|
|
4384
|
+
var styles21 = reactNative.StyleSheet.create({
|
|
4413
4385
|
modalRoot: {
|
|
4414
4386
|
flex: 1,
|
|
4415
4387
|
justifyContent: "flex-end"
|
|
@@ -4669,7 +4641,7 @@ var PoolseInbox = react.forwardRef(
|
|
|
4669
4641
|
},
|
|
4670
4642
|
[renderConversationRow, meExternalId, labelFor, avatarFor, unreadCounts]
|
|
4671
4643
|
);
|
|
4672
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [
|
|
4644
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles22.root, { backgroundColor: theme.colors.paper }], children: [
|
|
4673
4645
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4674
4646
|
reactNative.Animated.View,
|
|
4675
4647
|
{
|
|
@@ -4680,7 +4652,7 @@ var PoolseInbox = react.forwardRef(
|
|
|
4680
4652
|
reactNative.View,
|
|
4681
4653
|
{
|
|
4682
4654
|
style: [
|
|
4683
|
-
|
|
4655
|
+
styles22.listHeader,
|
|
4684
4656
|
{
|
|
4685
4657
|
backgroundColor: theme.colors.surface,
|
|
4686
4658
|
borderBottomColor: theme.colors.border
|
|
@@ -4691,13 +4663,13 @@ var PoolseInbox = react.forwardRef(
|
|
|
4691
4663
|
reactNative.Text,
|
|
4692
4664
|
{
|
|
4693
4665
|
style: [
|
|
4694
|
-
|
|
4666
|
+
styles22.listTitle,
|
|
4695
4667
|
{ color: theme.colors.ink, fontFamily: theme.type.fontDisplay }
|
|
4696
4668
|
],
|
|
4697
4669
|
children: title
|
|
4698
4670
|
}
|
|
4699
4671
|
),
|
|
4700
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
4672
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles22.headerActions, children: [
|
|
4701
4673
|
users ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4702
4674
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4703
4675
|
HeaderIconButton,
|
|
@@ -4810,7 +4782,7 @@ function HeaderIconButton({
|
|
|
4810
4782
|
hitSlop: 10,
|
|
4811
4783
|
accessibilityLabel: label,
|
|
4812
4784
|
style: ({ pressed }) => [
|
|
4813
|
-
|
|
4785
|
+
styles22.iconBtn,
|
|
4814
4786
|
{
|
|
4815
4787
|
backgroundColor: pressed ? theme.colors.surface2 : "transparent"
|
|
4816
4788
|
}
|
|
@@ -4840,31 +4812,31 @@ function DefaultConversationRow({
|
|
|
4840
4812
|
{
|
|
4841
4813
|
onPress,
|
|
4842
4814
|
style: [
|
|
4843
|
-
|
|
4815
|
+
styles22.row,
|
|
4844
4816
|
{
|
|
4845
4817
|
backgroundColor: selected ? theme.colors.surface2 : "transparent",
|
|
4846
4818
|
borderBottomColor: theme.colors.border
|
|
4847
4819
|
}
|
|
4848
4820
|
],
|
|
4849
4821
|
children: [
|
|
4850
|
-
avatarUrl ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Image, { source: { uri: avatarUrl }, style:
|
|
4851
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
4822
|
+
avatarUrl ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Image, { source: { uri: avatarUrl }, style: styles22.rowAvatar }) : /* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: null, name: title, seed: avatarSeed, size: "md" }),
|
|
4823
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles22.rowBody, children: [
|
|
4852
4824
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4853
4825
|
reactNative.Text,
|
|
4854
4826
|
{
|
|
4855
|
-
style: [
|
|
4827
|
+
style: [styles22.rowTitle, { color: theme.colors.ink, fontFamily: theme.type.fontBody }],
|
|
4856
4828
|
numberOfLines: 1,
|
|
4857
4829
|
children: title
|
|
4858
4830
|
}
|
|
4859
4831
|
),
|
|
4860
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
4832
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles22.rowSubtitle, { color: theme.colors.ink3 }], numberOfLines: 1, children: conv.last_message_preview ?? (isDirect ? otherExtId ?? "" : `${(conv.member_external_ids ?? []).length} members`) })
|
|
4861
4833
|
] }),
|
|
4862
|
-
unread > 0 ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [
|
|
4834
|
+
unread > 0 ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles22.unreadPill, { backgroundColor: theme.colors.unreadPill }], children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles22.unreadText, { color: theme.colors.unreadPillText }], children: unread > 99 ? "99+" : String(unread) }) }) : null
|
|
4863
4835
|
]
|
|
4864
4836
|
}
|
|
4865
4837
|
);
|
|
4866
4838
|
}
|
|
4867
|
-
var
|
|
4839
|
+
var styles22 = reactNative.StyleSheet.create({
|
|
4868
4840
|
root: {
|
|
4869
4841
|
flex: 1,
|
|
4870
4842
|
overflow: "hidden"
|
|
@@ -5068,10 +5040,10 @@ function VoiceRoomBar({
|
|
|
5068
5040
|
reactNative.View,
|
|
5069
5041
|
{
|
|
5070
5042
|
style: [
|
|
5071
|
-
|
|
5043
|
+
styles23.bar,
|
|
5072
5044
|
{ backgroundColor: theme.colors.surface, borderBottomColor: theme.colors.border }
|
|
5073
5045
|
],
|
|
5074
|
-
children: unavailableSlot ?? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
5046
|
+
children: unavailableSlot ?? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles23.hint, { color: theme.colors.ink3 }], children: "Voice needs react-native-webrtc and a development build." })
|
|
5075
5047
|
}
|
|
5076
5048
|
);
|
|
5077
5049
|
}
|
|
@@ -5079,22 +5051,22 @@ function VoiceRoomBar({
|
|
|
5079
5051
|
reactNative.View,
|
|
5080
5052
|
{
|
|
5081
5053
|
style: [
|
|
5082
|
-
|
|
5054
|
+
styles23.bar,
|
|
5083
5055
|
{ backgroundColor: theme.colors.surface, borderBottomColor: theme.colors.border }
|
|
5084
5056
|
],
|
|
5085
5057
|
children: [
|
|
5086
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
5058
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles23.row, children: [
|
|
5087
5059
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5088
5060
|
reactNative.View,
|
|
5089
5061
|
{
|
|
5090
5062
|
style: [
|
|
5091
|
-
|
|
5063
|
+
styles23.dot,
|
|
5092
5064
|
{ backgroundColor: connected ? theme.colors.brand : theme.colors.ink3 }
|
|
5093
5065
|
]
|
|
5094
5066
|
}
|
|
5095
5067
|
),
|
|
5096
5068
|
connected ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5097
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style:
|
|
5069
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles23.people, children: participants.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles23.hint, { color: theme.colors.ink3 }], children: "Waiting for others\u2026" }) : participants.map((p) => /* @__PURE__ */ jsxRuntime.jsx(ParticipantChip, { participant: p, label: label(p.userId) }, p.userId)) }),
|
|
5098
5070
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5099
5071
|
reactNative.Pressable,
|
|
5100
5072
|
{
|
|
@@ -5102,7 +5074,7 @@ function VoiceRoomBar({
|
|
|
5102
5074
|
accessibilityRole: "button",
|
|
5103
5075
|
accessibilityState: { selected: muted },
|
|
5104
5076
|
style: [
|
|
5105
|
-
|
|
5077
|
+
styles23.btn,
|
|
5106
5078
|
{
|
|
5107
5079
|
borderColor: muted ? theme.colors.brand : theme.colors.border,
|
|
5108
5080
|
backgroundColor: muted ? theme.colors.brandSoft : theme.colors.paper
|
|
@@ -5116,25 +5088,25 @@ function VoiceRoomBar({
|
|
|
5116
5088
|
{
|
|
5117
5089
|
onPress: leave,
|
|
5118
5090
|
accessibilityRole: "button",
|
|
5119
|
-
style: [
|
|
5091
|
+
style: [styles23.btn, { borderColor: theme.colors.error }],
|
|
5120
5092
|
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: { color: theme.colors.error }, children: "Leave" })
|
|
5121
5093
|
}
|
|
5122
5094
|
)
|
|
5123
5095
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5124
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
5096
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles23.hint, { color: theme.colors.ink3 }], children: status === "connecting" ? "Connecting\u2026" : "Talk to everyone here" }),
|
|
5125
5097
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5126
5098
|
reactNative.Pressable,
|
|
5127
5099
|
{
|
|
5128
5100
|
onPress: () => void join(),
|
|
5129
5101
|
disabled: status === "connecting",
|
|
5130
5102
|
accessibilityRole: "button",
|
|
5131
|
-
style: [
|
|
5103
|
+
style: [styles23.btn, styles23.btnPrimary, { backgroundColor: theme.colors.brand }],
|
|
5132
5104
|
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: { color: theme.colors.onBrand, fontWeight: "600" }, children: status === "connecting" ? "Joining\u2026" : "Join Voice" })
|
|
5133
5105
|
}
|
|
5134
5106
|
)
|
|
5135
5107
|
] })
|
|
5136
5108
|
] }),
|
|
5137
|
-
error && /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
5109
|
+
error && /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles23.error, { color: theme.colors.error }], children: error.message })
|
|
5138
5110
|
]
|
|
5139
5111
|
}
|
|
5140
5112
|
);
|
|
@@ -5145,7 +5117,7 @@ function ParticipantChip({ participant, label }) {
|
|
|
5145
5117
|
reactNative.View,
|
|
5146
5118
|
{
|
|
5147
5119
|
style: [
|
|
5148
|
-
|
|
5120
|
+
styles23.chip,
|
|
5149
5121
|
{
|
|
5150
5122
|
backgroundColor: theme.colors.paper,
|
|
5151
5123
|
// The speaking ring is a border colour swap rather than an
|
|
@@ -5164,7 +5136,7 @@ function ParticipantChip({ participant, label }) {
|
|
|
5164
5136
|
}
|
|
5165
5137
|
);
|
|
5166
5138
|
}
|
|
5167
|
-
var
|
|
5139
|
+
var styles23 = reactNative.StyleSheet.create({
|
|
5168
5140
|
bar: { paddingHorizontal: 14, paddingVertical: 8, borderBottomWidth: reactNative.StyleSheet.hairlineWidth },
|
|
5169
5141
|
row: { flexDirection: "row", alignItems: "center", gap: 8, flexWrap: "wrap" },
|
|
5170
5142
|
dot: { width: 8, height: 8, borderRadius: 4 },
|
|
@@ -5183,6 +5155,668 @@ var styles24 = reactNative.StyleSheet.create({
|
|
|
5183
5155
|
hint: { fontSize: 13, flexShrink: 1 },
|
|
5184
5156
|
error: { fontSize: 12, marginTop: 6 }
|
|
5185
5157
|
});
|
|
5158
|
+
|
|
5159
|
+
// src/voice/callTheme.ts
|
|
5160
|
+
var callColors = {
|
|
5161
|
+
/** Behind everything. Near-black, warmed very slightly to match the brand. */
|
|
5162
|
+
bg: "#101012",
|
|
5163
|
+
/** Behind a participant tile with no video. */
|
|
5164
|
+
tile: "#1c1c20",
|
|
5165
|
+
/** Scrim under the top/bottom chrome so text stays legible over video. */
|
|
5166
|
+
scrim: "rgba(0,0,0,0.45)",
|
|
5167
|
+
text: "#ffffff",
|
|
5168
|
+
textDim: "rgba(255,255,255,0.72)",
|
|
5169
|
+
textFaint: "rgba(255,255,255,0.5)",
|
|
5170
|
+
/** A control that is off / inactive — translucent over whatever is behind. */
|
|
5171
|
+
control: "rgba(255,255,255,0.16)",
|
|
5172
|
+
/**
|
|
5173
|
+
* A control that is ENGAGED (muted, speaker on, camera off).
|
|
5174
|
+
*
|
|
5175
|
+
* Inverted rather than tinted: at a glance the user needs to see
|
|
5176
|
+
* *which* controls are doing something, and a solid white circle is
|
|
5177
|
+
* unmistakable against five translucent ones in a dim room.
|
|
5178
|
+
*/
|
|
5179
|
+
controlActive: "#ffffff",
|
|
5180
|
+
controlActiveIcon: "#101012",
|
|
5181
|
+
danger: "#ef4444",
|
|
5182
|
+
accept: "#22c55e",
|
|
5183
|
+
onAction: "#ffffff"
|
|
5184
|
+
};
|
|
5185
|
+
var CONTROL_SIZE = 58;
|
|
5186
|
+
var CONTROL_SIZE_LARGE = 68;
|
|
5187
|
+
var ICONS2 = {
|
|
5188
|
+
speaker: "speaker",
|
|
5189
|
+
earpiece: "phone",
|
|
5190
|
+
headset: "headphones",
|
|
5191
|
+
bluetooth: "bluetooth",
|
|
5192
|
+
auto: "phone"
|
|
5193
|
+
};
|
|
5194
|
+
function AudioRouteSheet({
|
|
5195
|
+
visible,
|
|
5196
|
+
routes,
|
|
5197
|
+
selectedRouteId,
|
|
5198
|
+
onSelect,
|
|
5199
|
+
onClose
|
|
5200
|
+
}) {
|
|
5201
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.Modal, { visible, transparent: true, animationType: "fade", onRequestClose: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { style: styles24.backdrop, onPress: onClose, accessibilityRole: "button", children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { style: styles24.sheet, onPress: () => {
|
|
5202
|
+
}, children: [
|
|
5203
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles24.grabber }),
|
|
5204
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles24.title, children: "Audio output" }),
|
|
5205
|
+
routes.map((route) => {
|
|
5206
|
+
const selected = route.id === selectedRouteId;
|
|
5207
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5208
|
+
reactNative.Pressable,
|
|
5209
|
+
{
|
|
5210
|
+
onPress: () => {
|
|
5211
|
+
onSelect(route.id);
|
|
5212
|
+
onClose();
|
|
5213
|
+
},
|
|
5214
|
+
accessibilityRole: "button",
|
|
5215
|
+
accessibilityState: { selected },
|
|
5216
|
+
style: ({ pressed }) => [styles24.row, pressed && styles24.rowPressed],
|
|
5217
|
+
children: [
|
|
5218
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5219
|
+
PoolseIcon,
|
|
5220
|
+
{
|
|
5221
|
+
name: ICONS2[route.kind],
|
|
5222
|
+
size: 21,
|
|
5223
|
+
color: selected ? callColors.accept : callColors.text,
|
|
5224
|
+
label: null
|
|
5225
|
+
}
|
|
5226
|
+
),
|
|
5227
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles24.label, selected && styles24.labelSelected], children: route.label }),
|
|
5228
|
+
selected && /* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "check", size: 19, color: callColors.accept, label: "selected" })
|
|
5229
|
+
]
|
|
5230
|
+
},
|
|
5231
|
+
route.id
|
|
5232
|
+
);
|
|
5233
|
+
})
|
|
5234
|
+
] }) }) });
|
|
5235
|
+
}
|
|
5236
|
+
var styles24 = reactNative.StyleSheet.create({
|
|
5237
|
+
backdrop: { flex: 1, backgroundColor: "rgba(0,0,0,0.55)", justifyContent: "flex-end" },
|
|
5238
|
+
sheet: {
|
|
5239
|
+
backgroundColor: callColors.tile,
|
|
5240
|
+
borderTopLeftRadius: 22,
|
|
5241
|
+
borderTopRightRadius: 22,
|
|
5242
|
+
paddingHorizontal: 12,
|
|
5243
|
+
paddingTop: 10,
|
|
5244
|
+
paddingBottom: 34,
|
|
5245
|
+
gap: 2
|
|
5246
|
+
},
|
|
5247
|
+
grabber: {
|
|
5248
|
+
alignSelf: "center",
|
|
5249
|
+
width: 38,
|
|
5250
|
+
height: 4,
|
|
5251
|
+
borderRadius: 2,
|
|
5252
|
+
backgroundColor: callColors.textFaint,
|
|
5253
|
+
marginBottom: 12
|
|
5254
|
+
},
|
|
5255
|
+
title: {
|
|
5256
|
+
color: callColors.textDim,
|
|
5257
|
+
fontSize: 12.5,
|
|
5258
|
+
fontWeight: "600",
|
|
5259
|
+
textTransform: "uppercase",
|
|
5260
|
+
letterSpacing: 0.6,
|
|
5261
|
+
paddingHorizontal: 12,
|
|
5262
|
+
paddingBottom: 8
|
|
5263
|
+
},
|
|
5264
|
+
row: {
|
|
5265
|
+
flexDirection: "row",
|
|
5266
|
+
alignItems: "center",
|
|
5267
|
+
gap: 14,
|
|
5268
|
+
paddingHorizontal: 12,
|
|
5269
|
+
paddingVertical: 15,
|
|
5270
|
+
borderRadius: 14
|
|
5271
|
+
},
|
|
5272
|
+
rowPressed: { backgroundColor: "rgba(255,255,255,0.08)" },
|
|
5273
|
+
label: { flex: 1, color: callColors.text, fontSize: 16, fontWeight: "500" },
|
|
5274
|
+
labelSelected: { color: callColors.accept }
|
|
5275
|
+
});
|
|
5276
|
+
function CallAvatar({ name, seed, size, speaking = false }) {
|
|
5277
|
+
const ring = Math.max(2, Math.round(size * 0.045));
|
|
5278
|
+
const outer = size + ring * 4;
|
|
5279
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5280
|
+
reactNative.View,
|
|
5281
|
+
{
|
|
5282
|
+
style: [
|
|
5283
|
+
styles25.ring,
|
|
5284
|
+
{
|
|
5285
|
+
width: outer,
|
|
5286
|
+
height: outer,
|
|
5287
|
+
borderRadius: outer / 2,
|
|
5288
|
+
borderWidth: ring,
|
|
5289
|
+
borderColor: speaking ? callColors.accept : "transparent"
|
|
5290
|
+
}
|
|
5291
|
+
],
|
|
5292
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5293
|
+
reactNative.View,
|
|
5294
|
+
{
|
|
5295
|
+
style: [
|
|
5296
|
+
styles25.circle,
|
|
5297
|
+
{
|
|
5298
|
+
width: size,
|
|
5299
|
+
height: size,
|
|
5300
|
+
borderRadius: size / 2,
|
|
5301
|
+
backgroundColor: userColor(seed)
|
|
5302
|
+
}
|
|
5303
|
+
],
|
|
5304
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5305
|
+
reactNative.Text,
|
|
5306
|
+
{
|
|
5307
|
+
style: [styles25.initials, { fontSize: Math.round(size * 0.38) }],
|
|
5308
|
+
numberOfLines: 1,
|
|
5309
|
+
allowFontScaling: false,
|
|
5310
|
+
children: initialsOf(name)
|
|
5311
|
+
}
|
|
5312
|
+
)
|
|
5313
|
+
}
|
|
5314
|
+
)
|
|
5315
|
+
}
|
|
5316
|
+
);
|
|
5317
|
+
}
|
|
5318
|
+
function initialsOf(name) {
|
|
5319
|
+
const parts = name.trim().split(/\s+/).filter(Boolean);
|
|
5320
|
+
if (parts.length === 0) return "?";
|
|
5321
|
+
if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();
|
|
5322
|
+
return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
|
|
5323
|
+
}
|
|
5324
|
+
var styles25 = reactNative.StyleSheet.create({
|
|
5325
|
+
ring: { alignItems: "center", justifyContent: "center" },
|
|
5326
|
+
circle: { alignItems: "center", justifyContent: "center" },
|
|
5327
|
+
initials: { color: "#ffffff", fontWeight: "600" }
|
|
5328
|
+
});
|
|
5329
|
+
function CallControlButton({
|
|
5330
|
+
icon,
|
|
5331
|
+
label,
|
|
5332
|
+
active = false,
|
|
5333
|
+
tone = "neutral",
|
|
5334
|
+
large = false,
|
|
5335
|
+
disabled = false,
|
|
5336
|
+
onPress,
|
|
5337
|
+
accessibilityLabel
|
|
5338
|
+
}) {
|
|
5339
|
+
const size = large ? CONTROL_SIZE_LARGE : CONTROL_SIZE;
|
|
5340
|
+
const background = tone === "danger" ? callColors.danger : tone === "accept" ? callColors.accept : active ? callColors.controlActive : callColors.control;
|
|
5341
|
+
const iconColor = tone === "neutral" && active ? callColors.controlActiveIcon : callColors.onAction;
|
|
5342
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles26.slot, children: [
|
|
5343
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5344
|
+
reactNative.Pressable,
|
|
5345
|
+
{
|
|
5346
|
+
onPress,
|
|
5347
|
+
disabled,
|
|
5348
|
+
accessibilityRole: "button",
|
|
5349
|
+
accessibilityState: { disabled, selected: active },
|
|
5350
|
+
accessibilityLabel: accessibilityLabel ?? label ?? icon,
|
|
5351
|
+
hitSlop: 8,
|
|
5352
|
+
style: ({ pressed }) => [
|
|
5353
|
+
styles26.button,
|
|
5354
|
+
{
|
|
5355
|
+
width: size,
|
|
5356
|
+
height: size,
|
|
5357
|
+
borderRadius: size / 2,
|
|
5358
|
+
backgroundColor: background,
|
|
5359
|
+
// Feedback without a layout shift — scaling a round button
|
|
5360
|
+
// inside a fixed slot keeps the row from twitching.
|
|
5361
|
+
opacity: disabled ? 0.4 : pressed ? 0.75 : 1
|
|
5362
|
+
}
|
|
5363
|
+
],
|
|
5364
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: icon, size: large ? 30 : 25, color: iconColor, label: null })
|
|
5365
|
+
}
|
|
5366
|
+
),
|
|
5367
|
+
label ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { numberOfLines: 1, style: styles26.label, children: label }) : null
|
|
5368
|
+
] });
|
|
5369
|
+
}
|
|
5370
|
+
var styles26 = reactNative.StyleSheet.create({
|
|
5371
|
+
// Fixed width so captions of different lengths cannot shift the row.
|
|
5372
|
+
slot: { width: 76, alignItems: "center", gap: 7 },
|
|
5373
|
+
button: { alignItems: "center", justifyContent: "center" },
|
|
5374
|
+
label: { color: callColors.textDim, fontSize: 11.5, fontWeight: "500" }
|
|
5375
|
+
});
|
|
5376
|
+
function CallParticipantTile({
|
|
5377
|
+
participant,
|
|
5378
|
+
VideoTrack,
|
|
5379
|
+
label,
|
|
5380
|
+
style,
|
|
5381
|
+
avatarSize = 72,
|
|
5382
|
+
bleed = false,
|
|
5383
|
+
hideName = false
|
|
5384
|
+
}) {
|
|
5385
|
+
const name = participant.isSelf ? "You" : participant.name ?? label(participant.userId);
|
|
5386
|
+
const hasVideo = Boolean(participant.videoTrackRef && VideoTrack);
|
|
5387
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5388
|
+
reactNative.View,
|
|
5389
|
+
{
|
|
5390
|
+
style: [
|
|
5391
|
+
styles27.tile,
|
|
5392
|
+
bleed ? styles27.bleed : styles27.rounded,
|
|
5393
|
+
{
|
|
5394
|
+
backgroundColor: callColors.tile,
|
|
5395
|
+
// A ring rather than a badge: it reads at a glance across a
|
|
5396
|
+
// grid, and it doesn't cover anyone's face.
|
|
5397
|
+
borderColor: participant.speaking ? callColors.accept : "transparent"
|
|
5398
|
+
},
|
|
5399
|
+
style
|
|
5400
|
+
],
|
|
5401
|
+
children: [
|
|
5402
|
+
hasVideo && VideoTrack ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5403
|
+
VideoTrack,
|
|
5404
|
+
{
|
|
5405
|
+
trackRef: participant.videoTrackRef,
|
|
5406
|
+
style: reactNative.StyleSheet.absoluteFillObject,
|
|
5407
|
+
objectFit: "cover",
|
|
5408
|
+
mirror: participant.isSelf,
|
|
5409
|
+
zOrder: participant.isSelf ? 1 : 0
|
|
5410
|
+
}
|
|
5411
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles27.placeholder, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5412
|
+
CallAvatar,
|
|
5413
|
+
{
|
|
5414
|
+
name,
|
|
5415
|
+
seed: participant.userId,
|
|
5416
|
+
size: avatarSize,
|
|
5417
|
+
speaking: participant.speaking
|
|
5418
|
+
}
|
|
5419
|
+
) }),
|
|
5420
|
+
!hideName && /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles27.chip, bleed ? styles27.chipBleed : styles27.chipTile], children: [
|
|
5421
|
+
!participant.micEnabled && // Worth showing even for yourself — it is the answer to
|
|
5422
|
+
// "why can nobody hear me".
|
|
5423
|
+
/* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "mic-off", size: 13, color: callColors.text, label: "muted" }),
|
|
5424
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { numberOfLines: 1, style: styles27.name, children: name })
|
|
5425
|
+
] })
|
|
5426
|
+
]
|
|
5427
|
+
}
|
|
5428
|
+
);
|
|
5429
|
+
}
|
|
5430
|
+
var styles27 = reactNative.StyleSheet.create({
|
|
5431
|
+
tile: { overflow: "hidden", justifyContent: "flex-end", borderWidth: 2 },
|
|
5432
|
+
rounded: { borderRadius: 18 },
|
|
5433
|
+
bleed: { borderRadius: 0, borderWidth: 0 },
|
|
5434
|
+
placeholder: { ...reactNative.StyleSheet.absoluteFillObject, alignItems: "center", justifyContent: "center" },
|
|
5435
|
+
chip: {
|
|
5436
|
+
flexDirection: "row",
|
|
5437
|
+
alignItems: "center",
|
|
5438
|
+
gap: 5,
|
|
5439
|
+
alignSelf: "flex-start",
|
|
5440
|
+
borderRadius: 999,
|
|
5441
|
+
// Legible over both a bright video frame and a flat placeholder.
|
|
5442
|
+
backgroundColor: "rgba(0,0,0,0.55)"
|
|
5443
|
+
},
|
|
5444
|
+
chipTile: { margin: 8, paddingHorizontal: 9, paddingVertical: 4.5, maxWidth: "92%" },
|
|
5445
|
+
chipBleed: { margin: 14, paddingHorizontal: 11, paddingVertical: 6, maxWidth: "80%" },
|
|
5446
|
+
name: { color: callColors.text, fontSize: 12.5, fontWeight: "600", flexShrink: 1 }
|
|
5447
|
+
});
|
|
5448
|
+
var PIP_WIDTH = 108;
|
|
5449
|
+
var PIP_HEIGHT = 152;
|
|
5450
|
+
var MARGIN = 14;
|
|
5451
|
+
function LocalVideoPip({
|
|
5452
|
+
participant,
|
|
5453
|
+
VideoTrack,
|
|
5454
|
+
label,
|
|
5455
|
+
bounds,
|
|
5456
|
+
insets,
|
|
5457
|
+
onPress
|
|
5458
|
+
}) {
|
|
5459
|
+
const top = insets?.top ?? 0;
|
|
5460
|
+
const bottom = insets?.bottom ?? 0;
|
|
5461
|
+
const corners = react.useMemo(() => {
|
|
5462
|
+
const right = Math.max(MARGIN, bounds.width - PIP_WIDTH - MARGIN);
|
|
5463
|
+
const low = Math.max(MARGIN, bounds.height - PIP_HEIGHT - bottom - MARGIN);
|
|
5464
|
+
const high = top + MARGIN;
|
|
5465
|
+
return [
|
|
5466
|
+
{ x: MARGIN, y: high },
|
|
5467
|
+
{ x: right, y: high },
|
|
5468
|
+
{ x: MARGIN, y: low },
|
|
5469
|
+
{ x: right, y: low }
|
|
5470
|
+
];
|
|
5471
|
+
}, [bounds.width, bounds.height, top, bottom]);
|
|
5472
|
+
const [corner, setCorner] = react.useState(1);
|
|
5473
|
+
const pan = react.useRef(new reactNative.Animated.ValueXY(corners[1])).current;
|
|
5474
|
+
const cornersRef = react.useRef(corners);
|
|
5475
|
+
cornersRef.current = corners;
|
|
5476
|
+
const cornerRef = react.useRef(corner);
|
|
5477
|
+
cornerRef.current = corner;
|
|
5478
|
+
const dragged = react.useRef(false);
|
|
5479
|
+
const responder = react.useMemo(
|
|
5480
|
+
() => reactNative.PanResponder.create({
|
|
5481
|
+
// Claim the gesture only once it is clearly a drag. A lower
|
|
5482
|
+
// threshold would swallow the taps that flip the camera.
|
|
5483
|
+
onMoveShouldSetPanResponder: (_evt, g) => Math.abs(g.dx) > 4 || Math.abs(g.dy) > 4,
|
|
5484
|
+
onPanResponderGrant: () => {
|
|
5485
|
+
dragged.current = true;
|
|
5486
|
+
const at = cornersRef.current[cornerRef.current] ?? cornersRef.current[1];
|
|
5487
|
+
pan.setOffset({ x: at.x, y: at.y });
|
|
5488
|
+
pan.setValue({ x: 0, y: 0 });
|
|
5489
|
+
},
|
|
5490
|
+
onPanResponderMove: reactNative.Animated.event([null, { dx: pan.x, dy: pan.y }], {
|
|
5491
|
+
useNativeDriver: false
|
|
5492
|
+
}),
|
|
5493
|
+
onPanResponderRelease: (_evt, g) => {
|
|
5494
|
+
pan.flattenOffset();
|
|
5495
|
+
const at = cornersRef.current[cornerRef.current] ?? cornersRef.current[1];
|
|
5496
|
+
const dropped = { x: at.x + g.dx, y: at.y + g.dy };
|
|
5497
|
+
let best = 0;
|
|
5498
|
+
let bestDistance = Number.POSITIVE_INFINITY;
|
|
5499
|
+
cornersRef.current.forEach((c, index) => {
|
|
5500
|
+
const distance = (c.x - dropped.x) ** 2 + (c.y - dropped.y) ** 2;
|
|
5501
|
+
if (distance < bestDistance) {
|
|
5502
|
+
bestDistance = distance;
|
|
5503
|
+
best = index;
|
|
5504
|
+
}
|
|
5505
|
+
});
|
|
5506
|
+
setCorner(best);
|
|
5507
|
+
reactNative.Animated.spring(pan, {
|
|
5508
|
+
toValue: cornersRef.current[best],
|
|
5509
|
+
useNativeDriver: false,
|
|
5510
|
+
friction: 8,
|
|
5511
|
+
tension: 70
|
|
5512
|
+
}).start(() => {
|
|
5513
|
+
dragged.current = false;
|
|
5514
|
+
});
|
|
5515
|
+
}
|
|
5516
|
+
}),
|
|
5517
|
+
[pan]
|
|
5518
|
+
);
|
|
5519
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5520
|
+
reactNative.Animated.View,
|
|
5521
|
+
{
|
|
5522
|
+
...responder.panHandlers,
|
|
5523
|
+
style: [styles28.pip, { transform: pan.getTranslateTransform() }],
|
|
5524
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5525
|
+
reactNative.Pressable,
|
|
5526
|
+
{
|
|
5527
|
+
onPress: () => {
|
|
5528
|
+
if (dragged.current) return;
|
|
5529
|
+
onPress?.();
|
|
5530
|
+
},
|
|
5531
|
+
accessibilityRole: "button",
|
|
5532
|
+
accessibilityLabel: "Your camera. Drag to move, tap to switch camera.",
|
|
5533
|
+
style: styles28.fill,
|
|
5534
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles28.fill, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5535
|
+
CallParticipantTile,
|
|
5536
|
+
{
|
|
5537
|
+
participant,
|
|
5538
|
+
VideoTrack,
|
|
5539
|
+
label,
|
|
5540
|
+
avatarSize: 48,
|
|
5541
|
+
hideName: true,
|
|
5542
|
+
style: styles28.fill
|
|
5543
|
+
}
|
|
5544
|
+
) })
|
|
5545
|
+
}
|
|
5546
|
+
)
|
|
5547
|
+
}
|
|
5548
|
+
);
|
|
5549
|
+
}
|
|
5550
|
+
var styles28 = reactNative.StyleSheet.create({
|
|
5551
|
+
pip: {
|
|
5552
|
+
position: "absolute",
|
|
5553
|
+
top: 0,
|
|
5554
|
+
left: 0,
|
|
5555
|
+
width: PIP_WIDTH,
|
|
5556
|
+
height: PIP_HEIGHT,
|
|
5557
|
+
borderRadius: 16,
|
|
5558
|
+
overflow: "hidden",
|
|
5559
|
+
// Lifted off the video so it reads as floating rather than inset.
|
|
5560
|
+
shadowColor: "#000",
|
|
5561
|
+
shadowOpacity: 0.4,
|
|
5562
|
+
shadowRadius: 12,
|
|
5563
|
+
shadowOffset: { width: 0, height: 4 },
|
|
5564
|
+
elevation: 8
|
|
5565
|
+
},
|
|
5566
|
+
fill: { flex: 1 }
|
|
5567
|
+
});
|
|
5568
|
+
var GAP = 8;
|
|
5569
|
+
var MIN_TILE_HEIGHT = 132;
|
|
5570
|
+
function CallVideoGrid({
|
|
5571
|
+
participants,
|
|
5572
|
+
livekitReactNative,
|
|
5573
|
+
labelFor,
|
|
5574
|
+
onLocalPress,
|
|
5575
|
+
chromeInsets
|
|
5576
|
+
}) {
|
|
5577
|
+
const label = labelFor ?? ((id) => `User ${id.slice(0, 6)}`);
|
|
5578
|
+
const VideoTrack = livekitReactNative?.VideoTrack;
|
|
5579
|
+
const [size, setSize] = react.useState({ width: 0, height: 0 });
|
|
5580
|
+
const onLayout = (event) => {
|
|
5581
|
+
const { width: width2, height } = event.nativeEvent.layout;
|
|
5582
|
+
setSize(
|
|
5583
|
+
(current) => current.width === width2 && current.height === height ? current : { width: width2, height }
|
|
5584
|
+
);
|
|
5585
|
+
};
|
|
5586
|
+
const self = participants.find((p) => p.isSelf) ?? null;
|
|
5587
|
+
const others = react.useMemo(() => participants.filter((p) => !p.isSelf), [participants]);
|
|
5588
|
+
const columns = others.length + 1 <= 6 ? 2 : 3;
|
|
5589
|
+
const rows = Math.ceil((others.length + 1) / columns);
|
|
5590
|
+
const tileHeight = size.height > 0 ? (size.height - GAP * (rows - 1)) / rows : 0;
|
|
5591
|
+
const scrolls = tileHeight > 0 && tileHeight < MIN_TILE_HEIGHT;
|
|
5592
|
+
if (participants.length === 0) return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles29.stage, onLayout });
|
|
5593
|
+
if (others.length <= 1) {
|
|
5594
|
+
const spotlight = others[0] ?? self;
|
|
5595
|
+
if (!spotlight) return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles29.stage, onLayout });
|
|
5596
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles29.stage, onLayout, children: [
|
|
5597
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5598
|
+
CallParticipantTile,
|
|
5599
|
+
{
|
|
5600
|
+
participant: spotlight,
|
|
5601
|
+
VideoTrack,
|
|
5602
|
+
label,
|
|
5603
|
+
avatarSize: Math.min(148, Math.max(96, Math.round(size.width * 0.36))),
|
|
5604
|
+
bleed: true,
|
|
5605
|
+
hideName: others.length === 1,
|
|
5606
|
+
style: styles29.fill
|
|
5607
|
+
}
|
|
5608
|
+
),
|
|
5609
|
+
self && others.length === 1 && size.width > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5610
|
+
LocalVideoPip,
|
|
5611
|
+
{
|
|
5612
|
+
participant: self,
|
|
5613
|
+
VideoTrack,
|
|
5614
|
+
label,
|
|
5615
|
+
bounds: size,
|
|
5616
|
+
insets: chromeInsets ?? { top: 0, bottom: 0 },
|
|
5617
|
+
onPress: onLocalPress
|
|
5618
|
+
}
|
|
5619
|
+
)
|
|
5620
|
+
] });
|
|
5621
|
+
}
|
|
5622
|
+
const tiles = [...others, ...self ? [self] : []];
|
|
5623
|
+
const width = size.width > 0 ? (size.width - GAP * (columns - 1)) / columns : 0;
|
|
5624
|
+
const grid = /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles29.grid, scrolls ? styles29.gridScrolling : styles29.gridFilling], children: tiles.map((participant) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5625
|
+
CallParticipantTile,
|
|
5626
|
+
{
|
|
5627
|
+
participant,
|
|
5628
|
+
VideoTrack,
|
|
5629
|
+
label,
|
|
5630
|
+
avatarSize: columns === 2 ? 66 : 46,
|
|
5631
|
+
style: {
|
|
5632
|
+
width: width || void 0,
|
|
5633
|
+
height: scrolls ? MIN_TILE_HEIGHT : tileHeight || void 0
|
|
5634
|
+
}
|
|
5635
|
+
},
|
|
5636
|
+
participant.userId
|
|
5637
|
+
)) });
|
|
5638
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles29.stage, onLayout, children: scrolls ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5639
|
+
reactNative.ScrollView,
|
|
5640
|
+
{
|
|
5641
|
+
contentContainerStyle: [
|
|
5642
|
+
styles29.scroll,
|
|
5643
|
+
{ paddingBottom: (chromeInsets?.bottom ?? 0) + GAP }
|
|
5644
|
+
],
|
|
5645
|
+
showsVerticalScrollIndicator: false,
|
|
5646
|
+
children: grid
|
|
5647
|
+
}
|
|
5648
|
+
) : grid });
|
|
5649
|
+
}
|
|
5650
|
+
var styles29 = reactNative.StyleSheet.create({
|
|
5651
|
+
stage: { flex: 1, overflow: "hidden" },
|
|
5652
|
+
fill: { ...reactNative.StyleSheet.absoluteFillObject },
|
|
5653
|
+
grid: { flexDirection: "row", flexWrap: "wrap", gap: GAP },
|
|
5654
|
+
gridFilling: { flex: 1, alignContent: "center" },
|
|
5655
|
+
gridScrolling: { alignContent: "flex-start" },
|
|
5656
|
+
scroll: { paddingVertical: GAP }
|
|
5657
|
+
});
|
|
5658
|
+
|
|
5659
|
+
// src/voice/livekit-rn.ts
|
|
5660
|
+
function describeRoute(id) {
|
|
5661
|
+
switch (id) {
|
|
5662
|
+
case "speaker":
|
|
5663
|
+
case "force_speaker":
|
|
5664
|
+
return { id, kind: "speaker", label: "Speaker" };
|
|
5665
|
+
case "earpiece":
|
|
5666
|
+
return { id, kind: "earpiece", label: "Phone" };
|
|
5667
|
+
case "headset":
|
|
5668
|
+
return { id, kind: "headset", label: "Headphones" };
|
|
5669
|
+
case "bluetooth":
|
|
5670
|
+
return { id, kind: "bluetooth", label: "Bluetooth" };
|
|
5671
|
+
case "default":
|
|
5672
|
+
return { id, kind: "auto", label: "iPhone" };
|
|
5673
|
+
default:
|
|
5674
|
+
return { id, kind: "auto", label: id };
|
|
5675
|
+
}
|
|
5676
|
+
}
|
|
5677
|
+
|
|
5678
|
+
// src/voice/useCallAudio.ts
|
|
5679
|
+
var IOS_AUTO = "default";
|
|
5680
|
+
var IOS_SPEAKER = "force_speaker";
|
|
5681
|
+
function useCallAudio({
|
|
5682
|
+
active,
|
|
5683
|
+
video,
|
|
5684
|
+
livekitReactNative
|
|
5685
|
+
}) {
|
|
5686
|
+
const session = livekitReactNative?.AudioSession;
|
|
5687
|
+
const ios = reactNative.Platform.OS === "ios";
|
|
5688
|
+
const [routes, setRoutes] = react.useState([]);
|
|
5689
|
+
const [selectedRouteId, setSelectedRouteId] = react.useState(null);
|
|
5690
|
+
const preferSpeaker = react.useRef(video);
|
|
5691
|
+
if (!active) preferSpeaker.current = video;
|
|
5692
|
+
const userChose = react.useRef(false);
|
|
5693
|
+
if (!active) userChose.current = false;
|
|
5694
|
+
const refreshRoutes = react.useCallback(() => {
|
|
5695
|
+
if (!session) return;
|
|
5696
|
+
void session.getAudioOutputs().then((ids) => setRoutes(ids.map(describeRoute))).catch(() => {
|
|
5697
|
+
});
|
|
5698
|
+
}, [session]);
|
|
5699
|
+
react.useEffect(() => {
|
|
5700
|
+
if (!active || !session) return;
|
|
5701
|
+
const wantsSpeaker = preferSpeaker.current;
|
|
5702
|
+
let disposePolicy;
|
|
5703
|
+
void (async () => {
|
|
5704
|
+
try {
|
|
5705
|
+
await session.configureAudio({
|
|
5706
|
+
android: {
|
|
5707
|
+
// Best device first. A headset or car kit outranks the
|
|
5708
|
+
// built-in outputs either way; the media type only decides
|
|
5709
|
+
// which built-in output wins when nothing is plugged in.
|
|
5710
|
+
preferredOutputList: wantsSpeaker ? ["bluetooth", "headset", "speaker", "earpiece"] : ["bluetooth", "headset", "earpiece", "speaker"]
|
|
5711
|
+
},
|
|
5712
|
+
ios: { defaultOutput: wantsSpeaker ? "speaker" : "earpiece" }
|
|
5713
|
+
});
|
|
5714
|
+
} catch {
|
|
5715
|
+
}
|
|
5716
|
+
disposePolicy = livekitReactNative?.setupIOSAudioManagement?.(wantsSpeaker);
|
|
5717
|
+
try {
|
|
5718
|
+
await session.startAudioSession();
|
|
5719
|
+
} catch {
|
|
5720
|
+
}
|
|
5721
|
+
refreshRoutes();
|
|
5722
|
+
})();
|
|
5723
|
+
return () => {
|
|
5724
|
+
void session.stopAudioSession().catch(() => {
|
|
5725
|
+
});
|
|
5726
|
+
disposePolicy?.();
|
|
5727
|
+
};
|
|
5728
|
+
}, [active, session, livekitReactNative, refreshRoutes]);
|
|
5729
|
+
react.useEffect(() => {
|
|
5730
|
+
if (active) return;
|
|
5731
|
+
setSelectedRouteId(null);
|
|
5732
|
+
setRoutes([]);
|
|
5733
|
+
}, [active]);
|
|
5734
|
+
react.useEffect(() => {
|
|
5735
|
+
if (!active) return;
|
|
5736
|
+
const events = livekitReactNative?.audioDeviceModuleEvents;
|
|
5737
|
+
if (!events) return;
|
|
5738
|
+
const onChange = () => refreshRoutes();
|
|
5739
|
+
try {
|
|
5740
|
+
events.addDevicesUpdatedListener(onChange);
|
|
5741
|
+
} catch {
|
|
5742
|
+
return;
|
|
5743
|
+
}
|
|
5744
|
+
return () => {
|
|
5745
|
+
try {
|
|
5746
|
+
events.removeDevicesUpdatedListener(onChange);
|
|
5747
|
+
} catch {
|
|
5748
|
+
}
|
|
5749
|
+
};
|
|
5750
|
+
}, [active, livekitReactNative, refreshRoutes]);
|
|
5751
|
+
const selectRoute = react.useCallback(
|
|
5752
|
+
(id) => {
|
|
5753
|
+
userChose.current = true;
|
|
5754
|
+
setSelectedRouteId(id);
|
|
5755
|
+
if (!session) return;
|
|
5756
|
+
void session.selectAudioOutput(id).catch(() => {
|
|
5757
|
+
refreshRoutes();
|
|
5758
|
+
});
|
|
5759
|
+
},
|
|
5760
|
+
[session, refreshRoutes]
|
|
5761
|
+
);
|
|
5762
|
+
const externalDevice = react.useMemo(
|
|
5763
|
+
() => routes.some((r) => r.kind === "headset" || r.kind === "bluetooth"),
|
|
5764
|
+
[routes]
|
|
5765
|
+
);
|
|
5766
|
+
const speakerOn = selectedRouteId === null ? preferSpeaker.current && !externalDevice : ios ? selectedRouteId === IOS_SPEAKER : selectedRouteId === "speaker";
|
|
5767
|
+
const setSpeaker = react.useCallback(
|
|
5768
|
+
(on) => {
|
|
5769
|
+
if (ios) {
|
|
5770
|
+
selectRoute(on ? IOS_SPEAKER : IOS_AUTO);
|
|
5771
|
+
return;
|
|
5772
|
+
}
|
|
5773
|
+
if (on) {
|
|
5774
|
+
selectRoute("speaker");
|
|
5775
|
+
return;
|
|
5776
|
+
}
|
|
5777
|
+
const fallback = routes.find((r) => r.kind === "bluetooth") ?? routes.find((r) => r.kind === "headset") ?? routes.find((r) => r.kind === "earpiece");
|
|
5778
|
+
if (fallback) selectRoute(fallback.id);
|
|
5779
|
+
},
|
|
5780
|
+
[ios, routes, selectRoute]
|
|
5781
|
+
);
|
|
5782
|
+
const toggleSpeaker = react.useCallback(() => setSpeaker(!speakerOn), [setSpeaker, speakerOn]);
|
|
5783
|
+
const openSystemRoutePicker = react.useCallback(() => {
|
|
5784
|
+
void session?.showAudioRoutePicker?.().catch(() => {
|
|
5785
|
+
});
|
|
5786
|
+
}, [session]);
|
|
5787
|
+
return {
|
|
5788
|
+
speakerOn,
|
|
5789
|
+
toggleSpeaker,
|
|
5790
|
+
setSpeaker,
|
|
5791
|
+
routes,
|
|
5792
|
+
selectedRouteId,
|
|
5793
|
+
selectRoute,
|
|
5794
|
+
externalDevice,
|
|
5795
|
+
canPickSystemRoute: ios && typeof session?.showAudioRoutePicker === "function",
|
|
5796
|
+
openSystemRoutePicker
|
|
5797
|
+
};
|
|
5798
|
+
}
|
|
5799
|
+
function useCallDuration(connected) {
|
|
5800
|
+
const startedAt = react.useRef(null);
|
|
5801
|
+
const [, tick] = react.useState(0);
|
|
5802
|
+
if (connected && startedAt.current === null) startedAt.current = Date.now();
|
|
5803
|
+
if (!connected && startedAt.current !== null) startedAt.current = null;
|
|
5804
|
+
react.useEffect(() => {
|
|
5805
|
+
if (!connected) return;
|
|
5806
|
+
const id = setInterval(() => tick((n) => n + 1), 1e3);
|
|
5807
|
+
return () => clearInterval(id);
|
|
5808
|
+
}, [connected]);
|
|
5809
|
+
if (!connected || startedAt.current === null) return null;
|
|
5810
|
+
return format(Math.max(0, Math.floor((Date.now() - startedAt.current) / 1e3)));
|
|
5811
|
+
}
|
|
5812
|
+
function format(total) {
|
|
5813
|
+
const hours = Math.floor(total / 3600);
|
|
5814
|
+
const minutes = Math.floor(total % 3600 / 60);
|
|
5815
|
+
const seconds = total % 60;
|
|
5816
|
+
const mm = hours > 0 ? String(minutes).padStart(2, "0") : String(minutes);
|
|
5817
|
+
return `${hours > 0 ? `${hours}:` : ""}${mm}:${String(seconds).padStart(2, "0")}`;
|
|
5818
|
+
}
|
|
5819
|
+
var CHROME_IDLE_MS = 4500;
|
|
5186
5820
|
function CallScreen({
|
|
5187
5821
|
userId,
|
|
5188
5822
|
labelFor,
|
|
@@ -5195,7 +5829,7 @@ function CallScreen({
|
|
|
5195
5829
|
onVideoChange,
|
|
5196
5830
|
nativeIncomingUi
|
|
5197
5831
|
}) {
|
|
5198
|
-
const
|
|
5832
|
+
const insets = reactNativeSafeAreaContext.useSafeAreaInsets();
|
|
5199
5833
|
const ownCalls = react$1.useCalls(callsProp ? null : userId);
|
|
5200
5834
|
const calls = callsProp ?? ownCalls;
|
|
5201
5835
|
const meshAvailable = isNativeWebRtcAvailable(webrtc);
|
|
@@ -5204,19 +5838,21 @@ function CallScreen({
|
|
|
5204
5838
|
[meshAvailable, webrtc]
|
|
5205
5839
|
);
|
|
5206
5840
|
const conversationId = calls.phase === "active" ? calls.activeConversationId : null;
|
|
5841
|
+
const isVideoCall = calls.media === "video";
|
|
5207
5842
|
const sfu = react$1.useCallRoom(livekit ? conversationId : null, {
|
|
5208
5843
|
livekit,
|
|
5209
|
-
video:
|
|
5844
|
+
video: isVideoCall
|
|
5210
5845
|
});
|
|
5211
5846
|
const mesh = react$1.useVoiceRoom(conversationId, opts);
|
|
5212
5847
|
const usingSfu = sfu.sfuAvailable === true;
|
|
5213
5848
|
const status = usingSfu ? toVoiceStatus(sfu.status) : mesh.status;
|
|
5849
|
+
const connected = calls.phase === "active" && status === "connected";
|
|
5214
5850
|
react.useEffect(() => {
|
|
5215
5851
|
if (calls.phase !== "active" || !conversationId) return;
|
|
5216
5852
|
let cancelled = false;
|
|
5217
5853
|
void (async () => {
|
|
5218
|
-
const
|
|
5219
|
-
if (cancelled ||
|
|
5854
|
+
const joined = livekit ? await sfu.join() : false;
|
|
5855
|
+
if (cancelled || joined) return;
|
|
5220
5856
|
if (meshAvailable) await mesh.join();
|
|
5221
5857
|
})();
|
|
5222
5858
|
return () => {
|
|
@@ -5234,79 +5870,217 @@ function CallScreen({
|
|
|
5234
5870
|
react.useEffect(() => {
|
|
5235
5871
|
onVideoChange?.(videoOn);
|
|
5236
5872
|
}, [videoOn, onVideoChange]);
|
|
5237
|
-
const
|
|
5238
|
-
|
|
5239
|
-
|
|
5873
|
+
const audio = useCallAudio({
|
|
5874
|
+
active: calls.phase !== "idle" && transport !== "mesh",
|
|
5875
|
+
video: isVideoCall,
|
|
5876
|
+
livekitReactNative
|
|
5877
|
+
});
|
|
5878
|
+
const [routesOpen, setRoutesOpen] = react.useState(false);
|
|
5879
|
+
const [chromeVisible, setChromeVisible] = react.useState(true);
|
|
5880
|
+
const hideAt = react.useRef(0);
|
|
5881
|
+
const chromeHides = connected && isVideoCall;
|
|
5882
|
+
react.useEffect(() => {
|
|
5883
|
+
if (!chromeHides) {
|
|
5884
|
+
setChromeVisible(true);
|
|
5885
|
+
return;
|
|
5886
|
+
}
|
|
5887
|
+
hideAt.current = Date.now() + CHROME_IDLE_MS;
|
|
5888
|
+
const timer = setInterval(() => {
|
|
5889
|
+
if (Date.now() >= hideAt.current) setChromeVisible(false);
|
|
5890
|
+
}, 500);
|
|
5891
|
+
return () => clearInterval(timer);
|
|
5892
|
+
}, [chromeHides, chromeVisible]);
|
|
5893
|
+
const wakeChrome = react.useCallback(() => {
|
|
5894
|
+
hideAt.current = Date.now() + CHROME_IDLE_MS;
|
|
5895
|
+
setChromeVisible(true);
|
|
5896
|
+
}, []);
|
|
5240
5897
|
const hangUp = react.useCallback(() => {
|
|
5241
5898
|
sfu.leave();
|
|
5242
5899
|
mesh.leave();
|
|
5243
5900
|
void calls.hangUp();
|
|
5244
5901
|
}, [sfu, mesh, calls]);
|
|
5902
|
+
const alone = usingSfu ? sfu.alone : mesh.alone;
|
|
5903
|
+
react.useEffect(() => {
|
|
5904
|
+
if (!alone || calls.phase !== "active") return;
|
|
5905
|
+
hangUp();
|
|
5906
|
+
}, [alone, calls.phase, hangUp]);
|
|
5245
5907
|
const micOn = usingSfu ? sfu.micEnabled : !mesh.muted;
|
|
5246
5908
|
const toggleMic = react.useCallback(() => {
|
|
5247
5909
|
if (usingSfu) void sfu.toggleMic();
|
|
5248
5910
|
else mesh.toggleMute();
|
|
5249
5911
|
}, [usingSfu, sfu, mesh]);
|
|
5912
|
+
const onSpeakerPress = react.useCallback(() => {
|
|
5913
|
+
if (audio.routes.length > 2) setRoutesOpen(true);
|
|
5914
|
+
else if (audio.canPickSystemRoute && audio.externalDevice) audio.openSystemRoutePicker();
|
|
5915
|
+
else audio.toggleSpeaker();
|
|
5916
|
+
}, [audio]);
|
|
5917
|
+
const label = react.useMemo(() => labelFor ?? ((id) => `User ${id.slice(0, 6)}`), [labelFor]);
|
|
5918
|
+
const ringingIn = calls.phase === "ringing-in";
|
|
5919
|
+
const ringingOut = calls.phase === "ringing-out";
|
|
5920
|
+
const ended = calls.phase === "declined" || calls.phase === "busy" || calls.phase === "timed-out";
|
|
5921
|
+
const visible = calls.phase !== "idle" && !(nativeIncomingUi && ringingIn);
|
|
5922
|
+
const duration = useCallDuration(connected);
|
|
5923
|
+
const participants = usingSfu ? sfu.participants : [];
|
|
5924
|
+
const others = participants.filter((p) => !p.isSelf);
|
|
5925
|
+
const isGroup = others.length > 1 || (calls.outgoing?.calleeUserIds.length ?? 0) > 1;
|
|
5926
|
+
const peerIds = ringingIn && calls.incoming ? [calls.incoming.callerUserId] : others.length > 0 ? others.map((p) => p.userId) : calls.outgoing?.calleeUserIds ?? [];
|
|
5927
|
+
const title = peerIds.length === 0 ? "Call" : peerIds.length <= 2 ? peerIds.map(label).join(", ") : `${label(peerIds[0])} and ${peerIds.length - 1} others`;
|
|
5928
|
+
const subtitle = duration ?? statusLine(calls, status);
|
|
5929
|
+
const showStage = connected && usingSfu && participants.length > 0;
|
|
5250
5930
|
const error = calls.error ?? (usingSfu ? sfu.error : mesh.error);
|
|
5251
|
-
const
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5931
|
+
const chromeInsets = {
|
|
5932
|
+
top: insets.top + 72,
|
|
5933
|
+
bottom: insets.bottom + 150
|
|
5934
|
+
};
|
|
5935
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5936
|
+
reactNative.Modal,
|
|
5937
|
+
{
|
|
5938
|
+
visible,
|
|
5939
|
+
animationType: "slide",
|
|
5940
|
+
transparent: false,
|
|
5941
|
+
supportedOrientations: ["portrait", "landscape"],
|
|
5942
|
+
onRequestClose: hangUp,
|
|
5943
|
+
children: [
|
|
5944
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.StatusBar, { barStyle: "light-content" }),
|
|
5945
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { style: styles30.screen, onPress: wakeChrome, accessible: false, children: [
|
|
5946
|
+
showStage ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5947
|
+
CallVideoGrid,
|
|
5948
|
+
{
|
|
5949
|
+
participants,
|
|
5950
|
+
livekitReactNative,
|
|
5951
|
+
labelFor: label,
|
|
5952
|
+
onLocalPress: () => void sfu.switchCamera(),
|
|
5953
|
+
chromeInsets
|
|
5954
|
+
}
|
|
5955
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles30.identity, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5956
|
+
CallAvatar,
|
|
5957
|
+
{
|
|
5958
|
+
name: peerIds.length === 1 ? label(peerIds[0]) : title,
|
|
5959
|
+
seed: peerIds[0] ?? "call",
|
|
5960
|
+
size: 132
|
|
5961
|
+
}
|
|
5962
|
+
) }),
|
|
5963
|
+
chromeVisible && /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles30.header, { paddingTop: insets.top + 14 }], pointerEvents: "box-none", children: [
|
|
5964
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { numberOfLines: 1, style: styles30.title, children: title }),
|
|
5965
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles30.subtitleRow, children: [
|
|
5966
|
+
isGroup && showStage && /* @__PURE__ */ jsxRuntime.jsx(PoolseIcon, { name: "users", size: 14, color: callColors.textDim, label: null }),
|
|
5967
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles30.subtitle, children: isGroup && showStage ? `${participants.length} \xB7 ${subtitle}` : subtitle })
|
|
5968
|
+
] })
|
|
5969
|
+
] }),
|
|
5970
|
+
chromeVisible && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5971
|
+
reactNative.View,
|
|
5972
|
+
{
|
|
5973
|
+
style: [styles30.controls, { paddingBottom: insets.bottom + 22 }],
|
|
5974
|
+
pointerEvents: "box-none",
|
|
5975
|
+
children: [
|
|
5976
|
+
error && /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles30.error, children: error.message }),
|
|
5977
|
+
!meshAvailable && !livekit && /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles30.error, children: "No WebRTC module supplied \u2014 this call has no audio." }),
|
|
5978
|
+
ringingIn ? /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles30.row, children: [
|
|
5979
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5980
|
+
CallControlButton,
|
|
5981
|
+
{
|
|
5982
|
+
icon: "phone-off",
|
|
5983
|
+
tone: "danger",
|
|
5984
|
+
large: true,
|
|
5985
|
+
onPress: () => void calls.decline(),
|
|
5986
|
+
accessibilityLabel: "Decline call"
|
|
5987
|
+
}
|
|
5988
|
+
),
|
|
5989
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5990
|
+
CallControlButton,
|
|
5991
|
+
{
|
|
5992
|
+
icon: isVideoCall ? "video" : "phone",
|
|
5993
|
+
tone: "accept",
|
|
5994
|
+
large: true,
|
|
5995
|
+
onPress: () => void calls.accept(),
|
|
5996
|
+
accessibilityLabel: "Accept call"
|
|
5997
|
+
}
|
|
5998
|
+
)
|
|
5999
|
+
] }) : ended ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles30.row, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6000
|
+
CallControlButton,
|
|
6001
|
+
{
|
|
6002
|
+
icon: "close",
|
|
6003
|
+
onPress: calls.reset,
|
|
6004
|
+
label: "Close",
|
|
6005
|
+
accessibilityLabel: "Close"
|
|
6006
|
+
}
|
|
6007
|
+
) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
6008
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles30.row, children: [
|
|
6009
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6010
|
+
CallControlButton,
|
|
6011
|
+
{
|
|
6012
|
+
icon: micOn ? "mic" : "mic-off",
|
|
6013
|
+
label: micOn ? "Mute" : "Unmute",
|
|
6014
|
+
active: !micOn,
|
|
6015
|
+
onPress: toggleMic,
|
|
6016
|
+
accessibilityLabel: micOn ? "Mute microphone" : "Unmute microphone"
|
|
6017
|
+
}
|
|
6018
|
+
),
|
|
6019
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6020
|
+
CallControlButton,
|
|
6021
|
+
{
|
|
6022
|
+
icon: speakerIcon(audio),
|
|
6023
|
+
label: speakerLabel(audio),
|
|
6024
|
+
active: audio.speakerOn,
|
|
6025
|
+
onPress: onSpeakerPress,
|
|
6026
|
+
accessibilityLabel: "Audio output"
|
|
6027
|
+
}
|
|
6028
|
+
),
|
|
6029
|
+
usingSfu && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6030
|
+
CallControlButton,
|
|
6031
|
+
{
|
|
6032
|
+
icon: videoOn ? "video" : "video-off",
|
|
6033
|
+
label: "Camera",
|
|
6034
|
+
active: !videoOn,
|
|
6035
|
+
onPress: () => void sfu.toggleCamera(),
|
|
6036
|
+
accessibilityLabel: videoOn ? "Turn camera off" : "Turn camera on"
|
|
6037
|
+
}
|
|
6038
|
+
),
|
|
6039
|
+
usingSfu && videoOn && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6040
|
+
CallControlButton,
|
|
6041
|
+
{
|
|
6042
|
+
icon: "camera-flip",
|
|
6043
|
+
label: "Flip",
|
|
6044
|
+
onPress: () => void sfu.switchCamera(),
|
|
6045
|
+
accessibilityLabel: "Switch camera"
|
|
6046
|
+
}
|
|
6047
|
+
)
|
|
6048
|
+
] }),
|
|
6049
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles30.hangUpRow, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6050
|
+
CallControlButton,
|
|
6051
|
+
{
|
|
6052
|
+
icon: "phone-off",
|
|
6053
|
+
tone: "danger",
|
|
6054
|
+
large: true,
|
|
6055
|
+
onPress: ringingOut ? () => void calls.cancel() : hangUp,
|
|
6056
|
+
accessibilityLabel: ringingOut ? "Cancel call" : "Hang up"
|
|
6057
|
+
}
|
|
6058
|
+
) })
|
|
6059
|
+
] })
|
|
6060
|
+
]
|
|
6061
|
+
}
|
|
6062
|
+
),
|
|
6063
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6064
|
+
AudioRouteSheet,
|
|
6065
|
+
{
|
|
6066
|
+
visible: routesOpen,
|
|
6067
|
+
routes: audio.routes,
|
|
6068
|
+
selectedRouteId: audio.selectedRouteId,
|
|
6069
|
+
onSelect: audio.selectRoute,
|
|
6070
|
+
onClose: () => setRoutesOpen(false)
|
|
6071
|
+
}
|
|
6072
|
+
)
|
|
6073
|
+
] })
|
|
6074
|
+
]
|
|
6075
|
+
}
|
|
6076
|
+
);
|
|
6077
|
+
}
|
|
6078
|
+
function speakerIcon(audio) {
|
|
6079
|
+
if (audio.externalDevice) return "headphones";
|
|
6080
|
+
return audio.speakerOn ? "speaker" : "speaker-off";
|
|
6081
|
+
}
|
|
6082
|
+
function speakerLabel(audio) {
|
|
6083
|
+
return audio.externalDevice ? "Audio" : "Speaker";
|
|
5310
6084
|
}
|
|
5311
6085
|
function toVoiceStatus(status) {
|
|
5312
6086
|
switch (status) {
|
|
@@ -5323,7 +6097,7 @@ function toVoiceStatus(status) {
|
|
|
5323
6097
|
function statusLine(calls, mediaStatus) {
|
|
5324
6098
|
switch (calls.phase) {
|
|
5325
6099
|
case "ringing-in":
|
|
5326
|
-
return calls.media === "video" ? "Incoming video call
|
|
6100
|
+
return calls.media === "video" ? "Incoming video call" : "Incoming call";
|
|
5327
6101
|
case "ringing-out":
|
|
5328
6102
|
return "Ringing\u2026";
|
|
5329
6103
|
case "declined":
|
|
@@ -5338,36 +6112,41 @@ function statusLine(calls, mediaStatus) {
|
|
|
5338
6112
|
return "";
|
|
5339
6113
|
}
|
|
5340
6114
|
}
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
}
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
},
|
|
5369
|
-
|
|
5370
|
-
|
|
6115
|
+
var styles30 = reactNative.StyleSheet.create({
|
|
6116
|
+
screen: { flex: 1, backgroundColor: callColors.bg },
|
|
6117
|
+
identity: { flex: 1, alignItems: "center", justifyContent: "center" },
|
|
6118
|
+
header: {
|
|
6119
|
+
position: "absolute",
|
|
6120
|
+
top: 0,
|
|
6121
|
+
left: 0,
|
|
6122
|
+
right: 0,
|
|
6123
|
+
alignItems: "center",
|
|
6124
|
+
gap: 5,
|
|
6125
|
+
paddingHorizontal: 24,
|
|
6126
|
+
paddingBottom: 18,
|
|
6127
|
+
backgroundColor: callColors.scrim
|
|
6128
|
+
},
|
|
6129
|
+
title: { color: callColors.text, fontSize: 22, fontWeight: "600", textAlign: "center" },
|
|
6130
|
+
subtitleRow: { flexDirection: "row", alignItems: "center", gap: 6 },
|
|
6131
|
+
subtitle: { color: callColors.textDim, fontSize: 14.5 },
|
|
6132
|
+
controls: {
|
|
6133
|
+
position: "absolute",
|
|
6134
|
+
left: 0,
|
|
6135
|
+
right: 0,
|
|
6136
|
+
bottom: 0,
|
|
6137
|
+
alignItems: "center",
|
|
6138
|
+
gap: 18,
|
|
6139
|
+
paddingTop: 20,
|
|
6140
|
+
backgroundColor: callColors.scrim
|
|
6141
|
+
},
|
|
6142
|
+
row: { flexDirection: "row", justifyContent: "center", flexWrap: "wrap", rowGap: 16 },
|
|
6143
|
+
hangUpRow: { flexDirection: "row", justifyContent: "center" },
|
|
6144
|
+
error: {
|
|
6145
|
+
color: callColors.danger,
|
|
6146
|
+
fontSize: 12.5,
|
|
6147
|
+
textAlign: "center",
|
|
6148
|
+
paddingHorizontal: 24
|
|
6149
|
+
}
|
|
5371
6150
|
});
|
|
5372
6151
|
function isCallOver(phase) {
|
|
5373
6152
|
if (phase === void 0) return false;
|
|
@@ -5549,7 +6328,11 @@ function guessApnsEnvironment() {
|
|
|
5549
6328
|
|
|
5550
6329
|
exports.AttachmentPicker = AttachmentPicker;
|
|
5551
6330
|
exports.AttachmentPreview = AttachmentPreview;
|
|
6331
|
+
exports.AudioRouteSheet = AudioRouteSheet;
|
|
5552
6332
|
exports.Avatar = Avatar;
|
|
6333
|
+
exports.CallAvatar = CallAvatar;
|
|
6334
|
+
exports.CallControlButton = CallControlButton;
|
|
6335
|
+
exports.CallParticipantTile = CallParticipantTile;
|
|
5553
6336
|
exports.CallScreen = CallScreen;
|
|
5554
6337
|
exports.CallVideoGrid = CallVideoGrid;
|
|
5555
6338
|
exports.ChatHeader = ChatHeader;
|
|
@@ -5558,6 +6341,7 @@ exports.ConversationView = ConversationView;
|
|
|
5558
6341
|
exports.DaySeparator = DaySeparator;
|
|
5559
6342
|
exports.GroupDetailsSheet = GroupDetailsSheet;
|
|
5560
6343
|
exports.ImageMosaic = ImageMosaic;
|
|
6344
|
+
exports.LocalVideoPip = LocalVideoPip;
|
|
5561
6345
|
exports.MemberList = MemberList;
|
|
5562
6346
|
exports.MentionInput = MentionInput;
|
|
5563
6347
|
exports.MessageActions = MessageActions;
|
|
@@ -5577,12 +6361,16 @@ exports.TypingIndicator = TypingIndicator;
|
|
|
5577
6361
|
exports.UploadQueueStrip = UploadQueueStrip;
|
|
5578
6362
|
exports.UserName = UserName;
|
|
5579
6363
|
exports.VoiceRoomBar = VoiceRoomBar;
|
|
6364
|
+
exports.callColors = callColors;
|
|
5580
6365
|
exports.createNativeWebRtcAdapter = createNativeWebRtcAdapter;
|
|
5581
6366
|
exports.defaultDarkTheme = defaultDarkTheme;
|
|
5582
6367
|
exports.defaultLightTheme = defaultLightTheme;
|
|
6368
|
+
exports.describeRoute = describeRoute;
|
|
5583
6369
|
exports.isNativeWebRtcAvailable = isNativeWebRtcAvailable;
|
|
5584
6370
|
exports.isStalePush = isStalePush;
|
|
5585
6371
|
exports.useAppStateLifecycle = useAppStateLifecycle;
|
|
6372
|
+
exports.useCallAudio = useCallAudio;
|
|
6373
|
+
exports.useCallDuration = useCallDuration;
|
|
5586
6374
|
exports.useDisplayName = useDisplayName;
|
|
5587
6375
|
exports.usePoolseTheme = usePoolseTheme;
|
|
5588
6376
|
exports.useVoipCalls = useVoipCalls;
|