@messenger-box/platform-mobile 10.0.3-alpha.23 → 10.0.3-alpha.232

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.
Files changed (116) hide show
  1. package/lib/components/messages-container-ui/BuildModeView.js +428 -0
  2. package/lib/components/messages-container-ui/BuildModeView.js.map +1 -0
  3. package/lib/components/messages-container-ui/MessagesContainerUI.js +55 -0
  4. package/lib/components/messages-container-ui/MessagesContainerUI.js.map +1 -0
  5. package/lib/components/messages-container-ui/PlanModeView.js +336 -0
  6. package/lib/components/messages-container-ui/PlanModeView.js.map +1 -0
  7. package/lib/compute.js +2 -3
  8. package/lib/compute.js.map +1 -1
  9. package/lib/index.js +1 -1
  10. package/lib/index.js.map +1 -1
  11. package/lib/module.js.map +1 -1
  12. package/lib/queries/inboxQueries.js +62 -0
  13. package/lib/queries/inboxQueries.js.map +1 -0
  14. package/lib/routes.json +2 -3
  15. package/lib/screens/inbox/DialogMessages.js +8 -3
  16. package/lib/screens/inbox/DialogMessages.js.map +1 -1
  17. package/lib/screens/inbox/DialogThreadMessages.js +6 -11
  18. package/lib/screens/inbox/DialogThreadMessages.js.map +1 -1
  19. package/lib/screens/inbox/DialogThreads.js +9 -11
  20. package/lib/screens/inbox/DialogThreads.js.map +1 -1
  21. package/lib/screens/inbox/Inbox.js.map +1 -1
  22. package/lib/screens/inbox/components/CachedImage/consts.js +1 -1
  23. package/lib/screens/inbox/components/CachedImage/consts.js.map +1 -1
  24. package/lib/screens/inbox/components/CachedImage/index.js +125 -96
  25. package/lib/screens/inbox/components/CachedImage/index.js.map +1 -1
  26. package/lib/screens/inbox/components/DialogItem.js +160 -0
  27. package/lib/screens/inbox/components/DialogItem.js.map +1 -0
  28. package/lib/screens/inbox/components/GiftedChatInboxComponent.js +315 -0
  29. package/lib/screens/inbox/components/GiftedChatInboxComponent.js.map +1 -0
  30. package/lib/screens/inbox/components/SlackMessageContainer/ImageViewerModal.js +3 -1
  31. package/lib/screens/inbox/components/SlackMessageContainer/ImageViewerModal.js.map +1 -1
  32. package/lib/screens/inbox/components/SlackMessageContainer/PaymentMessage.js +194 -0
  33. package/lib/screens/inbox/components/SlackMessageContainer/PaymentMessage.js.map +1 -0
  34. package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js +149 -36
  35. package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js.map +1 -1
  36. package/lib/screens/inbox/components/SlackMessageContainer/SlackMessage.js +4 -5
  37. package/lib/screens/inbox/components/SlackMessageContainer/SlackMessage.js.map +1 -1
  38. package/lib/screens/inbox/components/SubscriptionHandler.js +22 -0
  39. package/lib/screens/inbox/components/SubscriptionHandler.js.map +1 -0
  40. package/lib/screens/inbox/components/ThreadsViewItem.js +2 -4
  41. package/lib/screens/inbox/components/ThreadsViewItem.js.map +1 -1
  42. package/lib/screens/inbox/config/config.js +4 -2
  43. package/lib/screens/inbox/config/config.js.map +1 -1
  44. package/lib/screens/inbox/containers/ConversationView.js +1093 -1090
  45. package/lib/screens/inbox/containers/ConversationView.js.map +1 -1
  46. package/lib/screens/inbox/containers/Dialogs.js +130 -577
  47. package/lib/screens/inbox/containers/Dialogs.js.map +1 -1
  48. package/lib/screens/inbox/containers/ThreadConversationView.js +864 -1408
  49. package/lib/screens/inbox/containers/ThreadConversationView.js.map +1 -1
  50. package/lib/screens/inbox/containers/ThreadsView.js +9 -15
  51. package/lib/screens/inbox/containers/ThreadsView.js.map +1 -1
  52. package/lib/screens/inbox/hooks/useInboxMessages.js +31 -0
  53. package/lib/screens/inbox/hooks/useInboxMessages.js.map +1 -0
  54. package/lib/screens/inbox/hooks/useSafeDialogThreadsMachine.js +1 -1
  55. package/lib/screens/inbox/hooks/useSafeDialogThreadsMachine.js.map +1 -1
  56. package/lib/screens/inbox/workflow/dialog-threads-xstate.js.map +1 -1
  57. package/package.json +10 -8
  58. package/CHANGELOG.md +0 -172
  59. package/jest.config.js +0 -24
  60. package/lib/screens/inbox/components/DialogsListItem.js +0 -548
  61. package/lib/screens/inbox/components/DialogsListItem.js.map +0 -1
  62. package/lib/screens/inbox/components/ServiceDialogsListItem.js +0 -489
  63. package/lib/screens/inbox/components/ServiceDialogsListItem.js.map +0 -1
  64. package/lib/screens/inbox/components/workflow/dialogs-list-item-xstate.js +0 -175
  65. package/lib/screens/inbox/components/workflow/dialogs-list-item-xstate.js.map +0 -1
  66. package/lib/screens/inbox/components/workflow/service-dialogs-list-item-xstate.js +0 -191
  67. package/lib/screens/inbox/components/workflow/service-dialogs-list-item-xstate.js.map +0 -1
  68. package/lib/screens/inbox/containers/workflow/conversation-xstate.js +0 -380
  69. package/lib/screens/inbox/containers/workflow/conversation-xstate.js.map +0 -1
  70. package/lib/screens/inbox/containers/workflow/dialogs-xstate.js +0 -211
  71. package/lib/screens/inbox/containers/workflow/dialogs-xstate.js.map +0 -1
  72. package/lib/screens/inbox/containers/workflow/thread-conversation-xstate.js +0 -438
  73. package/lib/screens/inbox/containers/workflow/thread-conversation-xstate.js.map +0 -1
  74. package/rollup.config.mjs +0 -45
  75. package/src/components/index.ts +0 -0
  76. package/src/compute.ts +0 -63
  77. package/src/index.ts +0 -7
  78. package/src/module.ts +0 -10
  79. package/src/navigation/InboxNavigation.tsx +0 -102
  80. package/src/navigation/index.ts +0 -1
  81. package/src/screens/inbox/DialogMessages.tsx +0 -21
  82. package/src/screens/inbox/DialogThreadMessages.tsx +0 -97
  83. package/src/screens/inbox/DialogThreads.tsx +0 -125
  84. package/src/screens/inbox/Inbox.tsx +0 -17
  85. package/src/screens/inbox/components/CachedImage/consts.ts +0 -6
  86. package/src/screens/inbox/components/CachedImage/index.tsx +0 -223
  87. package/src/screens/inbox/components/DialogsHeader.tsx +0 -30
  88. package/src/screens/inbox/components/DialogsListItem.tsx +0 -819
  89. package/src/screens/inbox/components/ServiceDialogsListItem.tsx +0 -679
  90. package/src/screens/inbox/components/SlackMessageContainer/ImageViewerModal.tsx +0 -113
  91. package/src/screens/inbox/components/SlackMessageContainer/SlackBubble.tsx +0 -313
  92. package/src/screens/inbox/components/SlackMessageContainer/SlackMessage.tsx +0 -145
  93. package/src/screens/inbox/components/SlackMessageContainer/index.ts +0 -3
  94. package/src/screens/inbox/components/SmartLoader.tsx +0 -61
  95. package/src/screens/inbox/components/SupportServiceDialogsListItem.tsx +0 -301
  96. package/src/screens/inbox/components/ThreadsViewItem.tsx +0 -233
  97. package/src/screens/inbox/components/workflow/dialogs-list-item-xstate.ts +0 -145
  98. package/src/screens/inbox/components/workflow/service-dialogs-list-item-xstate.ts +0 -159
  99. package/src/screens/inbox/config/config.ts +0 -15
  100. package/src/screens/inbox/config/index.ts +0 -1
  101. package/src/screens/inbox/containers/ConversationView.tsx +0 -1784
  102. package/src/screens/inbox/containers/Dialogs.tsx +0 -829
  103. package/src/screens/inbox/containers/SupportServiceDialogs.tsx +0 -119
  104. package/src/screens/inbox/containers/ThreadConversationView.tsx +0 -2295
  105. package/src/screens/inbox/containers/ThreadsView.tsx +0 -224
  106. package/src/screens/inbox/containers/workflow/apollo/handleResult.ts +0 -20
  107. package/src/screens/inbox/containers/workflow/conversation-xstate.ts +0 -313
  108. package/src/screens/inbox/containers/workflow/dialogs-xstate.ts +0 -196
  109. package/src/screens/inbox/containers/workflow/thread-conversation-xstate.ts +0 -401
  110. package/src/screens/inbox/hooks/useSafeDialogThreadsMachine.ts +0 -136
  111. package/src/screens/inbox/index.ts +0 -37
  112. package/src/screens/inbox/machines/threadsMachine.ts +0 -147
  113. package/src/screens/inbox/workflow/dialog-threads-xstate.ts +0 -163
  114. package/src/screens/index.ts +0 -4
  115. package/tsconfig.json +0 -13
  116. package/webpack.config.js +0 -58
@@ -1,4 +1,4 @@
1
- import React__default,{useState,useRef,useCallback,useEffect,useMemo}from'react';import {Button,Box,Image,Text,ButtonText,Spinner,HStack,VStack,Avatar,AvatarFallbackText,AvatarImage,Center}from'@admin-layout/gluestack-ui-mobile';import {Platform,View,TouchableHighlight,SafeAreaView,Alert,Linking}from'react-native';import {useRoute,useNavigation,useFocusEffect}from'@react-navigation/native';import {useSelector}from'react-redux';import {orderBy,startCase,uniqBy}from'lodash-es';import*as ImagePicker from'expo-image-picker';import {MaterialIcons,MaterialCommunityIcons,Ionicons}from'@expo/vector-icons';import {Send,Actions as Actions$1,InputToolbar,MessageText,GiftedChat}from'react-native-gifted-chat';import {PreDefinedRole}from'common';import {useCreatePostThreadMutation,useSendExpoNotificationOnPostMutation,useGetPostThreadLazyQuery,OnThreadChatMessageAddedDocument}from'common/graphql';import {useUploadFilesNative}from'@messenger-box/platform-client';import {objectId}from'@messenger-box/core';import {format,isToday,isYesterday}from'date-fns';import {userSelector}from'@adminide-stack/user-auth0-client';import {config}from'../config/config.js';import Message from'../components/SlackMessageContainer/SlackMessage.js';import ImageViewerModal from'../components/SlackMessageContainer/ImageViewerModal.js';import CachedImage from'../components/CachedImage/index.js';import colors from'tailwindcss/colors';import {Actions,BaseState,MainState}from'./workflow/thread-conversation-xstate.js';var __defProp = Object.defineProperty;
1
+ import React__default,{useState,useRef,useEffect,useCallback,useMemo}from'react';import {useToast,Button,Spinner,Box,ButtonText,HStack,Avatar,AvatarFallbackText,AvatarImage,Text,Image,VStack,Skeleton}from'@admin-layout/gluestack-ui-mobile';import {Platform,Keyboard,View,TouchableHighlight,ScrollView,TouchableOpacity,RefreshControl,Animated}from'react-native';import {useRoute,useNavigation,useFocusEffect}from'@react-navigation/native';import {useSelector}from'react-redux';import {uniqBy,orderBy,startCase}from'lodash-es';import*as ImagePicker from'expo-image-picker';import'base-64';import {MaterialIcons,MaterialCommunityIcons,Ionicons}from'@expo/vector-icons';import {Send,MessageText,Actions,InputToolbar}from'react-native-gifted-chat';import {FileRefType,PreDefinedRole}from'common';import {useCreatePostThread,useSendExpoNotification,useGetPostThreadLazy,CHAT_MESSAGE_ADDED}from'../../../queries/inboxQueries.js';import {useUploadFilesNative}from'@messenger-box/platform-client';import {objectId}from'@messenger-box/core';import {format,isToday,isYesterday}from'date-fns';import {userSelector}from'@adminide-stack/user-auth0-client';import {config}from'../config/config.js';import Message from'../components/SlackMessageContainer/SlackMessage.js';import ImageViewerModal from'../components/SlackMessageContainer/ImageViewerModal.js';import CachedImage from'../components/CachedImage/index.js';import colors from'tailwindcss/colors';import {GiftedChatInboxComponent}from'../components/GiftedChatInboxComponent.js';var __defProp = Object.defineProperty;
2
2
  var __defProps = Object.defineProperties;
3
3
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
4
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
@@ -25,847 +25,504 @@ const {
25
25
  CALL_TO_ACTION_TEXT_COLOR
26
26
  } = config;
27
27
  const createdAtText = (value) => {
28
- if (!value)
29
- return "";
30
- try {
31
- const timestamp = new Date(value).getTime();
32
- if (isNaN(timestamp)) {
33
- console.warn(`Invalid date value in createdAtText: ${value}`);
34
- return "Unknown date";
35
- }
36
- let date = new Date(value);
37
- if (isToday(date))
38
- return "Today";
39
- if (isYesterday(date))
40
- return "Yesterday";
41
- return format(date, "MMM dd, yyyy");
42
- } catch (error) {
43
- console.error(`Error processing date in createdAtText: ${value}`, error);
44
- return "Unknown date";
45
- }
28
+ if (!value) return "";
29
+ let date = new Date(value);
30
+ if (isToday(date)) return "Today";
31
+ if (isYesterday(date)) return "Yesterday";
32
+ return format(new Date(value), "MMM dd, yyyy");
46
33
  };
