@messenger-box/platform-mobile 10.0.3-alpha.40 → 10.0.3-alpha.46

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 (54) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/lib/compute.js +2 -3
  3. package/lib/index.js.map +1 -1
  4. package/lib/queries/inboxQueries.js +77 -0
  5. package/lib/queries/inboxQueries.js.map +1 -0
  6. package/lib/routes.json +2 -3
  7. package/lib/screens/inbox/DialogThreadMessages.js +3 -7
  8. package/lib/screens/inbox/DialogThreadMessages.js.map +1 -1
  9. package/lib/screens/inbox/DialogThreads.js +3 -7
  10. package/lib/screens/inbox/DialogThreads.js.map +1 -1
  11. package/lib/screens/inbox/components/DialogsListItem.js +47 -46
  12. package/lib/screens/inbox/components/DialogsListItem.js.map +1 -1
  13. package/lib/screens/inbox/components/GiftedChatInboxComponent.js +313 -0
  14. package/lib/screens/inbox/components/GiftedChatInboxComponent.js.map +1 -0
  15. package/lib/screens/inbox/components/ServiceDialogsListItem.js +72 -57
  16. package/lib/screens/inbox/components/ServiceDialogsListItem.js.map +1 -1
  17. package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js +115 -14
  18. package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js.map +1 -1
  19. package/lib/screens/inbox/components/SubscriptionHandler.js +24 -0
  20. package/lib/screens/inbox/components/SubscriptionHandler.js.map +1 -0
  21. package/lib/screens/inbox/containers/ConversationView.js +640 -493
  22. package/lib/screens/inbox/containers/ConversationView.js.map +1 -1
  23. package/lib/screens/inbox/containers/Dialogs.js +100 -181
  24. package/lib/screens/inbox/containers/Dialogs.js.map +1 -1
  25. package/lib/screens/inbox/containers/ThreadConversationView.js +659 -245
  26. package/lib/screens/inbox/containers/ThreadConversationView.js.map +1 -1
  27. package/lib/screens/inbox/containers/ThreadsView.js +3 -3
  28. package/lib/screens/inbox/containers/ThreadsView.js.map +1 -1
  29. package/lib/screens/inbox/hooks/useInboxMessages.js +31 -0
  30. package/lib/screens/inbox/hooks/useInboxMessages.js.map +1 -0
  31. package/package.json +4 -4
  32. package/src/index.ts +2 -0
  33. package/src/queries/inboxQueries.ts +298 -0
  34. package/src/queries/index.d.ts +2 -0
  35. package/src/queries/index.ts +1 -0
  36. package/src/screens/inbox/DialogThreadMessages.tsx +3 -11
  37. package/src/screens/inbox/DialogThreads.tsx +3 -7
  38. package/src/screens/inbox/components/Actionsheet.tsx +30 -0
  39. package/src/screens/inbox/components/DialogsListItem.tsx +89 -148
  40. package/src/screens/inbox/components/ExpandableInput.tsx +460 -0
  41. package/src/screens/inbox/components/ExpandableInputActionSheet.tsx +518 -0
  42. package/src/screens/inbox/components/GiftedChatInboxComponent.tsx +411 -0
  43. package/src/screens/inbox/components/ServiceDialogsListItem.tsx +202 -221
  44. package/src/screens/inbox/components/SlackInput.tsx +23 -0
  45. package/src/screens/inbox/components/SlackMessageContainer/SlackBubble.tsx +216 -30
  46. package/src/screens/inbox/components/SubscriptionHandler.tsx +41 -0
  47. package/src/screens/inbox/components/SupportServiceDialogsListItem.tsx +6 -7
  48. package/src/screens/inbox/containers/ConversationView.tsx +1109 -669
  49. package/src/screens/inbox/containers/Dialogs.tsx +198 -342
  50. package/src/screens/inbox/containers/SupportServiceDialogs.tsx +2 -2
  51. package/src/screens/inbox/containers/ThreadConversationView.tsx +1141 -402
  52. package/src/screens/inbox/containers/ThreadsView.tsx +5 -5
  53. package/src/screens/inbox/hooks/useInboxMessages.ts +34 -0
  54. package/src/screens/inbox/machines/threadsMachine.ts +2 -2
