@messenger-box/platform-mobile 10.0.3-alpha.7 → 10.0.3-alpha.72

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 (98) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/lib/compute.js +2 -3
  3. package/lib/compute.js.map +1 -1
  4. package/lib/index.js.map +1 -1
  5. package/lib/queries/inboxQueries.js +65 -0
  6. package/lib/queries/inboxQueries.js.map +1 -0
  7. package/lib/routes.json +2 -3
  8. package/lib/screens/inbox/DialogMessages.js +1 -1
  9. package/lib/screens/inbox/DialogMessages.js.map +1 -1
  10. package/lib/screens/inbox/DialogThreadMessages.js +4 -8
  11. package/lib/screens/inbox/DialogThreadMessages.js.map +1 -1
  12. package/lib/screens/inbox/DialogThreads.js +57 -12
  13. package/lib/screens/inbox/DialogThreads.js.map +1 -1
  14. package/lib/screens/inbox/Inbox.js +1 -1
  15. package/lib/screens/inbox/Inbox.js.map +1 -1
  16. package/lib/screens/inbox/components/CachedImage/consts.js +1 -1
  17. package/lib/screens/inbox/components/CachedImage/consts.js.map +1 -1
  18. package/lib/screens/inbox/components/CachedImage/index.js +168 -46
  19. package/lib/screens/inbox/components/CachedImage/index.js.map +1 -1
  20. package/lib/screens/inbox/components/DialogItem.js +169 -0
  21. package/lib/screens/inbox/components/DialogItem.js.map +1 -0
  22. package/lib/screens/inbox/components/GiftedChatInboxComponent.js +313 -0
  23. package/lib/screens/inbox/components/GiftedChatInboxComponent.js.map +1 -0
  24. package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js +147 -31
  25. package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js.map +1 -1
  26. package/lib/screens/inbox/components/SlackMessageContainer/SlackMessage.js +6 -1
  27. package/lib/screens/inbox/components/SlackMessageContainer/SlackMessage.js.map +1 -1
  28. package/lib/screens/inbox/components/SubscriptionHandler.js +24 -0
  29. package/lib/screens/inbox/components/SubscriptionHandler.js.map +1 -0
  30. package/lib/screens/inbox/components/ThreadsViewItem.js +66 -55
  31. package/lib/screens/inbox/components/ThreadsViewItem.js.map +1 -1
  32. package/lib/screens/inbox/config/config.js +2 -2
  33. package/lib/screens/inbox/config/config.js.map +1 -1
  34. package/lib/screens/inbox/containers/ConversationView.js +1111 -434
  35. package/lib/screens/inbox/containers/ConversationView.js.map +1 -1
  36. package/lib/screens/inbox/containers/Dialogs.js +193 -80
  37. package/lib/screens/inbox/containers/Dialogs.js.map +1 -1
  38. package/lib/screens/inbox/containers/ThreadConversationView.js +725 -216
  39. package/lib/screens/inbox/containers/ThreadConversationView.js.map +1 -1
  40. package/lib/screens/inbox/containers/ThreadsView.js +83 -50
  41. package/lib/screens/inbox/containers/ThreadsView.js.map +1 -1
  42. package/lib/screens/inbox/hooks/useInboxMessages.js +31 -0
  43. package/lib/screens/inbox/hooks/useInboxMessages.js.map +1 -0
  44. package/lib/screens/inbox/hooks/useSafeDialogThreadsMachine.js +108 -0
  45. package/lib/screens/inbox/hooks/useSafeDialogThreadsMachine.js.map +1 -0
  46. package/lib/screens/inbox/workflow/dialog-threads-xstate.js +151 -0
  47. package/lib/screens/inbox/workflow/dialog-threads-xstate.js.map +1 -0
  48. package/package.json +4 -4
  49. package/src/compute.ts +5 -6
  50. package/src/index.ts +2 -0
  51. package/src/navigation/InboxNavigation.tsx +3 -3
  52. package/src/queries/inboxQueries.ts +299 -0
  53. package/src/queries/index.d.ts +2 -0
  54. package/src/queries/index.ts +1 -0
  55. package/src/screens/inbox/DialogMessages.tsx +1 -1
  56. package/src/screens/inbox/DialogThreadMessages.tsx +7 -14
  57. package/src/screens/inbox/DialogThreads.tsx +55 -61
  58. package/src/screens/inbox/Inbox.tsx +1 -1
  59. package/src/screens/inbox/components/Actionsheet.tsx +30 -0
  60. package/src/screens/inbox/components/CachedImage/consts.ts +4 -3
  61. package/src/screens/inbox/components/CachedImage/index.tsx +232 -61
  62. package/src/screens/inbox/components/DialogItem.tsx +306 -0
  63. package/src/screens/inbox/components/DialogsHeader.tsx +6 -13
  64. package/src/screens/inbox/components/DialogsListItem.tsx +262 -198
  65. package/src/screens/inbox/components/ExpandableInput.tsx +460 -0
  66. package/src/screens/inbox/components/ExpandableInputActionSheet.tsx +518 -0
  67. package/src/screens/inbox/components/GiftedChatInboxComponent.tsx +411 -0
  68. package/src/screens/inbox/components/ServiceDialogsListItem.tsx +337 -194
  69. package/src/screens/inbox/components/SlackInput.tsx +23 -0
  70. package/src/screens/inbox/components/SlackMessageContainer/SlackBubble.tsx +233 -23
  71. package/src/screens/inbox/components/SlackMessageContainer/SlackMessage.tsx +1 -1
  72. package/src/screens/inbox/components/SmartLoader.tsx +61 -0
  73. package/src/screens/inbox/components/SubscriptionHandler.tsx +41 -0
  74. package/src/screens/inbox/components/SupportServiceDialogsListItem.tsx +53 -55
  75. package/src/screens/inbox/components/ThreadsViewItem.tsx +178 -285
  76. package/src/screens/inbox/components/workflow/dialogs-list-item-xstate.ts +145 -0
  77. package/src/screens/inbox/components/workflow/service-dialogs-list-item-xstate.ts +159 -0
  78. package/src/screens/inbox/config/config.ts +2 -2
  79. package/src/screens/inbox/containers/ConversationView.tsx +1843 -702
  80. package/src/screens/inbox/containers/ConversationView.tsx.bk +1467 -0
  81. package/src/screens/inbox/containers/Dialogs.tsx +402 -204
  82. package/src/screens/inbox/containers/SupportServiceDialogs.tsx +4 -4
  83. package/src/screens/inbox/containers/ThreadConversationView.tsx +1350 -319
  84. package/src/screens/inbox/containers/ThreadsView.tsx +105 -193
  85. package/src/screens/inbox/containers/workflow/apollo/handleResult.ts +20 -0
  86. package/src/screens/inbox/containers/workflow/conversation-xstate.ts +313 -0
  87. package/src/screens/inbox/containers/workflow/dialogs-xstate.ts +196 -0
  88. package/src/screens/inbox/containers/workflow/thread-conversation-xstate.ts +401 -0
  89. package/src/screens/inbox/hooks/useInboxMessages.ts +34 -0
  90. package/src/screens/inbox/hooks/useSafeDialogThreadsMachine.ts +136 -0
  91. package/src/screens/inbox/index.ts +37 -0
  92. package/src/screens/inbox/machines/threadsMachine.ts +147 -0
  93. package/src/screens/inbox/workflow/dialog-threads-xstate.ts +163 -0
  94. package/tsconfig.json +11 -54
  95. package/lib/screens/inbox/components/DialogsListItem.js +0 -171
  96. package/lib/screens/inbox/components/DialogsListItem.js.map +0 -1
  97. package/lib/screens/inbox/components/ServiceDialogsListItem.js +0 -171
  98. package/lib/screens/inbox/components/ServiceDialogsListItem.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import React__default,{useState,useRef,useEffect,useCallback,useMemo}from'react';import {Button,Spinner,VStack,HStack,Avatar,AvatarFallbackText,AvatarImage,Box,Text,Center,Image,ButtonText}from'@admin-layout/gluestack-ui-mobile';import {Platform}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 {encode}from'base-64';import {MaterialIcons,Ionicons,MaterialCommunityIcons}from'@expo/vector-icons';import {GiftedChat,Actions,MessageText,Send}from'react-native-gifted-chat';import {PreDefinedRole}from'common';import {useCreatePostThreadMutation,useSendExpoNotificationOnPostMutation,useGetPostThreadLazyQuery,OnThreadChatMessageAddedDocument}from'common/lib/generated/generated.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';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;
