@messenger-box/platform-mobile 10.0.3-alpha.16 → 10.0.3-alpha.162
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 +248 -0
- package/lib/compute.js +2 -3
- package/lib/compute.js.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/module.js.map +1 -1
- package/lib/queries/inboxQueries.js +65 -0
- package/lib/queries/inboxQueries.js.map +1 -0
- package/lib/routes.json +13 -1
- package/lib/screens/inbox/DialogMessages.js +5 -3
- package/lib/screens/inbox/DialogMessages.js.map +1 -1
- package/lib/screens/inbox/DialogThreadMessages.js +3 -7
- package/lib/screens/inbox/DialogThreadMessages.js.map +1 -1
- package/lib/screens/inbox/DialogThreads.js +57 -18
- package/lib/screens/inbox/DialogThreads.js.map +1 -1
- package/lib/screens/inbox/Inbox.js.map +1 -1
- package/lib/screens/inbox/components/CachedImage/consts.js +1 -1
- package/lib/screens/inbox/components/CachedImage/consts.js.map +1 -1
- package/lib/screens/inbox/components/CachedImage/index.js +168 -46
- package/lib/screens/inbox/components/CachedImage/index.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/components/GiftedChatInboxComponent.js +313 -0
- package/lib/screens/inbox/components/GiftedChatInboxComponent.js.map +1 -0
- package/lib/screens/inbox/components/SlackMessageContainer/ImageViewerModal.js.map +1 -1
- package/lib/screens/inbox/components/SlackMessageContainer/PaymentMessage.js +197 -0
- package/lib/screens/inbox/components/SlackMessageContainer/PaymentMessage.js.map +1 -0
- package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js +141 -31
- package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js.map +1 -1
- package/lib/screens/inbox/components/SlackMessageContainer/SlackMessage.js.map +1 -1
- package/lib/screens/inbox/components/SubscriptionHandler.js +24 -0
- package/lib/screens/inbox/components/SubscriptionHandler.js.map +1 -0
- package/lib/screens/inbox/components/ThreadsViewItem.js +66 -44
- package/lib/screens/inbox/components/ThreadsViewItem.js.map +1 -1
- package/lib/screens/inbox/config/config.js +2 -2
- package/lib/screens/inbox/config/config.js.map +1 -1
- package/lib/screens/inbox/containers/ConversationView.js +1205 -432
- package/lib/screens/inbox/containers/ConversationView.js.map +1 -1
- package/lib/screens/inbox/containers/Dialogs.js +193 -80
- package/lib/screens/inbox/containers/Dialogs.js.map +1 -1
- package/lib/screens/inbox/containers/ThreadConversationView.js +724 -207
- package/lib/screens/inbox/containers/ThreadConversationView.js.map +1 -1
- package/lib/screens/inbox/containers/ThreadsView.js +83 -50
- package/lib/screens/inbox/containers/ThreadsView.js.map +1 -1
- package/lib/screens/inbox/hooks/useInboxMessages.js +31 -0
- package/lib/screens/inbox/hooks/useInboxMessages.js.map +1 -0
- package/lib/screens/inbox/hooks/useSafeDialogThreadsMachine.js +108 -0
- package/lib/screens/inbox/hooks/useSafeDialogThreadsMachine.js.map +1 -0
- package/lib/screens/inbox/workflow/dialog-threads-xstate.js +151 -0
- package/lib/screens/inbox/workflow/dialog-threads-xstate.js.map +1 -0
- package/package.json +5 -5
- package/src/index.ts +2 -0
- package/src/queries/inboxQueries.ts +299 -0
- package/src/queries/index.d.ts +2 -0
- package/src/queries/index.ts +1 -0
- package/src/screens/inbox/DialogMessages.tsx +2 -1
- package/src/screens/inbox/DialogThreadMessages.tsx +3 -11
- package/src/screens/inbox/DialogThreads.tsx +53 -60
- package/src/screens/inbox/components/Actionsheet.tsx +30 -0
- package/src/screens/inbox/components/CachedImage/consts.ts +4 -3
- package/src/screens/inbox/components/CachedImage/index.tsx +232 -61
- package/src/screens/inbox/components/DialogItem.tsx +306 -0
- package/src/screens/inbox/components/DialogsListItem.tsx +230 -170
- package/src/screens/inbox/components/ExpandableInput.tsx +460 -0
- package/src/screens/inbox/components/ExpandableInputActionSheet.tsx +518 -0
- package/src/screens/inbox/components/GiftedChatInboxComponent.tsx +411 -0
- package/src/screens/inbox/components/ServiceDialogsListItem.tsx +330 -171
- package/src/screens/inbox/components/SlackInput.tsx +23 -0
- package/src/screens/inbox/components/SlackMessageContainer/PaymentMessage.tsx +199 -0
- package/src/screens/inbox/components/SlackMessageContainer/SlackBubble.tsx +233 -23
- package/src/screens/inbox/components/SmartLoader.tsx +61 -0
- package/src/screens/inbox/components/SubscriptionHandler.tsx +41 -0
- package/src/screens/inbox/components/SupportServiceDialogsListItem.tsx +41 -24
- package/src/screens/inbox/components/ThreadsViewItem.tsx +177 -265
- package/src/screens/inbox/components/workflow/dialogs-list-item-xstate.ts +145 -0
- package/src/screens/inbox/components/workflow/service-dialogs-list-item-xstate.ts +159 -0
- package/src/screens/inbox/config/config.ts +2 -2
- package/src/screens/inbox/containers/ConversationView.tsx +2004 -698
- package/src/screens/inbox/containers/ConversationView.tsx.bk +1467 -0
- package/src/screens/inbox/containers/Dialogs.tsx +402 -196
- package/src/screens/inbox/containers/SupportServiceDialogs.tsx +2 -2
- package/src/screens/inbox/containers/ThreadConversationView.tsx +1337 -301
- package/src/screens/inbox/containers/ThreadsView.tsx +105 -186
- package/src/screens/inbox/containers/workflow/apollo/handleResult.ts +20 -0
- package/src/screens/inbox/containers/workflow/conversation-xstate.ts +313 -0
- package/src/screens/inbox/containers/workflow/dialogs-xstate.ts +196 -0
- package/src/screens/inbox/containers/workflow/thread-conversation-xstate.ts +401 -0
- package/src/screens/inbox/hooks/useInboxMessages.ts +34 -0
- package/src/screens/inbox/hooks/useSafeDialogThreadsMachine.ts +136 -0
- package/src/screens/inbox/index.ts +37 -0
- package/src/screens/inbox/machines/threadsMachine.ts +147 -0
- package/src/screens/inbox/workflow/dialog-threads-xstate.ts +163 -0
- package/lib/screens/inbox/components/DialogsListItem.js +0 -175
- package/lib/screens/inbox/components/DialogsListItem.js.map +0 -1
- package/lib/screens/inbox/components/ServiceDialogsListItem.js +0 -165
- package/lib/screens/inbox/components/ServiceDialogsListItem.js.map +0 -1
|
@@ -16,23 +16,35 @@ import { format, isToday, isYesterday } from 'date-fns';
|
|
|
16
16
|
import { useFocusEffect } from '@react-navigation/native';
|
|
17
17
|
import { IChannel, IUserAccount } from 'common';
|
|
18
18
|
import {
|
|
19
|
+
THREAD_CREATED_UPDATED,
|
|
20
|
+
CHAT_MESSAGE_ADDED,
|
|
19
21
|
useThreadMessagesQuery,
|
|
22
|
+
useThreadCreatedUpdatedSubscription,
|
|
23
|
+
useThreadChatMessageAddedSubscription,
|
|
20
24
|
useMessagesQuery,
|
|
21
|
-
|
|
22
|
-
useOnThreadCreatedUpdatedSubscription,
|
|
23
|
-
useOnThreadChatMessageAddedSubscription,
|
|
24
|
-
OnThreadCreatedUpdatedDocument as THREAD_CHAT_ADDED,
|
|
25
|
-
OnThreadChatMessageAddedDocument as CHAT_MESSAGE_ADDED,
|
|
26
|
-
} from 'common/graphql';
|
|
25
|
+
} from '../../../queries/inboxQueries';
|
|
27
26
|
import { startCase } from 'lodash-es';
|
|
28
27
|
import colors from 'tailwindcss/colors';
|
|
29
28
|
|
|
30
29
|
const createdAtText = (value: string) => {
|
|
31
30
|
if (!value) return '';
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
// Validate the date before processing
|
|
34
|
+
const timestamp = new Date(value).getTime();
|
|
35
|
+
if (isNaN(timestamp)) {
|
|
36
|
+
console.warn(`Invalid date value in createdAtText: ${value}`);
|
|
37
|
+
return 'Unknown date';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let date = new Date(value);
|
|
41
|
+
if (isToday(date)) return 'Today';
|
|
42
|
+
if (isYesterday(date)) return 'Yesterday';
|
|
43
|
+
return format(date, 'MMM dd, yyyy');
|
|
44
|
+
} catch (error) {
|
|
45
|
+
console.error(`Error processing date in createdAtText: ${value}`, error);
|
|
46
|
+
return 'Unknown date';
|
|
47
|
+
}
|
|
36
48
|
};
|
|
37
49
|
|
|
38
50
|
export interface IDialogListChannel extends IChannel {
|
|
@@ -191,7 +203,7 @@ export const SupportServiceDialogsListItemComponent: React.FC<IDialogListItemPro
|
|
|
191
203
|
lastMessage={lastMessage}
|
|
192
204
|
subscribeToNewMessages={() =>
|
|
193
205
|
subscribeToMore({
|
|
194
|
-
document:
|
|
206
|
+
document: THREAD_CREATED_UPDATED,
|
|
195
207
|
variables: {
|
|
196
208
|
channelId: channel?.id?.toString(),
|
|
197
209
|
postParentId: postParentId ? servicePostParentId : null,
|
|
@@ -250,6 +262,23 @@ export const SupportServiceDialogsListItemComponent: React.FC<IDialogListItemPro
|
|
|
250
262
|
|
|
251
263
|
const ServiceChannelWithLastMessage = React.memo(({ channel, lastMessage, subscribeToNewMessages }: any) => {
|
|
252
264
|
React.useEffect(() => subscribeToNewMessages(), []);
|
|
265
|
+
|
|
266
|
+
// Define message display text
|
|
267
|
+
let displayMessage = 'No messages yet';
|
|
268
|
+
|
|
269
|
+
if (lastMessage) {
|
|
270
|
+
// Check for file attachments
|
|
271
|
+
const hasFileAttachments = lastMessage.files?.data?.length > 0;
|
|
272
|
+
|
|
273
|
+
if (hasFileAttachments) {
|
|
274
|
+
displayMessage = '📎 File attachment';
|
|
275
|
+
} else if (lastMessage.message && lastMessage.message.trim() !== '') {
|
|
276
|
+
displayMessage = lastMessage.message;
|
|
277
|
+
} else {
|
|
278
|
+
displayMessage = '(Empty message)';
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
253
282
|
return (
|
|
254
283
|
<HStack space={'sm'} className="flex-1 justify-center items-center">
|
|
255
284
|
<Box className="flex-[0.8]">
|
|
@@ -257,23 +286,11 @@ const ServiceChannelWithLastMessage = React.memo(({ channel, lastMessage, subscr
|
|
|
257
286
|
{channel?.title}
|
|
258
287
|
</Text>
|
|
259
288
|
<Text color={colors.gray[600]} numberOfLines={1}>
|
|
260
|
-
{
|
|
261
|
-
? lastMessageCreatorAndMembers?.message ?? ''
|
|
262
|
-
: lastMessage?.message ?? ''} */}
|
|
263
|
-
{lastMessage?.message ?? ''}
|
|
289
|
+
{displayMessage}
|
|
264
290
|
</Text>
|
|
265
291
|
</Box>
|
|
266
292
|
|
|
267
293
|
<Box className="flex-[0.2]">
|
|
268
|
-
{/* {creatorAndMembersId?.length && creatorAndMembersId?.includes(currentUser?.id) ? (
|
|
269
|
-
<Text color="gray.500">
|
|
270
|
-
{lastMessageCreatorAndMembers
|
|
271
|
-
? createdAtText(lastMessageCreatorAndMembers?.createdAt)
|
|
272
|
-
: ''}
|
|
273
|
-
</Text>
|
|
274
|
-
) : (
|
|
275
|
-
<Text color="gray.500">{lastMessage ? createdAtText(lastMessage?.createdAt) : ''}</Text>
|
|
276
|
-
)} */}
|
|
277
294
|
<Text color={colors.gray[500]}>{lastMessage ? createdAtText(lastMessage?.createdAt) : ''}</Text>
|
|
278
295
|
</Box>
|
|
279
296
|
</HStack>
|
|
@@ -2,51 +2,47 @@ import React, { useMemo } from 'react';
|
|
|
2
2
|
import {
|
|
3
3
|
VStack,
|
|
4
4
|
Text,
|
|
5
|
-
Image,
|
|
6
5
|
Pressable,
|
|
7
6
|
HStack,
|
|
8
7
|
Box,
|
|
9
|
-
AvatarGroup,
|
|
10
8
|
Avatar,
|
|
11
9
|
AvatarFallbackText,
|
|
12
10
|
AvatarImage,
|
|
13
|
-
AvatarBadge,
|
|
14
|
-
View,
|
|
15
11
|
Button,
|
|
16
12
|
ButtonText,
|
|
13
|
+
Icon,
|
|
14
|
+
Badge,
|
|
15
|
+
BadgeText,
|
|
16
|
+
Link,
|
|
17
|
+
LinkText,
|
|
17
18
|
} from '@admin-layout/gluestack-ui-mobile';
|
|
18
19
|
import { format, isToday, isYesterday } from 'date-fns';
|
|
19
20
|
import { useFocusEffect } from '@react-navigation/native';
|
|
20
21
|
import { IChannel, IUserAccount } from 'common';
|
|
21
|
-
import {
|
|
22
|
-
useThreadMessagesQuery,
|
|
23
|
-
useMessagesQuery,
|
|
24
|
-
useUserAccountQuery,
|
|
25
|
-
useOnThreadChatMessageAddedSubscription,
|
|
26
|
-
useOnThreadCreatedUpdatedSubscription,
|
|
27
|
-
} from 'common/graphql';
|
|
28
22
|
import { startCase } from 'lodash-es';
|
|
29
23
|
import colors from 'tailwindcss/colors';
|
|
24
|
+
import { useSelector } from 'react-redux';
|
|
25
|
+
import { userSelector } from '@adminide-stack/user-auth0-client';
|
|
30
26
|
|
|
31
|
-
const
|
|
27
|
+
const timeFormat = (value: string) => {
|
|
32
28
|
if (!value) return '';
|
|
33
29
|
let date = new Date(value);
|
|
34
|
-
if (isToday(date)) return '
|
|
35
|
-
|
|
36
|
-
return format(new Date(value), 'MMM dd, yyyy');
|
|
30
|
+
if (isToday(date)) return format(date, 'h:mm a').toUpperCase();
|
|
31
|
+
return format(date, 'MMM do').toUpperCase();
|
|
37
32
|
};
|
|
38
33
|
|
|
39
34
|
export interface IDialogListChannel extends IChannel {
|
|
40
35
|
users: IUserAccount[];
|
|
41
36
|
}
|
|
42
37
|
|
|
43
|
-
export interface
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
38
|
+
export interface ThreadViewItemProps {
|
|
39
|
+
id: string;
|
|
40
|
+
post: any;
|
|
41
|
+
channel: any;
|
|
42
|
+
replies: any[];
|
|
43
|
+
onPress: (id: any, title: any, postParentId?: any) => void;
|
|
44
|
+
channelId?: string;
|
|
45
|
+
channelsDetail?: any;
|
|
50
46
|
}
|
|
51
47
|
|
|
52
48
|
/**
|
|
@@ -54,267 +50,183 @@ export interface IDialogListItemProps {
|
|
|
54
50
|
* - Get Reservation info: reservation date, status
|
|
55
51
|
* - Add ability to get property information: name, logo
|
|
56
52
|
*/
|
|
57
|
-
export const ThreadViewItemComponent: React.FC<
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
53
|
+
export const ThreadViewItemComponent: React.FC<ThreadViewItemProps> = function ThreadViewItem({
|
|
54
|
+
id,
|
|
55
|
+
post,
|
|
56
|
+
channel,
|
|
57
|
+
replies,
|
|
58
|
+
onPress,
|
|
59
|
+
channelId,
|
|
60
|
+
channelsDetail,
|
|
64
61
|
}) {
|
|
65
|
-
|
|
66
|
-
// variables: {
|
|
67
|
-
// channelId: thread?.channel?.id?.toString(),
|
|
68
|
-
// postParentId: thread?.post?.id?.toString(),
|
|
69
|
-
// },
|
|
70
|
-
// });
|
|
71
|
-
|
|
72
|
-
useFocusEffect(
|
|
73
|
-
React.useCallback(() => {
|
|
74
|
-
// Do something when the screen is focused
|
|
75
|
-
return () => {
|
|
76
|
-
// Do something when the screen is unfocused
|
|
77
|
-
// Useful for cleanup functions
|
|
78
|
-
};
|
|
79
|
-
}, []),
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
const threadPostReply = React.useMemo(() => {
|
|
83
|
-
if (!thread?.replies) return null;
|
|
84
|
-
return thread?.replies;
|
|
85
|
-
}, [thread]);
|
|
62
|
+
const currentUser = useSelector(userSelector);
|
|
86
63
|
|
|
87
|
-
//
|
|
88
|
-
|
|
89
|
-
|
|
64
|
+
// Prepare thread replies for display
|
|
65
|
+
const threadReplies = useMemo(() => {
|
|
66
|
+
return replies || [];
|
|
67
|
+
}, [replies]);
|
|
90
68
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
// return threadCreatedUpdated?.threadCreatedUpdated?.data?.replies;
|
|
95
|
-
// } else return thread?.replies;
|
|
96
|
-
// }, [thread, threadCreatedUpdated]);
|
|
97
|
-
|
|
98
|
-
// const lastMessage = useMemo(() => {
|
|
99
|
-
// if (!threadPost) {
|
|
100
|
-
// return null;
|
|
101
|
-
// }
|
|
102
|
-
// const replies = threadPost?.replies?.filter((p: any) => p?.message !== '') ?? [];
|
|
103
|
-
// if (replies?.length) {
|
|
104
|
-
// return replies[0];
|
|
105
|
-
// // return replies[replies.length - 1];
|
|
106
|
-
// } else {
|
|
107
|
-
// const post = threadPost?.post ?? null;
|
|
108
|
-
// return post ? post?.post : null;
|
|
109
|
-
// }
|
|
110
|
-
// }, [threadPost]);
|
|
69
|
+
if (!threadReplies || threadReplies.length === 0) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
111
72
|
|
|
112
|
-
//
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
|
|
73
|
+
// Get the last reply for the thread preview
|
|
74
|
+
const lastReply = threadReplies[0]; // Most recent reply should be first in the array
|
|
75
|
+
// Get total number of replies
|
|
76
|
+
const totalReplies = threadReplies.length;
|
|
116
77
|
|
|
117
|
-
//
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
// participants
|
|
121
|
-
// ?.map((p: any) => {
|
|
122
|
-
// return p?.user?.givenName + ' ' + p?.user?.familyName ?? '';
|
|
123
|
-
// })
|
|
124
|
-
// ?.join(', ') ?? ''
|
|
125
|
-
// );
|
|
126
|
-
// }, [participants]);
|
|
78
|
+
// Get the first user in the thread as the primary user
|
|
79
|
+
const primaryUser = channel?.users?.[0] || lastReply?.author;
|
|
80
|
+
const channelName = channel?.title || `${primaryUser?.givenName || ''} ${primaryUser?.familyName || ''}`;
|
|
127
81
|
|
|
128
|
-
if
|
|
129
|
-
|
|
130
|
-
}
|
|
82
|
+
// Determine if the current user is in the thread
|
|
83
|
+
const userIsInThread = channel?.users?.some((user: any) => user.id === currentUser?.id);
|
|
131
84
|
|
|
132
85
|
return (
|
|
133
|
-
<
|
|
134
|
-
|
|
135
|
-
|
|
86
|
+
<Pressable
|
|
87
|
+
onPress={() => onPress(channel?.id, 'Thread', post?.id)}
|
|
88
|
+
style={{
|
|
89
|
+
marginVertical: 5,
|
|
90
|
+
backgroundColor: 'white',
|
|
91
|
+
borderRadius: 10,
|
|
92
|
+
paddingVertical: 5,
|
|
93
|
+
elevation: 1,
|
|
94
|
+
shadowColor: '#000',
|
|
95
|
+
shadowOffset: { width: 0, height: 1 },
|
|
96
|
+
shadowOpacity: 0.1,
|
|
97
|
+
shadowRadius: 2,
|
|
98
|
+
}}
|
|
136
99
|
>
|
|
137
|
-
<
|
|
138
|
-
<
|
|
139
|
-
{/*
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
</Text>
|
|
147
|
-
</Box>
|
|
100
|
+
<Box className="mb-3">
|
|
101
|
+
<VStack space="md">
|
|
102
|
+
{/* Thread header with green dot and users */}
|
|
103
|
+
{/* <HStack space="sm" className="px-4 items-center">
|
|
104
|
+
<Box
|
|
105
|
+
className="bg-green-500 rounded-full"
|
|
106
|
+
style={{ width: 8, height: 8 }}
|
|
107
|
+
/>
|
|
108
|
+
<Text className="text-base text-gray-900">{channelName}</Text>
|
|
148
109
|
</HStack> */}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
110
|
+
|
|
111
|
+
{/* Thread members */}
|
|
112
|
+
<Text className="text-sm font-medium text-gray-600 px-4 pt-2">
|
|
113
|
+
{channel?.users?.map((user: any) => user?.givenName || user?.username)?.join(', ')}
|
|
114
|
+
</Text>
|
|
115
|
+
|
|
116
|
+
{/* Thread messages preview - show up to 3 most recent messages */}
|
|
117
|
+
{threadReplies.slice(0, 3).map((reply: any, index: number) => {
|
|
118
|
+
// Group consecutive messages from the same user
|
|
119
|
+
const previousReply = index > 0 ? threadReplies.slice(0, 3)[index - 1] : null;
|
|
120
|
+
const isConsecutiveReply = previousReply && previousReply.author?.id === reply.author?.id;
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<HStack key={reply.id || index} space="md" className="px-4 py-1">
|
|
124
|
+
{!isConsecutiveReply ? (
|
|
153
125
|
<Avatar
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
126
|
+
size="md"
|
|
127
|
+
style={{
|
|
128
|
+
width: 40,
|
|
129
|
+
height: 40,
|
|
130
|
+
backgroundColor:
|
|
131
|
+
reply?.author?.id === currentUser?.id ? '#2EB67D' : '#E8A54A',
|
|
159
132
|
}}
|
|
160
133
|
>
|
|
161
|
-
|
|
134
|
+
<AvatarFallbackText>
|
|
135
|
+
{startCase(reply?.author?.username?.charAt(0) || 'U')}
|
|
136
|
+
</AvatarFallbackText>
|
|
137
|
+
{reply?.author?.picture && (
|
|
138
|
+
<AvatarImage
|
|
139
|
+
alt={reply?.author?.username || 'User'}
|
|
140
|
+
source={{
|
|
141
|
+
uri: reply?.author?.picture,
|
|
142
|
+
}}
|
|
143
|
+
/>
|
|
144
|
+
)}
|
|
162
145
|
</Avatar>
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
{!thread?.replies?.length && (
|
|
178
|
-
<Button
|
|
179
|
-
size={'xs'}
|
|
180
|
-
w={150}
|
|
181
|
-
variant={'outline'}
|
|
182
|
-
_text={{ fontSize: 12, color: '#000' }}
|
|
183
|
-
onPress={() =>
|
|
184
|
-
onOpen(thread?.channel?.id, thread?.channel?.title, thread?.post?.id)
|
|
185
|
-
}
|
|
186
|
-
>
|
|
187
|
-
Reply
|
|
188
|
-
</Button>
|
|
146
|
+
) : (
|
|
147
|
+
<Box style={{ width: 40 }} />
|
|
148
|
+
)}
|
|
149
|
+
|
|
150
|
+
<VStack space="xs" className="flex-1">
|
|
151
|
+
{!isConsecutiveReply && (
|
|
152
|
+
<HStack space="sm" className="items-center">
|
|
153
|
+
<Text className="font-bold text-gray-900">
|
|
154
|
+
{reply?.author?.givenName || reply?.author?.username || 'User'}
|
|
155
|
+
</Text>
|
|
156
|
+
<Text className="text-xs text-gray-500">
|
|
157
|
+
{timeFormat(reply?.createdAt)}
|
|
158
|
+
</Text>
|
|
159
|
+
</HStack>
|
|
189
160
|
)}
|
|
190
|
-
</Box>
|
|
191
|
-
</HStack> */}
|
|
192
|
-
{threadPostReply?.length > 0 && (
|
|
193
|
-
<>
|
|
194
|
-
{threadPostReply
|
|
195
|
-
?.slice(0, 2)
|
|
196
|
-
?.reverse()
|
|
197
|
-
?.map((reply: any, index: any) => (
|
|
198
|
-
<HStack key={index} space={'sm'} className="pb-2 pt-1">
|
|
199
|
-
<Box>
|
|
200
|
-
<Avatar
|
|
201
|
-
key={'thread-view-key-' + index}
|
|
202
|
-
size={'md'}
|
|
203
|
-
className="bg-transparent top-0 right-0 z-[1]"
|
|
204
|
-
>
|
|
205
|
-
<AvatarFallbackText>
|
|
206
|
-
{' '}
|
|
207
|
-
{startCase(reply?.author?.username?.charAt(0))}
|
|
208
|
-
</AvatarFallbackText>
|
|
209
|
-
<AvatarImage
|
|
210
|
-
alt="image"
|
|
211
|
-
style={{
|
|
212
|
-
borderRadius: 6,
|
|
213
|
-
borderWidth: 2,
|
|
214
|
-
borderColor: '#fff',
|
|
215
|
-
}}
|
|
216
|
-
source={{
|
|
217
|
-
uri: reply?.author?.picture,
|
|
218
|
-
}}
|
|
219
|
-
/>
|
|
220
|
-
</Avatar>
|
|
221
|
-
</Box>
|
|
222
|
-
<Box>
|
|
223
|
-
<HStack space={'md'}>
|
|
224
|
-
<Text>
|
|
225
|
-
{reply?.author?.givenName ?? '' ?? ''}{' '}
|
|
226
|
-
{reply?.author?.familyName ?? '' ?? ''}
|
|
227
|
-
{/* {lastMessage?.author?.givenName +
|
|
228
|
-
' ' +
|
|
229
|
-
lastMessage?.author?.familyName ?? ''} */}
|
|
230
|
-
</Text>
|
|
231
|
-
<Text color={colors.gray[500]}>
|
|
232
|
-
{reply?.createdAt ? createdAtText(reply?.createdAt) : ''}
|
|
233
|
-
{/* {lastMessage ? createdAtText(lastMessage?.createdAt) : ''} */}
|
|
234
|
-
</Text>
|
|
235
|
-
</HStack>
|
|
236
|
-
<VStack space={'sm'}>
|
|
237
|
-
{reply?.message && (
|
|
238
|
-
<Text color={colors.gray[600]} numberOfLines={2}>
|
|
239
|
-
{reply?.message.length < 70
|
|
240
|
-
? `${reply?.message}`
|
|
241
|
-
: `${reply?.message.substring(0, 68)}....`}
|
|
242
|
-
</Text>
|
|
243
|
-
)}
|
|
244
|
-
{/* <Text color="gray.600" noOfLines={2}>
|
|
245
|
-
{reply?.message
|
|
246
|
-
? reply?.message.length < 70
|
|
247
|
-
? `${reply?.message}`
|
|
248
|
-
: `${reply?.message.substring(0, 68)}....`
|
|
249
|
-
: ''}
|
|
250
|
-
</Text> */}
|
|
251
161
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
className="bg-transparent"
|
|
259
|
-
size={'md'}
|
|
260
|
-
>
|
|
261
|
-
<AvatarFallbackText> I</AvatarFallbackText>
|
|
262
|
-
<AvatarImage
|
|
263
|
-
alt="image"
|
|
264
|
-
style={{
|
|
265
|
-
borderRadius: 6,
|
|
266
|
-
borderWidth: 2,
|
|
267
|
-
borderColor: '#fff',
|
|
268
|
-
}}
|
|
269
|
-
source={{
|
|
270
|
-
uri: f?.url,
|
|
271
|
-
}}
|
|
272
|
-
/>
|
|
273
|
-
</Avatar>
|
|
274
|
-
</Box>
|
|
275
|
-
))}
|
|
276
|
-
</>
|
|
277
|
-
</VStack>
|
|
162
|
+
{reply?.message && (
|
|
163
|
+
<Text color={colors.gray[700]} numberOfLines={2} className="text-base">
|
|
164
|
+
{reply?.message}
|
|
165
|
+
{reply?.edited && <Text className="text-xs text-gray-500"> (edited)</Text>}
|
|
166
|
+
</Text>
|
|
167
|
+
)}
|
|
278
168
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
169
|
+
{reply.email && <Text className="text-blue-500">{reply.email}</Text>}
|
|
170
|
+
|
|
171
|
+
{reply?.files?.data?.length > 0 && (
|
|
172
|
+
<HStack space="sm" className="my-1">
|
|
173
|
+
{reply?.files?.data?.map((file: any, fileIndex: number) => (
|
|
174
|
+
<Box
|
|
175
|
+
key={fileIndex}
|
|
176
|
+
className="overflow-hidden"
|
|
177
|
+
style={{ width: 80, height: 80 }}
|
|
178
|
+
>
|
|
179
|
+
<AvatarImage
|
|
180
|
+
alt="attachment"
|
|
181
|
+
className="rounded-none border-none"
|
|
182
|
+
style={{
|
|
183
|
+
width: '100%',
|
|
184
|
+
height: '100%',
|
|
185
|
+
}}
|
|
186
|
+
source={{
|
|
187
|
+
uri: file?.url,
|
|
188
|
+
}}
|
|
189
|
+
/>
|
|
297
190
|
</Box>
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
191
|
+
))}
|
|
192
|
+
</HStack>
|
|
193
|
+
)}
|
|
194
|
+
</VStack>
|
|
195
|
+
</HStack>
|
|
196
|
+
);
|
|
197
|
+
})}
|
|
198
|
+
|
|
199
|
+
{/* Show more replies indicator */}
|
|
200
|
+
{totalReplies > 3 && (
|
|
201
|
+
<HStack className="px-4 items-center" space="sm">
|
|
202
|
+
<Box style={{ width: 40 }} />
|
|
203
|
+
<Link onPress={() => onPress(channel?.id, 'Thread', post?.id)}>
|
|
204
|
+
<LinkText className="text-blue-600 mt-1">
|
|
205
|
+
{totalReplies - 3} more {totalReplies - 3 === 1 ? 'reply' : 'replies'}
|
|
206
|
+
</LinkText>
|
|
207
|
+
</Link>
|
|
208
|
+
</HStack>
|
|
209
|
+
)}
|
|
210
|
+
|
|
211
|
+
{/* Reply button */}
|
|
212
|
+
<Box className="px-4 pb-2">
|
|
213
|
+
<Button
|
|
214
|
+
size="sm"
|
|
215
|
+
className="self-start rounded-full"
|
|
216
|
+
variant="outline"
|
|
217
|
+
style={{
|
|
218
|
+
borderColor: '#E2E8F0',
|
|
219
|
+
paddingHorizontal: 16,
|
|
220
|
+
paddingVertical: 6,
|
|
221
|
+
}}
|
|
222
|
+
onPress={() => onPress(channel?.id, 'Thread', post?.id)}
|
|
223
|
+
>
|
|
224
|
+
<ButtonText style={{ fontSize: 14, color: colors.gray[800] }}>Reply</ButtonText>
|
|
225
|
+
</Button>
|
|
226
|
+
</Box>
|
|
227
|
+
</VStack>
|
|
228
|
+
</Box>
|
|
229
|
+
</Pressable>
|
|
318
230
|
);
|
|
319
231
|
};
|
|
320
232
|
|