@@ -1,4 +1,4 @@
1
- import React__default,{useState,useRef,useEffect,useCallback,useMemo}from'react';import {Button,Box,ButtonText,Image,Spinner,Text,Skeleton,VStack,HStack,Avatar,AvatarFallbackText,AvatarImage,Center}from'@admin-layout/gluestack-ui-mobile';import {Platform,View,TouchableHighlight}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,InputToolbar,GiftedChat,Actions}from'react-native-gifted-chat';import {FileRefType,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';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();
@@ -69,17 +118,27 @@ const ThreadConversationViewComponent = ({
69
118
  const [threadPost, setThreadPost] = useState([]);
70
119
  const [isScrollToBottom, setIsScrollToBottom] = useState(false);
71
120
  const threadMessageListRef = useRef(null);
72
- const [sendThreadMessage] = useCreatePostThreadMutation();
73
- 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();
74
129
  const [getThreadMessages, {
75
130
  data,
76
131
  loading: threadLoading,
77
132
  fetchMore: fetchMoreMessages,
78
133
  refetch: refetchThreadMessages,
79
134
  subscribeToMore
80
- }] = useGetPostThreadLazyQuery({
135
+ }] = useGetPostThreadLazy({
81
136
  fetchPolicy: "cache-and-network"
82
137
  });
138
+ const [pendingUploads, setPendingUploads] = useState({});
139
+ const [uploadErrors, setUploadErrors] = useState({});
140
+ const [isUploadingImage, setIsUploadingImage] = useState(false);
141
+ const [refreshing, setRefreshing] = useState(false);
83
142
  useFocusEffect(React__default.useCallback(() => {
84
143
  var _a2;
85
144
  navigation.setOptions({
@@ -149,6 +208,7 @@ const ThreadConversationViewComponent = ({
149
208
  const onFetchOld = useCallback(() => {
150
209
  if (totalCount > channelMessages.length && !loadingOldMessages) {
151
210
  setLoadEarlierMsg(true);
211
+ setLoadingOldMessages(true);
152
212
  fetchMoreMessages({
153
213
  variables: {
154
214
  channelId: channelId == null ? void 0 : channelId.toString(),
@@ -169,12 +229,20 @@ const ThreadConversationViewComponent = ({
169
229
  }).finally(() => {
170
230
  setLoadEarlierMsg(false);
171
231
  setLoadingOldMessages(false);
232
+ setRefreshing(false);
172
233
  }).catch((error) => {
173
234
  setLoadEarlierMsg(false);
174
235
  setLoadingOldMessages(false);
236
+ setRefreshing(false);
175
237
  });
238
+ } else {
239
+ setRefreshing(false);
176
240
  }
177
241
  }, [parentId, channelId, totalCount, channelMessages]);
242
+ const onRefresh = useCallback(() => {
243
+ setRefreshing(true);
244
+ onFetchOld();
245
+ }, [onFetchOld]);
178
246
  const isCloseToTop = ({
179
247
  layoutMeasurement,
180
248
  contentOffset,
@@ -183,100 +251,197 @@ const ThreadConversationViewComponent = ({
183
251
  const paddingToTop = 60;
184
252
  return contentSize.height - layoutMeasurement.height - paddingToTop <= contentOffset.y;
185
253
  };
254
+ const removeMessageFromUI = useCallback((messageId) => {
255
+ setPendingUploads((prev) => {
256
+ const newPending = __spreadValues({}, prev);
257
+ delete newPending[messageId];
258
+ return newPending;
259
+ });
260
+ setUploadErrors((prev) => {
261
+ const newErrors = __spreadValues({}, prev);
262
+ delete newErrors[messageId];
263
+ return newErrors;
264
+ });
265
+ setIsUploadingImage(false);
266
+ }, []);
186
267
  const onSelectImages = async () => {
187
- var _a2;
188
- setImageLoading(true);
268
+ setLoading(true);
189
269
  try {
190
270
  let imageSource = await ImagePicker.launchImageLibraryAsync({
191
271
  mediaTypes: ImagePicker.MediaTypeOptions.Images,
192
- allowsEditing: true,
272
+ allowsEditing: false,
193
273
  aspect: [4, 3],
194
274
  quality: 0.8,
195
275
  base64: true,
196
- exif: false
276
+ exif: false,
277
+ allowsMultipleSelection: true
197
278
  });
198
279
  if (!(imageSource == null ? void 0 : imageSource.canceled)) {
199
- const selectedAsset = (_a2 = imageSource == null ? void 0 : imageSource.assets) == null ? void 0 : _a2[0];
200
- if (!selectedAsset) {
201
- setImageLoading(false);
280
+ const selectedAssets = (imageSource == null ? void 0 : imageSource.assets) || [];
281
+ if (selectedAssets.length === 0) {
282
+ setLoading(false);
202
283
  return;
203
284
  }
204
- const base64Data = selectedAsset.base64;
205
- const previewImage = base64Data ? `data:image/jpeg;base64,${base64Data}` : selectedAsset.uri;
206
- const asset = __spreadProps(__spreadValues({}, selectedAsset), {
207
- url: selectedAsset.uri,
208
- fileName: selectedAsset.fileName || `image_${Date.now()}.jpg`,
209
- mimeType: "image/jpeg"
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;
210
294
  });
211
- setImage(previewImage);
212
- setImages([asset]);
213
- setImageLoading(false);
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);
214
302
  } else {
215
- setImageLoading(false);
303
+ setLoading(false);
216
304
  }
217
305
  } catch (error) {
218
- console.error("Error selecting image:", error);
219
- setImageLoading(false);
306
+ setLoading(false);
220
307
  }
221
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);
222
326
  const handleSend = useCallback(async (message) => {
223
- var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2;
327
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2;
328
+ const newMessageText = message && message.length > 0 ? message || " " : " ";
224
329
  if (!channelId)
225
330
  return;
226
- if (!message && message !== " " && images.length === 0)
331
+ const hasText = !!newMessageText && newMessageText !== " ";
332
+ const hasImages = images && images.length > 0;
333
+ if (!hasText && !hasImages)
227
334
  return;
335
+ setLoading(true);
228
336
  const postId = objectId();
229
337
  const currentDate = new Date();
230
- setUploadingMessageId(postId);
231
- images.length > 0 ? {
232
- id: objectId(),
233
- name: ((_a2 = images[0]) == null ? void 0 : _a2.fileName) || "image.jpg",
234
- refType: FileRefType.Post,
235
- height: ((_b2 = images[0]) == null ? void 0 : _b2.height) || 0,
236
- width: ((_c2 = images[0]) == null ? void 0 : _c2.width) || 0
237
- } : null;
238
- ({
239
- message: message || (images.length > 0 ? " " : ""),
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 ? " " : ""),
240
350
  createdAt: currentDate.toISOString(),
241
351
  author: {
242
- id: (_d2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _d2.id,
243
- givenName: (_e2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _e2.given_name,
244
- familyName: (_f2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _f2.family_name,
245
- picture: (_g2 = auth == null ? void 0 : auth.profile) == null ? void 0 : _g2.picture
246
- }});
247
- setMsg("");
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
+ }
248
382
  try {
249
383
  let fileIds = null;
250
- if (images && images.length > 0) {
251
- setLoading(true);
252
- const imagesToUpload = images.map((img) => {
253
- return __spreadProps(__spreadValues({}, img), {
254
- uri: img.uri || img.url,
255
- type: img.mimeType || "image/jpeg",
256
- name: img.fileName || `image_${Date.now()}.jpg`
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
+ });
257
396
  });
258
- });
259
- const uploadResponse = await startUpload({
260
- file: imagesToUpload,
261
- saveUploadedFile: {
262
- variables: {
263
- postId
397
+ setUploadingMessageId(postId);
398
+ setPendingUploads((prev) => __spreadProps(__spreadValues({}, prev), {
399
+ [postId]: {
400
+ images: validImages,
401
+ message: currentMessageText
264
402
  }
265
- },
266
- createUploadLink: {
267
- variables: {
268
- postId
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
  }
416
+ });
417
+ if (uploadResponse == null ? void 0 : uploadResponse.error) {
418
+ throw new Error(uploadResponse.error.toString());
270
419
  }
271
- });
272
- if (uploadResponse == null ? void 0 : uploadResponse.error)
273
- throw new Error(uploadResponse.error.toString());
274
- const uploadedFiles = uploadResponse.data;
275
- if (uploadResponse.data) {
276
- setImage("");
277
- setFiles([]);
278
- setImages([]);
279
- fileIds = (_h2 = uploadedFiles == null ? void 0 : uploadedFiles.map((f) => f.id)) != null ? _h2 : null;
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
+ });
280
445
  }
281
446
  }
282
447
  await sendThreadMessage({
@@ -286,11 +451,37 @@ const ThreadConversationViewComponent = ({
286
451
  postThreadId: postThread && (postThread == null ? void 0 : postThread.id),
287
452
  postParentId: !parentId || parentId === 0 ? null : parentId,
288
453
  threadMessageInput: {
289
- content: message,
454
+ content: currentMessageText,
290
455
  files: fileIds,
291
456
  role
292
457
  }
293
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
+ },
294
485
  update: (cache, {
295
486
  data: data2,
296
487
  errors
@@ -307,17 +498,31 @@ const ThreadConversationViewComponent = ({
307
498
  sendPushNotification(lastMessageId, channelId, parentId, (_g3 = (_f3 = data2 == null ? void 0 : data2.createPostThread) == null ? void 0 : _f3.data) == null ? void 0 : _g3.id);
308
499
  }
309
500
  });
310
- setChannelMessages((oldMessages) => oldMessages.map((msg2) => msg2.id === postId ? __spreadProps(__spreadValues({}, msg2), {
311
- isDelivered: true
312
- }) : msg2));
313
501
  } catch (error) {
314
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);
315
518
  setChannelMessages((oldMessages) => oldMessages.filter((msg2) => msg2.id !== postId));
519
+ removeMessageFromUI(postId);
316
520
  } finally {
317
521
  setLoading(false);
522
+ setIsUploadingImage(false);
318
523
  setUploadingMessageId(null);
319
524
  }
320
- }, [auth, channelId, channelToTop, images, parentId, postThread, selectedImage, setChannelMessages]);
525
+ }, [auth, channelId, channelToTop, images, parentId, postThread, selectedImage, setChannelMessages, removeMessageFromUI, role]);
321
526
  const sendPushNotification = async (messageId, channelId2, parentId2, threadId) => {
322
527
  var _a2;
323
528
  const notificationData = {
@@ -352,7 +557,7 @@ const ThreadConversationViewComponent = ({
352
557
  }) => id) : [];
353
558
  if (filteredMessages == null ? void 0 : filteredMessages.length) {
354
559
  orderBy(filteredMessages, ["createdAt"], ["desc"]).map((msg2) => {
355
- 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;
356
561
  let message = {
357
562
  _id: "",
358
563
  text: "",
@@ -372,7 +577,27 @@ const ThreadConversationViewComponent = ({
372
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,
373
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,
374
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
375
- }, 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;
376
601
  message.type = msg2 == null ? void 0 : msg2.type;
377
602
  message.propsConfiguration = msg2 == null ? void 0 : msg2.propsConfiguration;
378
603
  res.push(message);
@@ -383,12 +608,32 @@ const ThreadConversationViewComponent = ({
383
608
  }) => _id) : [];
384
609
  }, [channelMessages]);
385
610
  const renderSend = useCallback((props) => {
386
- return /* @__PURE__ */ React__default.createElement(Send, __spreadValues({}, props), /* @__PURE__ */ React__default.createElement(Box, null, /* @__PURE__ */ React__default.createElement(MaterialCommunityIcons, { name: "send-circle", style: {
387
- marginBottom: 5,
388
- marginRight: 5
389
- }, size: 32, color: "#2e64e5" })));
390
- }, []);
391
- const renderMessageText = 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) => {
392
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;
393
638
  const {
394
639
  currentMessage
@@ -441,12 +686,124 @@ const ThreadConversationViewComponent = ({
441
686
  } }));
442
687
  }
443
688
  }, [navigation, role]);
444
- const renderActions = (props) => {
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)
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) => {
445
799
  return /* @__PURE__ */ React__default.createElement(
446
800
  Actions,
447
801
  __spreadProps(__spreadValues({}, props), {
802
+ onPressActionButton: onSelectImages,
448
803
  options: {
449
- ["Choose from Library"]: onSelectImages,
804
+ ["Choose from Library"]: () => {
805
+ onSelectImages();
806
+ },
450
807
  ["Cancel"]: () => {
451
808
  }
452
809
  },
@@ -461,88 +818,86 @@ const ThreadConversationViewComponent = ({
461
818
  }
462
819
  })
463
820
  );
464
- };
465
- const renderAccessory = useCallback(() => {
466
- var _a2;
467
- if (!selectedImage) {
821
+ }, [onSelectImages]);
822
+ useCallback(() => {
823
+ if (!images.length)
468
824
  return null;
469
- }
470
- return /* @__PURE__ */ React__default.createElement(View, { style: {
825
+ return /* @__PURE__ */ React__default.createElement(Box, { style: {
826
+ position: "relative",
471
827
  height: 70,
472
- backgroundColor: "white",
473
- borderTopWidth: 1,
474
- borderTopColor: "#e0e0e0",
475
- flexDirection: "row",
476
- alignItems: "center",
477
- margin: 0,
478
- padding: 0,
479
- paddingVertical: 0,
480
- position: "absolute",
481
- bottom: Platform.OS === "ios" ? 105 : 95,
482
- left: 0,
483
- right: 0,
484
- zIndex: 1,
485
- elevation: 3,
486
- shadowColor: "#000",
487
- shadowOffset: {
488
- width: 0,
489
- height: -1
490
- },
491
- shadowOpacity: 0.05,
492
- shadowRadius: 2
493
- } }, /* @__PURE__ */ React__default.createElement(View, { style: {
494
- flex: 1,
828
+ backgroundColor: "transparent",
829
+ justifyContent: "center"
830
+ } }, /* @__PURE__ */ React__default.createElement(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, style: {
495
831
  flexDirection: "row",
496
- alignItems: "center",
497
832
  paddingLeft: 15,
498
833
  paddingRight: 5
499
- } }, /* @__PURE__ */ React__default.createElement(View, { style: {
500
- width: 56,
501
- height: 56,
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,
502
840
  marginRight: 15,
503
841
  borderRadius: 4,
504
842
  backgroundColor: colors.gray[200],
505
843
  overflow: "hidden",
506
844
  borderWidth: 1,
507
- borderColor: "#e0e0e0"
508
- } }, /* @__PURE__ */ React__default.createElement(Image, { key: selectedImage, alt: "selected image", source: {
509
- uri: selectedImage
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
510
850
  }, style: {
511
851
  width: "100%",
512
852
  height: "100%"
513
- }, size: "md" }), loading && /* @__PURE__ */ React__default.createElement(View, { style: {
514
- position: "absolute",
515
- top: 0,
516
- left: 0,
517
- right: 0,
518
- bottom: 0,
519
- backgroundColor: "rgba(255, 255, 255, 0.7)",
520
- justifyContent: "center",
521
- alignItems: "center"
522
- } }, /* @__PURE__ */ React__default.createElement(Spinner, { size: "small", color: colors.blue[500] }))), /* @__PURE__ */ React__default.createElement(View, { style: {
523
- flex: 1
524
- } }, /* @__PURE__ */ React__default.createElement(Text, { style: {
525
- fontSize: 14,
526
- fontWeight: "400",
527
- color: colors.gray[800]
528
- } }, ((_a2 = images[0]) == null ? void 0 : _a2.fileName) || "image_" + new Date().getTime() + ".jpg"), /* @__PURE__ */ React__default.createElement(Text, { style: {
529
- fontSize: 12,
530
- color: colors.gray[500],
531
- marginTop: 2
532
- } }, loading ? "Preparing..." : "Ready to send")), /* @__PURE__ */ React__default.createElement(TouchableHighlight, { underlayColor: "rgba(0,0,0,0.1)", onPress: () => {
533
- setFiles([]);
534
- setImage("");
535
- setImages([]);
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
+ }
536
860
  }, style: {
537
- backgroundColor: colors.red[500],
538
- borderRadius: 24,
539
- width: 36,
540
- height: 36,
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,
541
868
  alignItems: "center",
542
869
  justifyContent: "center",
543
- marginRight: 10
544
- } }, /* @__PURE__ */ React__default.createElement(Ionicons, { name: "close", size: 20, color: "white" }))));
545
- }, [selectedImage, loading, images]);
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]);
546
901
  const setImageViewerObject = useCallback((obj, v) => {
547
902
  setImageObject(obj);
548
903
  setImageViewer(v);
@@ -562,38 +917,55 @@ const ThreadConversationViewComponent = ({
562
917
  expiresIn: 86400
563
918
  }, alt: "image" });
564
919
  }, [imageObject]);
565
- const renderMessage = useCallback((props) => {
920
+ useCallback((props) => {
566
921
  const {
567
922
  currentMessage
568
923
  } = props;
569
- const isUploading = currentMessage._id === uploadingMessageId && loading;
570
- if (isUploading) {
571
- return /* @__PURE__ */ React__default.createElement(Box, { className: "p-3 mb-2 mr-3 self-end rounded-2xl bg-gray-100 max-w-[80%]" }, currentMessage.text && currentMessage.text.trim() !== "" && /* @__PURE__ */ React__default.createElement(Box, { className: "h-4 mb-2 rounded bg-gray-200 overflow-hidden" }, /* @__PURE__ */ React__default.createElement(Skeleton, { variant: "rounded", className: "flex-1" })), currentMessage.image && /* @__PURE__ */ React__default.createElement(Box, { className: "h-[150px] w-[150px] rounded-lg bg-gray-200 overflow-hidden mt-1" }, /* @__PURE__ */ React__default.createElement(Box, { className: "flex-1 items-center justify-center" }, /* @__PURE__ */ React__default.createElement(Spinner, { size: "small", color: colors.blue[500] })), /* @__PURE__ */ React__default.createElement(Skeleton, { variant: "rounded", className: "flex-1" })));
572
- }
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) => {
573
933
  return /* @__PURE__ */ React__default.createElement(Message, __spreadProps(__spreadValues({}, props), { isShowImageViewer, setImageViewer: setImageViewerObject }));
574
- }, [uploadingMessageId, loading, isShowImageViewer, setImageViewerObject]);
575
- const renderInputToolbar = useCallback((props) => {
576
- return /* @__PURE__ */ React__default.createElement(InputToolbar, __spreadProps(__spreadValues({}, props), { containerStyle: {
577
- backgroundColor: "white",
578
- borderTopWidth: 1,
579
- borderTopColor: colors.gray[200],
580
- paddingHorizontal: 4,
581
- paddingVertical: 0,
582
- paddingTop: 2,
583
- marginBottom: 0,
584
- marginTop: 0
585
- }, primaryStyle: {
586
- alignItems: "center"
587
- } }));
588
- }, []);
934
+ }, [isShowImageViewer]);
935
+ useCallback((props) => {
936
+ if (isActionSheetVisible)
937
+ return null;
938
+ return /* @__PURE__ */ React__default.createElement(
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]
947
+ },
948
+ primaryStyle: {
949
+ alignItems: "center",
950
+ justifyContent: "center",
951
+ flex: 1
952
+ }
953
+ })
954
+ );
955
+ }, [isActionSheetVisible, onSelectImages]);
589
956
  const renderLoadEarlier = useCallback(() => {
590
- return loadingOldMessages ? /* @__PURE__ */ React__default.createElement(Box, { style: {
957
+ return loadingOldMessages && !refreshing ? /* @__PURE__ */ React__default.createElement(Box, { style: {
591
958
  padding: 10,
592
959
  backgroundColor: "rgba(255,255,255,0.8)",
593
960
  borderRadius: 10,
594
- marginTop: 10
595
- } }, /* @__PURE__ */ React__default.createElement(Spinner, { size: "small", color: colors.blue[500] })) : null;
596
- }, [loadingOldMessages]);
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]);
597
969
  let onScroll = false;
598
970
  const onMomentumScrollBegin = ({
599
971
  nativeEvent
@@ -608,84 +980,126 @@ const ThreadConversationViewComponent = ({
608
980
  return;
609
981
  onScroll = false;
610
982
  };
611
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, 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: {
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: {
612
1030
  borderRadius: 6,
613
1031
  borderWidth: 2,
614
1032
  borderColor: "#fff"
615
1033
  }, source: {
616
1034
  uri: (_e = (_d = threadPost[0]) == null ? void 0 : _d.author) == null ? void 0 : _e.picture
617
- } })), /* @__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(GiftedChat, { ref: threadMessageListRef, wrapInSafeArea: true, renderLoading: () => /* @__PURE__ */ React__default.createElement(Skeleton, { variant: "rounded", style: {
618
- flex: 1
619
- } }), messages: messageList, listViewProps: {
620
- onEndReached,
621
- onEndReachedThreshold: 0.5,
622
- onMomentumScrollBegin
623
- }, onSend: (messages) => {
624
- var _a2, _b2;
625
- return handleSend((_b2 = (_a2 = messages[0]) == null ? void 0 : _a2.text) != null ? _b2 : " ");
626
- }, text: msg ? msg : " ", onInputTextChanged: (text) => setMsg(text), renderFooter: () => null, scrollToBottom: true, user: {
627
- _id: (auth == null ? void 0 : auth.id) || ""
628
- }, isTyping: false, alwaysShowSend: true, infiniteScroll: true, renderSend, renderMessageText, renderInputToolbar, minInputToolbarHeight: 50, renderActions, renderAccessory: !!selectedImage ? renderAccessory : void 0, renderMessage, renderLoadEarlier, loadEarlier: totalCount > channelMessages.length, isLoadingEarlier: loadingOldMessages, bottomOffset: Platform.OS === "ios" ? 10 : 0, textInputProps: {
629
- style: {
630
- borderWidth: 1,
631
- borderColor: colors.gray[300],
632
- backgroundColor: "#f8f8f8",
633
- borderRadius: 20,
634
- minHeight: 36,
635
- maxHeight: 80,
636
- color: "#000",
637
- padding: 8,
638
- paddingHorizontal: 15,
639
- fontSize: 16,
640
- flex: 1,
641
- marginVertical: 2,
642
- marginBottom: 0
643
- },
644
- multiline: true,
645
- returnKeyType: "default",
646
- enablesReturnKeyAutomatically: true,
647
- placeholderTextColor: colors.gray[400]
648
- }, minComposerHeight: 36, maxComposerHeight: 100, placeholder: "Type a message...", 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({
649
- document: OnThreadChatMessageAddedDocument,
650
- variables: {
651
- channelId: channelId == null ? void 0 : channelId.toString(),
652
- postParentId: !parentId || parentId == 0 ? null : parentId == null ? void 0 : parentId.toString()
653
- },
654
- updateQuery: (prev, {
655
- subscriptionData
656
- }) => {
657
- var _a2, _b2, _c2;
658
- if (!subscriptionData.data)
659
- return prev;
660
- const newMessage = (_a2 = subscriptionData == null ? void 0 : subscriptionData.data) == null ? void 0 : _a2.threadChatMessageAdded;
661
- const prevReplyCount = (_b2 = prev == null ? void 0 : prev.getPostThread) == null ? void 0 : _b2.replyCount;
662
- const newReplyCount = prevReplyCount || 0 + 1;
663
- const replies = ((_c2 = prev == null ? void 0 : prev.getPostThread) == null ? void 0 : _c2.replies) || [];
664
- setChannelMessages((oldMessages) => uniqBy([...oldMessages, newMessage], ({
665
- id
666
- }) => id));
667
- setTotalCount(newReplyCount);
668
- return Object.assign({}, prev, {
669
- getPostThread: __spreadProps(__spreadValues({}, prev == null ? void 0 : prev.getPostThread), {
670
- lastReplyAt: newMessage.createdAt,
671
- replies: [newMessage, ...replies],
672
- replyCount: newReplyCount,
673
- updatedAt: newMessage.createdAt
674
- })
675
- });
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,
1037
+ {
1038
+ ref: threadMessageListRef,
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
+ } }),
1051
+ messages: messageList,
1052
+ listViewProps: {
1053
+ onEndReached,
1054
+ onEndReachedThreshold: 0.5,
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] })
1064
+ },
1065
+ onSend: (messages) => {
1066
+ var _a2, _b2;
1067
+ return handleSend((_b2 = (_a2 = messages[0]) == null ? void 0 : _a2.text) != null ? _b2 : " ");
1068
+ },
1069
+ text: msg || " ",
1070
+ onInputTextChanged: (text) => setMsg(text),
1071
+ renderFooter: () => null,
1072
+ scrollToBottom: true,
1073
+ user: {
1074
+ _id: (auth == null ? void 0 : auth.id) || ""
1075
+ },
1076
+ placeholder: "Jot something down",
1077
+ infiniteScroll: true,
1078
+ renderSend,
1079
+ renderMessageText,
1080
+ renderMessage,
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 ? {
1095
+ transform: [{
1096
+ scaleY: -1
1097
+ }]
1098
+ } : {}), {
1099
+ paddingTop: 0
1100
+ })
676
1101
  }
677
- }) })), messagesContainerStyle: (messageList == null ? void 0 : messageList.length) == 0 && {
678
- transform: [{
679
- scaleY: -1
680
- }]
681
- }, 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: {
682
- underlayColor: "transparent",
683
- springConfig: {
684
- tension: 9e4,
685
- friction: 9e4
686
- },
687
- disabled: true
688
- } }));
1102
+ ));
689
1103
  };
690
1104
  const SubscriptionHandler = ({
691
1105
  subscribeToNewMessages,