@@ -34,6 +34,55 @@ const createdAtText = (value) => {
34
34
  return "Yesterday";
35
35
  return format(new Date(value), "MMM dd, yyyy");
36
36
  };
37
+ const ErrorNotification = ({
38
+ message,
39
+ onClose
40
+ }) => {
41
+ const opacity = useRef(new Animated.Value(0)).current;
42
+ useEffect(() => {
43
+ Animated.timing(opacity, {
44
+ toValue: 1,
45
+ duration: 300,
46
+ useNativeDriver: true
47
+ }).start();
48
+ const timer = setTimeout(() => {
49
+ Animated.timing(opacity, {
50
+ toValue: 0,
51
+ duration: 300,
52
+ useNativeDriver: true
53
+ }).start(() => onClose && onClose());
54
+ }, 4e3);
55
+ return () => clearTimeout(timer);
56
+ }, []);
57
+ return /* @__PURE__ */ React__default.createElement(Animated.View, { style: {
58
+ position: "absolute",
59
+ top: 10,
60
+ left: 10,
61
+ right: 10,
62
+ backgroundColor: "#f44336",
63
+ padding: 15,
64
+ borderRadius: 8,
65
+ shadowColor: "#000",
66
+ shadowOffset: {
67
+ width: 0,
68
+ height: 2
69
+ },
70
+ shadowOpacity: 0.25,
71
+ shadowRadius: 3.84,
72
+ elevation: 5,
73
+ zIndex: 1e3,
74
+ opacity
75
+ } }, /* @__PURE__ */ React__default.createElement(HStack, { className: "items-center justify-between" }, /* @__PURE__ */ React__default.createElement(Text, { style: {
76
+ color: "white",
77
+ fontWeight: "bold"
78
+ } }, "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: {
79
+ color: "white",
80
+ marginTop: 5
81
+ } }, message));
82
+ };
83
+ const isValidFileUrl = (url) => {
84
+ return !!url && typeof url === "string" && url.length > 0;
85
+ };
37
86
  const ThreadConversationViewComponent = ({
38
87
  channelId,
39
88
  postParentId,
@@ -48,7 +97,7 @@ const ThreadConversationViewComponent = ({
48
97
  const [channelMessages, setChannelMessages] = useState([]);
49
98
  const auth = useSelector(userSelector);
50
99
  const [totalCount, setTotalCount] = useState(0);
51
- const [selectedImage, setImage] = useState("");
100
+ const [selectedImage, setSelectedImage] = useState("");
52
101
  const [loadingOldMessages, setLoadingOldMessages] = useState(false);
53
102
  const [loadEarlierMsg, setLoadEarlierMsg] = useState(false);
54
103
  const navigation = useNavigation();
@@ -57,6 +106,7 @@ const ThreadConversationViewComponent = ({
57
106
  const [msg, setMsg] = useState("");
58
107
  const [loading, setLoading] = useState(false);
59
108
  const [imageLoading, setImageLoading] = useState(false);
109
+ const [uploadingMessageId, setUploadingMessageId] = useState(null);
60
110
  const [expoTokens, setExpoTokens] = useState([]);
61
111
  const [isShowImageViewer, setImageViewer] = useState(false);
62
112
  const [imageObject, setImageObject] = useState({});
@@ -68,22 +118,32 @@ const ThreadConversationViewComponent = ({
68
118
  const [threadPost, setThreadPost] = useState([]);
69
119
  const [isScrollToBottom, setIsScrollToBottom] = useState(false);
70
120
  const threadMessageListRef = useRef(null);
71
- const [sendThreadMessage] = useCreatePostThreadMutation();
72
- const [sendExpoNotificationOnPostMutation] = useSendExpoNotificationOnPostMutation();
121
+ useToast();
122
+ const [errorMessage, setErrorMessage] = useState("");
123
+ const [isActionSheetVisible, setActionSheetVisible] = useState(false);
124
+ const [textUpdatedInActionSheet, setTextUpdatedInActionSheet] = useState(false);
125
+ const [lastShownMsg, setLastShownMsg] = useState("");
126
+ const textInputRef = useRef(null);
127
+ const [sendThreadMessage] = useCreatePostThread();
128
+ const [sendExpoNotificationOnPostMutation] = useSendExpoNotification();
73
129
  const [getThreadMessages, {
74
130
  data,
75
131
  loading: threadLoading,
76
132
  fetchMore: fetchMoreMessages,
77
133
  refetch: refetchThreadMessages,
78
134
  subscribeToMore
79
- }] = useGetPostThreadLazyQuery({
135
+ }] = useGetPostThreadLazy({
80
136
  fetchPolicy: "cache-and-network"
81
137
  });
138
+ const [pendingUploads, setPendingUploads] = useState({});
139
+ const [uploadErrors, setUploadErrors] = useState({});
140
+ const [isUploadingImage, setIsUploadingImage] = useState(false);
141
+ const [refreshing, setRefreshing] = useState(false);
82
142
  useFocusEffect(React__default.useCallback(() => {
83
143
  var _a2;
84
144
  navigation.setOptions({
85
145
  title: (_a2 = params == null ? void 0 : params.title) != null ? _a2 : "Thread",
86
- headerLeft: (props) => /* @__PURE__ */ React__default.createElement(Button, { bg: "transparent", "$pressed-bg": "$trueGray200", "$active-bg": "$trueGray200", onPress: () => navigation.goBack() }, /* @__PURE__ */ React__default.createElement(MaterialIcons, { size: 20, name: "arrow-back-ios", color: "black" }))
146
+ 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" }))
87
147
  });
88
148
  if (postParentId) {
89
149
  refetchThreadMessages({
@@ -148,6 +208,7 @@ const ThreadConversationViewComponent = ({
148
208
  const onFetchOld = useCallback(() => {
149
209
  if (totalCount > channelMessages.length && !loadingOldMessages) {
150
210
  setLoadEarlierMsg(true);
211
+ setLoadingOldMessages(true);
151
212
  fetchMoreMessages({
152
213
  variables: {
153
214
  channelId: channelId == null ? void 0 : channelId.toString(),
@@ -168,12 +229,20 @@ const ThreadConversationViewComponent = ({
168
229
  }).finally(() => {
169
230
  setLoadEarlierMsg(false);
170
231
  setLoadingOldMessages(false);
232
+ setRefreshing(false);
171
233
  }).catch((error) => {
172
234
  setLoadEarlierMsg(false);
173
235
  setLoadingOldMessages(false);
236
+ setRefreshing(false);
174
237
  });
238
+ } else {
239
+ setRefreshing(false);
175
240
  }
176
241
  }, [parentId, channelId, totalCount, channelMessages]);
242
+ const onRefresh = useCallback(() => {
243
+ setRefreshing(true);
244
+ onFetchOld();
245
+ }, [onFetchOld]);
177
246
  const isCloseToTop = ({
178
247
  layoutMeasurement,
179
248
  contentOffset,
@@ -182,132 +251,278 @@ const ThreadConversationViewComponent = ({
182
251
  const paddingToTop = 60;
183
252
  return contentSize.height - layoutMeasurement.height - paddingToTop <= contentOffset.y;
184
253
  };
185
- const dataURLtoFile = (dataurl, filename) => {
186
- var arr = dataurl.split(","), mime = arr[0].match(/:(.*?);/)[1], bstr = encode(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
187
- while (n--) {
188
- u8arr[n] = bstr.charCodeAt(n);
189
- }
190
- return new File([u8arr], filename, {
191
- type: mime
254
+ const removeMessageFromUI = useCallback((messageId) => {
255
+ setPendingUploads((prev) => {
256
+ const newPending = __spreadValues({}, prev);
257
+ delete newPending[messageId];
258
+ return newPending;
192
259
  });
193
- };
194
- const onSelectImages = async () => {
195
- var _a2;
196
- setImageLoading(true);
197
- let imageSource = await ImagePicker.launchImageLibraryAsync({
198
- mediaTypes: ImagePicker.MediaTypeOptions.Images,
199
- allowsEditing: true,
200
- aspect: [4, 3],
201
- quality: 1,
202
- base64: true
260
+ setUploadErrors((prev) => {
261
+ const newErrors = __spreadValues({}, prev);
262
+ delete newErrors[messageId];
263
+ return newErrors;
203
264
  });
204
- if (!imageSource.canceled) {
205
- const image = "data:image/jpeg;base64," + ((_a2 = imageSource.assets[0]) == null ? void 0 : _a2.base64);
206
- setImage(image);
207
- const file = dataURLtoFile(image, "inputImage.jpg");
208
- setFiles((files2) => files2.concat(file));
209
- setImages((images2) => images2.concat(imageSource.assets[0]));
210
- }
211
- if (imageSource.canceled)
265
+ setIsUploadingImage(false);
266
+ }, []);
267
+ const onSelectImages = async () => {
268
+ setLoading(true);
269
+ try {
270
+ let imageSource = await ImagePicker.launchImageLibraryAsync({
271
+ mediaTypes: ImagePicker.MediaTypeOptions.Images,
272
+ allowsEditing: false,
273
+ aspect: [4, 3],
274
+ quality: 0.8,
275
+ base64: true,
276
+ exif: false,
277
+ allowsMultipleSelection: true
278
+ });
279
+ if (!(imageSource == null ? void 0 : imageSource.canceled)) {
280
+ const selectedAssets = (imageSource == null ? void 0 : imageSource.assets) || [];
281
+ if (selectedAssets.length === 0) {
282
+ setLoading(false);
283
+ return;
284
+ }
285
+ const newImages = selectedAssets.map((selectedAsset) => {
286
+ const base64Data = selectedAsset.base64;
287
+ const previewImage = base64Data ? `data:image/jpeg;base64,${base64Data}` : selectedAsset.uri;
288
+ const asset = __spreadProps(__spreadValues({}, selectedAsset), {
289
+ url: selectedAsset.uri,
290
+ fileName: selectedAsset.fileName || `image_${Date.now()}.jpg`,
291
+ mimeType: "image/jpeg"
292
+ });
293
+ return asset;
294
+ });
295
+ if (newImages.length > 0) {
296
+ const base64Data = newImages[0].base64;
297
+ const previewImage = base64Data ? `data:image/jpeg;base64,${base64Data}` : newImages[0].uri;
298
+ setSelectedImage(previewImage);
299
+ }
300
+ setImages((currentImages) => [...currentImages, ...newImages]);
301
+ setLoading(false);
302
+ } else {
303
+ setLoading(false);
304
+ }
305
+ } catch (error) {
212
306
  setLoading(false);
307
+ }
213
308
  };
309
+ useCallback(() => {
310
+ setLastShownMsg(msg);
311
+ setActionSheetVisible(true);
312
+ }, [msg]);
313
+ useCallback(() => {
314
+ setActionSheetVisible(false);
315
+ if (!textUpdatedInActionSheet) {
316
+ setMsg(lastShownMsg);
317
+ }
318
+ setTextUpdatedInActionSheet(false);
319
+ }, [textUpdatedInActionSheet, lastShownMsg]);
320
+ useEffect(() => {
321
+ if (isActionSheetVisible && Platform.OS === "ios") {
322
+ Keyboard.dismiss();
323
+ }
324
+ }, [isActionSheetVisible]);
325
+ const [isGiftedInputFocused, setIsGiftedInputFocused] = useState(false);
214
326
  const handleSend = useCallback(async (message) => {
215
- var _a2;
327
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2;
328
+ const newMessageText = message && message.length > 0 ? message || " " : " ";
216
329
  if (!channelId)
217
330
  return;
218
- if (!message && message != " " && images.length == 0)
331
+ const hasText = !!newMessageText && newMessageText !== " ";
332
+ const hasImages = images && images.length > 0;
333
+ if (!hasText && !hasImages)
219
334
  return;
335
+ setLoading(true);
220
336
  const postId = objectId();
221
- if (images && images.length > 0) {
222
- setLoading(true);
223
- const uploadResponse = await startUpload({
224
- file: images,
225
- saveUploadedFile: {
226
- variables: {
227
- postId
228
- }
229
- },
230
- createUploadLink: {
231
- variables: {
232
- postId
233
- }
234
- }
235
- });
236
- if (uploadResponse == null ? void 0 : uploadResponse.error)
237
- setLoading(false);
238
- const uploadedFiles = uploadResponse.data;
239
- if (uploadResponse.data) {
240
- setImage("");
241
- setFiles([]);
242
- setImages([]);
243
- const files2 = (_a2 = uploadedFiles == null ? void 0 : uploadedFiles.map((f) => f.id)) != null ? _a2 : null;
244
- await sendThreadMessage({
245
- variables: {
246
- postId,
247
- channelId,
248
- postThreadId: postThread && (postThread == null ? void 0 : postThread.id),
249
- postParentId: !parentId || parentId == 0 ? null : parentId,
250
- threadMessageInput: {
251
- content: message,
252
- files: files2,
253
- role
254
- }
255
- },
256
- update: (cache, {
257
- data: data2,
258
- errors
259
- }) => {
260
- var _a3, _b2, _c2, _d2, _e2, _f2, _g2;
261
- if (!data2 || errors) {
262
- setLoading(false);
263
- return;
337
+ const currentDate = new Date();
338
+ const currentMessageText = message || "";
339
+ const currentImages = [...images];
340
+ setMsg("");
341
+ setSelectedImage("");
342
+ setImages([]);
343
+ setFiles([]);
344
+ if (isActionSheetVisible) {
345
+ setActionSheetVisible(false);
346
+ }
347
+ const optimisticMessage = {
348
+ id: postId,
349
+ message: currentMessageText || (currentImages.length > 0 ? " " : ""),
350
+ createdAt: currentDate.toISOString(),
351
+ author: {
352
+ id: (_a2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _a2.id,
353
+ givenName: (_b2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _b2.given_name,
354
+ familyName: (_c2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _c2.family_name,
355
+ picture: (_d2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _d2.picture
356
+ },
357
+ isDelivered: false,
358
+ isRead: false,
359
+ isOptimistic: true,
360
+ files: currentImages.length > 0 ? {
361
+ data: currentImages.filter((img) => img && (img.uri || img.url)).map((img) => ({
362
+ id: objectId(),
363
+ url: img.uri || img.url,
364
+ localUri: img.uri || img.url,
365
+ name: img.fileName || `image_${Date.now()}.jpg`,
366
+ extension: "jpg",
367
+ mimeType: "image/jpeg",
368
+ refType: FileRefType.Post,
369
+ height: img.height || 0,
370
+ width: img.width || 0,
371
+ isUploading: true
372
+ })),
373
+ totalCount: currentImages.filter((img) => img && (img.uri || img.url)).length
374
+ } : void 0
375
+ };
376
+ if (optimisticMessage.message && optimisticMessage.message.trim() !== "" || optimisticMessage.files && optimisticMessage.files.data && optimisticMessage.files.data.length > 0) {
377
+ setChannelMessages((oldMessages) => uniqBy([optimisticMessage, ...oldMessages], ({
378
+ id
379
+ }) => id));
380
+ setIsScrollToBottom(true);
381
+ }
382
+ try {
383
+ let fileIds = null;
384
+ if (currentImages && currentImages.length > 0) {
385
+ const validImages = currentImages.filter((img) => img && (img.uri || img.url));
386
+ if (validImages.length === 0) {
387
+ setIsUploadingImage(false);
388
+ } else {
389
+ setIsUploadingImage(true);
390
+ const imagesToUpload = validImages.map((img) => {
391
+ return __spreadProps(__spreadValues({}, img), {
392
+ uri: img.uri || img.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
264
402
  }
265
- setPostThread((_a3 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _a3.data);
266
- const lastMessageId = (_c2 = (_b2 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _b2.lastMessage) == null ? void 0 : _c2.id;
267
- if (!parentId || parentId == 0) {
268
- setParentId((_e2 = (_d2 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _d2.lastMessage) == null ? void 0 : _e2.id);
403
+ }));
404
+ const uploadResponse = await startUpload({
405
+ file: imagesToUpload,
406
+ saveUploadedFile: {
407
+ variables: {
408
+ postId
409
+ }
410
+ },
411
+ createUploadLink: {
412
+ variables: {
413
+ postId
414
+ }
269
415
  }
270
- setChannelToTop(channelToTop + 1);
271
- setLoading(false);
272
- setMsg("");
273
- sendPushNotification(lastMessageId, channelId, parentId, (_g2 = (_f2 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _f2.data) == null ? void 0 : _g2.id);
416
+ });
417
+ if (uploadResponse == null ? void 0 : uploadResponse.error) {
418
+ throw new Error(uploadResponse.error.toString());
274
419
  }
275
- });
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
+ }
276
446
  }
277
- } else {
278
- setLoading(true);
279
447
  await sendThreadMessage({
280
448
  variables: {
449
+ postId,
281
450
  channelId,
282
451
  postThreadId: postThread && (postThread == null ? void 0 : postThread.id),
283
- postParentId: !parentId || parentId == 0 ? null : parentId,
452
+ postParentId: !parentId || parentId === 0 ? null : parentId,
284
453
  threadMessageInput: {
285
- content: message,
454
+ content: currentMessageText,
455
+ files: fileIds,
286
456
  role
287
457
  }
288
458
  },
459
+ optimisticResponse: {
460
+ createPostThread: {
461
+ __typename: "ThreadMessageSent",
462
+ lastMessage: {
463
+ __typename: "Post",
464
+ id: postId,
465
+ message: currentMessageText || " ",
466
+ createdAt: 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
+ data: {
480
+ __typename: "PostThread",
481
+ id: (postThread == null ? void 0 : postThread.id) || objectId()
482
+ }
483
+ }
484
+ },
289
485
  update: (cache, {
290
486
  data: data2,
291
487
  errors
292
488
  }) => {
293
- var _a3, _b2, _c2, _d2, _e2, _f2;
294
- if (!data2 || errors) {
295
- setLoading(false);
489
+ var _a3, _b3, _c3, _d3, _e3, _f3, _g3;
490
+ if (!data2 || errors)
296
491
  return;
297
- }
298
- setPostThread(data2 == null ? void 0 : data2.createPostThread.data);
299
- const lastMessageId = (_b2 = (_a3 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _a3.lastMessage) == null ? void 0 : _b2.id;
300
- if (!parentId || parentId == 0) {
301
- setParentId((_d2 = (_c2 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _c2.lastMessage) == null ? void 0 : _d2.id);
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);
302
496
  }
303
497
  setChannelToTop(channelToTop + 1);
304
- setLoading(false);
305
- setMsg("");
306
- sendPushNotification(lastMessageId, channelId, parentId, (_f2 = (_e2 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _e2.data) == null ? void 0 : _f2.id);
498
+ sendPushNotification(lastMessageId, channelId, parentId, (_g3 = (_f3 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _f3.data) == null ? void 0 : _g3.id);
307
499
  }
308
500
  });
501
+ } catch (error) {
502
+ console.error("Error sending message:", error);
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";
509
+ }
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.";
515
+ }
516
+ }
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);
309
524
  }
310
- }, [setChannelMessages, channelId, images, parentId, expoTokens]);
525
+ }, [auth, channelId, channelToTop, images, parentId, postThread, selectedImage, setChannelMessages, removeMessageFromUI, role]);
311
526
  const sendPushNotification = async (messageId, channelId2, parentId2, threadId) => {
312
527
  var _a2;
313
528
  const notificationData = {
@@ -342,7 +557,7 @@ const ThreadConversationViewComponent = ({
342
557
  }) => id) : [];
343
558
  if (filteredMessages == null ? void 0 : filteredMessages.length) {
344
559
  orderBy(filteredMessages, ["createdAt"], ["desc"]).map((msg2) => {
345
- var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2;
560
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2, _o2, _p2;
346
561
  let message = {
347
562
  _id: "",
348
563
  text: "",
@@ -362,7 +577,27 @@ const ThreadConversationViewComponent = ({
362
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,
363
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,
364
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
365
- }, message.image = (_n2 = (_m2 = msg2.files) == null ? void 0 : _m2.data[0]) == null ? void 0 : _n2.url, message.sent = msg2 == null ? void 0 : msg2.isDelivered, message.received = msg2 == null ? void 0 : msg2.isRead;
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
+ }
598
+ }
599
+ message.sent = msg2 == null ? void 0 : msg2.isDelivered;
600
+ message.received = msg2 == null ? void 0 : msg2.isRead;
366
601
  message.type = msg2 == null ? void 0 : msg2.type;
367
602
  message.propsConfiguration = msg2 == null ? void 0 : msg2.propsConfiguration;
368
603
  res.push(message);
@@ -372,13 +607,33 @@ const ThreadConversationViewComponent = ({
372
607
  _id
373
608
  }) => _id) : [];
374
609
  }, [channelMessages]);
375
- const renderSend = (props) => {
376
- return /* @__PURE__ */ React__default.createElement(Send, __spreadValues({}, props), /* @__PURE__ */ React__default.createElement(Box, null, /* @__PURE__ */ React__default.createElement(MaterialCommunityIcons, { name: "send-circle", style: {
377
- marginBottom: 5,
378
- marginRight: 5
379
- }, size: 32, color: "#2e64e5" })));
380
- };
381
- const renderMessageText = (props) => {
610
+ const renderSend = 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;
617
+ return /* @__PURE__ */ React__default.createElement(
618
+ Send,
619
+ __spreadProps(__spreadValues({}, props), {
620
+ disabled: isDisabled,
621
+ containerStyle: {
622
+ justifyContent: "center",
623
+ alignItems: "center",
624
+ height: 40,
625
+ width: 44,
626
+ marginRight: 4,
627
+ marginBottom: 0,
628
+ marginLeft: 4
629
+ }
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] }))
634
+ );
635
+ }, [channelId, images, isUploadingImage, loading, isActionSheetVisible]);
636
+ useCallback((props) => {
382
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;
383
638
  const {
384
639
  currentMessage
@@ -412,16 +667,7 @@ const ThreadConversationViewComponent = ({
412
667
  reservationId: actionId
413
668
  };
414
669
  }
415
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, (attachment == null ? void 0 : attachment.callToAction) && action ? /* @__PURE__ */ React__default.createElement(Box, { bg: CALL_TO_ACTION_BOX_BGCOLOR, borderRadius: 15, pb: 2 }, /* @__PURE__ */ React__default.createElement(
416
- Button,
417
- {
418
- variant: "outline",
419
- size: "sm",
420
- borderColor: CALL_TO_ACTION_BUTTON_BORDERCOLOR,
421
- onPress: () => action && params2 && navigation.navigate(action, params2)
422
- },
423
- /* @__PURE__ */ React__default.createElement(ButtonText, { color: CALL_TO_ACTION_TEXT_COLOR }, attachment.callToAction.title)
424
- ), /* @__PURE__ */ React__default.createElement(MessageText, __spreadProps(__spreadValues({}, props), { textStyle: {
670
+ 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: {
425
671
  left: {
426
672
  marginLeft: 5,
427
673
  color: CALL_TO_ACTION_TEXT_COLOR,
@@ -439,156 +685,419 @@ const ThreadConversationViewComponent = ({
439
685
  }
440
686
  } }));
441
687
  }
442
- };
443
- const renderActions = (props) => {
444
- return /* @__PURE__ */ React__default.createElement(Actions, __spreadProps(__spreadValues({}, props), { icon: () => /* @__PURE__ */ React__default.createElement(Ionicons, { name: "image", size: 30, color: "black", onPress: onSelectImages }) }));
445
- };
446
- const renderAccessory = (props) => {
447
- return /* @__PURE__ */ React__default.createElement(Box, null, selectedImage !== "" ? /* @__PURE__ */ React__default.createElement(HStack, { alignItems: "center" }, /* @__PURE__ */ React__default.createElement(Image, { ml: "$3", key: selectedImage, alt: "image", source: {
448
- uri: selectedImage
449
- }, size: "xs" }), /* @__PURE__ */ React__default.createElement(
450
- Button,
451
- {
452
- variant: "solid",
453
- bg: "transparent",
454
- onPress: () => {
455
- setFiles([]);
456
- setImage("");
457
- setImages([]);
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;
458
717
  }
459
- },
460
- /* @__PURE__ */ React__default.createElement(ButtonText, { color: "$black" }, "Cancel")
461
- )) : null);
462
- };
463
- const setImageViewerObject = (obj, v) => {
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)
737
+ navigation.navigate(config.THREAD_MESSEGE_PATH, {
738
+ channelId,
739
+ title: "Message",
740
+ postParentId: currentMessage == null ? void 0 : currentMessage._id,
741
+ isPostParentIdThread: true
742
+ });
743
+ } }, /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(MessageText, __spreadProps(__spreadValues({}, props), { textStyle: {
744
+ left: {
745
+ marginLeft: 5
746
+ }
747
+ } })), ((_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) => {
748
+ var _a3, _b3;
749
+ 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);
750
+ }) === i)) == null ? void 0 : _H.slice(0, 2)) == null ? void 0 : _I.reverse()) == null ? void 0 : _J.map((p, i) => {
751
+ var _a3, _b3, _c3;
752
+ 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: {
753
+ borderRadius: 6,
754
+ borderWidth: 2,
755
+ borderColor: "#fff"
756
+ }, source: {
757
+ uri: (_c3 = p == null ? void 0 : p.author) == null ? void 0 : _c3.picture
758
+ } }));
759
+ })), /* @__PURE__ */ React__default.createElement(Text, { style: {
760
+ fontSize: 12
761
+ }, 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: {
762
+ fontSize: 12
763
+ }, className: "font-bold color-gray-500" }, lastReply ? createdAtText(lastReply == null ? void 0 : lastReply.createdAt) : "")))));
764
+ } else {
765
+ return /* @__PURE__ */ React__default.createElement(TouchableHighlight, { underlayColor: "#c0c0c0", style: {
766
+ width: "100%"
767
+ }, onPress: () => {
768
+ if (currentMessage == null ? void 0 : currentMessage.isShowThreadMessage)
769
+ navigation.navigate(config.THREAD_MESSEGE_PATH, {
770
+ channelId,
771
+ title: "Message",
772
+ postParentId: currentMessage == null ? void 0 : currentMessage._id,
773
+ isPostParentIdThread: true
774
+ });
775
+ } }, /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(MessageText, __spreadProps(__spreadValues({}, props), { textStyle: {
776
+ left: {
777
+ marginLeft: 5
778
+ }
779
+ } })), ((_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) => {
780
+ var _a3, _b3;
781
+ 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);
782
+ }) === i)) == null ? void 0 : _Q.slice(0, 2)) == null ? void 0 : _R.reverse()) == null ? void 0 : _S.map((p, i) => {
783
+ var _a3, _b3, _c3;
784
+ 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: {
785
+ borderRadius: 6,
786
+ borderWidth: 2,
787
+ borderColor: "#fff"
788
+ }, source: {
789
+ uri: (_c3 = p == null ? void 0 : p.author) == null ? void 0 : _c3.picture
790
+ } }));
791
+ })), /* @__PURE__ */ React__default.createElement(Text, { style: {
792
+ fontSize: 12
793
+ }, 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: {
794
+ fontSize: 12
795
+ }, className: "font-bold color-gray-500" }, lastReply ? createdAtText(lastReply == null ? void 0 : lastReply.createdAt) : ""))));
796
+ }
797
+ }, [navigation, channelId, role]);
798
+ useCallback((props) => {
799
+ return /* @__PURE__ */ React__default.createElement(
800
+ Actions,
801
+ __spreadProps(__spreadValues({}, props), {
802
+ onPressActionButton: onSelectImages,
803
+ options: {
804
+ ["Choose from Library"]: () => {
805
+ onSelectImages();
806
+ },
807
+ ["Cancel"]: () => {
808
+ }
809
+ },
810
+ optionTintColor: "#000000",
811
+ cancelButtonIndex: 1,
812
+ 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] })),
813
+ containerStyle: {
814
+ alignItems: "center",
815
+ justifyContent: "center",
816
+ marginLeft: 8,
817
+ marginBottom: 0
818
+ }
819
+ })
820
+ );
821
+ }, [onSelectImages]);
822
+ useCallback(() => {
823
+ if (!images.length)
824
+ return null;
825
+ return /* @__PURE__ */ React__default.createElement(Box, { style: {
826
+ position: "relative",
827
+ height: 70,
828
+ backgroundColor: "transparent",
829
+ justifyContent: "center"
830
+ } }, /* @__PURE__ */ React__default.createElement(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, style: {
831
+ flexDirection: "row",
832
+ paddingLeft: 15,
833
+ paddingRight: 5
834
+ }, contentContainerStyle: {
835
+ alignItems: "center",
836
+ height: "100%"
837
+ } }, images.map((img, index) => /* @__PURE__ */ React__default.createElement(View, { key: `image-preview-${index}`, style: {
838
+ width: 40,
839
+ height: 40,
840
+ marginRight: 15,
841
+ borderRadius: 4,
842
+ backgroundColor: colors.gray[200],
843
+ overflow: "hidden",
844
+ borderWidth: 1,
845
+ borderColor: "#e0e0e0",
846
+ position: "relative",
847
+ zIndex: 10
848
+ } }, /* @__PURE__ */ React__default.createElement(Image, { alt: `selected image ${index + 1}`, source: {
849
+ uri: img.uri || img.url
850
+ }, style: {
851
+ width: "100%",
852
+ height: "100%"
853
+ }, size: "md" }), /* @__PURE__ */ React__default.createElement(TouchableOpacity, { onPress: () => {
854
+ const newImages = [...images];
855
+ newImages.splice(index, 1);
856
+ setImages(newImages);
857
+ if (newImages.length === 0) {
858
+ setSelectedImage("");
859
+ }
860
+ }, style: {
861
+ position: "absolute",
862
+ top: -1,
863
+ right: -1,
864
+ backgroundColor: "rgba(0,0,0,0.6)",
865
+ borderRadius: 12,
866
+ width: 20,
867
+ height: 20,
868
+ alignItems: "center",
869
+ justifyContent: "center",
870
+ zIndex: 9999
871
+ } }, /* @__PURE__ */ React__default.createElement(Ionicons, { name: "close", size: 16, color: "white" }))))));
872
+ }, [images]);
873
+ useCallback((props) => /* @__PURE__ */ React__default.createElement(TouchableOpacity, { style: {
874
+ flexDirection: "row",
875
+ alignItems: "center",
876
+ backgroundColor: "#fff",
877
+ minHeight: 48,
878
+ maxHeight: 48,
879
+ paddingHorizontal: 12,
880
+ paddingVertical: 0,
881
+ marginHorizontal: 8,
882
+ flex: 1
883
+ }, activeOpacity: 0.7, onPress: () => {
884
+ setActionSheetVisible(true);
885
+ } }, /* @__PURE__ */ React__default.createElement(TouchableOpacity, { onPress: (e) => {
886
+ e.stopPropagation();
887
+ onSelectImages();
888
+ }, style: {
889
+ width: 25,
890
+ height: 25,
891
+ borderRadius: 20,
892
+ backgroundColor: "#f5f5f5",
893
+ alignItems: "center",
894
+ justifyContent: "center",
895
+ marginRight: 8
896
+ } }, /* @__PURE__ */ React__default.createElement(MaterialIcons, { name: "add", size: 20, color: "#888" })), /* @__PURE__ */ React__default.createElement(Text, { style: {
897
+ fontSize: 16,
898
+ color: msg ? colors.gray[800] : colors.gray[400],
899
+ flex: 1
900
+ }, numberOfLines: 1, ellipsizeMode: "tail" }, msg ? msg : "Jot something down")), [msg, onSelectImages]);
901
+ const setImageViewerObject = useCallback((obj, v) => {
464
902
  setImageObject(obj);
465
903
  setImageViewer(v);
466
- };
467
- const modalContent = React__default.useMemo(() => {
904
+ }, []);
905
+ const modalContent = useMemo(() => {
468
906
  if (!imageObject)
469
907
  return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null);
470
908
  const {
471
909
  image,
472
910
  _id
473
911
  } = imageObject;
912
+ return /* @__PURE__ */ React__default.createElement(CachedImage, { style: {
913
+ width: "100%",
914
+ height: "100%"
915
+ }, resizeMode: "cover", cacheKey: `${_id}-slack-bubble-imageKey`, source: {
916
+ uri: image,
917
+ expiresIn: 86400
918
+ }, alt: "image" });
919
+ }, [imageObject]);
920
+ useCallback((props) => {
921
+ const {
922
+ currentMessage
923
+ } = props;
924
+ const customProps = __spreadProps(__spreadValues({}, props), {
925
+ isShowImageViewer,
926
+ setImageViewer: setImageViewerObject,
927
+ isUploading: currentMessage.isUploading || false,
928
+ isOptimistic: currentMessage.isOptimistic || false
929
+ });
930
+ return /* @__PURE__ */ React__default.createElement(Message, __spreadValues({}, customProps));
931
+ }, [isShowImageViewer, setImageViewerObject]);
932
+ const renderMessage = useCallback((props) => {
933
+ return /* @__PURE__ */ React__default.createElement(Message, __spreadProps(__spreadValues({}, props), { isShowImageViewer, setImageViewer: setImageViewerObject }));
934
+ }, [isShowImageViewer]);
935
+ useCallback((props) => {
936
+ if (isActionSheetVisible)
937
+ return null;
474
938
  return /* @__PURE__ */ React__default.createElement(
475
- CachedImage,
476
- {
477
- style: {
478
- width: "100%",
479
- height: "100%"
480
- },
481
- resizeMode: "cover",
482
- cacheKey: `${_id}-slack-bubble-imageKey`,
483
- source: {
484
- uri: image,
485
- expiresIn: 86400
939
+ InputToolbar,
940
+ __spreadProps(__spreadValues({}, props), {
941
+ containerStyle: {
942
+ backgroundColor: "transparent",
943
+ padding: 0,
944
+ margin: 0,
945
+ borderTopWidth: 1,
946
+ borderTopColor: colors.gray[200]
486
947
  },
487
- alt: "image"
488
- }
948
+ primaryStyle: {
949
+ alignItems: "center",
950
+ justifyContent: "center",
951
+ flex: 1
952
+ }
953
+ })
489
954
  );
490
- }, [imageObject]);
491
- const renderMessage = (props) => {
492
- return /* @__PURE__ */ React__default.createElement(Message, __spreadProps(__spreadValues({}, props), { isShowImageViewer, setImageViewer: setImageViewerObject }));
493
- };
955
+ }, [isActionSheetVisible, onSelectImages]);
956
+ const renderLoadEarlier = useCallback(() => {
957
+ return loadingOldMessages && !refreshing ? /* @__PURE__ */ React__default.createElement(Box, { style: {
958
+ padding: 10,
959
+ backgroundColor: "rgba(255,255,255,0.8)",
960
+ borderRadius: 10,
961
+ marginTop: 10,
962
+ alignItems: "center"
963
+ } }, /* @__PURE__ */ React__default.createElement(Spinner, { size: "small", color: colors.blue[500] }), /* @__PURE__ */ React__default.createElement(Text, { style: {
964
+ fontSize: 12,
965
+ color: colors.gray[600],
966
+ marginTop: 4
967
+ } }, "Loading earlier messages...")) : null;
968
+ }, [loadingOldMessages, refreshing]);
494
969
  let onScroll = false;
495
970
  const onMomentumScrollBegin = ({
496
971
  nativeEvent
497
972
  }) => {
498
973
  onScroll = true;
499
- console.log("scroll top");
500
974
  if (!loadingOldMessages && isCloseToTop(nativeEvent) && totalCount > (channelMessages == null ? void 0 : channelMessages.length)) {
501
975
  onFetchOld();
502
976
  }
503
977
  };
504
978
  const onEndReached = () => {
505
- console.log("on end reached");
506
979
  if (!onScroll)
507
980
  return;
508
981
  onScroll = false;
509
982
  };
510
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, (loadingOldMessages || loadEarlierMsg) && /* @__PURE__ */ React__default.createElement(Spinner, { color: "$blue500" }), 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, { px: "$2", pt: "$2", pb: "$0", space: "sm" }, /* @__PURE__ */ React__default.createElement(HStack, { space: "sm", alignItems: "center" }, /* @__PURE__ */ React__default.createElement(Avatar, { 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: {
983
+ const renderChatFooter = useCallback(() => {
984
+ 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({
985
+ document: CHAT_MESSAGE_ADDED,
986
+ variables: {
987
+ channelId: channelId == null ? void 0 : channelId.toString(),
988
+ postParentId: !parentId || parentId == 0 ? null : parentId == null ? void 0 : parentId.toString()
989
+ },
990
+ updateQuery: (prev, {
991
+ subscriptionData
992
+ }) => {
993
+ var _a2, _b2, _c2;
994
+ if (!subscriptionData.data)
995
+ return prev;
996
+ const newMessage = (_a2 = subscriptionData == null ? void 0 : subscriptionData.data) == null ? void 0 : _a2.threadChatMessageAdded;
997
+ const prevReplyCount = (_b2 = prev == null ? void 0 : prev.getPostThread) == null ? void 0 : _b2.replyCount;
998
+ const newReplyCount = prevReplyCount || 0 + 1;
999
+ const replies = ((_c2 = prev == null ? void 0 : prev.getPostThread) == null ? void 0 : _c2.replies) || [];
1000
+ setChannelMessages((oldMessages) => uniqBy([...oldMessages, newMessage], ({
1001
+ id
1002
+ }) => id));
1003
+ setTotalCount(newReplyCount);
1004
+ return Object.assign({}, prev, {
1005
+ getPostThread: __spreadProps(__spreadValues({}, prev == null ? void 0 : prev.getPostThread), {
1006
+ lastReplyAt: newMessage.createdAt,
1007
+ replies: [newMessage, ...replies],
1008
+ replyCount: newReplyCount,
1009
+ updatedAt: newMessage.createdAt
1010
+ })
1011
+ });
1012
+ }
1013
+ }) }));
1014
+ }, [channelId, isShowImageViewer, modalContent, parentId, setImageViewer, subscribeToMore]);
1015
+ const handleRemoveImage = useCallback((index) => {
1016
+ const newImages = [...images];
1017
+ newImages.splice(index, 1);
1018
+ setImages(newImages);
1019
+ if (newImages.length === 0) {
1020
+ setSelectedImage("");
1021
+ if (textInputRef.current && typeof textInputRef.current.focus === "function") {
1022
+ textInputRef.current.focus();
1023
+ }
1024
+ }
1025
+ }, [images]);
1026
+ return /* @__PURE__ */ React__default.createElement(View, { style: {
1027
+ flex: 1,
1028
+ marginTop: -40
1029
+ } }, 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: {
511
1030
  borderRadius: 6,
512
1031
  borderWidth: 2,
513
1032
  borderColor: "#fff"
514
1033
  }, source: {
515
1034
  uri: (_e = (_d = threadPost[0]) == null ? void 0 : _d.author) == null ? void 0 : _e.picture
516
- } })), /* @__PURE__ */ React__default.createElement(Box, null, /* @__PURE__ */ React__default.createElement(Text, { color: "$black", fontWeight: "$bold" }, (_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, { color: "$trueGray500", pl: "$0" }, 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, { px: "$2", space: "sm", alignItems: "center" }, /* @__PURE__ */ React__default.createElement(Text, null, (_o = (_n = threadPost[0]) == null ? void 0 : _n.message) != null ? _o : ""))), /* @__PURE__ */ React__default.createElement(Box, { py: "$4" }, /* @__PURE__ */ React__default.createElement(Box, { px: "$4", borderTopWidth: "$1", borderBottomWidth: "$1", py: "$2", borderColor: "$trueGray200" }, /* @__PURE__ */ React__default.createElement(Text, { color: "$trueGray600", fontWeight: "$bold" }, (_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(
517
- GiftedChat,
1035
+ } })), /* @__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(
1036
+ GiftedChatInboxComponent,
518
1037
  {
519
1038
  ref: threadMessageListRef,
520
- wrapInSafeArea: false,
521
- renderLoading: () => /* @__PURE__ */ React__default.createElement(Spinner, { color: "$blue500" }),
1039
+ onRemoveImage: handleRemoveImage,
1040
+ images,
1041
+ onSelectImages,
1042
+ selectedImage,
1043
+ setSelectedImage,
1044
+ isUploadingImage,
1045
+ loading,
1046
+ wrapInSafeArea: true,
1047
+ inverted: true,
1048
+ renderLoading: () => /* @__PURE__ */ React__default.createElement(Skeleton, { variant: "rounded", style: {
1049
+ flex: 1
1050
+ } }),
522
1051
  messages: messageList,
523
1052
  listViewProps: {
524
1053
  onEndReached,
525
1054
  onEndReachedThreshold: 0.5,
526
- onMomentumScrollBegin
1055
+ onMomentumScrollBegin,
1056
+ style: {
1057
+ marginTop: 0
1058
+ },
1059
+ contentContainerStyle: {
1060
+ paddingTop: 0,
1061
+ paddingBottom: selectedImage ? 90 : 0
1062
+ },
1063
+ refreshControl: /* @__PURE__ */ React__default.createElement(RefreshControl, { refreshing, onRefresh, colors: [colors.blue[500]], tintColor: colors.blue[500], title: "Loading earlier messages...", titleColor: colors.gray[600] })
527
1064
  },
528
1065
  onSend: (messages) => {
529
1066
  var _a2, _b2;
530
1067
  return handleSend((_b2 = (_a2 = messages[0]) == null ? void 0 : _a2.text) != null ? _b2 : " ");
531
1068
  },
532
- text: msg ? msg : " ",
1069
+ text: msg || " ",
533
1070
  onInputTextChanged: (text) => setMsg(text),
534
- renderFooter: () => loading ? /* @__PURE__ */ React__default.createElement(Spinner, { color: "$blue500" }) : imageLoading ? /* @__PURE__ */ React__default.createElement(Spinner, { color: "$blue500" }) : "",
1071
+ renderFooter: () => null,
535
1072
  scrollToBottom: true,
536
1073
  user: {
537
1074
  _id: (auth == null ? void 0 : auth.id) || ""
538
1075
  },
539
- isTyping: true,
540
- alwaysShowSend: loading ? false : true,
1076
+ placeholder: "Jot something down",
541
1077
  infiniteScroll: true,
542
1078
  renderSend,
543
1079
  renderMessageText,
544
- minInputToolbarHeight: 50,
545
- renderActions,
546
- renderAccessory,
547
1080
  renderMessage,
548
- 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({
549
- document: OnThreadChatMessageAddedDocument,
550
- variables: {
551
- channelId: channelId == null ? void 0 : channelId.toString(),
552
- postParentId: !parentId || parentId == 0 ? null : parentId == null ? void 0 : parentId.toString()
553
- },
554
- updateQuery: (prev, {
555
- subscriptionData
556
- }) => {
557
- var _a2, _b2, _c2;
558
- if (!subscriptionData.data)
559
- return prev;
560
- const newMessage = (_a2 = subscriptionData == null ? void 0 : subscriptionData.data) == null ? void 0 : _a2.threadChatMessageAdded;
561
- const prevReplyCount = (_b2 = prev == null ? void 0 : prev.getPostThread) == null ? void 0 : _b2.replyCount;
562
- const newReplyCount = prevReplyCount || 0 + 1;
563
- const replies = ((_c2 = prev == null ? void 0 : prev.getPostThread) == null ? void 0 : _c2.replies) || [];
564
- setChannelMessages((oldMessages) => uniqBy([...oldMessages, newMessage], ({
565
- id
566
- }) => id));
567
- setTotalCount(newReplyCount);
568
- return Object.assign({}, prev, {
569
- getPostThread: __spreadProps(__spreadValues({}, prev == null ? void 0 : prev.getPostThread), {
570
- lastReplyAt: newMessage.createdAt,
571
- replies: [newMessage, ...replies],
572
- replyCount: newReplyCount,
573
- updatedAt: newMessage.createdAt
574
- })
575
- });
576
- }
577
- }) })),
578
- messagesContainerStyle: (messageList == null ? void 0 : messageList.length) == 0 && {
1081
+ renderLoadEarlier,
1082
+ loadEarlier: totalCount > channelMessages.length,
1083
+ isLoadingEarlier: loadingOldMessages,
1084
+ textInputProps: {
1085
+ multiline: true,
1086
+ returnKeyType: "default",
1087
+ enablesReturnKeyAutomatically: true,
1088
+ placeholderTextColor: colors.gray[400],
1089
+ editable: true,
1090
+ onFocus: () => setIsGiftedInputFocused(true),
1091
+ onBlur: () => setIsGiftedInputFocused(false)
1092
+ },
1093
+ renderChatFooter,
1094
+ messagesContainerStyle: __spreadProps(__spreadValues({}, (messageList == null ? void 0 : messageList.length) == 0 ? {
579
1095
  transform: [{
580
1096
  scaleY: -1
581
1097
  }]
582
- },
583
- renderChatEmpty: () => /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, !threadLoading && messageList && (messageList == null ? void 0 : messageList.length) == 0 && /* @__PURE__ */ React__default.createElement(Box, { p: "$5" }, /* @__PURE__ */ React__default.createElement(Center, { mt: "$6" }, /* @__PURE__ */ React__default.createElement(Ionicons, { name: "chatbubbles", size: 30 }), /* @__PURE__ */ React__default.createElement(Text, null, "You don't have any message yet!")))),
584
- lightboxProps: {
585
- underlayColor: "transparent",
586
- springConfig: {
587
- tension: 9e4,
588
- friction: 9e4
589
- },
590
- disabled: true
591
- }
1098
+ } : {}), {
1099
+ paddingTop: 0
1100
+ })
592
1101
  }
593
1102
  ));
594
1103
  };