47
- function useSafeMachine(machine) {
48
- const [state, setState] = useState({
49
- context: {
50
- channelId: null,
51
- postParentId: null,
52
- role: null,
53
- threadMessages: [],
54
- totalCount: 0,
55
- skip: 0,
56
- loading: false,
57
- loadingOldMessages: false,
58
- error: null,
59
- selectedImage: "",
60
- files: [],
61
- images: [],
62
- messageText: "",
63
- imageLoading: false,
64
- postThread: null,
65
- threadPost: [],
66
- isScrollToBottom: false
67
- },
68
- value: "idle"
69
- });
70
- const send = useCallback((event) => {
71
- var _a, _b, _c, _d;
72
- try {
73
- console.log("Thread Event received:", event.type);
74
- if (event.type === Actions.INITIAL_CONTEXT) {
75
- setState((prev) => {
76
- var _a2, _b2, _c2;
77
- return __spreadProps(__spreadValues({}, prev), {
78
- context: __spreadProps(__spreadValues({}, prev.context), {
79
- channelId: ((_a2 = event.data) == null ? void 0 : _a2.channelId) || null,
80
- postParentId: ((_b2 = event.data) == null ? void 0 : _b2.postParentId) || null,
81
- role: ((_c2 = event.data) == null ? void 0 : _c2.role) || null
82
- }),
83
- value: BaseState.FetchThreadMessages
84
- });
85
- });
86
- } else if (event.type === Actions.SET_THREAD_MESSAGES) {
87
- setState((prev) => {
88
- var _a2, _b2, _c2, _d2;
89
- return __spreadProps(__spreadValues({}, prev), {
90
- context: __spreadProps(__spreadValues({}, prev.context), {
91
- threadMessages: ((_a2 = event.data) == null ? void 0 : _a2.messages) || [],
92
- totalCount: ((_b2 = event.data) == null ? void 0 : _b2.totalCount) || 0,
93
- loading: false,
94
- loadingOldMessages: false,
95
- threadPost: ((_c2 = event.data) == null ? void 0 : _c2.threadPost) || [],
96
- postThread: ((_d2 = event.data) == null ? void 0 : _d2.postThread) || null
97
- }),
98
- value: "active"
99
- });
100
- });
101
- } else if (event.type === Actions.CLEAR_MESSAGES) {
102
- setState((prev) => __spreadProps(__spreadValues({}, prev), {
103
- context: __spreadProps(__spreadValues({}, prev.context), {
104
- threadMessages: [],
105
- totalCount: 0
106
- })
107
- }));
108
- } else if (event.type === Actions.SET_MESSAGE_TEXT) {
109
- setState((prev) => {
110
- var _a2;
111
- return __spreadProps(__spreadValues({}, prev), {
112
- context: __spreadProps(__spreadValues({}, prev.context), {
113
- messageText: ((_a2 = event.data) == null ? void 0 : _a2.messageText) || ""
114
- })
115
- });
116
- });
117
- } else if (event.type === Actions.FETCH_MORE_MESSAGES) {
118
- setState((prev) => __spreadProps(__spreadValues({}, prev), {
119
- context: __spreadProps(__spreadValues({}, prev.context), {
120
- loadingOldMessages: true
121
- }),
122
- value: MainState.FetchMoreMessages
123
- }));
124
- } else if (event.type === Actions.SET_IMAGE) {
125
- setState((prev) => {
126
- var _a2, _b2, _c2;
127
- return __spreadProps(__spreadValues({}, prev), {
128
- context: __spreadProps(__spreadValues({}, prev.context), {
129
- selectedImage: ((_a2 = event.data) == null ? void 0 : _a2.image) || "",
130
- images: ((_b2 = event.data) == null ? void 0 : _b2.images) || [],
131
- files: ((_c2 = event.data) == null ? void 0 : _c2.files) || [],
132
- imageLoading: false
133
- })
134
- });
135
- });
136
- } else if (event.type === Actions.CLEAR_IMAGE) {
137
- setState((prev) => __spreadProps(__spreadValues({}, prev), {
138
- context: __spreadProps(__spreadValues({}, prev.context), {
139
- selectedImage: "",
140
- images: [],
141
- files: []
142
- })
143
- }));
144
- } else if (event.type === Actions.START_LOADING) {
145
- setState((prev) => __spreadProps(__spreadValues({}, prev), {
146
- context: __spreadProps(__spreadValues({}, prev.context), {
147
- loading: true
148
- })
149
- }));
150
- } else if (event.type === Actions.STOP_LOADING) {
151
- setState((prev) => {
152
- var _a2;
153
- return __spreadProps(__spreadValues({}, prev), {
154
- context: __spreadProps(__spreadValues({}, prev.context), {
155
- loading: false,
156
- loadingOldMessages: ((_a2 = event.data) == null ? void 0 : _a2.loadingOldMessages) === false ? false : prev.context.loadingOldMessages
157
- })
158
- });
159
- });
160
- } else if (event.type === Actions.SEND_THREAD_MESSAGE) {
161
- console.log("Sending message event with text:", (_a = event.data) == null ? void 0 : _a.messageText);
162
- setState((prev) => {
163
- var _a2;
164
- return __spreadProps(__spreadValues({}, prev), {
165
- context: __spreadProps(__spreadValues({}, prev.context), {
166
- loading: true,
167
- messageText: ((_a2 = event.data) == null ? void 0 : _a2.messageText) || prev.context.messageText
168
- }),
169
- value: MainState.SendThreadMessage
170
- });
171
- });
172
- } else if (event.type === Actions.SEND_THREAD_MESSAGE_WITH_FILE) {
173
- console.log("Sending message with file event, text:", (_b = event.data) == null ? void 0 : _b.messageText);
174
- setState((prev) => {
175
- var _a2;
176
- return __spreadProps(__spreadValues({}, prev), {
177
- context: __spreadProps(__spreadValues({}, prev.context), {
178
- loading: true,
179
- messageText: ((_a2 = event.data) == null ? void 0 : _a2.messageText) || prev.context.messageText
180
- }),
181
- value: MainState.SendThreadMessageWithFile
182
- });
183
- });
184
- } else if (event.type === "SEND_THREAD_MESSAGE_SUCCESS" || event.type === "SEND_THREAD_MESSAGE_WITH_FILE_SUCCESS") {
185
- console.log("Handling send success event:", event.type, "with message:", (_d = (_c = event.data) == null ? void 0 : _c.message) == null ? void 0 : _d.id);
186
- setState((prev) => {
187
- var _a2;
188
- if (!((_a2 = event.data) == null ? void 0 : _a2.message)) {
189
- console.warn("Send success event without message data");
190
- return __spreadProps(__spreadValues({}, prev), {
191
- context: __spreadProps(__spreadValues({}, prev.context), {
192
- loading: false,
193
- messageText: "",
194
- images: [],
195
- selectedImage: "",
196
- files: []
197
- }),
198
- value: "active"
199
- });
200
- }
201
- const newMessage = event.data.message;
202
- const updatedMessages = [newMessage, ...prev.context.threadMessages];
203
- console.log("Updated thread messages list after send, now has", updatedMessages.length, "messages");
204
- return __spreadProps(__spreadValues({}, prev), {
205
- context: __spreadProps(__spreadValues({}, prev.context), {
206
- loading: false,
207
- messageText: "",
208
- images: [],
209
- selectedImage: "",
210
- files: [],
211
- threadMessages: updatedMessages,
212
- totalCount: prev.context.totalCount + 1
213
- }),
214
- value: "active"
215
- });
216
- });
217
- } else if (event.type === "FETCH_MORE_MESSAGES_SUCCESS") {
218
- setState((prev) => {
219
- var _a2, _b2;
220
- const newMessages = ((_a2 = event.data) == null ? void 0 : _a2.messages) || [];
221
- const apiTotalCount = (_b2 = event.data) == null ? void 0 : _b2.totalCount;
222
- console.log(`Merging ${newMessages.length} older messages with ${prev.context.threadMessages.length} existing messages`);
223
- if (newMessages.length > 0) {
224
- try {
225
- console.log("First new message date:", !isNaN(new Date(newMessages[0].createdAt).getTime()) ? new Date(newMessages[0].createdAt).toISOString() : "Invalid date");
226
- console.log("Last new message date:", !isNaN(new Date(newMessages[newMessages.length - 1].createdAt).getTime()) ? new Date(newMessages[newMessages.length - 1].createdAt).toISOString() : "Invalid date");
227
- } catch (error) {
228
- console.error("Error logging new message dates:", error);
229
- }
230
- }
231
- if (prev.context.threadMessages.length > 0) {
232
- try {
233
- console.log("First existing message date:", !isNaN(new Date(prev.context.threadMessages[0].createdAt).getTime()) ? new Date(prev.context.threadMessages[0].createdAt).toISOString() : "Invalid date");
234
- console.log("Last existing message date:", !isNaN(new Date(prev.context.threadMessages[prev.context.threadMessages.length - 1].createdAt).getTime()) ? new Date(prev.context.threadMessages[prev.context.threadMessages.length - 1].createdAt).toISOString() : "Invalid date");
235
- } catch (error) {
236
- console.error("Error logging existing message dates:", error);
237
- }
238
- }
239
- if (newMessages.length === 0 && prev.context.totalCount > prev.context.threadMessages.length) {
240
- console.log("No new messages found despite totalCount indicating more should exist");
241
- return __spreadProps(__spreadValues({}, prev), {
242
- context: __spreadProps(__spreadValues({}, prev.context), {
243
- loadingOldMessages: false,
244
- totalCount: prev.context.threadMessages.length
245
- }),
246
- value: "active"
247
- });
248
- }
249
- const combinedMessages = uniqBy([...prev.context.threadMessages, ...newMessages], "id");
250
- const sortedMessages = orderBy(combinedMessages, [(msg) => {
251
- try {
252
- return !isNaN(new Date(msg.createdAt).getTime()) ? new Date(msg.createdAt).getTime() : 0;
253
- } catch (error) {
254
- console.error(`Error sorting message by date: ${msg.id}`, error);
255
- return 0;
256
- }
257
- }], ["desc"]);
258
- const newTotalCount = typeof apiTotalCount === "number" ? apiTotalCount : Math.max(sortedMessages.length, prev.context.totalCount);
259
- console.log(`Total messages after merge and sort: ${sortedMessages.length}, totalCount: ${newTotalCount}`);
260
- return __spreadProps(__spreadValues({}, prev), {
261
- context: __spreadProps(__spreadValues({}, prev.context), {
262
- loadingOldMessages: false,
263
- threadMessages: sortedMessages,
264
- totalCount: newTotalCount
265
- }),
266
- value: "active"
267
- });
268
- });
269
- } else if (event.type === "ERROR") {
270
- setState((prev) => {
271
- var _a2;
272
- return __spreadProps(__spreadValues({}, prev), {
273
- context: __spreadProps(__spreadValues({}, prev.context), {
274
- loading: false,
275
- loadingOldMessages: false,
276
- error: ((_a2 = event.data) == null ? void 0 : _a2.message) || "Unknown error"
277
- }),
278
- value: "error"
279
- });
280
- });
281
- }
282
- } catch (error) {
283
- console.error("Error in thread conversation send function:", error);
284
- }
34
+ const ErrorNotification = ({
35
+ message,
36
+ onClose
37
+ }) => {
38
+ const opacity = useRef(new Animated.Value(0)).current;
39
+ useEffect(() => {
40
+ Animated.timing(opacity, {
41
+ toValue: 1,
42
+ duration: 300,
43
+ useNativeDriver: true
44
+ }).start();
45
+ const timer = setTimeout(() => {
46
+ Animated.timing(opacity, {
47
+ toValue: 0,
48
+ duration: 300,
49
+ useNativeDriver: true
50
+ }).start(() => onClose && onClose());
51
+ }, 4e3);
52
+ return () => clearTimeout(timer);
285
53
  }, []);
286
- const stateWithMatches = useMemo(() => {
287
- return __spreadProps(__spreadValues({}, state), {
288
- matches: (checkState) => {
289
- return state.value === checkState;
290
- }
291
- });
292
- }, [state]);
293
- return [stateWithMatches, send];
294
- }
54
+ return /* @__PURE__ */ React__default.createElement(Animated.View, { style: {
55
+ position: "absolute",
56
+ top: 10,
57
+ left: 10,
58
+ right: 10,
59
+ backgroundColor: "#f44336",
60
+ padding: 15,
61
+ borderRadius: 8,
62
+ shadowColor: "#000",
63
+ shadowOffset: {
64
+ width: 0,
65
+ height: 2
66
+ },
67
+ shadowOpacity: 0.25,
68
+ shadowRadius: 3.84,
69
+ elevation: 5,
70
+ zIndex: 1e3,
71
+ opacity
72
+ } }, /* @__PURE__ */ React__default.createElement(HStack, { className: "items-center justify-between" }, /* @__PURE__ */ React__default.createElement(Text, { style: {
73
+ color: "white",
74
+ fontWeight: "bold"
75
+ } }, "Upload Failed"), /* @__PURE__ */ React__default.createElement(TouchableOpacity, { onPress: onClose }, /* @__PURE__ */ React__default.createElement(Ionicons, { name: "close", size: 20, color: "white" }))), /* @__PURE__ */ React__default.createElement(Text, { style: {
76
+ color: "white",
77
+ marginTop: 5
78
+ } }, message));
79
+ };
80
+ const isValidFileUrl = (url) => {
81
+ return !!url && typeof url === "string" && url.length > 0;
82
+ };
295
83
  const ThreadConversationViewComponent = ({
296
84
  channelId,
297
85
  postParentId,
298
86
  isPostParentIdThread,
299
87
  role
300
88
  }) => {
301
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u;
89
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
302
90
  const {
303
91
  params
304
92
  } = useRoute();
305
93
  const [channelToTop, setChannelToTop] = useState(0);
306
- useRef(true);
307
- const [state, send] = useSafeMachine();
308
- useCallback(() => {
309
- try {
310
- return (state == null ? void 0 : state.context) || {};
311
- } catch (error) {
312
- console.error("Error accessing state.context:", error);
313
- return {};
314
- }
315
- }, [state]);
316
- const safeContextProperty = useCallback((property, defaultValue = null) => {
317
- var _a2, _b2;
318
- try {
319
- return (_b2 = (_a2 = state == null ? void 0 : state.context) == null ? void 0 : _a2[property]) != null ? _b2 : defaultValue;
320
- } catch (error) {
321
- console.error(`Error accessing state.context.${property}:`, error);
322
- return defaultValue;
323
- }
324
- }, [state]);
325
- const safeMatches = useCallback((stateValue) => {
326
- var _a2;
327
- try {
328
- return ((_a2 = state == null ? void 0 : state.matches) == null ? void 0 : _a2.call(state, stateValue)) || false;
329
- } catch (error) {
330
- console.error(`Error calling state.matches with ${stateValue}:`, error);
331
- return false;
332
- }
333
- }, [state]);
334
- const safeSend = useCallback((event) => {
335
- try {
336
- send(event);
337
- } catch (error) {
338
- console.error("Error sending event to state machine:", error, event);
339
- }
340
- }, [send]);
341
- const stateRef = useRef(state);
342
- useEffect(() => {
343
- stateRef.current = state;
344
- }, [state]);
94
+ const [channelMessages, setChannelMessages] = useState([]);
345
95
  const auth = useSelector(userSelector);
346
- const [selectedImage, setImage] = useState("");
96
+ const [totalCount, setTotalCount] = useState(0);
97
+ const [selectedImage, setSelectedImage] = useState("");
98
+ const [loadingOldMessages, setLoadingOldMessages] = useState(false);
99
+ const [loadEarlierMsg, setLoadEarlierMsg] = useState(false);
347
100
  const navigation = useNavigation();
348
101
  const [files, setFiles] = useState([]);
349
102
  const [images, setImages] = useState([]);
103
+ const [msg, setMsg] = useState("");
104
+ const [loading, setLoading] = useState(false);
105
+ const [imageLoading, setImageLoading] = useState(false);
106
+ const [uploadingMessageId, setUploadingMessageId] = useState(null);
107
+ const [expoTokens, setExpoTokens] = useState([]);
350
108
  const [isShowImageViewer, setImageViewer] = useState(false);
351
109
  const [imageObject, setImageObject] = useState({});
352
110
  const [parentId, setParentId] = useState(postParentId);
353
- const [expoTokens, setExpoTokens] = useState([]);
354
- const threadMessageListRef = useRef(null);
355
- const [sendThreadMessage] = useCreatePostThreadMutation();
356
- const [sendExpoNotificationOnPostMutation] = useSendExpoNotificationOnPostMutation();
111
+ const [postThread, setPostThread] = useState();
357
112
  const {
358
113
  startUpload
359
114
  } = useUploadFilesNative();
115
+ const [threadPost, setThreadPost] = useState([]);
116
+ const [isScrollToBottom, setIsScrollToBottom] = useState(false);
117
+ const threadMessageListRef = useRef(null);
118
+ useToast();
119
+ const [errorMessage, setErrorMessage] = useState("");
120
+ const [isActionSheetVisible, setActionSheetVisible] = useState(false);
121
+ const [textUpdatedInActionSheet, setTextUpdatedInActionSheet] = useState(false);
122
+ const [lastShownMsg, setLastShownMsg] = useState("");
123
+ const textInputRef = useRef(null);
124
+ const [sendThreadMessage] = useCreatePostThread();
125
+ const [sendExpoNotificationOnPostMutation] = useSendExpoNotification();
360
126
  const [getThreadMessages, {
361
127
  data,
362
128
  loading: threadLoading,
363
129
  fetchMore: fetchMoreMessages,
364
130
  refetch: refetchThreadMessages,
365
131
  subscribeToMore
366
- }] = useGetPostThreadLazyQuery({
132
+ }] = useGetPostThreadLazy({
367
133
  fetchPolicy: "cache-and-network"
368
134
  });
369
- const forceRefreshMessages = useCallback(() => {
370
- console.log("Force refreshing all messages");
371
- safeSend({
372
- type: Actions.CLEAR_MESSAGES
373
- });
374
- if (channelId && parentId) {
375
- safeSend({
376
- type: Actions.START_LOADING,
377
- data: {
378
- loading: true
379
- }
380
- });
381
- getThreadMessages({
382
- variables: {
383
- channelId: channelId == null ? void 0 : channelId.toString(),
384
- role: role == null ? void 0 : role.toString(),
385
- postParentId: !parentId || parentId == 0 ? null : parentId == null ? void 0 : parentId.toString(),
386
- selectedFields: "id channel post replies replyCount lastReplyAt createdAt updatedAt",
387
- limit: 50
388
- }
389
- }).then(({
390
- data: data2
391
- }) => {
392
- var _a2, _b2, _c2;
393
- if (data2 == null ? void 0 : data2.getPostThread) {
394
- const threads = data2.getPostThread;
395
- const threadPost = (_a2 = threads == null ? void 0 : threads.post) != null ? _a2 : [];
396
- const threadReplies = (_b2 = threads == null ? void 0 : threads.replies) != null ? _b2 : [];
397
- const messageTotalCount = (_c2 = threads == null ? void 0 : threads.replyCount) != null ? _c2 : 0;
398
- const messages = [...threadReplies];
399
- console.log(`Force refresh complete. Got ${messages.length} messages of ${messageTotalCount} total`);
400
- safeSend({
401
- type: Actions.SET_THREAD_MESSAGES,
402
- data: {
403
- messages,
404
- totalCount: messageTotalCount,
405
- threadPost,
406
- postThread: threads
407
- }
408
- });
409
- }
410
- }).catch((error) => {
411
- console.error("Error during force refresh:", error);
412
- safeSend({
413
- type: "ERROR",
414
- data: {
415
- message: error.message
416
- }
417
- });
418
- });
419
- }
420
- }, [channelId, parentId, getThreadMessages, safeSend]);
135
+ const [pendingUploads, setPendingUploads] = useState({});
136
+ const [uploadErrors, setUploadErrors] = useState({});
137
+ const [isUploadingImage, setIsUploadingImage] = useState(false);
138
+ const [refreshing, setRefreshing] = useState(false);
421
139
  useFocusEffect(React__default.useCallback(() => {
422
140
  var _a2;
423
141
  navigation.setOptions({
424
142
  title: (_a2 = params == null ? void 0 : params.title) != null ? _a2 : "Thread",
425
- headerLeft: (props) => /* @__PURE__ */ React__default.createElement(Button, { className: "bg-transparent active:bg-gray-200 ", onPress: () => navigation.goBack() }, /* @__PURE__ */ React__default.createElement(MaterialIcons, { size: 20, name: "arrow-back-ios", color: "black" })),
426
- headerRight: () => /* @__PURE__ */ React__default.createElement(Button, { className: "bg-transparent active:bg-gray-200 mr-2", onPress: forceRefreshMessages }, /* @__PURE__ */ React__default.createElement(MaterialIcons, { size: 20, name: "refresh", color: "black" }))
143
+ headerLeft: (props) => /* @__PURE__ */ React__default.createElement(Button, { className: "bg-transparent active:bg-gray-200 ", onPress: () => navigation.goBack() }, /* @__PURE__ */ React__default.createElement(MaterialIcons, { size: 20, name: "arrow-back-ios", color: "black" }))
427
144
  });
428
- if (channelId && postParentId) {
429
- safeSend({
430
- type: Actions.INITIAL_CONTEXT,
431
- data: {
432
- channelId,
433
- postParentId,
434
- role
435
- }
145
+ if (postParentId) {
146
+ refetchThreadMessages({
147
+ channelId: channelId == null ? void 0 : channelId.toString(),
148
+ role: role == null ? void 0 : role.toString(),
149
+ postParentId: postParentId == null ? void 0 : postParentId.toString(),
150
+ selectedFields: "id channel post replies replyCount lastReplyAt createdAt updatedAt",
151
+ limit: MESSAGES_PER_PAGE
436
152
  });
437
153
  }
438
154
  setParentId(postParentId);
439
155
  return () => {
440
- safeSend({
441
- type: Actions.CLEAR_MESSAGES
442
- });
156
+ setTotalCount(0);
157
+ setChannelMessages([]);
158
+ setThreadPost([]);
443
159
  };
444
- }, [postParentId, forceRefreshMessages]));
445
- useEffect(() => {
446
- if (safeMatches(BaseState.FetchThreadMessages)) {
447
- fetchThreadMessages();
448
- }
449
- }, [state.value]);
450
- useEffect(() => {
451
- if (safeMatches(MainState.FetchMoreMessages)) {
452
- onFetchOld();
453
- }
454
- }, [state.value]);
455
- useEffect(() => {
456
- if (safeMatches(MainState.SendThreadMessage)) {
457
- const messageText = safeContextProperty("messageText", "");
458
- console.log("Sending message from state transition, text:", messageText);
459
- sendThreadMessageHandler(messageText);
460
- }
461
- }, [state.value]);
160
+ }, [postParentId]));
462
161
  useEffect(() => {
463
- if (safeMatches(MainState.SendThreadMessageWithFile)) {
464
- const messageText = safeContextProperty("messageText", "");
465
- const images2 = safeContextProperty("images", []);
466
- sendThreadMessageWithFileHandler(messageText, images2);
467
- }
468
- }, [state.value]);
469
- const fetchThreadMessages = useCallback(() => {
470
162
  if (channelId && parentId) {
471
- if (__DEV__)
472
- console.log("Initial fetch of thread messages using larger limit (50)");
473
- safeSend({
474
- type: Actions.START_LOADING,
475
- data: {
476
- loading: true
477
- }
478
- });
479
163
  getThreadMessages({
480
164
  variables: {
481
165
  channelId: channelId == null ? void 0 : channelId.toString(),
482
166
  role: role == null ? void 0 : role.toString(),
483
167
  postParentId: !parentId || parentId == 0 ? null : parentId == null ? void 0 : parentId.toString(),
484
168
  selectedFields: "id channel post replies replyCount lastReplyAt createdAt updatedAt",
485
- limit: 50
486
- }
487
- }).then(({
488
- data: data2
489
- }) => {
490
- var _a2, _b2, _c2;
491
- if (data2 == null ? void 0 : data2.getPostThread) {
492
- const threads = data2.getPostThread;
493
- const threadPost = (_a2 = threads == null ? void 0 : threads.post) != null ? _a2 : [];
494
- const threadReplies = (_b2 = threads == null ? void 0 : threads.replies) != null ? _b2 : [];
495
- const messageTotalCount = (_c2 = threads == null ? void 0 : threads.replyCount) != null ? _c2 : 0;
496
- const messages = [...threadReplies];
497
- if (__DEV__)
498
- console.log(`Initial fetch complete. Got ${messages.length} messages of ${messageTotalCount} total`);
499
- safeSend({
500
- type: Actions.SET_THREAD_MESSAGES,
501
- data: {
502
- messages,
503
- totalCount: messageTotalCount,
504
- threadPost,
505
- postThread: threads
506
- }
507
- });
169
+ limit: MESSAGES_PER_PAGE
508
170
  }
509
- }).catch((error) => {
510
- safeSend({
511
- type: "ERROR",
512
- data: {
513
- message: error.message
514
- }
515
- });
516
171
  });
517
172
  }
518
- }, [channelId, parentId, role, getThreadMessages, safeSend]);
173
+ }, [parentId]);
519
174
  React__default.useEffect(() => {
520
175
  var _a2, _b2, _c2;
521
176
  if (data == null ? void 0 : data.getPostThread) {
522
177
  const threads = data.getPostThread;
523
- const threadPost = (_a2 = threads == null ? void 0 : threads.post) != null ? _a2 : [];
178
+ const threadPost2 = (_a2 = threads == null ? void 0 : threads.post) != null ? _a2 : [];
524
179
  const threadReplies = (_b2 = threads == null ? void 0 : threads.replies) != null ? _b2 : [];
525
180
  const messeageTotalCount = (_c2 = threads == null ? void 0 : threads.replyCount) != null ? _c2 : 0;
526
- const messages = [...threadReplies];
527
- safeSend({
528
- type: Actions.SET_THREAD_MESSAGES,
529
- data: {
530
- messages,
531
- totalCount: messeageTotalCount,
532
- threadPost,
533
- postThread: threads
534
- }
535
- });
181
+ const messages = [threadPost2, ...threadReplies];
182
+ if (messages && messages.length > 0 && messeageTotalCount > totalCount || messages && messages.length > 0 && channelMessages.length === 0) {
183
+ setThreadMessages(messages, messeageTotalCount);
184
+ }
536
185
  }
537
- }, [data]);
186
+ if (isScrollToBottom && channelMessages) scrollToBottom();
187
+ }, [data, channelMessages, loadingOldMessages, totalCount, isPostParentIdThread, isScrollToBottom]);
188
+ const setThreadMessages = (messages, messagesTotalCount) => {
189
+ setChannelMessages((oldMessages) => uniqBy([...messages, ...oldMessages], ({
190
+ id
191
+ }) => id));
192
+ setTotalCount(messagesTotalCount);
193
+ };
538
194
  React__default.useEffect(() => {
539
- if (safeContextProperty("selectedImage")) {
540
- safeSend({
541
- type: Actions.STOP_LOADING
542
- });
195
+ if (selectedImage) setImageLoading(false);
196
+ }, [selectedImage]);
197
+ const scrollToBottom = React__default.useCallback(() => {
198
+ if (threadMessageListRef == null ? void 0 : threadMessageListRef.current) {
199
+ setIsScrollToBottom(false);
200
+ threadMessageListRef.current.scrollTop = threadMessageListRef.current.scrollHeight;
543
201
  }
544
- }, [safeContextProperty("selectedImage")]);
545
- React__default.useEffect(() => {
546
- const isLoading = safeContextProperty("loadingOldMessages", false);
547
- if (isLoading) {
548
- console.log("Message loading timeout safety started");
549
- const timeoutId = setTimeout(() => {
550
- if (safeContextProperty("loadingOldMessages", false)) {
551
- console.log("Message loading timed out - resetting state");
552
- safeSend({
553
- type: Actions.STOP_LOADING,
554
- data: {
555
- loadingOldMessages: false
556
- }
557
- });
202
+ }, [threadMessageListRef]);
203
+ const onFetchOld = useCallback(() => {
204
+ if (totalCount > channelMessages.length && !loadingOldMessages) {
205
+ setLoadEarlierMsg(true);
206
+ setLoadingOldMessages(true);
207
+ fetchMoreMessages({
208
+ variables: {
209
+ channelId: channelId == null ? void 0 : channelId.toString(),
210
+ role: role == null ? void 0 : role.toString(),
211
+ postParentId: parentId == null ? void 0 : parentId.toString(),
212
+ selectedFields: "id channel post replies replyCount lastReplyAt createdAt updatedAt",
213
+ limit: MESSAGES_PER_PAGE,
214
+ skip: channelMessages.length - 1
558
215
  }
559
- }, 1e4);
560
- return () => clearTimeout(timeoutId);
561
- }
562
- }, [safeContextProperty("loadingOldMessages")]);
563
- const failedLoadAttemptsRef = useRef(0);
564
- const registerLoadAttemptResult = useCallback((success) => {
565
- if (!success) {
566
- failedLoadAttemptsRef.current += 1;
567
- console.log(`Failed load attempt registered, count: ${failedLoadAttemptsRef.current}`);
216
+ }).then((res) => {
217
+ var _a2, _b2, _c2, _d2;
218
+ if ((_a2 = res == null ? void 0 : res.data) == null ? void 0 : _a2.getPostThread) {
219
+ const threads = (_b2 = res == null ? void 0 : res.data) == null ? void 0 : _b2.getPostThread;
220
+ const threadReplies = (_c2 = threads == null ? void 0 : threads.replies) != null ? _c2 : [];
221
+ const messeageTotalCount = (_d2 = threads == null ? void 0 : threads.replyCount) != null ? _d2 : 0;
222
+ setThreadMessages(threadReplies, messeageTotalCount);
223
+ }
224
+ }).finally(() => {
225
+ setLoadEarlierMsg(false);
226
+ setLoadingOldMessages(false);
227
+ setRefreshing(false);
228
+ }).catch((error) => {
229
+ setLoadEarlierMsg(false);
230
+ setLoadingOldMessages(false);
231
+ setRefreshing(false);
232
+ });
568
233
  } else {
569
- failedLoadAttemptsRef.current = 0;
570
- }
571
- }, []);
572
- React__default.useEffect(() => {
573
- const isLoading = safeContextProperty("loadingOldMessages", false);
574
- const totalCount = safeContextProperty("totalCount", 0);
575
- const messagesCount = safeContextProperty("threadMessages", []).length;
576
- if (!isLoading && totalCount > messagesCount) {
577
- if (failedLoadAttemptsRef.current >= 2) {
578
- console.log(`Auto-fixing incorrect message count after ${failedLoadAttemptsRef.current + 1} failed load attempts`);
579
- console.log(`Adjusting totalCount from ${totalCount} to ${messagesCount}`);
580
- safeSend({
581
- type: Actions.SET_THREAD_MESSAGES,
582
- data: {
583
- messages: safeContextProperty("threadMessages", []),
584
- totalCount: messagesCount,
585
- threadPost: safeContextProperty("threadPost", []),
586
- postThread: safeContextProperty("postThread", null)
587
- }
588
- });
589
- failedLoadAttemptsRef.current = 0;
590
- }
591
- }
592
- }, [safeContextProperty("loadingOldMessages"), safeContextProperty("threadMessages")]);
593
- React__default.useCallback(() => {
594
- if (threadMessageListRef == null ? void 0 : threadMessageListRef.current) {
595
- threadMessageListRef.current.scrollToBottom();
234
+ setRefreshing(false);
596
235
  }
597
- }, [threadMessageListRef]);
598
- const isCloseToTop = useCallback(({
236
+ }, [parentId, channelId, totalCount, channelMessages]);
237
+ const onRefresh = useCallback(() => {
238
+ setRefreshing(true);
239
+ onFetchOld();
240
+ }, [onFetchOld]);
241
+ const isCloseToTop = ({
599
242
  layoutMeasurement,
600
243
  contentOffset,
601
244
  contentSize
602
245
  }) => {
603
- const visibleHeight = layoutMeasurement.height;
604
- const topThreshold = Math.min(80, visibleHeight * 0.15);
605
- return contentOffset.y <= topThreshold;
606
- }, []);
607
- const handleScrollToTop = useCallback(({
608
- nativeEvent
609
- }) => {
610
- if (isCloseToTop(nativeEvent)) {
611
- const isLoading = safeContextProperty("loadingOldMessages", false);
612
- const totalCount = safeContextProperty("totalCount", 0);
613
- const currentCount = safeContextProperty("threadMessages", []).length;
614
- const hasMoreMessages = totalCount > currentCount;
615
- if (__DEV__)
616
- console.log(`Scroll near top - Loading state: ${isLoading}, Messages: ${currentCount}/${totalCount}, Has more: ${hasMoreMessages}`);
617
- if (!isLoading && hasMoreMessages) {
618
- if (__DEV__)
619
- console.log("Near top of list - loading older messages");
620
- safeSend({
621
- type: Actions.FETCH_MORE_MESSAGES
622
- });
623
- }
624
- }
625
- }, [isCloseToTop, safeContextProperty, safeSend]);
626
- const handleEndReached = () => {
627
- console.log("Reached end of message list");
246
+ const paddingToTop = 60;
247
+ return contentSize.height - layoutMeasurement.height - paddingToTop <= contentOffset.y;
628
248
  };
249
+ const removeMessageFromUI = useCallback((messageId) => {
250
+ setPendingUploads((prev) => {
251
+ const newPending = __spreadValues({}, prev);
252
+ delete newPending[messageId];
253
+ return newPending;
254
+ });
255
+ setUploadErrors((prev) => {
256
+ const newErrors = __spreadValues({}, prev);
257
+ delete newErrors[messageId];
258
+ return newErrors;
259
+ });
260
+ setIsUploadingImage(false);
261
+ }, []);
629
262
  const onSelectImages = async () => {
630
- var _a2;
263
+ setLoading(true);
631
264
  try {
632
- safeSend({
633
- type: Actions.START_LOADING
634
- });
635
- const imageSource = await ImagePicker.launchImageLibraryAsync({
265
+ let imageSource = await ImagePicker.launchImageLibraryAsync({
636
266
  mediaTypes: ImagePicker.MediaTypeOptions.Images,
637
- allowsEditing: true,
267
+ allowsEditing: false,
638
268
  aspect: [4, 3],
639
269
  quality: 0.8,
640
270
  base64: true,
641
- allowsMultipleSelection: false
271
+ exif: false,
272
+ allowsMultipleSelection: true
273
+ // Enable multiple selection
642
274
  });
643
- if (imageSource.canceled) {
644
- console.log("Image selection was canceled");
645
- safeSend({
646
- type: Actions.STOP_LOADING
647
- });
648
- return;
649
- }
650
- if (!imageSource.assets || imageSource.assets.length === 0 || !((_a2 = imageSource.assets[0]) == null ? void 0 : _a2.base64)) {
651
- console.error("No valid image data received");
652
- safeSend({
653
- type: "ERROR",
654
- data: {
655
- message: "No valid image data received"
656
- }
275
+ if (!(imageSource == null ? void 0 : imageSource.canceled)) {
276
+ const selectedAssets = (imageSource == null ? void 0 : imageSource.assets) || [];
277
+ if (selectedAssets.length === 0) {
278
+ setLoading(false);
279
+ return;
280
+ }
281
+ const newImages = selectedAssets.map((selectedAsset) => {
282
+ const base64Data = selectedAsset.base64;
283
+ const previewImage = base64Data ? `data:image/jpeg;base64,${base64Data}` : selectedAsset.uri;
284
+ const asset = __spreadProps(__spreadValues({}, selectedAsset), {
285
+ url: selectedAsset.uri,
286
+ fileName: selectedAsset.fileName || `image_${Date.now()}.jpg`,
287
+ mimeType: "image/jpeg"
288
+ });
289
+ return asset;
657
290
  });
658
- return;
659
- }
660
- const asset = imageSource.assets[0];
661
- const fileExtension = asset.mimeType ? asset.mimeType.split("/").pop() || "jpg" : "jpg";
662
- const filename = `image_${Date.now()}.${fileExtension}`;
663
- const mimeType = asset.mimeType || "image/jpeg";
664
- const image = `data:${mimeType};base64,${asset.base64}`;
665
- const fileData = {
666
- uri: asset.uri,
667
- type: mimeType,
668
- name: filename,
669
- base64: asset.base64
670
- };
671
- console.log(`Selected image: ${filename}, type: ${mimeType}`);
672
- safeSend({
673
- type: Actions.SET_IMAGE,
674
- data: {
675
- image,
676
- files: [fileData],
677
- images: [asset]
291
+ if (newImages.length > 0) {
292
+ const base64Data = newImages[0].base64;
293
+ const previewImage = base64Data ? `data:image/jpeg;base64,${base64Data}` : newImages[0].uri;
294
+ setSelectedImage(previewImage);
678
295
  }
679
- });
296
+ setImages((currentImages) => [...currentImages, ...newImages]);
297
+ setLoading(false);
298
+ } else {
299
+ setLoading(false);
300
+ }
680
301
  } catch (error) {
681
- console.error("Error selecting image:", error);
682
- safeSend({
683
- type: "ERROR",
684
- data: {
685
- message: error.message || "Failed to select image"
686
- }
687
- });
302
+ setLoading(false);
688
303
  }
689
304
  };
690
- const sendThreadMessageHandler = useCallback(async (message) => {
691
- var _a2, _b2;
692
- console.log("Sending message:", message);
693
- if (!channelId) {
694
- console.error("No channelId provided");
695
- return;
305
+ useCallback(() => {
306
+ setLastShownMsg(msg);
307
+ setActionSheetVisible(true);
308
+ }, [msg]);
309
+ useCallback(() => {
310
+ setActionSheetVisible(false);
311
+ if (!textUpdatedInActionSheet) {
312
+ setMsg(lastShownMsg);
696
313
  }
697
- const messageContent = (message == null ? void 0 : message.trim()) || " ";
698
- console.log("Using message content for sending:", messageContent);
314
+ setTextUpdatedInActionSheet(false);
315
+ }, [textUpdatedInActionSheet, lastShownMsg]);
316
+ useEffect(() => {
317
+ if (isActionSheetVisible && Platform.OS === "ios") {
318
+ Keyboard.dismiss();
319
+ }
320
+ }, [isActionSheetVisible]);
321
+ const [isGiftedInputFocused, setIsGiftedInputFocused] = useState(false);
322
+ const handleSend = useCallback(async (message) => {
323
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2;
324
+ const newMessageText = message && message.length > 0 ? message || " " : " ";
325
+ if (!channelId) return;
326
+ const hasText = newMessageText !== " ";
327
+ const hasImages = images && images.length > 0;
328
+ if (!hasText && !hasImages) return;
329
+ setLoading(true);
699
330
  const postId = objectId();
700
- console.log("Generated postId:", postId);
701
- safeSend({
702
- type: Actions.START_LOADING
703
- });
331
+ const currentDate = /* @__PURE__ */ new Date();
332
+ const currentMessageText = message || "";
333
+ const currentImages = [...images];
334
+ setMsg("");
335
+ setSelectedImage("");
336
+ setImages([]);
337
+ setFiles([]);
338
+ if (isActionSheetVisible) {
339
+ setActionSheetVisible(false);
340
+ }
341
+ const optimisticMessage = {
342
+ id: postId,
343
+ message: currentMessageText || (currentImages.length > 0 ? " " : ""),
344
+ createdAt: currentDate.toISOString(),
345
+ author: {
346
+ id: (_a2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _a2.id,
347
+ givenName: (_b2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _b2.given_name,
348
+ familyName: (_c2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _c2.family_name,
349
+ picture: (_d2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _d2.picture
350
+ },
351
+ isDelivered: false,
352
+ // Mark as not delivered yet during upload
353
+ isRead: false,
354
+ isOptimistic: true,
355
+ // Flag to identify optimistic messages
356
+ files: currentImages.length > 0 ? {
357
+ data: currentImages.filter((img) => img && (img.uri || img.url)).map((img) => ({
358
+ id: objectId(),
359
+ url: img.uri || img.url,
360
+ localUri: img.uri || img.url,
361
+ // Keep local URI for preview
362
+ name: img.fileName || `image_${Date.now()}.jpg`,
363
+ extension: "jpg",
364
+ mimeType: "image/jpeg",
365
+ refType: FileRefType.Post,
366
+ height: img.height || 0,
367
+ width: img.width || 0,
368
+ isUploading: true
369
+ // Flag to indicate this file is uploading
370
+ })),
371
+ totalCount: currentImages.filter((img) => img && (img.uri || img.url)).length
372
+ // Only count valid images
373
+ } : void 0
374
+ };
375
+ if (optimisticMessage.message && optimisticMessage.message.trim() !== "" || optimisticMessage.files && optimisticMessage.files.data && optimisticMessage.files.data.length > 0) {
376
+ setChannelMessages((oldMessages) => uniqBy([optimisticMessage, ...oldMessages], ({
377
+ id
378
+ }) => id));
379
+ setIsScrollToBottom(true);
380
+ }
704
381
  try {
705
- console.log("Sending mutation with variables:", {
706
- channelId,
707
- postThreadId: (_a2 = safeContextProperty("postThread")) == null ? void 0 : _a2.id,
708
- postParentId: !parentId || parentId == 0 ? null : parentId,
709
- message: messageContent
710
- });
711
- const result = await sendThreadMessage({
382
+ let fileIds = null;
383
+ if (currentImages && currentImages.length > 0) {
384
+ const validImages = currentImages.filter((img) => img && (img.uri || img.url));
385
+ if (validImages.length === 0) {
386
+ setIsUploadingImage(false);
387
+ } else {
388
+ setIsUploadingImage(true);
389
+ const imagesToUpload = validImages.map((img) => {
390
+ return __spreadProps(__spreadValues({}, img), {
391
+ uri: img.uri || img.url,
392
+ // Use either uri or url
393
+ type: img.mimeType || "image/jpeg",
394
+ name: img.fileName || `image_${Date.now()}.jpg`
395
+ });
396
+ });
397
+ setUploadingMessageId(postId);
398
+ setPendingUploads((prev) => __spreadProps(__spreadValues({}, prev), {
399
+ [postId]: {
400
+ images: validImages,
401
+ message: currentMessageText
402
+ }
403
+ }));
404
+ const uploadResponse = await startUpload({
405
+ file: imagesToUpload,
406
+ saveUploadedFile: {
407
+ variables: {
408
+ postId
409
+ }
410
+ },
411
+ createUploadLink: {
412
+ variables: {
413
+ postId
414
+ }
415
+ }
416
+ });
417
+ if (uploadResponse == null ? void 0 : uploadResponse.error) {
418
+ throw new Error(uploadResponse.error.toString());
419
+ }
420
+ const uploadedFiles = uploadResponse.data;
421
+ if (uploadResponse.data) {
422
+ fileIds = (_e2 = uploadedFiles == null ? void 0 : uploadedFiles.map((f) => f.id)) != null ? _e2 : null;
423
+ setChannelMessages((oldMessages) => {
424
+ return oldMessages.map((msg2) => {
425
+ if (msg2.id === postId && msg2.isOptimistic) {
426
+ return __spreadProps(__spreadValues({}, msg2), {
427
+ isOptimistic: false,
428
+ files: __spreadProps(__spreadValues({}, msg2.files), {
429
+ data: uploadedFiles.filter((file) => isValidFileUrl(file.url)).map((file, index) => __spreadProps(__spreadValues({}, msg2.files.data[index]), {
430
+ url: file.url,
431
+ isUploading: false
432
+ }))
433
+ })
434
+ });
435
+ }
436
+ return msg2;
437
+ });
438
+ });
439
+ }
440
+ setPendingUploads((prev) => {
441
+ const newPending = __spreadValues({}, prev);
442
+ delete newPending[postId];
443
+ return newPending;
444
+ });
445
+ }
446
+ }
447
+ await sendThreadMessage({
712
448
  variables: {
449
+ postId,
713
450
  channelId,
714
- postThreadId: safeContextProperty("postThread") && ((_b2 = safeContextProperty("postThread")) == null ? void 0 : _b2.id),
715
- postParentId: !parentId || parentId == 0 ? null : parentId,
451
+ postThreadId: postThread && (postThread == null ? void 0 : postThread.id),
452
+ postParentId: !parentId || parentId === 0 ? null : parentId,
716
453
  threadMessageInput: {
717
- content: messageContent,
454
+ content: currentMessageText,
455
+ files: fileIds,
718
456
  role
719
457
  }
720
458
  },
459
+ optimisticResponse: {
460
+ createPostThread: {
461
+ __typename: "ThreadMessageSent",
462
+ lastMessage: {
463
+ __typename: "Post",
464
+ id: postId,
465
+ message: currentMessageText || " ",
466
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
467
+ author: {
468
+ __typename: "UserAccount",
469
+ id: (_f2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _f2.id,
470
+ givenName: (_g2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _g2.given_name,
471
+ familyName: (_h2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _h2.family_name,
472
+ picture: (_i2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _i2.picture
473
+ },
474
+ channel: {
475
+ __typename: "Channel",
476
+ id: channelId.toString()
477
+ }
478
+ },
479
+ // Type assertion to avoid TypeScript errors
480
+ data: {
481
+ __typename: "PostThread",
482
+ id: (postThread == null ? void 0 : postThread.id) || objectId()
483
+ }
484
+ }
485
+ },
721
486
  update: (cache, {
722
487
  data: data2,
723
488
  errors
724
489
  }) => {
725
- var _a3, _b3, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2;
726
- console.log("Send message update callback - data:", data2, "errors:", errors);
727
- if (!data2 || errors) {
728
- console.error("Send message failed:", errors);
729
- safeSend({
730
- type: Actions.STOP_LOADING
731
- });
732
- return;
733
- }
734
- console.log("Message sent successfully:", (_a3 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _a3.lastMessage);
735
- const newMessage = (_b3 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _b3.lastMessage;
736
- safeSend({
737
- type: "SEND_THREAD_MESSAGE_SUCCESS",
738
- data: {
739
- message: newMessage,
740
- messageText: ""
741
- }
742
- });
743
- if (!parentId || parentId == 0) {
744
- console.log("Setting new parentId:", (_d2 = (_c2 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _c2.lastMessage) == null ? void 0 : _d2.id);
745
- setParentId((_f2 = (_e2 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _e2.lastMessage) == null ? void 0 : _f2.id);
490
+ var _a3, _b3, _c3, _d3, _e3, _f3, _g3;
491
+ if (!data2 || errors) return;
492
+ setPostThread((_a3 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _a3.data);
493
+ const lastMessageId = (_c3 = (_b3 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _b3.lastMessage) == null ? void 0 : _c3.id;
494
+ if (!parentId || parentId === 0) {
495
+ setParentId((_e3 = (_d3 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _d3.lastMessage) == null ? void 0 : _e3.id);
746
496
  }
747
497
  setChannelToTop(channelToTop + 1);
748
- const lastMessageId = (_h2 = (_g2 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _g2.lastMessage) == null ? void 0 : _h2.id;
749
- sendPushNotification(lastMessageId, channelId, parentId, (_j2 = (_i2 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _i2.data) == null ? void 0 : _j2.id);
498
+ sendPushNotification(lastMessageId, channelId, parentId, (_g3 = (_f3 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _f3.data) == null ? void 0 : _g3.id);
750
499
  }
751
500
  });
752
- console.log("Send mutation result:", result);
753
501
  } catch (error) {
754
502
  console.error("Error sending message:", error);
755
- safeSend({
756
- type: "ERROR",
757
- data: {
758
- message: error.message || "Failed to send message"
503
+ let formattedErrorMessage = "Failed to upload image. Please try again.";
504
+ if (__DEV__) {
505
+ if (error.name === "ApolloError") {
506
+ formattedErrorMessage = error.message.replace("[ApolloError: ", "").replace("]", "").split(";")[0];
507
+ } else {
508
+ formattedErrorMessage = error.message || "Unknown error occurred";
759
509
  }
760
- });
761
- }
762
- }, [channelId, parentId, state.context, role]);
763
- const sendThreadMessageWithFileHandler = useCallback(async (message, images2) => {
764
- var _a2, _b2;
765
- console.log("Sending message with file:", message, "Images:", images2.length);
766
- if (!channelId) {
767
- console.error("No channelId provided");
768
- return;
769
- }
770
- if (images2.length === 0) {
771
- console.error("No images to send");
772
- return;
773
- }
774
- const messageContent = (message == null ? void 0 : message.trim()) || " ";
775
- console.log("Using message content for file send:", messageContent);
776
- const postId = objectId();
777
- console.log("Generated postId for file upload:", postId);
778
- try {
779
- const preparedImages = images2.map((img) => ({
780
- uri: img.uri,
781
- type: img.mimeType || "image/jpeg",
782
- name: img.fileName || `image_${Date.now()}.jpg`,
783
- base64: img.base64,
784
- width: img.width || 0,
785
- height: img.height || 0
786
- }));
787
- console.log("Starting file upload with prepared images:", preparedImages.length);
788
- const uploadResponse = await startUpload({
789
- file: preparedImages,
790
- saveUploadedFile: {
791
- variables: {
792
- postId
793
- }
794
- },
795
- createUploadLink: {
796
- variables: {
797
- postId
798
- }
510
+ } else {
511
+ if (((_j2 = error.message) == null ? void 0 : _j2.includes("network")) || ((_k2 = error.message) == null ? void 0 : _k2.includes("timeout"))) {
512
+ formattedErrorMessage = "Network error. Please check your connection.";
513
+ } else if ((_l2 = error.message) == null ? void 0 : _l2.includes("permission")) {
514
+ formattedErrorMessage = "Permission denied for this operation.";
799
515
  }
800
- });
801
- if (uploadResponse == null ? void 0 : uploadResponse.error) {
802
- console.error("File upload failed:", uploadResponse.error);
803
- safeSend({
804
- type: Actions.STOP_LOADING
805
- });
806
- return;
807
516
  }
808
- const uploadedFiles = uploadResponse.data;
809
- console.log("Files uploaded successfully:", uploadedFiles == null ? void 0 : uploadedFiles.length);
810
- if (uploadResponse.data) {
811
- const files2 = (_a2 = uploadedFiles == null ? void 0 : uploadedFiles.map((f) => f.id)) != null ? _a2 : null;
812
- console.log("File IDs for message:", files2);
813
- console.log("Sending message with attached files");
814
- const result = await sendThreadMessage({
815
- variables: {
816
- postId,
817
- channelId,
818
- postThreadId: safeContextProperty("postThread") && ((_b2 = safeContextProperty("postThread")) == null ? void 0 : _b2.id),
819
- postParentId: !parentId || parentId == 0 ? null : parentId,
820
- threadMessageInput: {
821
- content: messageContent,
822
- files: files2,
823
- role
824
- }
825
- },
826
- update: (cache, {
827
- data: data2,
828
- errors
829
- }) => {
830
- var _a3, _b3, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2;
831
- console.log("Send message with file update callback - data:", data2, "errors:", errors);
832
- if (!data2 || errors) {
833
- console.error("Send message with file failed:", errors);
834
- safeSend({
835
- type: Actions.STOP_LOADING
836
- });
837
- return;
838
- }
839
- console.log("Message with file sent successfully:", (_a3 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _a3.lastMessage);
840
- const newMessage = (_b3 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _b3.lastMessage;
841
- safeSend({
842
- type: "SEND_THREAD_MESSAGE_WITH_FILE_SUCCESS",
843
- data: {
844
- message: newMessage,
845
- messageText: ""
846
- }
847
- });
848
- if (!parentId || parentId == 0) {
849
- console.log("Setting new parentId:", (_d2 = (_c2 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _c2.lastMessage) == null ? void 0 : _d2.id);
850
- setParentId((_f2 = (_e2 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _e2.lastMessage) == null ? void 0 : _f2.id);
851
- }
852
- setChannelToTop(channelToTop + 1);
853
- const lastMessageId = (_h2 = (_g2 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _g2.lastMessage) == null ? void 0 : _h2.id;
854
- sendPushNotification(lastMessageId, channelId, parentId, (_j2 = (_i2 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _i2.data) == null ? void 0 : _j2.id);
855
- }
856
- });
857
- console.log("Send with file mutation result:", result);
858
- }
859
- } catch (error) {
860
- console.error("Error sending message with file:", error);
861
- safeSend({
862
- type: "ERROR",
863
- data: {
864
- message: error.message || "Failed to send message with file"
865
- }
866
- });
517
+ setErrorMessage(formattedErrorMessage);
518
+ setChannelMessages((oldMessages) => oldMessages.filter((msg2) => msg2.id !== postId));
519
+ removeMessageFromUI(postId);
520
+ } finally {
521
+ setLoading(false);
522
+ setIsUploadingImage(false);
523
+ setUploadingMessageId(null);
867
524
  }
868
- }, [channelId, parentId, state.context, role, startUpload]);
525
+ }, [auth, channelId, channelToTop, images, parentId, postThread, selectedImage, setChannelMessages, removeMessageFromUI, role]);
869
526
  const sendPushNotification = async (messageId, channelId2, parentId2, threadId) => {
870
527
  var _a2;
871
528
  const notificationData = {
@@ -894,167 +551,90 @@ const ThreadConversationViewComponent = ({
894
551
  }
895
552
  };
896
553
  const messageList = useMemo(() => {
897
- const threadMessages = safeContextProperty("threadMessages", []);
898
- if (__DEV__)
899
- console.log(`Creating message list from ${threadMessages.length} thread messages`);
900
- if (!(threadMessages == null ? void 0 : threadMessages.length))
901
- return [];
902
- const messageIds = /* @__PURE__ */ new Set();
903
- const res = threadMessages.filter((msg) => {
904
- if (!msg.id || messageIds.has(msg.id))
905
- return false;
906
- messageIds.add(msg.id);
907
- return true;
908
- }).map((msg) => {
909
- var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2;
910
- const uniqueId = msg.id || `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
911
- let messageDate;
912
- try {
913
- if (msg.createdAt && !isNaN(new Date(msg.createdAt).getTime())) {
914
- messageDate = new Date(msg.createdAt);
915
- } else {
916
- messageDate = new Date();
917
- }
918
- } catch (error) {
919
- messageDate = new Date();
920
- }
921
- let imageUrl = null;
922
- if (((_a2 = msg.files) == null ? void 0 : _a2.data) && msg.files.data.length > 0) {
923
- const fileData = msg.files.data[0];
924
- if (fileData && fileData.url) {
925
- imageUrl = fileData.url;
554
+ let res = [];
555
+ const filteredMessages = channelMessages && (channelMessages == null ? void 0 : channelMessages.length) > 0 ? uniqBy([...channelMessages], ({
556
+ id
557
+ }) => id) : [];
558
+ if (filteredMessages == null ? void 0 : filteredMessages.length) {
559
+ orderBy(filteredMessages, ["createdAt"], ["desc"]).map((msg2) => {
560
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2, _o2, _p2;
561
+ let message = {
562
+ _id: "",
563
+ text: "",
564
+ createdAt: 0,
565
+ user: {
566
+ _id: "",
567
+ name: "",
568
+ avatar: ""
569
+ },
570
+ type: ""
571
+ };
572
+ const date = new Date(msg2.createdAt);
573
+ message._id = msg2.id;
574
+ message.text = msg2.message;
575
+ message.createdAt = date;
576
+ message.user = {
577
+ _id: (_c2 = (_a2 = msg2 == null ? void 0 : msg2.author) == null ? void 0 : _a2.id) != null ? _c2 : (_b2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _b2.id,
578
+ name: (_i2 = (_g2 = (_d2 = msg2 == null ? void 0 : msg2.author) == null ? void 0 : _d2.givenName) != null ? _g2 : ((_e2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _e2.given_name) + " " + ((_f2 = msg2 == null ? void 0 : msg2.author) == null ? void 0 : _f2.familyName)) != null ? _i2 : (_h2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _h2.family_name,
579
+ avatar: (_l2 = (_j2 = msg2 == null ? void 0 : msg2.author) == null ? void 0 : _j2.picture) != null ? _l2 : (_k2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _k2.picture
580
+ };
581
+ message.isOptimistic = (msg2 == null ? void 0 : msg2.isOptimistic) || false;
582
+ message.isUploading = ((_n2 = (_m2 = msg2.files) == null ? void 0 : _m2.data) == null ? void 0 : _n2.some((file) => file.isUploading)) || false;
583
+ if (((_p2 = (_o2 = msg2.files) == null ? void 0 : _o2.data) == null ? void 0 : _p2.length) > 0) {
584
+ const validFiles = msg2.files.data.filter((file) => file && (file.url || file.localUri) && typeof (file.url || file.localUri) === "string");
585
+ if (validFiles.length > 0) {
586
+ const firstFile = validFiles[0];
587
+ const imageUrl = firstFile.isUploading ? firstFile.localUri || firstFile.url : firstFile.url || firstFile.localUri;
588
+ if (imageUrl) {
589
+ message.image = imageUrl;
590
+ }
591
+ if (validFiles.length > 1) {
592
+ message.images = validFiles.map((file) => file.isUploading ? file.localUri || file.url : file.url || file.localUri).filter((url) => !!url);
593
+ if (message.images.length === 0) {
594
+ delete message.images;
595
+ }
596
+ }
597
+ }
926
598
  }
927
- }
928
- let messageText = msg.message || "";
929
- return {
930
- _id: uniqueId,
931
- text: messageText,
932
- createdAt: messageDate,
933
- user: {
934
- _id: (_d2 = (_b2 = msg == null ? void 0 : msg.author) == null ? void 0 : _b2.id) != null ? _d2 : (_c2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _c2.id,
935
- name: (_j2 = (_h2 = (_e2 = msg == null ? void 0 : msg.author) == null ? void 0 : _e2.givenName) != null ? _h2 : ((_f2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _f2.given_name) + " " + ((_g2 = msg == null ? void 0 : msg.author) == null ? void 0 : _g2.familyName)) != null ? _j2 : (_i2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _i2.family_name,
936
- avatar: (_m2 = (_k2 = msg == null ? void 0 : msg.author) == null ? void 0 : _k2.picture) != null ? _m2 : (_l2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _l2.picture
937
- },
938
- type: (msg == null ? void 0 : msg.type) || "",
939
- image: imageUrl,
940
- sent: (msg == null ? void 0 : msg.isDelivered) || true,
941
- received: (msg == null ? void 0 : msg.isRead) || false,
942
- propsConfiguration: msg == null ? void 0 : msg.propsConfiguration
943
- };
944
- });
945
- return orderBy(res, [(msg) => {
946
- try {
947
- return msg.createdAt instanceof Date ? msg.createdAt.getTime() : new Date().getTime();
948
- } catch (error) {
949
- return 0;
950
- }
951
- }], ["desc"]);
952
- }, [safeContextProperty("threadMessages"), auth]);
599
+ message.sent = msg2 == null ? void 0 : msg2.isDelivered;
600
+ message.received = msg2 == null ? void 0 : msg2.isRead;
601
+ message.type = msg2 == null ? void 0 : msg2.type;
602
+ message.propsConfiguration = msg2 == null ? void 0 : msg2.propsConfiguration;
603
+ res.push(message);
604
+ });
605
+ }
606
+ return (res == null ? void 0 : res.length) > 0 ? uniqBy([...res], ({
607
+ _id
608
+ }) => _id) : [];
609
+ }, [channelMessages]);
953
610
  const renderSend = useCallback((props) => {
954
- const hasImage = safeContextProperty("selectedImage", "") !== "";
955
- const isDisabled = !hasImage && (!props.text || props.text.trim().length === 0);
956
- return /* @__PURE__ */ React__default.createElement(Send, __spreadProps(__spreadValues({}, props), { containerStyle: {
957
- alignItems: "center",
958
- justifyContent: "center",
959
- marginHorizontal: 4,
960
- marginBottom: 0
961
- }, disabled: isDisabled }), /* @__PURE__ */ React__default.createElement(Box, { style: {
962
- width: 32,
963
- height: 32,
964
- alignItems: "center",
965
- justifyContent: "center"
966
- } }, /* @__PURE__ */ React__default.createElement(MaterialCommunityIcons, { name: "send-circle", size: 30, color: isDisabled ? colors.gray[400] : colors.blue[500] })));
967
- }, [safeContextProperty]);
968
- const renderActions = useCallback((props) => {
611
+ if (isActionSheetVisible) {
612
+ return null;
613
+ }
614
+ const hasContent = !!props.text || (images == null ? void 0 : images.length) > 0;
615
+ const canSend = channelId && hasContent;
616
+ const isDisabled = !canSend || isUploadingImage || loading;
969
617
  return /* @__PURE__ */ React__default.createElement(
970
- Actions$1,
618
+ Send,
971
619
  __spreadProps(__spreadValues({}, props), {
972
- options: {
973
- ["Choose from Library"]: onSelectImages,
974
- ["Cancel"]: () => {
975
- }
976
- },
977
- optionTintColor: "#000000",
978
- cancelButtonIndex: 1,
979
- icon: () => /* @__PURE__ */ React__default.createElement(Box, { style: {
980
- width: 32,
981
- height: 32,
982
- alignItems: "center",
983
- justifyContent: "center"
984
- } }, /* @__PURE__ */ React__default.createElement(Ionicons, { name: "image", size: 24, color: colors.blue[500] })),
620
+ disabled: isDisabled,
985
621
  containerStyle: {
986
- alignItems: "center",
987
622
  justifyContent: "center",
988
- marginLeft: 8,
989
- marginBottom: 0
623
+ alignItems: "center",
624
+ height: 40,
625
+ width: 44,
626
+ marginRight: 4,
627
+ marginBottom: 0,
628
+ marginLeft: 4
990
629
  }
991
- })
630
+ }),
631
+ /* @__PURE__ */ React__default.createElement(View, { style: {
632
+ padding: 4
633
+ } }, isUploadingImage || loading ? /* @__PURE__ */ React__default.createElement(Spinner, { size: "small", color: colors.blue[500] }) : /* @__PURE__ */ React__default.createElement(MaterialCommunityIcons, { name: "send-circle", size: 32, color: isDisabled ? colors.gray[400] : colors.blue[500] }))
992
634
  );
993
- }, [onSelectImages]);
994
- const renderAccessory = useCallback((props) => {
995
- var _a2, _b2;
996
- const selectedImage2 = safeContextProperty("selectedImage", "");
997
- if (!selectedImage2) {
998
- return null;
999
- }
1000
- return /* @__PURE__ */ React__default.createElement(View, { style: {
1001
- height: 80,
1002
- padding: 10,
1003
- backgroundColor: "white",
1004
- borderTopWidth: 1,
1005
- borderTopColor: "#e0e0e0",
1006
- flexDirection: "row",
1007
- alignItems: "center"
1008
- } }, /* @__PURE__ */ React__default.createElement(View, { style: {
1009
- flex: 1,
1010
- flexDirection: "row",
1011
- alignItems: "center",
1012
- paddingHorizontal: 20
1013
- } }, /* @__PURE__ */ React__default.createElement(Image, { key: (_a2 = state == null ? void 0 : state.context) == null ? void 0 : _a2.selectedImage, alt: "selected image", source: {
1014
- uri: (_b2 = state == null ? void 0 : state.context) == null ? void 0 : _b2.selectedImage
1015
- }, size: "xs", style: {
1016
- width: 5,
1017
- height: 5,
1018
- borderRadius: 5,
1019
- marginRight: 20
1020
- } }), /* @__PURE__ */ React__default.createElement(TouchableHighlight, { underlayColor: "#dddddd", onPress: () => safeSend({
1021
- type: Actions.CLEAR_IMAGE
1022
- }), style: {
1023
- backgroundColor: "#f44336",
1024
- paddingVertical: 2,
1025
- paddingHorizontal: 5,
1026
- borderRadius: 5,
1027
- marginLeft: 10,
1028
- elevation: 3,
1029
- shadowColor: "#000",
1030
- shadowOffset: {
1031
- width: 0,
1032
- height: 1
1033
- },
1034
- shadowOpacity: 0.3,
1035
- shadowRadius: 2
1036
- } }, /* @__PURE__ */ React__default.createElement(Text, { style: {
1037
- color: "white",
1038
- fontWeight: "bold"
1039
- } }, "X"))));
1040
- }, [(_a = state == null ? void 0 : state.context) == null ? void 0 : _a.selectedImage, safeSend]);
1041
- const renderInputToolbar = useCallback((props) => {
1042
- return /* @__PURE__ */ React__default.createElement(InputToolbar, __spreadProps(__spreadValues({}, props), { containerStyle: {
1043
- backgroundColor: "white",
1044
- borderTopWidth: 1,
1045
- borderTopColor: colors.gray[200],
1046
- paddingHorizontal: 4,
1047
- paddingVertical: 4
1048
- }, primaryStyle: {
1049
- alignItems: "center"
1050
- } }));
1051
- }, []);
1052
- const setImageViewerObject = (obj, v) => {
1053
- setImageObject(obj);
1054
- setImageViewer(v);
1055
- };
1056
- const renderMessageText = useCallback((props) => {
1057
- var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2, _o2, _p2, _q2, _r2, _s2, _t2, _u2, _v, _w, _x, _y;
635
+ }, [channelId, images, isUploadingImage, loading, isActionSheetVisible]);
636
+ useCallback((props) => {
637
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2, _o2, _p2, _q2, _r2, _s2, _t, _u, _v, _w, _x, _y;
1058
638
  const {
1059
639
  currentMessage
1060
640
  } = props;
@@ -1075,8 +655,8 @@ const ThreadConversationViewComponent = ({
1075
655
  path = ((_l2 = route == null ? void 0 : route.host) == null ? void 0 : _l2.name) ? (_n2 = (_m2 = route == null ? void 0 : route.host) == null ? void 0 : _m2.name) != null ? _n2 : null : null;
1076
656
  param = ((_o2 = route == null ? void 0 : route.host) == null ? void 0 : _o2.params) ? (_q2 = (_p2 = route == null ? void 0 : route.host) == null ? void 0 : _p2.params) != null ? _q2 : null : null;
1077
657
  } else {
1078
- path = ((_r2 = route == null ? void 0 : route.host) == null ? void 0 : _r2.name) ? (_t2 = (_s2 = route == null ? void 0 : route.host) == null ? void 0 : _s2.name) != null ? _t2 : null : null;
1079
- param = ((_u2 = route == null ? void 0 : route.host) == null ? void 0 : _u2.params) ? (_w = (_v = route == null ? void 0 : route.host) == null ? void 0 : _v.params) != null ? _w : null : null;
658
+ path = ((_r2 = route == null ? void 0 : route.host) == null ? void 0 : _r2.name) ? (_t = (_s2 = route == null ? void 0 : route.host) == null ? void 0 : _s2.name) != null ? _t : null : null;
659
+ param = ((_u = route == null ? void 0 : route.host) == null ? void 0 : _u.params) ? (_w = (_v = route == null ? void 0 : route.host) == null ? void 0 : _v.params) != null ? _w : null : null;
1080
660
  }
1081
661
  action = path;
1082
662
  params2 = __spreadValues({}, param);
@@ -1098,8 +678,6 @@ const ThreadConversationViewComponent = ({
1098
678
  marginLeft: 5
1099
679
  }
1100
680
  } })));
1101
- } else if (currentMessage.text === "\u{1F4CE} File attachment") {
1102
- return null;
1103
681
  } else {
1104
682
  return /* @__PURE__ */ React__default.createElement(MessageText, __spreadProps(__spreadValues({}, props), { textStyle: {
1105
683
  left: {
@@ -1107,13 +685,223 @@ const ThreadConversationViewComponent = ({
1107
685
  }
1108
686
  } }));
1109
687
  }
1110
- }, [role, navigation]);
1111
- const renderMessage = useCallback((props) => {
1112
- return /* @__PURE__ */ React__default.createElement(Message, __spreadProps(__spreadValues({}, props), { isShowImageViewer, setImageViewer: setImageViewerObject }));
1113
- }, [isShowImageViewer, setImageViewerObject]);
1114
- const modalContent = React__default.useMemo(() => {
1115
- if (!imageObject)
1116
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null);
688
+ }, [navigation, role]);
689
+ const renderMessageText = useCallback((props) => {
690
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2, _o2, _p2, _q2, _r2, _s2, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U;
691
+ const {
692
+ currentMessage
693
+ } = props;
694
+ const lastReply = ((_b2 = (_a2 = currentMessage == null ? void 0 : currentMessage.replies) == null ? void 0 : _a2.data) == null ? void 0 : _b2.length) > 0 ? (_d2 = (_c2 = currentMessage == null ? void 0 : currentMessage.replies) == null ? void 0 : _c2.data) == null ? void 0 : _d2[0] : null;
695
+ if (!(currentMessage == null ? void 0 : currentMessage.text) || currentMessage.text.trim() === "") {
696
+ return null;
697
+ }
698
+ if (currentMessage.type === "ALERT") {
699
+ const attachment = (_f2 = (_e2 = currentMessage == null ? void 0 : currentMessage.propsConfiguration) == null ? void 0 : _e2.contents) == null ? void 0 : _f2.attachment;
700
+ let action = "";
701
+ let actionId = "";
702
+ let params2 = {};
703
+ if ((_g2 = attachment == null ? void 0 : attachment.callToAction) == null ? void 0 : _g2.extraParams) {
704
+ const extraParams = (_h2 = attachment == null ? void 0 : attachment.callToAction) == null ? void 0 : _h2.extraParams;
705
+ const route = (_i2 = extraParams == null ? void 0 : extraParams.route) != null ? _i2 : null;
706
+ let path = null;
707
+ let param = null;
708
+ if (role && role == PreDefinedRole.Guest) {
709
+ path = ((_j2 = route == null ? void 0 : route.guest) == null ? void 0 : _j2.name) ? (_l2 = (_k2 = route == null ? void 0 : route.guest) == null ? void 0 : _k2.name) != null ? _l2 : null : null;
710
+ param = ((_m2 = route == null ? void 0 : route.guest) == null ? void 0 : _m2.params) ? (_o2 = (_n2 = route == null ? void 0 : route.guest) == null ? void 0 : _n2.params) != null ? _o2 : null : null;
711
+ } else if (role && role == PreDefinedRole.Owner) {
712
+ path = ((_p2 = route == null ? void 0 : route.host) == null ? void 0 : _p2.name) ? (_r2 = (_q2 = route == null ? void 0 : route.host) == null ? void 0 : _q2.name) != null ? _r2 : null : null;
713
+ param = ((_s2 = route == null ? void 0 : route.host) == null ? void 0 : _s2.params) ? (_u = (_t = route == null ? void 0 : route.host) == null ? void 0 : _t.params) != null ? _u : null : null;
714
+ } else {
715
+ path = ((_v = route == null ? void 0 : route.host) == null ? void 0 : _v.name) ? (_x = (_w = route == null ? void 0 : route.host) == null ? void 0 : _w.name) != null ? _x : null : null;
716
+ param = ((_y = route == null ? void 0 : route.host) == null ? void 0 : _y.params) ? (_A = (_z = route == null ? void 0 : route.host) == null ? void 0 : _z.params) != null ? _A : null : null;
717
+ }
718
+ action = path;
719
+ params2 = __spreadValues({}, param);
720
+ } else if ((_B = attachment == null ? void 0 : attachment.callToAction) == null ? void 0 : _B.link) {
721
+ action = CALL_TO_ACTION_PATH;
722
+ actionId = (_C = attachment == null ? void 0 : attachment.callToAction) == null ? void 0 : _C.link.split("/").pop();
723
+ params2 = {
724
+ reservationId: actionId
725
+ };
726
+ }
727
+ return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, (attachment == null ? void 0 : attachment.callToAction) && action ? /* @__PURE__ */ React__default.createElement(Box, { className: `bg-[${CALL_TO_ACTION_BOX_BGCOLOR}] rounded-[15] pb-2` }, /* @__PURE__ */ React__default.createElement(Button, { variant: "outline", size: "sm", className: `border-[${CALL_TO_ACTION_BUTTON_BORDERCOLOR}]`, onPress: () => action && params2 && navigation.navigate(action, params2) }, /* @__PURE__ */ React__default.createElement(ButtonText, { className: `color-[${CALL_TO_ACTION_TEXT_COLOR}]` }, attachment.callToAction.title)), /* @__PURE__ */ React__default.createElement(MessageText, __spreadProps(__spreadValues({}, props), { textStyle: {
728
+ left: {
729
+ marginLeft: 5,
730
+ color: CALL_TO_ACTION_TEXT_COLOR,
731
+ paddingHorizontal: 2
732
+ }
733
+ } }))) : /* @__PURE__ */ React__default.createElement(TouchableHighlight, { underlayColor: "#c0c0c0", style: {
734
+ width: "100%"
735
+ }, onPress: () => {
736
+ if (currentMessage == null ? void 0 : currentMessage.isShowThreadMessage) navigation.navigate(config.THREAD_MESSEGE_PATH, {
737
+ channelId,
738
+ title: "Message",
739
+ postParentId: currentMessage == null ? void 0 : currentMessage._id,
740
+ isPostParentIdThread: true
741
+ });
742
+ } }, /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(MessageText, __spreadProps(__spreadValues({}, props), { textStyle: {
743
+ left: {
744
+ marginLeft: 5
745
+ }
746
+ } })), ((_E = (_D = currentMessage == null ? void 0 : currentMessage.replies) == null ? void 0 : _D.data) == null ? void 0 : _E.length) > 0 && /* @__PURE__ */ React__default.createElement(HStack, { space: "sm", className: "px-1 items-center" }, /* @__PURE__ */ React__default.createElement(HStack, null, (_J = (_I = (_H = (_G = (_F = currentMessage == null ? void 0 : currentMessage.replies) == null ? void 0 : _F.data) == null ? void 0 : _G.filter((v, i, a) => a.findIndex((t) => {
747
+ var _a3, _b3;
748
+ return ((_a3 = t == null ? void 0 : t.author) == null ? void 0 : _a3.id) === ((_b3 = v == null ? void 0 : v.author) == null ? void 0 : _b3.id);
749
+ }) === i)) == null ? void 0 : _H.slice(0, 2)) == null ? void 0 : _I.reverse()) == null ? void 0 : _J.map((p, i) => {
750
+ var _a3, _b3, _c3;
751
+ return /* @__PURE__ */ React__default.createElement(Avatar, { key: "conversations-view-key-" + i, size: "sm", className: "bg-transparent" }, /* @__PURE__ */ React__default.createElement(AvatarFallbackText, null, startCase((_b3 = (_a3 = p == null ? void 0 : p.author) == null ? void 0 : _a3.username) == null ? void 0 : _b3.charAt(0))), /* @__PURE__ */ React__default.createElement(AvatarImage, { alt: "user image", style: {
752
+ borderRadius: 6,
753
+ borderWidth: 2,
754
+ borderColor: "#fff"
755
+ }, source: {
756
+ uri: (_c3 = p == null ? void 0 : p.author) == null ? void 0 : _c3.picture
757
+ } }));
758
+ })), /* @__PURE__ */ React__default.createElement(Text, { style: {
759
+ fontSize: 12
760
+ }, className: "font-bold color-blue-800" }, (_K = currentMessage == null ? void 0 : currentMessage.replies) == null ? void 0 : _K.totalCount, " ", ((_L = currentMessage == null ? void 0 : currentMessage.replies) == null ? void 0 : _L.totalCount) == 1 ? "reply" : "replies"), /* @__PURE__ */ React__default.createElement(Text, { style: {
761
+ fontSize: 12
762
+ }, className: "font-bold color-gray-500" }, lastReply ? createdAtText(lastReply == null ? void 0 : lastReply.createdAt) : "")))));
763
+ } else {
764
+ return /* @__PURE__ */ React__default.createElement(TouchableHighlight, { underlayColor: "#c0c0c0", style: {
765
+ width: "100%"
766
+ }, onPress: () => {
767
+ if (currentMessage == null ? void 0 : currentMessage.isShowThreadMessage) navigation.navigate(config.THREAD_MESSEGE_PATH, {
768
+ channelId,
769
+ title: "Message",
770
+ postParentId: currentMessage == null ? void 0 : currentMessage._id,
771
+ isPostParentIdThread: true
772
+ });
773
+ } }, /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(MessageText, __spreadProps(__spreadValues({}, props), { textStyle: {
774
+ left: {
775
+ marginLeft: 5
776
+ }
777
+ } })), ((_N = (_M = currentMessage == null ? void 0 : currentMessage.replies) == null ? void 0 : _M.data) == null ? void 0 : _N.length) > 0 && /* @__PURE__ */ React__default.createElement(HStack, { space: "sm", className: "px-1 items-center" }, /* @__PURE__ */ React__default.createElement(HStack, null, (_S = (_R = (_Q = (_P = (_O = currentMessage == null ? void 0 : currentMessage.replies) == null ? void 0 : _O.data) == null ? void 0 : _P.filter((v, i, a) => a.findIndex((t) => {
778
+ var _a3, _b3;
779
+ return ((_a3 = t == null ? void 0 : t.author) == null ? void 0 : _a3.id) === ((_b3 = v == null ? void 0 : v.author) == null ? void 0 : _b3.id);
780
+ }) === i)) == null ? void 0 : _Q.slice(0, 2)) == null ? void 0 : _R.reverse()) == null ? void 0 : _S.map((p, i) => {
781
+ var _a3, _b3, _c3;
782
+ return /* @__PURE__ */ React__default.createElement(Avatar, { key: "conversation-replies-key-" + i, className: "bg-transparent", size: "sm" }, /* @__PURE__ */ React__default.createElement(AvatarFallbackText, null, startCase((_b3 = (_a3 = p == null ? void 0 : p.author) == null ? void 0 : _a3.username) == null ? void 0 : _b3.charAt(0))), /* @__PURE__ */ React__default.createElement(AvatarImage, { alt: "user image", style: {
783
+ borderRadius: 6,
784
+ borderWidth: 2,
785
+ borderColor: "#fff"
786
+ }, source: {
787
+ uri: (_c3 = p == null ? void 0 : p.author) == null ? void 0 : _c3.picture
788
+ } }));
789
+ })), /* @__PURE__ */ React__default.createElement(Text, { style: {
790
+ fontSize: 12
791
+ }, className: "font-bold color-blue-800" }, (_T = currentMessage == null ? void 0 : currentMessage.replies) == null ? void 0 : _T.totalCount, " ", ((_U = currentMessage == null ? void 0 : currentMessage.replies) == null ? void 0 : _U.totalCount) == 1 ? "reply" : "replies"), /* @__PURE__ */ React__default.createElement(Text, { style: {
792
+ fontSize: 12
793
+ }, className: "font-bold color-gray-500" }, lastReply ? createdAtText(lastReply == null ? void 0 : lastReply.createdAt) : ""))));
794
+ }
795
+ }, [navigation, channelId, role]);
796
+ useCallback((props) => {
797
+ return /* @__PURE__ */ React__default.createElement(
798
+ Actions,
799
+ __spreadProps(__spreadValues({}, props), {
800
+ onPressActionButton: onSelectImages,
801
+ options: {
802
+ ["Choose from Library"]: () => {
803
+ onSelectImages();
804
+ },
805
+ ["Cancel"]: () => {
806
+ }
807
+ // Add this option to make the sheet dismissible
808
+ },
809
+ optionTintColor: "#000000",
810
+ cancelButtonIndex: 1,
811
+ icon: () => /* @__PURE__ */ React__default.createElement(Box, { className: "w-8 h-8 items-center justify-center" }, /* @__PURE__ */ React__default.createElement(Ionicons, { name: "image", size: 24, color: colors.blue[500] })),
812
+ containerStyle: {
813
+ alignItems: "center",
814
+ justifyContent: "center",
815
+ marginLeft: 8,
816
+ marginBottom: 0
817
+ }
818
+ })
819
+ );
820
+ }, [onSelectImages]);
821
+ useCallback(() => {
822
+ if (!images.length) return null;
823
+ return /* @__PURE__ */ React__default.createElement(Box, { style: {
824
+ position: "relative",
825
+ height: 70,
826
+ backgroundColor: "transparent",
827
+ justifyContent: "center"
828
+ } }, /* @__PURE__ */ React__default.createElement(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, style: {
829
+ flexDirection: "row",
830
+ paddingLeft: 15,
831
+ paddingRight: 5
832
+ }, contentContainerStyle: {
833
+ alignItems: "center",
834
+ height: "100%"
835
+ } }, images.map((img, index) => /* @__PURE__ */ React__default.createElement(View, { key: `image-preview-${index}`, style: {
836
+ width: 40,
837
+ height: 40,
838
+ marginRight: 15,
839
+ borderRadius: 4,
840
+ backgroundColor: colors.gray[200],
841
+ overflow: "hidden",
842
+ borderWidth: 1,
843
+ borderColor: "#e0e0e0",
844
+ position: "relative",
845
+ zIndex: 10
846
+ } }, /* @__PURE__ */ React__default.createElement(Image, { alt: `selected image ${index + 1}`, source: {
847
+ uri: img.uri || img.url
848
+ }, style: {
849
+ width: "100%",
850
+ height: "100%"
851
+ }, size: "md" }), /* @__PURE__ */ React__default.createElement(TouchableOpacity, { onPress: () => {
852
+ const newImages = [...images];
853
+ newImages.splice(index, 1);
854
+ setImages(newImages);
855
+ if (newImages.length === 0) {
856
+ setSelectedImage("");
857
+ }
858
+ }, style: {
859
+ position: "absolute",
860
+ top: -1,
861
+ right: -1,
862
+ backgroundColor: "rgba(0,0,0,0.6)",
863
+ borderRadius: 12,
864
+ width: 20,
865
+ height: 20,
866
+ alignItems: "center",
867
+ justifyContent: "center",
868
+ zIndex: 9999
869
+ } }, /* @__PURE__ */ React__default.createElement(Ionicons, { name: "close", size: 16, color: "white" }))))));
870
+ }, [images]);
871
+ useCallback((props) => /* @__PURE__ */ React__default.createElement(TouchableOpacity, { style: {
872
+ flexDirection: "row",
873
+ alignItems: "center",
874
+ backgroundColor: "#fff",
875
+ minHeight: 48,
876
+ maxHeight: 48,
877
+ paddingHorizontal: 12,
878
+ paddingVertical: 0,
879
+ marginHorizontal: 8,
880
+ flex: 1
881
+ }, activeOpacity: 0.7, onPress: () => {
882
+ setActionSheetVisible(true);
883
+ } }, /* @__PURE__ */ React__default.createElement(TouchableOpacity, { onPress: (e) => {
884
+ e.stopPropagation();
885
+ onSelectImages();
886
+ }, style: {
887
+ width: 25,
888
+ height: 25,
889
+ borderRadius: 20,
890
+ backgroundColor: "#f5f5f5",
891
+ alignItems: "center",
892
+ justifyContent: "center",
893
+ marginRight: 8
894
+ } }, /* @__PURE__ */ React__default.createElement(MaterialIcons, { name: "add", size: 20, color: "#888" })), /* @__PURE__ */ React__default.createElement(Text, { style: {
895
+ fontSize: 16,
896
+ color: msg ? colors.gray[800] : colors.gray[400],
897
+ flex: 1
898
+ }, numberOfLines: 1, ellipsizeMode: "tail" }, msg ? msg : "Jot something down")), [msg, onSelectImages]);
899
+ const setImageViewerObject = useCallback((obj, v) => {
900
+ setImageObject(obj);
901
+ setImageViewer(v);
902
+ }, []);
903
+ const modalContent = useMemo(() => {
904
+ if (!imageObject) return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null);
1117
905
  const {
1118
906
  image,
1119
907
  _id
@@ -1126,521 +914,189 @@ const ThreadConversationViewComponent = ({
1126
914
  expiresIn: 86400
1127
915
  }, alt: "image" });
1128
916
  }, [imageObject]);
1129
- const currentMessageText = useMemo(() => {
1130
- const text = safeContextProperty("messageText", "") || " ";
1131
- return text;
1132
- }, [safeContextProperty("messageText")]);
1133
- const forceLoadMessages = useCallback((skipValue) => {
1134
- console.log(`Force loading messages with explicit skip=${skipValue}, limit=50`);
1135
- if (channelId && parentId) {
1136
- safeSend({
1137
- type: Actions.START_LOADING,
1138
- data: {
1139
- loading: true
1140
- }
1141
- });
1142
- getThreadMessages({
1143
- variables: {
1144
- channelId: channelId == null ? void 0 : channelId.toString(),
1145
- role: role == null ? void 0 : role.toString(),
1146
- postParentId: !parentId || parentId == 0 ? null : parentId == null ? void 0 : parentId.toString(),
1147
- selectedFields: "id channel post replies replyCount lastReplyAt createdAt updatedAt",
1148
- skip: skipValue,
1149
- limit: 50
1150
- }
1151
- }).then(({
1152
- data: data2
1153
- }) => {
1154
- var _a2, _b2, _c2;
1155
- if (data2 == null ? void 0 : data2.getPostThread) {
1156
- const threads = data2.getPostThread;
1157
- const threadPost = (_a2 = threads == null ? void 0 : threads.post) != null ? _a2 : [];
1158
- const threadReplies = (_b2 = threads == null ? void 0 : threads.replies) != null ? _b2 : [];
1159
- const messageTotalCount = (_c2 = threads == null ? void 0 : threads.replyCount) != null ? _c2 : 0;
1160
- const messages = [...threadReplies];
1161
- console.log(`Force load with skip=${skipValue} complete. Got ${messages.length} messages of ${messageTotalCount} total`);
1162
- safeSend({
1163
- type: Actions.SET_THREAD_MESSAGES,
1164
- data: {
1165
- messages,
1166
- totalCount: messageTotalCount,
1167
- threadPost,
1168
- postThread: threads
1169
- }
1170
- });
1171
- }
1172
- }).catch((error) => {
1173
- console.error("Error during force load:", error);
1174
- safeSend({
1175
- type: "ERROR",
1176
- data: {
1177
- message: error.message
1178
- }
1179
- });
1180
- });
1181
- }
1182
- }, [channelId, parentId, getThreadMessages, safeSend]);
1183
- const onFetchOld = useCallback(() => {
1184
- const totalCount = safeContextProperty("totalCount", 0);
1185
- const threadMessages = safeContextProperty("threadMessages", []);
1186
- const isLoading = safeContextProperty("loadingOldMessages", false);
1187
- if (totalCount <= threadMessages.length || isLoading) {
1188
- if (isLoading) {
1189
- safeSend({
1190
- type: Actions.STOP_LOADING,
1191
- data: {
1192
- loadingOldMessages: false
1193
- }
1194
- });
1195
- }
1196
- if (__DEV__)
1197
- console.log("No more messages to load or already loading");
1198
- return;
1199
- }
1200
- if (__DEV__)
1201
- console.log("Loading more messages - current count:", threadMessages.length, "of", totalCount);
1202
- safeSend({
1203
- type: Actions.FETCH_MORE_MESSAGES,
1204
- data: {
1205
- loadingOldMessages: true
1206
- }
917
+ useCallback((props) => {
918
+ const {
919
+ currentMessage
920
+ } = props;
921
+ const customProps = __spreadProps(__spreadValues({}, props), {
922
+ isShowImageViewer,
923
+ setImageViewer: setImageViewerObject,
924
+ // Pass custom flags to indicate uploading/optimistic states
925
+ isUploading: currentMessage.isUploading || false,
926
+ isOptimistic: currentMessage.isOptimistic || false
1207
927
  });
1208
- if (__DEV__)
1209
- console.log("Using proven approach: Skip=0, Limit=50");
1210
- const queryVariables = {
1211
- channelId: channelId == null ? void 0 : channelId.toString(),
1212
- role: role == null ? void 0 : role.toString(),
1213
- postParentId: !parentId || parentId == 0 ? null : parentId == null ? void 0 : parentId.toString(),
1214
- selectedFields: "id channel post replies replyCount lastReplyAt createdAt updatedAt",
1215
- limit: 50,
1216
- skip: 0
1217
- };
1218
- if (__DEV__)
1219
- console.log("Query variables:", JSON.stringify(queryVariables));
1220
- fetchMoreMessages({
1221
- variables: queryVariables
1222
- }).then((res) => {
1223
- var _a2, _b2, _c2, _d2;
1224
- if (__DEV__)
1225
- console.log("API response received with status:", res ? "success" : "empty");
1226
- if ((_a2 = res == null ? void 0 : res.data) == null ? void 0 : _a2.getPostThread) {
1227
- const threads = (_b2 = res == null ? void 0 : res.data) == null ? void 0 : _b2.getPostThread;
1228
- const threadReplies = (_c2 = threads == null ? void 0 : threads.replies) != null ? _c2 : [];
1229
- const actualTotalCount = (_d2 = threads == null ? void 0 : threads.replyCount) != null ? _d2 : 0;
1230
- if (__DEV__) {
1231
- console.log("API response details:");
1232
- console.log("- replyCount:", threads == null ? void 0 : threads.replyCount);
1233
- console.log("- replies array length:", threadReplies.length);
1234
- }
1235
- if (threadReplies.length > 0) {
1236
- const existingIds = new Set(threadMessages.map((msg) => msg.id));
1237
- const newUniqueMessages = threadReplies.filter((msg) => !existingIds.has(msg.id));
1238
- if (__DEV__)
1239
- console.log(`Found ${newUniqueMessages.length} unique new messages out of ${threadReplies.length} received`);
1240
- if (newUniqueMessages.length === 0) {
1241
- if (__DEV__)
1242
- console.log("No new unique messages found, adjusting total count");
1243
- registerLoadAttemptResult(false);
1244
- safeSend({
1245
- type: Actions.SET_THREAD_MESSAGES,
1246
- data: {
1247
- messages: threadMessages,
1248
- totalCount: threadMessages.length,
1249
- threadPost: safeContextProperty("threadPost", []),
1250
- postThread: safeContextProperty("postThread", null)
1251
- }
1252
- });
1253
- return;
1254
- }
1255
- registerLoadAttemptResult(true);
1256
- if (__DEV__)
1257
- console.log(`Adding ${newUniqueMessages.length} new messages to thread`);
1258
- safeSend({
1259
- type: "FETCH_MORE_MESSAGES_SUCCESS",
1260
- data: {
1261
- messages: newUniqueMessages,
1262
- totalCount: actualTotalCount,
1263
- loadingOldMessages: false
1264
- }
1265
- });
1266
- } else {
1267
- if (__DEV__)
1268
- console.log("No thread replies returned when loading more messages");
1269
- registerLoadAttemptResult(false);
1270
- safeSend({
1271
- type: Actions.SET_THREAD_MESSAGES,
1272
- data: {
1273
- messages: threadMessages,
1274
- totalCount: threadMessages.length,
1275
- threadPost: safeContextProperty("threadPost", []),
1276
- postThread: safeContextProperty("postThread", null)
1277
- }
1278
- });
1279
- }
1280
- } else {
1281
- if (__DEV__)
1282
- console.log("No thread data returned when loading more messages");
1283
- registerLoadAttemptResult(false);
1284
- safeSend({
1285
- type: Actions.STOP_LOADING,
1286
- data: {
1287
- loadingOldMessages: false
1288
- }
1289
- });
1290
- }
1291
- }).catch((error) => {
1292
- console.error("Error fetching more messages:", error);
1293
- registerLoadAttemptResult(false);
1294
- safeSend({
1295
- type: "ERROR",
1296
- data: {
1297
- message: error.message,
1298
- loadingOldMessages: false
928
+ return /* @__PURE__ */ React__default.createElement(Message, __spreadValues({}, customProps));
929
+ }, [isShowImageViewer, setImageViewerObject]);
930
+ const renderMessage = useCallback((props) => {
931
+ return /* @__PURE__ */ React__default.createElement(Message, __spreadProps(__spreadValues({}, props), { isShowImageViewer, setImageViewer: setImageViewerObject }));
932
+ }, [isShowImageViewer]);
933
+ useCallback((props) => {
934
+ if (isActionSheetVisible) return null;
935
+ return /* @__PURE__ */ React__default.createElement(
936
+ InputToolbar,
937
+ __spreadProps(__spreadValues({}, props), {
938
+ containerStyle: {
939
+ backgroundColor: "transparent",
940
+ padding: 0,
941
+ margin: 0,
942
+ borderTopWidth: 1,
943
+ borderTopColor: colors.gray[200]
944
+ },
945
+ primaryStyle: {
946
+ alignItems: "center",
947
+ justifyContent: "center",
948
+ flex: 1
1299
949
  }
1300
- });
1301
- });
1302
- }, [parentId, channelId, role, safeContextProperty, safeSend, fetchMoreMessages, registerLoadAttemptResult]);
1303
- return /* @__PURE__ */ React__default.createElement(SafeAreaView, { style: {
1304
- flex: 1
1305
- } }, safeContextProperty("loadingOldMessages", false) === true && /* @__PURE__ */ React__default.createElement(Box, { className: "absolute top-10 left-0 right-0 z-10 items-center" }, /* @__PURE__ */ React__default.createElement(Box, { className: "bg-blue-500/20 rounded-full px-4 py-2 flex-row items-center" }, /* @__PURE__ */ React__default.createElement(Spinner, { color: colors.blue[500], size: "small" }), /* @__PURE__ */ React__default.createElement(Text, { className: "text-sm font-medium color-blue-600 ml-2" }, "Loading messages..."))), !safeContextProperty("loadingOldMessages", false) && safeContextProperty("totalCount", 0) > safeContextProperty("threadMessages", []).length && /* @__PURE__ */ React__default.createElement(Box, { className: "absolute top-10 left-0 right-0 z-10 items-center" }, /* @__PURE__ */ React__default.createElement(HStack, { space: 2, className: "px-2" }, /* @__PURE__ */ React__default.createElement(TouchableHighlight, { onPress: () => {
1306
- console.log("Manual load more pressed");
1307
- Alert.alert("Load Options", "Choose loading method", [{
1308
- text: "Normal Load",
1309
- onPress: () => safeSend({
1310
- type: Actions.FETCH_MORE_MESSAGES
1311
950
  })
1312
- }, {
1313
- text: "Try Skip=0",
1314
- onPress: () => forceLoadMessages(0)
1315
- }, {
1316
- text: "Try Skip=0, Limit=50",
1317
- onPress: () => {
1318
- console.log("Force loading with explicit skip=0, limit=50");
1319
- safeSend({
1320
- type: Actions.START_LOADING,
1321
- data: {
1322
- loadingOldMessages: true
1323
- }
1324
- });
1325
- fetchMoreMessages({
1326
- variables: {
1327
- channelId: channelId == null ? void 0 : channelId.toString(),
1328
- role: role == null ? void 0 : role.toString(),
1329
- postParentId: !parentId || parentId == 0 ? null : parentId == null ? void 0 : parentId.toString(),
1330
- selectedFields: "id channel post replies replyCount lastReplyAt createdAt updatedAt",
1331
- limit: 50,
1332
- skip: 0
1333
- }
1334
- }).then((res) => {
1335
- var _a2, _b2, _c2, _d2;
1336
- console.log("LARGE LIMIT response:", JSON.stringify(res == null ? void 0 : res.data, null, 2));
1337
- if ((_a2 = res == null ? void 0 : res.data) == null ? void 0 : _a2.getPostThread) {
1338
- const threads = (_b2 = res == null ? void 0 : res.data) == null ? void 0 : _b2.getPostThread;
1339
- const threadReplies = (_c2 = threads == null ? void 0 : threads.replies) != null ? _c2 : [];
1340
- const actualTotalCount = (_d2 = threads == null ? void 0 : threads.replyCount) != null ? _d2 : 0;
1341
- console.log(`Large limit load complete. Got ${threadReplies.length} messages of ${actualTotalCount} total`);
1342
- if (threadReplies.length > 0) {
1343
- safeSend({
1344
- type: Actions.SET_THREAD_MESSAGES,
1345
- data: {
1346
- messages: threadReplies,
1347
- totalCount: actualTotalCount,
1348
- threadPost: safeContextProperty("threadPost", []),
1349
- postThread: threads
1350
- }
1351
- });
1352
- } else {
1353
- safeSend({
1354
- type: Actions.SET_THREAD_MESSAGES,
1355
- data: {
1356
- messages: safeContextProperty("threadMessages", []),
1357
- totalCount: safeContextProperty("threadMessages", []).length,
1358
- threadPost: safeContextProperty("threadPost", []),
1359
- postThread: safeContextProperty("postThread", null)
1360
- }
1361
- });
1362
- }
1363
- } else {
1364
- safeSend({
1365
- type: Actions.STOP_LOADING,
1366
- data: {
1367
- loadingOldMessages: false
1368
- }
1369
- });
1370
- }
1371
- }).catch((error) => {
1372
- console.error("Error in large limit load:", error);
1373
- safeSend({
1374
- type: Actions.STOP_LOADING,
1375
- data: {
1376
- loadingOldMessages: false
1377
- }
1378
- });
1379
- });
1380
- }
1381
- }, {
1382
- text: "Try Direct Fetch",
1383
- onPress: () => {
1384
- const currentCount = safeContextProperty("threadMessages", []).length;
1385
- const totalCount = safeContextProperty("totalCount", 0);
1386
- const missingCount = totalCount - currentCount;
1387
- if (missingCount <= 0) {
1388
- Alert.alert("Info", "No missing messages to fetch");
1389
- return;
1390
- }
1391
- console.log(`Attempting direct fetch of missing ${missingCount} messages`);
1392
- safeSend({
1393
- type: Actions.START_LOADING,
1394
- data: {
1395
- loadingOldMessages: true
1396
- }
1397
- });
1398
- getThreadMessages({
1399
- variables: {
1400
- channelId: channelId == null ? void 0 : channelId.toString(),
1401
- role: role == null ? void 0 : role.toString(),
1402
- postParentId: !parentId || parentId == 0 ? null : parentId == null ? void 0 : parentId.toString(),
1403
- selectedFields: "id channel post replies replyCount lastReplyAt createdAt updatedAt",
1404
- limit: missingCount,
1405
- skip: 0
1406
- }
1407
- }).then(({
1408
- data: data2
1409
- }) => {
1410
- var _a2, _b2;
1411
- console.log("DIRECT FETCH response:", JSON.stringify(data2, null, 2));
1412
- if (data2 == null ? void 0 : data2.getPostThread) {
1413
- const threads = data2.getPostThread;
1414
- const threadReplies = (_a2 = threads == null ? void 0 : threads.replies) != null ? _a2 : [];
1415
- const actualTotalCount = (_b2 = threads == null ? void 0 : threads.replyCount) != null ? _b2 : 0;
1416
- console.log(`Direct fetch complete. Got ${threadReplies.length} messages of ${actualTotalCount} total`);
1417
- console.log("Message IDs:", threadReplies.map((msg) => msg.id).join(", "));
1418
- const existingIds = new Set(safeContextProperty("threadMessages", []).map((msg) => msg.id));
1419
- const newMessages = threadReplies.filter((msg) => !existingIds.has(msg.id));
1420
- console.log(`Found ${newMessages.length} new messages that we didn't have before`);
1421
- if (newMessages.length > 0) {
1422
- safeSend({
1423
- type: "FETCH_MORE_MESSAGES_SUCCESS",
1424
- data: {
1425
- messages: newMessages,
1426
- totalCount: actualTotalCount,
1427
- loadingOldMessages: false
1428
- }
1429
- });
1430
- Alert.alert("Success", `Found ${newMessages.length} new messages`);
1431
- } else {
1432
- console.log("No new messages found, adjusting count");
1433
- safeSend({
1434
- type: Actions.SET_THREAD_MESSAGES,
1435
- data: {
1436
- messages: safeContextProperty("threadMessages", []),
1437
- totalCount: safeContextProperty("threadMessages", []).length,
1438
- threadPost: safeContextProperty("threadPost", []),
1439
- postThread: safeContextProperty("postThread", null)
1440
- }
1441
- });
1442
- Alert.alert("Info", "No new messages found. Count has been adjusted.");
1443
- }
1444
- } else {
1445
- Alert.alert("Error", "Could not fetch thread messages");
1446
- safeSend({
1447
- type: Actions.STOP_LOADING,
1448
- data: {
1449
- loadingOldMessages: false
1450
- }
1451
- });
1452
- }
1453
- }).catch((error) => {
1454
- console.error("Error in direct fetch:", error);
1455
- Alert.alert("Error", "Failed to fetch messages: " + error.message);
1456
- safeSend({
1457
- type: Actions.STOP_LOADING,
1458
- data: {
1459
- loadingOldMessages: false
1460
- }
1461
- });
951
+ );
952
+ }, [isActionSheetVisible, onSelectImages]);
953
+ const renderLoadEarlier = useCallback(() => {
954
+ return loadingOldMessages && !refreshing ? /* @__PURE__ */ React__default.createElement(Box, { style: {
955
+ padding: 10,
956
+ backgroundColor: "rgba(255,255,255,0.8)",
957
+ borderRadius: 10,
958
+ marginTop: 10,
959
+ alignItems: "center"
960
+ } }, /* @__PURE__ */ React__default.createElement(Spinner, { size: "small", color: colors.blue[500] }), /* @__PURE__ */ React__default.createElement(Text, { style: {
961
+ fontSize: 12,
962
+ color: colors.gray[600],
963
+ marginTop: 4
964
+ } }, "Loading earlier messages...")) : null;
965
+ }, [loadingOldMessages, refreshing]);
966
+ let onScroll = false;
967
+ const onMomentumScrollBegin = ({
968
+ nativeEvent
969
+ }) => {
970
+ onScroll = true;
971
+ if (!loadingOldMessages && isCloseToTop(nativeEvent) && totalCount > (channelMessages == null ? void 0 : channelMessages.length)) {
972
+ onFetchOld();
973
+ }
974
+ };
975
+ const onEndReached = () => {
976
+ if (!onScroll) return;
977
+ onScroll = false;
978
+ };
979
+ const renderChatFooter = useCallback(() => {
980
+ return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(ImageViewerModal, { isVisible: isShowImageViewer, setVisible: setImageViewer, modalContent }), /* @__PURE__ */ React__default.createElement(SubscriptionHandler, { channelId, subscribeToNewMessages: () => subscribeToMore({
981
+ document: CHAT_MESSAGE_ADDED,
982
+ variables: {
983
+ channelId: channelId == null ? void 0 : channelId.toString(),
984
+ postParentId: !parentId || parentId == 0 ? null : parentId == null ? void 0 : parentId.toString()
985
+ },
986
+ updateQuery: (prev, {
987
+ subscriptionData
988
+ }) => {
989
+ var _a2, _b2, _c2;
990
+ if (!subscriptionData.data) return prev;
991
+ const newMessage = (_a2 = subscriptionData == null ? void 0 : subscriptionData.data) == null ? void 0 : _a2.threadChatMessageAdded;
992
+ const prevReplyCount = (_b2 = prev == null ? void 0 : prev.getPostThread) == null ? void 0 : _b2.replyCount;
993
+ const newReplyCount = prevReplyCount || 0 + 1;
994
+ const replies = ((_c2 = prev == null ? void 0 : prev.getPostThread) == null ? void 0 : _c2.replies) || [];
995
+ setChannelMessages((oldMessages) => uniqBy([...oldMessages, newMessage], ({
996
+ id
997
+ }) => id));
998
+ setTotalCount(newReplyCount);
999
+ return Object.assign({}, prev, {
1000
+ getPostThread: __spreadProps(__spreadValues({}, prev == null ? void 0 : prev.getPostThread), {
1001
+ lastReplyAt: newMessage.createdAt,
1002
+ replies: [newMessage, ...replies],
1003
+ replyCount: newReplyCount,
1004
+ updatedAt: newMessage.createdAt
1005
+ })
1462
1006
  });
1463
1007
  }
1464
- }, {
1465
- text: "Reset Count",
1466
- style: "destructive",
1467
- onPress: () => {
1468
- console.log("Resetting message count to match reality");
1469
- safeSend({
1470
- type: Actions.SET_THREAD_MESSAGES,
1471
- data: {
1472
- messages: safeContextProperty("threadMessages", []),
1473
- totalCount: safeContextProperty("threadMessages", []).length,
1474
- threadPost: safeContextProperty("threadPost", []),
1475
- postThread: safeContextProperty("postThread", null)
1476
- }
1477
- });
1008
+ }) }));
1009
+ }, [channelId, isShowImageViewer, modalContent, parentId, setImageViewer, subscribeToMore]);
1010
+ const handleRemoveImage = useCallback((index) => {
1011
+ const newImages = [...images];
1012
+ newImages.splice(index, 1);
1013
+ setImages(newImages);
1014
+ if (newImages.length === 0) {
1015
+ setSelectedImage("");
1016
+ if (textInputRef.current && typeof textInputRef.current.focus === "function") {
1017
+ textInputRef.current.focus();
1478
1018
  }
1479
- }, {
1480
- text: "Cancel",
1481
- style: "cancel"
1482
- }]);
1483
- }, underlayColor: "#e6e6e6" }, /* @__PURE__ */ React__default.createElement(Box, { className: "bg-gray-200 rounded-full px-4 py-2 flex-row items-center" }, /* @__PURE__ */ React__default.createElement(MaterialIcons, { name: "arrow-upward", size: 16, color: colors.blue[500] }), /* @__PURE__ */ React__default.createElement(Text, { className: "text-sm font-medium color-blue-600 ml-2" }, "Load More (", safeContextProperty("totalCount", 0) - safeContextProperty("threadMessages", []).length, ")"))), /* @__PURE__ */ React__default.createElement(TouchableHighlight, { onPress: forceRefreshMessages, underlayColor: "#e6e6e6" }, /* @__PURE__ */ React__default.createElement(Box, { className: "bg-gray-200 rounded-full px-4 py-2 flex-row items-center" }, /* @__PURE__ */ React__default.createElement(MaterialIcons, { name: "refresh", size: 16, color: colors.blue[500] }), /* @__PURE__ */ React__default.createElement(Text, { className: "text-sm font-medium color-blue-600 ml-2" }, "Refresh All"))))), isPostParentIdThread && /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, ((_b = safeContextProperty("threadPost", [])) == null ? void 0 : _b.length) > 0 && /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(VStack, { className: "px-2 pt-2 pb-0", space: "sm" }, /* @__PURE__ */ React__default.createElement(HStack, { space: "sm", className: "items-center" }, /* @__PURE__ */ React__default.createElement(Avatar, { className: "bg-transparent", size: "md" }, /* @__PURE__ */ React__default.createElement(AvatarFallbackText, null, startCase((_e = (_d = (_c = safeContextProperty("threadPost")[0]) == null ? void 0 : _c.author) == null ? void 0 : _d.username) == null ? void 0 : _e.charAt(0))), /* @__PURE__ */ React__default.createElement(AvatarImage, { alt: "image", style: {
1019
+ }
1020
+ }, [images]);
1021
+ return /* @__PURE__ */ React__default.createElement(View, { style: {
1022
+ flex: 1,
1023
+ marginTop: -40
1024
+ } }, errorMessage ? /* @__PURE__ */ React__default.createElement(ErrorNotification, { message: errorMessage, onClose: () => setErrorMessage("") }) : null, loading && /* @__PURE__ */ React__default.createElement(Spinner, { color: "#3b82f6" }), isPostParentIdThread && /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, (threadPost == null ? void 0 : threadPost.length) > 0 && /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(VStack, { className: "px-2 pt-2 pb-0", space: "sm" }, /* @__PURE__ */ React__default.createElement(HStack, { space: "sm", className: "items-center" }, /* @__PURE__ */ React__default.createElement(Avatar, { className: "bg-transparent", size: "md" }, /* @__PURE__ */ React__default.createElement(AvatarFallbackText, null, startCase((_c = (_b = (_a = threadPost[0]) == null ? void 0 : _a.author) == null ? void 0 : _b.username) == null ? void 0 : _c.charAt(0))), /* @__PURE__ */ React__default.createElement(AvatarImage, { alt: "image", style: {
1484
1025
  borderRadius: 6,
1485
1026
  borderWidth: 2,
1486
1027
  borderColor: "#fff"
1487
1028
  }, source: {
1488
- uri: (_g = (_f = safeContextProperty("threadPost")[0]) == null ? void 0 : _f.author) == null ? void 0 : _g.picture
1489
- } })), /* @__PURE__ */ React__default.createElement(Box, null, /* @__PURE__ */ React__default.createElement(Text, { className: "font-bold color-black" }, (_j = (_i = (_h = safeContextProperty("threadPost")[0]) == null ? void 0 : _h.author) == null ? void 0 : _i.givenName) != null ? _j : "", " ", (_m = (_l = (_k = safeContextProperty("threadPost")[0]) == null ? void 0 : _k.author) == null ? void 0 : _l.familyName) != null ? _m : ""), /* @__PURE__ */ React__default.createElement(Text, { className: "pl-0 color-gray-500" }, createdAtText((_n = safeContextProperty("threadPost")[0]) == null ? void 0 : _n.createdAt), " at", " ", (() => {
1490
- var _a2;
1491
- try {
1492
- const createdAt = (_a2 = safeContextProperty("threadPost")[0]) == null ? void 0 : _a2.createdAt;
1493
- if (createdAt && !isNaN(new Date(createdAt).getTime())) {
1494
- return format(new Date(createdAt), "hh:mm:a");
1495
- } else {
1496
- return "unknown time";
1497
- }
1498
- } catch (error) {
1499
- console.error("Error formatting thread post time:", error);
1500
- return "unknown time";
1501
- }
1502
- })()))), /* @__PURE__ */ React__default.createElement(HStack, { space: "sm", className: "px-2 items-center" }, /* @__PURE__ */ React__default.createElement(Text, null, (_p = (_o = safeContextProperty("threadPost")[0]) == null ? void 0 : _o.message) != null ? _p : ""))), /* @__PURE__ */ React__default.createElement(Box, { className: "py-4" }, /* @__PURE__ */ React__default.createElement(Box, { className: "px-4 py-2 border-t border-b border-gray-200" }, /* @__PURE__ */ React__default.createElement(Text, { className: "font-bold color-gray-600" }, (_r = (_q = safeContextProperty("threadPost")[0]) == null ? void 0 : _q.replies) == null ? void 0 : _r.totalCount, " ", ((_t = (_s = safeContextProperty("threadPost")[0]) == null ? void 0 : _s.replies) == null ? void 0 : _t.totalCount) > 0 ? "replies" : "reply"))))), /* @__PURE__ */ React__default.createElement(GiftedChat, { ref: threadMessageListRef, wrapInSafeArea: false, renderLoading: () => /* @__PURE__ */ React__default.createElement(Spinner, { color: colors.blue[500] }), messages: messageList, listViewProps: {
1503
- onScroll: handleScrollToTop,
1504
- onEndReached: handleEndReached,
1505
- onEndReachedThreshold: 0.2,
1506
- contentContainerStyle: {
1507
- paddingBottom: 10
1508
- },
1509
- maintainVisibleContentPosition: {
1510
- minIndexForVisible: 0,
1511
- autoscrollToTopThreshold: 100
1512
- },
1513
- scrollEventThrottle: 16,
1514
- keyboardDismissMode: "on-drag",
1515
- keyboardShouldPersistTaps: "handled"
1516
- }, onSend: (messages) => {
1517
- var _a2, _b2;
1518
- if (!messages || messages.length === 0) {
1519
- console.log("No messages to send");
1520
- return;
1521
- }
1522
- const currentInputText = currentMessageText;
1523
- const messageToSend = (currentInputText == null ? void 0 : currentInputText.trim()) || ((_b2 = (_a2 = messages[0]) == null ? void 0 : _a2.text) == null ? void 0 : _b2.trim()) || " ";
1524
- if (__DEV__)
1525
- console.log("GiftedChat onSend triggered with text from state:", messageToSend);
1526
- safeSend({
1527
- type: Actions.SET_MESSAGE_TEXT,
1528
- data: {
1529
- messageText: ""
1530
- }
1531
- });
1532
- if (safeContextProperty("images", []).length > 0) {
1533
- if (__DEV__)
1534
- console.log("Sending message with file:", messageToSend, "Images:", safeContextProperty("images", []).length);
1535
- safeSend({
1536
- type: Actions.SEND_THREAD_MESSAGE_WITH_FILE,
1537
- data: {
1538
- messageText: messageToSend
1539
- }
1540
- });
1541
- } else {
1542
- if (__DEV__)
1543
- console.log("Sending text message:", messageToSend);
1544
- safeSend({
1545
- type: Actions.SEND_THREAD_MESSAGE,
1546
- data: {
1547
- messageText: messageToSend
1548
- }
1549
- });
1550
- }
1551
- }, text: currentMessageText, onInputTextChanged: (text) => {
1552
- safeSend({
1553
- type: Actions.SET_MESSAGE_TEXT,
1554
- data: {
1555
- messageText: text
1556
- }
1557
- });
1558
- }, renderFooter: () => safeContextProperty("loading", false) && !safeContextProperty("loadingOldMessages", false) ? /* @__PURE__ */ React__default.createElement(Box, { className: "w-full py-2 items-center" }, /* @__PURE__ */ React__default.createElement(Spinner, { color: colors.blue[500] })) : safeContextProperty("imageLoading", false) ? /* @__PURE__ */ React__default.createElement(Box, { className: "w-full py-2 items-center" }, /* @__PURE__ */ React__default.createElement(Spinner, { color: colors.blue[500] })) : /* @__PURE__ */ React__default.createElement(React__default.Fragment, null), scrollToBottom: true, loadEarlier: false, isLoadingEarlier: false, user: {
1559
- _id: (auth == null ? void 0 : auth.id) || ""
1560
- }, isTyping: safeContextProperty("loading", false), alwaysShowSend: safeContextProperty("loading", false) ? false : true, infiniteScroll: true, renderSend, renderInputToolbar, minInputToolbarHeight: 50, renderActions, renderAccessory: !!((_u = state == null ? void 0 : state.context) == null ? void 0 : _u.selectedImage) ? renderAccessory : void 0, renderMessage, renderMessageText, maxInputLength: 1e3, placeholder: "Type a message...", showUserAvatar: true, showAvatarForEveryMessage: false, inverted: true, parsePatterns: (linkStyle) => [{
1561
- type: "url",
1562
- style: __spreadProps(__spreadValues({}, linkStyle), {
1563
- color: colors.blue[500]
1564
- }),
1565
- onPress: (url) => Linking.openURL(url)
1566
- }, {
1567
- type: "phone",
1568
- style: __spreadProps(__spreadValues({}, linkStyle), {
1569
- color: colors.blue[500]
1570
- }),
1571
- onPress: (phone) => Linking.openURL(`tel:${phone}`)
1572
- }, {
1573
- type: "email",
1574
- style: __spreadProps(__spreadValues({}, linkStyle), {
1575
- color: colors.blue[500]
1576
- }),
1577
- onPress: (email) => Linking.openURL(`mailto:${email}`)
1578
- }], textInputProps: {
1579
- style: {
1580
- borderWidth: 1,
1581
- borderColor: colors.gray[300],
1582
- backgroundColor: "#f8f8f8",
1583
- borderRadius: 20,
1584
- minHeight: 40,
1585
- maxHeight: 80,
1586
- color: "#000",
1587
- padding: 10,
1588
- paddingHorizontal: 20,
1589
- fontSize: 16,
1590
- flex: 1
1591
- },
1592
- multiline: true,
1593
- returnKeyType: "default",
1594
- enablesReturnKeyAutomatically: true,
1595
- placeholderTextColor: colors.gray[400]
1596
- }, minComposerHeight: 44, isKeyboardInternallyHandled: true, bottomOffset: Platform.OS === "ios" ? 20 : 0, renderChatFooter: () => /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(ImageViewerModal, { isVisible: isShowImageViewer, setVisible: setImageViewer, modalContent }), /* @__PURE__ */ React__default.createElement(SubscriptionHandler, { channelId, subscribeToNewMessages: () => subscribeToMore({
1597
- document: OnThreadChatMessageAddedDocument,
1598
- variables: {
1599
- channelId: channelId == null ? void 0 : channelId.toString(),
1600
- postParentId: !parentId || parentId == 0 ? null : parentId == null ? void 0 : parentId.toString()
1601
- },
1602
- updateQuery: (prev, {
1603
- subscriptionData
1604
- }) => {
1605
- var _a2, _b2, _c2;
1606
- if (!subscriptionData.data)
1607
- return prev;
1608
- const newMessage = (_a2 = subscriptionData == null ? void 0 : subscriptionData.data) == null ? void 0 : _a2.threadChatMessageAdded;
1609
- const prevReplyCount = (_b2 = prev == null ? void 0 : prev.getPostThread) == null ? void 0 : _b2.replyCount;
1610
- const newReplyCount = (prevReplyCount || 0) + 1;
1611
- const replies = ((_c2 = prev == null ? void 0 : prev.getPostThread) == null ? void 0 : _c2.replies) || [];
1612
- safeSend({
1613
- type: Actions.SET_THREAD_MESSAGES,
1614
- data: {
1615
- messages: uniqBy([...safeContextProperty("threadMessages", []), newMessage], ({
1616
- id
1617
- }) => id),
1618
- totalCount: newReplyCount,
1619
- threadPost: safeContextProperty("threadPost", []),
1620
- postThread: safeContextProperty("postThread", null)
1621
- }
1622
- });
1623
- return Object.assign({}, prev, {
1624
- getPostThread: __spreadProps(__spreadValues({}, prev == null ? void 0 : prev.getPostThread), {
1625
- lastReplyAt: newMessage.createdAt,
1626
- replies: [newMessage, ...replies],
1627
- replyCount: newReplyCount,
1628
- updatedAt: newMessage.createdAt
1629
- })
1630
- });
1029
+ uri: (_e = (_d = threadPost[0]) == null ? void 0 : _d.author) == null ? void 0 : _e.picture
1030
+ } })), /* @__PURE__ */ React__default.createElement(Box, null, /* @__PURE__ */ React__default.createElement(Text, { className: "font-bold color-black" }, (_h = (_g = (_f = threadPost[0]) == null ? void 0 : _f.author) == null ? void 0 : _g.givenName) != null ? _h : "", " ", (_k = (_j = (_i = threadPost[0]) == null ? void 0 : _i.author) == null ? void 0 : _j.familyName) != null ? _k : ""), /* @__PURE__ */ React__default.createElement(Text, { className: "pl-0 color-gray-500" }, createdAtText((_l = threadPost[0]) == null ? void 0 : _l.createdAt), " at", " ", format(new Date((_m = threadPost[0]) == null ? void 0 : _m.createdAt), "hh:ss:a")))), /* @__PURE__ */ React__default.createElement(HStack, { space: "sm", className: "px-2 items-center" }, /* @__PURE__ */ React__default.createElement(Text, null, (_o = (_n = threadPost[0]) == null ? void 0 : _n.message) != null ? _o : ""))), /* @__PURE__ */ React__default.createElement(Box, { className: "py-4" }, /* @__PURE__ */ React__default.createElement(Box, { className: "px-4 py-2 border-t border-b border-gray-200" }, /* @__PURE__ */ React__default.createElement(Text, { className: "font-bold color-gray-600" }, (_q = (_p = threadPost[0]) == null ? void 0 : _p.replies) == null ? void 0 : _q.totalCount, " ", ((_s = (_r = threadPost[0]) == null ? void 0 : _r.replies) == null ? void 0 : _s.totalCount) > 0 ? "replies" : "reply"))))), /* @__PURE__ */ React__default.createElement(
1031
+ GiftedChatInboxComponent,
1032
+ {
1033
+ ref: threadMessageListRef,
1034
+ onRemoveImage: handleRemoveImage,
1035
+ images,
1036
+ onSelectImages,
1037
+ selectedImage,
1038
+ setSelectedImage,
1039
+ isUploadingImage,
1040
+ loading,
1041
+ wrapInSafeArea: true,
1042
+ inverted: true,
1043
+ renderLoading: () => /* @__PURE__ */ React__default.createElement(Skeleton, { variant: "rounded", style: {
1044
+ flex: 1
1045
+ } }),
1046
+ messages: messageList,
1047
+ listViewProps: {
1048
+ onEndReached,
1049
+ onEndReachedThreshold: 0.5,
1050
+ onMomentumScrollBegin,
1051
+ style: {
1052
+ marginTop: 0
1053
+ },
1054
+ contentContainerStyle: {
1055
+ paddingTop: 0,
1056
+ paddingBottom: selectedImage ? 90 : 0
1057
+ },
1058
+ refreshControl: /* @__PURE__ */ React__default.createElement(RefreshControl, { refreshing, onRefresh, colors: [colors.blue[500]], tintColor: colors.blue[500], title: "Loading earlier messages...", titleColor: colors.gray[600] })
1059
+ },
1060
+ onSend: (messages) => {
1061
+ var _a2, _b2;
1062
+ return handleSend((_b2 = (_a2 = messages[0]) == null ? void 0 : _a2.text) != null ? _b2 : " ");
1063
+ },
1064
+ text: msg || " ",
1065
+ onInputTextChanged: (text) => setMsg(text),
1066
+ renderFooter: () => null,
1067
+ scrollToBottom: true,
1068
+ user: {
1069
+ _id: (auth == null ? void 0 : auth.id) || ""
1070
+ },
1071
+ placeholder: "Jot something down",
1072
+ infiniteScroll: true,
1073
+ renderSend,
1074
+ renderMessageText,
1075
+ renderMessage,
1076
+ renderLoadEarlier,
1077
+ loadEarlier: totalCount > channelMessages.length,
1078
+ isLoadingEarlier: loadingOldMessages,
1079
+ textInputProps: {
1080
+ multiline: true,
1081
+ returnKeyType: "default",
1082
+ enablesReturnKeyAutomatically: true,
1083
+ placeholderTextColor: colors.gray[400],
1084
+ // Allow direct editing in the main input too for better UX
1085
+ editable: true,
1086
+ onFocus: () => setIsGiftedInputFocused(true),
1087
+ onBlur: () => setIsGiftedInputFocused(false)
1088
+ },
1089
+ renderChatFooter,
1090
+ messagesContainerStyle: __spreadProps(__spreadValues({}, (messageList == null ? void 0 : messageList.length) == 0 ? {
1091
+ transform: [{
1092
+ scaleY: -1
1093
+ }]
1094
+ } : {}), {
1095
+ // marginTop: -40, // Negative margin to remove the top padding
1096
+ paddingTop: 0
1097
+ })
1631
1098
  }
1632
- }) })), messagesContainerStyle: (messageList == null ? void 0 : messageList.length) == 0 ? {
1633
- transform: [{
1634
- scaleY: -1
1635
- }]
1636
- } : void 0, renderChatEmpty: () => /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, !threadLoading && messageList && (messageList == null ? void 0 : messageList.length) == 0 && /* @__PURE__ */ React__default.createElement(Box, { className: "p-5" }, /* @__PURE__ */ React__default.createElement(Center, { className: "mt-6" }, /* @__PURE__ */ React__default.createElement(Ionicons, { name: "chatbubbles", size: 30 }), /* @__PURE__ */ React__default.createElement(Text, null, "You don't have any message yet!")))), lightboxProps: {
1637
- underlayColor: "transparent",
1638
- springConfig: {
1639
- tension: 9e4,
1640
- friction: 9e4
1641
- },
1642
- disabled: true
1643
- } }));
1099
+ ));
1644
1100
  };
1645
1101
  const SubscriptionHandler = ({
1646
1102
  subscribeToNewMessages,
@@ -1649,4 +1105,4 @@ const SubscriptionHandler = ({
1649
1105
  useEffect(() => subscribeToNewMessages(), [channelId]);
1650
1106
  return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null);
1651
1107
  };
1652
- const ThreadConversationView = React__default.memo(ThreadConversationViewComponent);export{ThreadConversationView};//# sourceMappingURL=ThreadConversationView.js.map
1108
+ const ThreadConversationView = ThreadConversationViewComponent;export{ThreadConversationView};//# sourceMappingURL=ThreadConversationView.js.map