@messenger-box/platform-mobile 10.0.3-alpha.47 → 10.0.3-alpha.48
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 +4 -0
- package/lib/queries/inboxQueries.js +2 -13
- package/lib/queries/inboxQueries.js.map +1 -1
- package/lib/screens/inbox/components/DialogItem.js +169 -0
- package/lib/screens/inbox/components/DialogItem.js.map +1 -0
- package/lib/screens/inbox/containers/Dialogs.js +10 -20
- package/lib/screens/inbox/containers/Dialogs.js.map +1 -1
- package/package.json +4 -4
- package/src/screens/inbox/components/DialogItem.tsx +306 -0
- package/src/screens/inbox/components/DialogsListItem.tsx +140 -305
- package/src/screens/inbox/components/ServiceDialogsListItem.tsx +171 -264
- package/src/screens/inbox/containers/Dialogs.tsx +104 -45
- package/lib/screens/inbox/components/DialogsListItem.js +0 -355
- package/lib/screens/inbox/components/DialogsListItem.js.map +0 -1
- package/lib/screens/inbox/components/ServiceDialogsListItem.js +0 -402
- package/lib/screens/inbox/components/ServiceDialogsListItem.js.map +0 -1
|
@@ -1,27 +1,17 @@
|
|
|
1
1
|
import React, { useMemo, useState, useCallback, useRef } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Text,
|
|
4
|
-
Image,
|
|
5
4
|
Pressable,
|
|
6
5
|
HStack,
|
|
7
6
|
Box,
|
|
8
|
-
AvatarGroup,
|
|
9
7
|
Avatar,
|
|
10
8
|
AvatarFallbackText,
|
|
11
9
|
AvatarImage,
|
|
12
|
-
AvatarBadge,
|
|
13
|
-
View,
|
|
14
10
|
} from '@admin-layout/gluestack-ui-mobile';
|
|
15
11
|
import { format, isToday, isYesterday } from 'date-fns';
|
|
16
12
|
import { useFocusEffect } from '@react-navigation/native';
|
|
17
13
|
import { IChannel, IUserAccount } from 'common';
|
|
18
|
-
import {
|
|
19
|
-
THREAD_CREATED_UPDATED,
|
|
20
|
-
CHAT_MESSAGE_ADDED,
|
|
21
|
-
useThreadMessagesQuery,
|
|
22
|
-
useThreadCreatedUpdatedSubscription,
|
|
23
|
-
useThreadChatMessageAddedSubscription,
|
|
24
|
-
} from '../../../queries/inboxQueries';
|
|
14
|
+
import { THREAD_CREATED_UPDATED, CHAT_MESSAGE_ADDED, useThreadMessagesQuery } from '../../../queries/inboxQueries';
|
|
25
15
|
import { startCase } from 'lodash-es';
|
|
26
16
|
import colors from 'tailwindcss/colors';
|
|
27
17
|
import { SubscriptionHandler } from './SubscriptionHandler';
|
|
@@ -122,136 +112,63 @@ const computeLastMessage = (threadMessages) => {
|
|
|
122
112
|
}, allMessages[0]);
|
|
123
113
|
};
|
|
124
114
|
|
|
125
|
-
const ServiceChannelWithLastMessage = React.memo(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
channel: any;
|
|
136
|
-
lastMessage: any;
|
|
137
|
-
subscribeToNewMessages: () => void;
|
|
138
|
-
subscribeToChatMessages: () => void;
|
|
139
|
-
subscribeToMore: any;
|
|
140
|
-
postParentId: any;
|
|
141
|
-
servicePostParentId: any;
|
|
142
|
-
}) => {
|
|
143
|
-
React.useEffect(() => {
|
|
144
|
-
console.log(`Setting up subscriptions for channel ${channel?.id}`);
|
|
145
|
-
// Subscribe and store the unsubscribe functions
|
|
146
|
-
let threadUnsubscribe;
|
|
147
|
-
let chatUnsubscribe;
|
|
148
|
-
|
|
149
|
-
try {
|
|
150
|
-
threadUnsubscribe = subscribeToNewMessages();
|
|
151
|
-
chatUnsubscribe = subscribeToChatMessages();
|
|
152
|
-
} catch (error) {
|
|
153
|
-
console.error(`Error setting up subscriptions for channel ${channel?.id}:`, error);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return () => {
|
|
157
|
-
// Cleanup subscriptions on unmount
|
|
158
|
-
if (threadUnsubscribe && typeof threadUnsubscribe === 'function') {
|
|
159
|
-
try {
|
|
160
|
-
console.log(`Cleaning up thread subscription for channel ${channel?.id}`);
|
|
161
|
-
threadUnsubscribe();
|
|
162
|
-
} catch (error) {
|
|
163
|
-
console.error(`Error cleaning up thread subscription for channel ${channel?.id}:`, error);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
115
|
+
const ServiceChannelWithLastMessage = React.memo(({ channel, lastMessage }: { channel: any; lastMessage: any }) => {
|
|
116
|
+
// Debug output for component rendering
|
|
117
|
+
React.useEffect(() => {
|
|
118
|
+
console.log(`ServiceChannelWithLastMessage rendered for channel ${channel?.id}:`, {
|
|
119
|
+
hasLastMessage: !!lastMessage,
|
|
120
|
+
messageId: lastMessage?.id,
|
|
121
|
+
messageText: lastMessage?.message?.substring(0, 20) + (lastMessage?.message?.length > 20 ? '...' : ''),
|
|
122
|
+
date: lastMessage?.createdAt ? safeDate(lastMessage.createdAt)?.toISOString() : 'none',
|
|
123
|
+
});
|
|
124
|
+
}, [lastMessage, channel?.id]);
|
|
166
125
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
if (lastMessage) {
|
|
195
|
-
// Check for file attachments
|
|
196
|
-
const hasFileAttachments = lastMessage.files?.data?.length > 0;
|
|
197
|
-
|
|
198
|
-
// Check if the message appears to be an image
|
|
199
|
-
const isImageMessage =
|
|
200
|
-
lastMessage.message?.includes('<img') ||
|
|
201
|
-
lastMessage.message?.includes('[Image]') ||
|
|
202
|
-
lastMessage.message?.includes('![') ||
|
|
203
|
-
(/\.(jpeg|jpg|gif|png|bmp|webp)/i.test(lastMessage.message || '') &&
|
|
204
|
-
((lastMessage.message || '').includes('http') || (lastMessage.message || '').includes('/images/')));
|
|
205
|
-
|
|
206
|
-
if (hasFileAttachments) {
|
|
207
|
-
displayMessage = '📎 File attachment';
|
|
208
|
-
} else if (isImageMessage) {
|
|
209
|
-
displayMessage = '[Image]';
|
|
210
|
-
} else if (lastMessage.message && lastMessage.message.trim() !== '') {
|
|
211
|
-
displayMessage = lastMessage.message;
|
|
212
|
-
} else {
|
|
213
|
-
displayMessage = '(Empty message)';
|
|
214
|
-
}
|
|
126
|
+
const count = 30;
|
|
127
|
+
const title = channel?.title.slice(0, count) + (channel?.title.length > count ? '...' : '');
|
|
128
|
+
|
|
129
|
+
// Define message display text
|
|
130
|
+
let displayMessage = 'No messages yet';
|
|
131
|
+
|
|
132
|
+
if (lastMessage) {
|
|
133
|
+
// Check for file attachments
|
|
134
|
+
const hasFileAttachments = lastMessage.files?.data?.length > 0;
|
|
135
|
+
|
|
136
|
+
// Check if the message appears to be an image
|
|
137
|
+
const isImageMessage =
|
|
138
|
+
lastMessage.message?.includes('<img') ||
|
|
139
|
+
lastMessage.message?.includes('[Image]') ||
|
|
140
|
+
lastMessage.message?.includes('![') ||
|
|
141
|
+
(/\.(jpeg|jpg|gif|png|bmp|webp)/i.test(lastMessage.message || '') &&
|
|
142
|
+
((lastMessage.message || '').includes('http') || (lastMessage.message || '').includes('/images/')));
|
|
143
|
+
|
|
144
|
+
if (hasFileAttachments) {
|
|
145
|
+
displayMessage = '📎 File attachment';
|
|
146
|
+
} else if (isImageMessage) {
|
|
147
|
+
displayMessage = '[Image]';
|
|
148
|
+
} else if (lastMessage.message && lastMessage.message.trim() !== '') {
|
|
149
|
+
displayMessage = lastMessage.message;
|
|
150
|
+
} else {
|
|
151
|
+
displayMessage = '(Empty message)';
|
|
215
152
|
}
|
|
153
|
+
}
|
|
216
154
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
}}
|
|
235
|
-
updateQuery={undefined} // Provide custom updateQuery if needed
|
|
236
|
-
/>
|
|
237
|
-
<HStack space={'sm'} className="flex-1 justify-between">
|
|
238
|
-
<Box className="flex-[0.8]">
|
|
239
|
-
<Text color={colors.gray[600]} className="text-base text-wrap flex-wrap font-semibold">
|
|
240
|
-
{title}
|
|
241
|
-
</Text>
|
|
242
|
-
<Text color={colors.gray[600]} numberOfLines={1}>
|
|
243
|
-
{displayMessage}
|
|
244
|
-
</Text>
|
|
245
|
-
</Box>
|
|
246
|
-
|
|
247
|
-
<Box className="flex-[0.2]">
|
|
248
|
-
<Text color={colors.gray[500]}>{lastMessage ? createdAtText(lastMessage?.createdAt) : ''}</Text>
|
|
249
|
-
</Box>
|
|
250
|
-
</HStack>
|
|
251
|
-
</>
|
|
252
|
-
);
|
|
253
|
-
},
|
|
254
|
-
);
|
|
155
|
+
return (
|
|
156
|
+
<HStack space={'sm'} className="flex-1 justify-between">
|
|
157
|
+
<Box className="flex-[0.8]">
|
|
158
|
+
<Text color={colors.gray[600]} className="text-base text-wrap flex-wrap font-semibold">
|
|
159
|
+
{title}
|
|
160
|
+
</Text>
|
|
161
|
+
<Text color={colors.gray[600]} numberOfLines={1}>
|
|
162
|
+
{displayMessage}
|
|
163
|
+
</Text>
|
|
164
|
+
</Box>
|
|
165
|
+
|
|
166
|
+
<Box className="flex-[0.2]">
|
|
167
|
+
<Text color={colors.gray[500]}>{lastMessage ? createdAtText(lastMessage?.createdAt) : ''}</Text>
|
|
168
|
+
</Box>
|
|
169
|
+
</HStack>
|
|
170
|
+
);
|
|
171
|
+
});
|
|
255
172
|
|
|
256
173
|
/**
|
|
257
174
|
* TODO:
|
|
@@ -403,133 +320,123 @@ export const ServiceDialogsListItemComponent: React.FC<IDialogListItemProps> = f
|
|
|
403
320
|
key={`channel-${channel?.id}-${subscriptionsTimestamp}`}
|
|
404
321
|
channel={channel}
|
|
405
322
|
lastMessage={lastMessage}
|
|
406
|
-
subscribeToNewMessages={() =>
|
|
407
|
-
shouldQuery
|
|
408
|
-
? subscribeToMore({
|
|
409
|
-
document: THREAD_CREATED_UPDATED,
|
|
410
|
-
variables: {
|
|
411
|
-
channelId: channel?.id?.toString(),
|
|
412
|
-
postParentId: postParentId || servicePostParentId || null,
|
|
413
|
-
},
|
|
414
|
-
updateQuery: (prev, { subscriptionData }: any) => {
|
|
415
|
-
if (!subscriptionData?.data) {
|
|
416
|
-
return prev;
|
|
417
|
-
}
|
|
418
|
-
try {
|
|
419
|
-
const newPostThreadData: any =
|
|
420
|
-
subscriptionData?.data?.threadCreatedUpdated?.data;
|
|
421
|
-
const newMessage: any =
|
|
422
|
-
subscriptionData?.data?.threadCreatedUpdated?.lastMessage;
|
|
423
|
-
if (!newPostThreadData || !newMessage) {
|
|
424
|
-
return prev;
|
|
425
|
-
}
|
|
426
|
-
const prevThreads = prev?.threadMessages?.data || [];
|
|
427
|
-
const threadExists = prevThreads.some(
|
|
428
|
-
(t: any) => t.id === newPostThreadData?.id,
|
|
429
|
-
);
|
|
430
|
-
let updatedThreads;
|
|
431
|
-
if (threadExists) {
|
|
432
|
-
updatedThreads = prevThreads.map((t: any) =>
|
|
433
|
-
t.id === newPostThreadData?.id
|
|
434
|
-
? {
|
|
435
|
-
...t,
|
|
436
|
-
replies: [...(t?.replies || []), newMessage],
|
|
437
|
-
replyCount: newPostThreadData?.replyCount,
|
|
438
|
-
lastReplyAt: newPostThreadData?.lastReplyAt,
|
|
439
|
-
updatedAt: newPostThreadData?.updatedAt,
|
|
440
|
-
}
|
|
441
|
-
: t,
|
|
442
|
-
);
|
|
443
|
-
} else {
|
|
444
|
-
updatedThreads = [...prevThreads, newPostThreadData];
|
|
445
|
-
}
|
|
446
|
-
return {
|
|
447
|
-
...prev,
|
|
448
|
-
threadMessages: {
|
|
449
|
-
...prev?.threadMessages,
|
|
450
|
-
totalCount:
|
|
451
|
-
newPostThreadData?.totalCount ??
|
|
452
|
-
prev?.threadMessages?.totalCount ??
|
|
453
|
-
0,
|
|
454
|
-
data: updatedThreads,
|
|
455
|
-
},
|
|
456
|
-
};
|
|
457
|
-
} catch (error) {
|
|
458
|
-
return prev;
|
|
459
|
-
}
|
|
460
|
-
},
|
|
461
|
-
onError: (error) => {
|
|
462
|
-
console.error(`Thread subscription error for channel ${channel?.id}:`, error);
|
|
463
|
-
},
|
|
464
|
-
})
|
|
465
|
-
: undefined
|
|
466
|
-
}
|
|
467
|
-
subscribeToChatMessages={() =>
|
|
468
|
-
shouldQuery
|
|
469
|
-
? subscribeToMore({
|
|
470
|
-
document: CHAT_MESSAGE_ADDED,
|
|
471
|
-
variables: {
|
|
472
|
-
channelId: channel?.id?.toString(),
|
|
473
|
-
postParentId: postParentId || servicePostParentId || null,
|
|
474
|
-
},
|
|
475
|
-
updateQuery: (prev, { subscriptionData }: any) => {
|
|
476
|
-
if (!subscriptionData?.data) {
|
|
477
|
-
return prev;
|
|
478
|
-
}
|
|
479
|
-
try {
|
|
480
|
-
const newMessage = subscriptionData?.data?.chatMessageAdded;
|
|
481
|
-
if (!newMessage) {
|
|
482
|
-
return prev;
|
|
483
|
-
}
|
|
484
|
-
const prevThreads = prev?.threadMessages?.data || [];
|
|
485
|
-
const threadIndex = prevThreads.findIndex((t: any) => {
|
|
486
|
-
if (newMessage.parentId && t.post?.id === newMessage.parentId) {
|
|
487
|
-
return true;
|
|
488
|
-
}
|
|
489
|
-
if (
|
|
490
|
-
t.replies &&
|
|
491
|
-
t.replies.some((r: any) => r.id === newMessage.parentId)
|
|
492
|
-
) {
|
|
493
|
-
return true;
|
|
494
|
-
}
|
|
495
|
-
return false;
|
|
496
|
-
});
|
|
497
|
-
if (threadIndex === -1) {
|
|
498
|
-
return prev;
|
|
499
|
-
}
|
|
500
|
-
const updatedThreads = [...prevThreads];
|
|
501
|
-
const thread = { ...updatedThreads[threadIndex] };
|
|
502
|
-
thread.replies = [...(thread.replies || []), newMessage];
|
|
503
|
-
const currentReplyCount =
|
|
504
|
-
typeof thread.replyCount === 'number' ? thread.replyCount : 0;
|
|
505
|
-
thread.replyCount = currentReplyCount + 1;
|
|
506
|
-
thread.lastReplyAt = newMessage.createdAt;
|
|
507
|
-
thread.updatedAt = newMessage.createdAt;
|
|
508
|
-
updatedThreads[threadIndex] = thread;
|
|
509
|
-
return {
|
|
510
|
-
...prev,
|
|
511
|
-
threadMessages: {
|
|
512
|
-
...prev?.threadMessages,
|
|
513
|
-
data: updatedThreads,
|
|
514
|
-
},
|
|
515
|
-
};
|
|
516
|
-
} catch (error) {
|
|
517
|
-
return prev;
|
|
518
|
-
}
|
|
519
|
-
},
|
|
520
|
-
onError: (error) => {
|
|
521
|
-
console.error(
|
|
522
|
-
`Chat message subscription error for channel ${channel?.id}:`,
|
|
523
|
-
error,
|
|
524
|
-
);
|
|
525
|
-
},
|
|
526
|
-
})
|
|
527
|
-
: undefined
|
|
528
|
-
}
|
|
529
|
-
subscribeToMore={subscribeToMore}
|
|
530
|
-
postParentId={postParentId}
|
|
531
|
-
servicePostParentId={servicePostParentId}
|
|
532
323
|
/>
|
|
324
|
+
|
|
325
|
+
{/* Subscription handlers for real-time updates */}
|
|
326
|
+
{shouldQuery && (
|
|
327
|
+
<>
|
|
328
|
+
<SubscriptionHandler
|
|
329
|
+
subscribeToMore={subscribeToMore}
|
|
330
|
+
document={THREAD_CREATED_UPDATED}
|
|
331
|
+
variables={{
|
|
332
|
+
channelId: channel?.id?.toString(),
|
|
333
|
+
postParentId: postParentId || servicePostParentId || null,
|
|
334
|
+
}}
|
|
335
|
+
updateQuery={(prev, { subscriptionData }: any) => {
|
|
336
|
+
if (!subscriptionData?.data) {
|
|
337
|
+
return prev;
|
|
338
|
+
}
|
|
339
|
+
try {
|
|
340
|
+
const newPostThreadData: any =
|
|
341
|
+
subscriptionData?.data?.threadCreatedUpdated?.data;
|
|
342
|
+
const newMessage: any =
|
|
343
|
+
subscriptionData?.data?.threadCreatedUpdated?.lastMessage;
|
|
344
|
+
if (!newPostThreadData || !newMessage) {
|
|
345
|
+
return prev;
|
|
346
|
+
}
|
|
347
|
+
const prevThreads = prev?.threadMessages?.data || [];
|
|
348
|
+
const threadExists = prevThreads.some(
|
|
349
|
+
(t: any) => t.id === newPostThreadData?.id,
|
|
350
|
+
);
|
|
351
|
+
let updatedThreads;
|
|
352
|
+
if (threadExists) {
|
|
353
|
+
updatedThreads = prevThreads.map((t: any) =>
|
|
354
|
+
t.id === newPostThreadData?.id
|
|
355
|
+
? {
|
|
356
|
+
...t,
|
|
357
|
+
replies: [...(t?.replies || []), newMessage],
|
|
358
|
+
replyCount: newPostThreadData?.replyCount,
|
|
359
|
+
lastReplyAt: newPostThreadData?.lastReplyAt,
|
|
360
|
+
updatedAt: newPostThreadData?.updatedAt,
|
|
361
|
+
}
|
|
362
|
+
: t,
|
|
363
|
+
);
|
|
364
|
+
} else {
|
|
365
|
+
updatedThreads = [...prevThreads, newPostThreadData];
|
|
366
|
+
}
|
|
367
|
+
return {
|
|
368
|
+
...prev,
|
|
369
|
+
threadMessages: {
|
|
370
|
+
...prev?.threadMessages,
|
|
371
|
+
totalCount:
|
|
372
|
+
newPostThreadData?.totalCount ??
|
|
373
|
+
prev?.threadMessages?.totalCount ??
|
|
374
|
+
0,
|
|
375
|
+
data: updatedThreads,
|
|
376
|
+
},
|
|
377
|
+
};
|
|
378
|
+
} catch (error) {
|
|
379
|
+
console.error(`Thread subscription error for channel ${channel?.id}:`, error);
|
|
380
|
+
return prev;
|
|
381
|
+
}
|
|
382
|
+
}}
|
|
383
|
+
/>
|
|
384
|
+
<SubscriptionHandler
|
|
385
|
+
subscribeToMore={subscribeToMore}
|
|
386
|
+
document={CHAT_MESSAGE_ADDED}
|
|
387
|
+
variables={{
|
|
388
|
+
channelId: channel?.id?.toString(),
|
|
389
|
+
postParentId: postParentId || servicePostParentId || null,
|
|
390
|
+
}}
|
|
391
|
+
updateQuery={(prev, { subscriptionData }: any) => {
|
|
392
|
+
if (!subscriptionData?.data) {
|
|
393
|
+
return prev;
|
|
394
|
+
}
|
|
395
|
+
try {
|
|
396
|
+
const newMessage = subscriptionData?.data?.chatMessageAdded;
|
|
397
|
+
if (!newMessage) {
|
|
398
|
+
return prev;
|
|
399
|
+
}
|
|
400
|
+
const prevThreads = prev?.threadMessages?.data || [];
|
|
401
|
+
const threadIndex = prevThreads.findIndex((t: any) => {
|
|
402
|
+
if (newMessage.parentId && t.post?.id === newMessage.parentId) {
|
|
403
|
+
return true;
|
|
404
|
+
}
|
|
405
|
+
if (t.replies && t.replies.some((r: any) => r.id === newMessage.parentId)) {
|
|
406
|
+
return true;
|
|
407
|
+
}
|
|
408
|
+
return false;
|
|
409
|
+
});
|
|
410
|
+
if (threadIndex === -1) {
|
|
411
|
+
return prev;
|
|
412
|
+
}
|
|
413
|
+
const updatedThreads = [...prevThreads];
|
|
414
|
+
const thread = { ...updatedThreads[threadIndex] };
|
|
415
|
+
thread.replies = [...(thread.replies || []), newMessage];
|
|
416
|
+
const currentReplyCount =
|
|
417
|
+
typeof thread.replyCount === 'number' ? thread.replyCount : 0;
|
|
418
|
+
thread.replyCount = currentReplyCount + 1;
|
|
419
|
+
thread.lastReplyAt = newMessage.createdAt;
|
|
420
|
+
thread.updatedAt = newMessage.createdAt;
|
|
421
|
+
updatedThreads[threadIndex] = thread;
|
|
422
|
+
return {
|
|
423
|
+
...prev,
|
|
424
|
+
threadMessages: {
|
|
425
|
+
...prev?.threadMessages,
|
|
426
|
+
data: updatedThreads,
|
|
427
|
+
},
|
|
428
|
+
};
|
|
429
|
+
} catch (error) {
|
|
430
|
+
console.error(
|
|
431
|
+
`Chat message subscription error for channel ${channel?.id}:`,
|
|
432
|
+
error,
|
|
433
|
+
);
|
|
434
|
+
return prev;
|
|
435
|
+
}
|
|
436
|
+
}}
|
|
437
|
+
/>
|
|
438
|
+
</>
|
|
439
|
+
)}
|
|
533
440
|
</Box>
|
|
534
441
|
</HStack>
|
|
535
442
|
</Pressable>
|