isometrik-chat 0.1.0

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 (188) hide show
  1. package/README.md +74 -0
  2. package/babel.config.js +6 -0
  3. package/dist/index.js +684 -0
  4. package/package.json +59 -0
  5. package/public/Logo-192x192.png +0 -0
  6. package/public/Logo-512x512.png +0 -0
  7. package/public/favicon.ico +0 -0
  8. package/public/fonts/BenjaminVictoria.ttf +0 -0
  9. package/public/icons/arrow_logo.svg +9 -0
  10. package/public/icons/assets/ic_placeholder_banner.svg +1 -0
  11. package/public/icons/attach-file.svg +9 -0
  12. package/public/icons/audio_pause.svg +1 -0
  13. package/public/icons/audio_play.svg +6 -0
  14. package/public/icons/back.svg +3 -0
  15. package/public/icons/bell.svg +1 -0
  16. package/public/icons/block.svg +1 -0
  17. package/public/icons/bottom-arrow.svg +1 -0
  18. package/public/icons/camera-switch.svg +12 -0
  19. package/public/icons/camera.svg +4 -0
  20. package/public/icons/cancel.svg +1 -0
  21. package/public/icons/chat empty placeholder.svg +58 -0
  22. package/public/icons/chat_audio_pause.png +0 -0
  23. package/public/icons/chat_audio_play.png +0 -0
  24. package/public/icons/close.svg +5 -0
  25. package/public/icons/crossCarousel.svg +3 -0
  26. package/public/icons/delete.svg +3 -0
  27. package/public/icons/disappear.svg +24 -0
  28. package/public/icons/document.png +0 -0
  29. package/public/icons/document.svg +1 -0
  30. package/public/icons/downloadCarousel.svg +6 -0
  31. package/public/icons/edit-pencil.svg +6 -0
  32. package/public/icons/emoji.svg +8 -0
  33. package/public/icons/emojiCarousel.svg +3 -0
  34. package/public/icons/filter.svg +1 -0
  35. package/public/icons/forwardCarousel.svg +3 -0
  36. package/public/icons/gallery.svg +1 -0
  37. package/public/icons/goToMessageCarousel.svg +3 -0
  38. package/public/icons/ic_uil_arrow-left.svg +1 -0
  39. package/public/icons/ic_uil_eye-slash.svg +1 -0
  40. package/public/icons/ic_uil_eye.svg +1 -0
  41. package/public/icons/leftArrowCarousel.svg +6 -0
  42. package/public/icons/light-mode.svg +14 -0
  43. package/public/icons/lock.svg +1 -0
  44. package/public/icons/login_background.png +0 -0
  45. package/public/icons/menu .svg +5 -0
  46. package/public/icons/menuCarousel.svg +5 -0
  47. package/public/icons/message.svg +3 -0
  48. package/public/icons/placeholder.svg +958 -0
  49. package/public/icons/poll.svg +1 -0
  50. package/public/icons/retake.png +0 -0
  51. package/public/icons/right-arrow.svg +3 -0
  52. package/public/icons/right.svg +3 -0
  53. package/public/icons/round-star.svg +1 -0
  54. package/public/icons/search.svg +3 -0
  55. package/public/icons/send.svg +10 -0
  56. package/public/icons/starCarousel.svg +3 -0
  57. package/public/icons/status.svg +1 -0
  58. package/public/icons/sticker.svg +1 -0
  59. package/public/icons/thumb-down.svg +1 -0
  60. package/public/icons/user.svg +1 -0
  61. package/public/icons/users.svg +1 -0
  62. package/public/icons/voice.png +0 -0
  63. package/public/index.html +38 -0
  64. package/public/logo192.png +0 -0
  65. package/public/logo512.png +0 -0
  66. package/public/manifest.json +25 -0
  67. package/public/offline.html +12 -0
  68. package/public/robots.txt +3 -0
  69. package/public/service-worker.js +81 -0
  70. package/src/App.js +15 -0
  71. package/src/App.test.js +8 -0
  72. package/src/Authpage.js +16 -0
  73. package/src/ChatContext.js +172 -0
  74. package/src/Data/index.js +110 -0
  75. package/src/assets/icons.js +49 -0
  76. package/src/assets/images/WhatsApp.html +258 -0
  77. package/src/assets/images/WhatsApp_files/301446776_522918349234681_1974693392291574064_n.jpg +0 -0
  78. package/src/assets/images/WhatsApp_files/app-bf223f825866ee433b07.css +242 -0
  79. package/src/assets/images/WhatsApp_files/app.77ee8aa7a4c593101105.js +77 -0
  80. package/src/assets/images/WhatsApp_files/lazy_loaded_high_priority_components.85a06e74a0a4ade1640b.css +16 -0
  81. package/src/assets/images/WhatsApp_files/lazy_loaded_low_priority_components.8621270bc215a9298a97.css +47 -0
  82. package/src/assets/images/WhatsApp_files/libsignal-protocol-ee5b8ba.min.js +21 -0
  83. package/src/assets/images/WhatsApp_files/main.48b845d68e066fb27a75.css +161 -0
  84. package/src/assets/images/WhatsApp_files/runtime.e6018f3c1e255e8f4dc7.js +2 -0
  85. package/src/assets/images/WhatsApp_files/stylex-d50abd61e6cf7eab2afd855adccf14e5.css +2841 -0
  86. package/src/assets/images/WhatsApp_files/vendor1_app.58a51d93a250f83ab555.js +79 -0
  87. package/src/assets/images/bg.jpeg +0 -0
  88. package/src/assets/images/drkbg.jpg +0 -0
  89. package/src/assets/images/notFound.jpeg +0 -0
  90. package/src/assets/images/watsapp.jpg +0 -0
  91. package/src/assets/images/watsappbg.png +0 -0
  92. package/src/assets/images/wb.jpg +0 -0
  93. package/src/assets/images/whatsapp.jpeg +0 -0
  94. package/src/components/ChatBox/AudioBubble.js +162 -0
  95. package/src/components/ChatBox/ChatBubble.js +232 -0
  96. package/src/components/ChatBox/DocumentBubble.js +87 -0
  97. package/src/components/ChatBox/MessagesBox.js +533 -0
  98. package/src/components/CustomModal.js +60 -0
  99. package/src/components/Icon.js +10 -0
  100. package/src/components/ImageComponent.js +24 -0
  101. package/src/components/MediaDocs.js +155 -0
  102. package/src/components/MediaDocumentContainer.js +55 -0
  103. package/src/components/MessageInfoDropdown.js +124 -0
  104. package/src/components/Modal/AllowMicPermissionModal.js +63 -0
  105. package/src/components/Modal/BlockUnblockChatModal.js +78 -0
  106. package/src/components/Modal/CameraPermissionBlockedModal.js +61 -0
  107. package/src/components/Modal/CameraPermissionRequestModal.js +60 -0
  108. package/src/components/Modal/ClearChatModal.js +78 -0
  109. package/src/components/Modal/DeleteChatModal.js +79 -0
  110. package/src/components/Modal/MicPermissionDisableModal.js +63 -0
  111. package/src/components/Modal/Modal.js +103 -0
  112. package/src/components/Modal/ModalDialog.js +103 -0
  113. package/src/components/Modal/ProfilePictureUploadPreview.js +160 -0
  114. package/src/components/OutsideAlerter/OutsideAlerter.js +38 -0
  115. package/src/components/ProfilePicture/ProfilePicture.js +127 -0
  116. package/src/components/Registration/Login.js +265 -0
  117. package/src/components/Registration/SignUp.js +322 -0
  118. package/src/components/SnackBar.js +42 -0
  119. package/src/components/common/Modal/useDetectOutsideClick.js +23 -0
  120. package/src/components/common/styled/PageWrapper.js +25 -0
  121. package/src/components/formcontrol/CustomButton.js +38 -0
  122. package/src/components/formcontrol/InputText.js +60 -0
  123. package/src/global-styles.js +42 -0
  124. package/src/hooks/useDeviceType.js +28 -0
  125. package/src/hooks/useThrottle.js +29 -0
  126. package/src/index.css +225 -0
  127. package/src/index.js +23 -0
  128. package/src/lib/constant.js +21 -0
  129. package/src/lib/functionality.js +13 -0
  130. package/src/lib/helpers.js +320 -0
  131. package/src/lib/mockData/index.js +76 -0
  132. package/src/lib/session/index.js +31 -0
  133. package/src/lib/validation.js +4 -0
  134. package/src/logo.svg +1 -0
  135. package/src/pages/WhatsappMainBox/index.js +574 -0
  136. package/src/reportWebVitals.js +13 -0
  137. package/src/services/deliveryStatus.js +27 -0
  138. package/src/setupTests.js +5 -0
  139. package/src/utils/chatSdk.js +14 -0
  140. package/src/utils/global.js +57 -0
  141. package/src/utils/media.js +79 -0
  142. package/src/view/component/BlockedContactSlide.js +134 -0
  143. package/src/view/component/Carousle/UpperMenuBar.js +106 -0
  144. package/src/view/component/Carousle/index.js +204 -0
  145. package/src/view/component/Chatbox.js/AudioRecorder.js +311 -0
  146. package/src/view/component/Chatbox.js/ChatBubbleReply.js +27 -0
  147. package/src/view/component/Chatbox.js/TakePhoto.js +363 -0
  148. package/src/view/component/Chatbox.js/index.js +856 -0
  149. package/src/view/component/Chatbox.js/styles.css +231 -0
  150. package/src/view/component/Contact/index.js +56 -0
  151. package/src/view/component/Contact/styles.css +208 -0
  152. package/src/view/component/ContactInfo/index.js +543 -0
  153. package/src/view/component/ContactInfo/styles.css +289 -0
  154. package/src/view/component/Context/index.js +3 -0
  155. package/src/view/component/DialogBox.js +15 -0
  156. package/src/view/component/ImageCropper/ImageCropper.js +128 -0
  157. package/src/view/component/Loader/Loader.js +52 -0
  158. package/src/view/component/Loader/UserPagingLoader.js +62 -0
  159. package/src/view/component/MainChatBox/index.js +819 -0
  160. package/src/view/component/MainChatBox/styles.css +124 -0
  161. package/src/view/component/Menu/index.js +261 -0
  162. package/src/view/component/Menu/styles.css +68 -0
  163. package/src/view/component/Profile/ProfileInfoContainer.js +112 -0
  164. package/src/view/component/Profile/ProfileUpdate.js +178 -0
  165. package/src/view/component/Profile/TakeProfilePhoto.js +391 -0
  166. package/src/view/component/Profile/index.js +550 -0
  167. package/src/view/component/Profile/styles.css +370 -0
  168. package/src/view/component/ReplyChatMessage/ReplyChatMessage.js +48 -0
  169. package/src/view/component/SeachBar/index.js +106 -0
  170. package/src/view/component/SeachBar/styles.css +53 -0
  171. package/src/view/component/Siderbar/index.js +512 -0
  172. package/src/view/component/Siderbar/styles.css +138 -0
  173. package/src/view/component/Toaster/Toaster.js +117 -0
  174. package/src/view/component/UserDetailsCard/UserDetailCard.js +337 -0
  175. package/src/view/component/deleteMessageMoal.js +80 -0
  176. package/src/view/component/emoji/index.js +22 -0
  177. package/src/view/component/emoji/sstyles.css +0 -0
  178. package/src/view/component/forwardData/index.js +327 -0
  179. package/src/view/component/forwardData/styles.css +112 -0
  180. package/src/view/component/forwardPopup/index.js +55 -0
  181. package/src/view/component/forwardPopup/styles.css +144 -0
  182. package/src/view/component/mediaList/index.js +92 -0
  183. package/src/view/component/menuDialog/index.js +71 -0
  184. package/src/view/component/menuDialog/styles.css +24 -0
  185. package/src/view/component/pagination/pagination.js +52 -0
  186. package/src/view/component/pagination/paginationForMsg.js +43 -0
  187. package/src/view/component/sidebarChat/index.js +321 -0
  188. package/src/view/component/sidebarChat/styles.css +109 -0
@@ -0,0 +1,533 @@
1
+ import React, { useEffect, useRef, useState } from "react";
2
+ import styled, { css } from "styled-components";
3
+ import ChatBubble from "./ChatBubble";
4
+ import Icon from "../Icon";
5
+ import { getCookie } from "../../lib/session";
6
+ import { getMediaUrl, getMessageDateSorted, mediaUploadValidator, validDocumentType } from "../../lib/helpers";
7
+ import { BOTTOM_ARROW } from "../../utils/global";
8
+ import { mobile } from "../../utils/media";
9
+ import SliderCarousal from "../../view/component/Carousle";
10
+ import DialogBox from "../../view/component/DialogBox";
11
+ import client from "../../utils/chatSdk";
12
+ import UpperMenuBar from "../../view/component/Carousle/UpperMenuBar";
13
+ import { MESSAGE_DELETE_FOR_ALL, MESSAGE_DELETE_LOCAL } from "../../lib/constant";
14
+ import Toaster from "../../view/component/Toaster/Toaster";
15
+ import ImageComponent from "../ImageComponent";
16
+
17
+ const ChatMessagesSection = styled.section`
18
+ display: flex;
19
+ justify-content: center;
20
+ margin: 15px 0 10px;
21
+ height: 100%;
22
+ ${mobile(css`
23
+ height: calc(100% - 10px)
24
+ `)}
25
+
26
+ .block {
27
+ display: block;
28
+ }
29
+
30
+ .hidden {
31
+ display: none;
32
+ }
33
+
34
+ .mediaContainer {
35
+ max-width: 21rem;
36
+ ${mobile(css`
37
+ max-width: 14rem;
38
+ `)}
39
+ }
40
+
41
+ .user_self_chat {
42
+ margin: 0.25rem 0 0.25rem auto;
43
+ max-width: 65%;
44
+ border-radius: 7.5px;
45
+ --wt-bg-opacity: 1;
46
+ padding:0.2rem 0.4rem;
47
+ background-color: var(--sender_chatbg);
48
+ position:relative;
49
+ ${mobile(css`
50
+ max-width: 90%;
51
+ `)}
52
+ }
53
+
54
+ .user_chat {
55
+ margin: 0.25rem 0;
56
+ max-width: 65%;
57
+ padding: 0.5rem;
58
+ width: fit-content;
59
+ border-bottom-right-radius: 7.5px;
60
+ border-bottom-left-radius: 7.5px;
61
+ --tw-bg-opacity: 1;
62
+ background-color: var(--white);
63
+ position:relative;
64
+
65
+ ${mobile(css`
66
+ max-width: 90%;
67
+ `)}
68
+ }
69
+ `;
70
+
71
+ const ChatMessagesMain = styled.div`
72
+ width: 100%;
73
+ display: flex;
74
+ flex-direction: column;
75
+ margin-bottom: 12px;
76
+ position: relative;
77
+ height: 100%;
78
+
79
+ .user_self_chat:first-of-type{
80
+ margin-top: auto !important;
81
+ }
82
+
83
+ .user_chat:first-of-type {
84
+ margin-top: auto !important;
85
+ }
86
+ `;
87
+
88
+ const ChatDateWrapper = styled.div`
89
+ text-align: center;
90
+ margin: 10px 0 14px;
91
+ position: relative;
92
+ `;
93
+
94
+ const ChatDate = styled.span`
95
+ background-color: var(--gray_color);
96
+ display: inline-block;
97
+ color: var(--black);
98
+ font-size: 0.75rem;
99
+ padding: 7px 10px;
100
+ border-radius: 5px;
101
+ max-width: fit-content;
102
+ margin: 0 auto;
103
+ box-shadow: 0 1px 0.5px rgba(var(--shadow-rgb),.13);
104
+ `;
105
+
106
+ const StickyChatDate = styled.span`
107
+ background-color: var(--gray_color);
108
+ position: fixed;
109
+ margin-top: 10px;
110
+ color: var(--black);
111
+ font-size: 0.75rem;
112
+ padding: 7px 10px;
113
+ border-radius: 5px;
114
+ z-index: 10;
115
+ box-shadow: 0 1px 0.5px rgba(var(--shadow-rgb),.13);
116
+ `;
117
+
118
+ const ScrollToBottom = styled.div`
119
+ position: fixed;
120
+ bottom: 90px;
121
+ right: 35px;
122
+ z-index: 10;
123
+ cursor: pointer;
124
+ border-radius: 50%;
125
+ padding: 6px;
126
+ background: white;
127
+ box-shadow: 0 0 10px rgba(0,0,0, 0.3);
128
+ ${mobile(css`
129
+ right: 15px;
130
+ `)}
131
+ `;
132
+
133
+ const ChatEncryptionMsg = styled.div`
134
+ background-color: var(--sender_chatbg);
135
+ color: var(--encrypted_color);
136
+ font-size: 0.77rem;
137
+ text-align: center;
138
+ padding: 5px 10px;
139
+ position: relative;
140
+ margin-bottom: 8px;
141
+ border-radius: 5px;
142
+ line-height: 20px;
143
+ `;
144
+
145
+ const ChatEncryptionIcon = styled(Icon)`
146
+ color: var(--encrypted_color);
147
+ margin: 0 5px 3px;
148
+ `;
149
+
150
+ const ChatImageSent = styled.div`
151
+ position: relative;
152
+ max-width: 280px;
153
+ max-height: 339px;
154
+ .chat_image{
155
+ width: 100%;
156
+ height: 100%;
157
+ }
158
+
159
+ `;
160
+
161
+ const ImageOverlay = styled.div`
162
+ width: 100%;
163
+ height: 100px;
164
+ position: absolute;
165
+ bottom: 0;
166
+ background-image: linear-gradient(rgba(0, 0, 0, 0) 70%, rgba(0, 0, 0, 0.6) 100%);
167
+ `;
168
+
169
+ const ChatVideo = styled.video`
170
+ max-height: 340px;
171
+ object-fit: contain;
172
+ `;
173
+
174
+
175
+ const MessagesBox = (props) => {
176
+ const {
177
+ chatProfileData,
178
+ getUsersChatMessagesDetail,
179
+ conversationId,
180
+ findUserId,
181
+ state,
182
+ setState,
183
+ chatContainerRef,
184
+ theme,
185
+ setslideShow,
186
+ setMessageInfo,
187
+ messageInfo,
188
+ setMessageChat,
189
+ setSearchShow,
190
+ setIsReply,
191
+ isReply,
192
+ setReply,
193
+ reply,
194
+ setDeleteMessage,
195
+ deleteMessage,
196
+ isDelete,
197
+ setMediaDocs,
198
+ userDetails,
199
+ handleImgVidClick,
200
+ setIsOpen,
201
+ isOpen
202
+ } = props;
203
+ const messages =
204
+ Object.keys(getUsersChatMessagesDetail).length > 0 &&
205
+ !!getUsersChatMessagesDetail?.[conversationId]
206
+ ? getUsersChatMessagesDetail[conversationId]?.length > 0
207
+ ? [...getUsersChatMessagesDetail[conversationId]]?.reverse()
208
+ : [getUsersChatMessagesDetail[conversationId]]?.reverse()
209
+ : "";
210
+
211
+ const [allMsg, setAllMsg] = useState([]);
212
+ const [deliverMessage, setDeliverMessage] = useState("");
213
+ const [readMessage, setReadMessage] = useState("");
214
+ const dateWithMessages = new Set([]);
215
+ const dateBadgesArr = [];
216
+ const [stickyDateBadge, setStickyDateBadge] = useState('');
217
+ const [showBadge, setShowBadge] = useState(false);
218
+ const [ showBottomScroller, setShowBottomScroller ] = useState(false);
219
+ // const [isOpen, setIsOpen] = useState(false);
220
+ const [toastStatus, setToastStatus] = useState({open: false, message: '', variant: ''});
221
+
222
+
223
+ useEffect(() => {
224
+ setAllMsg([...messages]);
225
+
226
+ }, [messages.length]);
227
+
228
+ // Commenting the reply message code as we don't need this feature now -
229
+ // const getReplyMessageData = (chat) => {
230
+ // const replyData = allMsg.filter(replyMessage => replyMessage.messageId === chat?.parentMessageId)[0];
231
+ // return replyData;
232
+ // }
233
+
234
+ // useEffect(() => {
235
+ // // component.scrollTo({
236
+ // // left: 0,
237
+ // // top: document?.body?.scrollHeight,
238
+ // // behavior: "smooth",
239
+ // // });
240
+ // const component = document.getElementById("chat-messages");
241
+ // component.scrollTo(0, document.documentElement.scrollHeight);
242
+ // }, [messages]);
243
+
244
+ const userId = getCookie("userId");
245
+
246
+
247
+ const handleOnDrop = (e) => {
248
+ try {
249
+ e.preventDefault();
250
+ e.stopImmediatePropagation();
251
+ const confirmSendMedia = window.confirm(`Are you sure you want to send ${e.dataTransfer.files.length} files?`);
252
+
253
+ let filesObj = {};
254
+ for (const file of e.dataTransfer.files) {
255
+ const { valid, error } = mediaUploadValidator(file);
256
+ if (!valid) {
257
+ setToastStatus({ open: true, message: error, variant: 'error' });
258
+ return;
259
+ }
260
+ const mediaId = String(new Date().getTime() + Math.floor(Math.random() * 1000));
261
+ filesObj[mediaId] = {
262
+ nameWithExtension: file?.name,
263
+ mediaType: 0,
264
+ mediaId,
265
+ size: file?.size,
266
+ mimeType: file?.type,
267
+ file
268
+ }
269
+ }
270
+
271
+ if(confirmSendMedia) uploadAndSendMedia(filesObj);
272
+ }
273
+ catch(error) {
274
+ console.log('error while dropping files in the chat box -- ', error);
275
+ setToastStatus({ open: true, message: error.messages || 'Error while dropping files, please try again!', variant: 'error' });
276
+ }
277
+ }
278
+
279
+ const handleOnDragover = (e) => {
280
+ e.preventDefault();
281
+ }
282
+
283
+ const uploadAndSendMedia = async (filesObj) => {
284
+ try {
285
+ const presignedUrlPayload = {
286
+ conversationId,
287
+ attachments: Object.values(filesObj)
288
+ }
289
+ const response = await client?.message?.postMessagesPresignedurls(presignedUrlPayload);
290
+ if (response?.presignedUrls) {
291
+ response?.presignedUrls.forEach(async (element) => {
292
+ const attachmentsForImg = [];
293
+ const fileExtensionType = filesObj[element?.mediaId].mimeType.split('/')[1];
294
+ attachmentsForImg.push({
295
+ thumbnailUrl: element?.thumbnailUrl,
296
+ mediaUrl: element?.mediaUrl,
297
+ mediaId: element?.mediaId,
298
+ size: filesObj[element?.mediaId].size,
299
+ mimeType: filesObj[element?.mediaId].mimeType,
300
+ name: filesObj[element?.mediaId].nameWithExtension,
301
+ extension: fileExtensionType,
302
+ attachmentType: 0
303
+ })
304
+ await getMediaUrl(element?.mediaPresignedUrl, filesObj[element.mediaId].file, filesObj[element.mediaId].file.type).then(async () => {
305
+ const messagePayload = {
306
+ showInConversation: true,
307
+ messageType: 0,
308
+ encrypted: true,
309
+ deviceId: 'PKQ1',
310
+ conversationId,
311
+ body: fileExtensionType === 'mp4' ? 'video' :
312
+ validDocumentType[fileExtensionType] ? 'document' : 'image',
313
+ parentMessageId: null,
314
+ metaData: null,
315
+ events: null,
316
+ attachments: attachmentsForImg,
317
+ notificationBody: `Sent you ${fileExtensionType === 'mp4' ? 'a video' :
318
+ validDocumentType[fileExtensionType] ? 'a document' : 'an image'} `,
319
+ notificationTitle: userDetails?.userName,
320
+ }
321
+ await client?.message?.postMessages(messagePayload);
322
+ }).catch((err) => {
323
+ console.log(err, 'err');
324
+ })
325
+ });
326
+ }
327
+ }
328
+ catch(err) {
329
+ console.log('error uploading files via drag and drop -- ', err )
330
+ }
331
+ }
332
+
333
+ const handleOnChatScroll = (e) => {
334
+ const showBottomScroller = (e.target.scrollTop + e.target.clientHeight) <= e.target.scrollHeight - 30;
335
+ setShowBottomScroller(showBottomScroller);
336
+ const isAtTop = e.target.scrollTop === 0;
337
+ const isAtBottom = e.target.scrollTop + e.target.clientHeight >= e.target.scrollHeight - 5;
338
+ if(isAtTop || isAtBottom) setShowBadge(false);
339
+ else setShowBadge(true);
340
+ }
341
+
342
+ const scrollToBottom = () => {
343
+ setTimeout(() => chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight, 100);
344
+ }
345
+
346
+ useEffect(() => {
347
+ if(!allMsg.length) return;
348
+ const component = document.getElementById("chat-messages");
349
+
350
+ if(allMsg[allMsg.length - 1]?.body) { // only for initial load or if we send/receive a new message
351
+ scrollToBottom();
352
+ }
353
+ // component.scrollTo({
354
+ // top: document.body.scrollHeight,
355
+ // behavior: "auto"
356
+ // });
357
+ component.addEventListener("scroll", handleOnChatScroll);
358
+ component.addEventListener("drop", handleOnDrop); // to get the files after they are dropped in the chat-box
359
+ component.addEventListener("dragover", handleOnDragover); // to enable drag and drop media files
360
+
361
+ const dateBadges = document.getElementsByClassName("date-badge");
362
+
363
+ const observer = new IntersectionObserver(([entry]) => {
364
+ const { top } = entry.boundingClientRect;
365
+
366
+ const isElementEnteringFromTop = entry.isIntersecting && top <= 110;
367
+ const isElementExitingFromTop = !entry.isIntersecting && top <= 110;
368
+
369
+
370
+ if(isElementEnteringFromTop) {
371
+ console.log('entry from top -- ', entry.target.innerHTML);
372
+ const idx = dateBadgesArr.findIndex((ele) => ele === entry.target.innerHTML);
373
+ if(idx <= dateBadgesArr.length - 1) {
374
+ setStickyDateBadge(dateBadgesArr[idx + 1]);
375
+ }
376
+ } else if(isElementExitingFromTop){
377
+ console.log('exit from top --- ', entry.target.innerHTML);
378
+ const idx = dateBadgesArr.findIndex((ele) => ele === entry.target.innerHTML);
379
+ setStickyDateBadge(dateBadgesArr[idx]);
380
+ }
381
+ }, { threshold: 1, rootMargin: '-100px 0px 0px 0px' })
382
+
383
+ if(dateBadges.length) {
384
+ Array.from(dateBadges).forEach(badge => observer.observe(badge));
385
+ }
386
+
387
+ return () => {
388
+ if(dateBadges.length) {
389
+ Array.from(dateBadges).forEach(badge => observer.unobserve(badge));
390
+ }
391
+ component.removeEventListener("scroll", handleOnChatScroll);
392
+ component.removeEventListener("drop", handleOnDrop);
393
+ component.removeEventListener("dragover", handleOnDragover);
394
+ }
395
+ }, [allMsg]);
396
+
397
+
398
+ const getDateBadge = (timeStamp) => {
399
+ if (dateWithMessages.has(getMessageDateSorted(timeStamp)) ) return;
400
+ dateWithMessages.add(getMessageDateSorted(timeStamp));
401
+ dateBadgesArr.unshift(getMessageDateSorted(timeStamp));
402
+ return <ChatDate className="date-badge">{ getMessageDateSorted(timeStamp)}</ChatDate>
403
+ }
404
+ const handleHoverOut = () => {
405
+ setIsOpen(false);
406
+ };
407
+
408
+ return (
409
+ <>
410
+ <ChatMessagesSection>
411
+ {/* <ChatDateWrapper> */}
412
+ {showBadge && <StickyChatDate>{stickyDateBadge}</StickyChatDate>}
413
+ {showBottomScroller && <ScrollToBottom onClick={scrollToBottom}><img src={BOTTOM_ARROW} alt="bottom_arrow_icon" /></ScrollToBottom>}
414
+ {/* </ChatDateWrapper> */}
415
+ {/* <ChatEncryptionMsg>
416
+ <ChatEncryptionIcon id="lock" className="chat__encryption-icon" />
417
+ Messages are end-to-end encrypted. No one outside of this chat, not even
418
+ WhatsApp, can read or listen to them. Click to learn more.
419
+ </ChatEncryptionMsg> */}
420
+ <ChatMessagesMain>
421
+ {allMsg &&
422
+ allMsg.map((chat, index) => {
423
+ if (chat.body) {
424
+ getMessageDateSorted(chat.sentAt);
425
+ }
426
+ return (
427
+ <>
428
+ {
429
+ (chat?.body || chat?.customType === 'audio') &&
430
+ <>
431
+ {getDateBadge(chat.sentAt)}
432
+ {chat.attachments && chat?.customType !== 'audio' && chat?.customType !== 'document' ?
433
+ chat.attachments.map((imgData, index) => (
434
+ <div
435
+ key={index}
436
+ onClick={() => handleImgVidClick(imgData?.mediaId)}
437
+ className={`d-flex flex-column pointer ${(chat.senderInfo?.userId || chat?.senderId) ===
438
+ chatProfileData?.userId
439
+ ? "user_chat mr-auto"
440
+ : "user_self_chat ml-auto"}`}>
441
+ {
442
+ imgData?.extension === 'mp4'
443
+ ?
444
+ <ChatVideo controls style={{ objectFit: 'contain' }}>
445
+ <source src={imgData.mediaUrl} type="video/mp4" />
446
+ </ChatVideo>
447
+ :
448
+ <ChatImageSent>
449
+ <ImageComponent className="chat_image" src={imgData.mediaUrl} alt="chat_image" />
450
+ <ImageOverlay />
451
+ </ChatImageSent>
452
+ }
453
+ <ChatBubble
454
+ chat={chat}
455
+ findUserId={findUserId}
456
+ state={state}
457
+ setState={setState}
458
+ chatProfileData={chatProfileData}
459
+ deliverMessage={deliverMessage}
460
+ readMessage={readMessage}
461
+ theme={theme}
462
+ setslideShow={setslideShow}
463
+ setMessageInfo={setMessageInfo}
464
+ messageInfo={messageInfo}
465
+ setMessageChat={setMessageChat}
466
+ setSearchShow={setSearchShow}
467
+ isMedia={chat?.attachments}
468
+ setIsReply={setIsReply}
469
+ isReply={isReply}
470
+ setReply={setReply}
471
+ reply={reply}
472
+ setDeleteMessage={setDeleteMessage}
473
+ deleteMessage={deleteMessage}
474
+ // getReplyMessageData={getReplyMessageData(chat)}
475
+ isOpen={isOpen}
476
+ setIsOpen={setIsOpen}
477
+
478
+ />
479
+ </div>
480
+ ))
481
+ :
482
+ <>
483
+ <div
484
+ key={index}
485
+ onMouseLeave={handleHoverOut}
486
+ className={`${(chat.senderInfo?.userId || chat?.senderId) ===
487
+ chatProfileData?.userId
488
+ ? "user_chat"
489
+ : "user_self_chat"
490
+ }`}
491
+ >
492
+ <ChatBubble
493
+ chat={chat}
494
+ findUserId={findUserId}
495
+ state={state}
496
+ setState={setState}
497
+ chatProfileData={chatProfileData}
498
+ deliverMessage={deliverMessage}
499
+ readMessage={readMessage}
500
+ theme={theme}
501
+ setslideShow={setslideShow}
502
+ setMessageInfo={setMessageInfo}
503
+ messageInfo={messageInfo}
504
+ setMessageChat={setMessageChat}
505
+ setSearchShow={setSearchShow}
506
+ isReply={isReply}
507
+ setIsReply={setIsReply}
508
+ setReply={setReply}
509
+ reply={reply}
510
+ setDeleteMessage={setDeleteMessage}
511
+ deleteMessage={deleteMessage}
512
+ // getReplyMessageData={getReplyMessageData(chat)}
513
+ isOpen={isOpen}
514
+ setIsOpen={setIsOpen}
515
+ />
516
+ </div>
517
+ </>
518
+ }
519
+ </>
520
+ }
521
+ </>
522
+ );
523
+ })}
524
+ </ChatMessagesMain>
525
+ </ChatMessagesSection>
526
+ {
527
+ <Toaster message={toastStatus.message} variant={toastStatus.variant} open={toastStatus.open} onClose={() => setToastStatus({open: false})} theme={theme} />
528
+ }
529
+ </>
530
+ );
531
+ };
532
+
533
+ export default MessagesBox;
@@ -0,0 +1,60 @@
1
+ import React from 'react'
2
+ import OutsideAlerter from './OutsideAlerter/OutsideAlerter';
3
+ const CustomModal = (props) => {
4
+ const {
5
+ modelWidth,
6
+ backDropClick = false, // close the model if clicked outside the model
7
+ onClose,
8
+ } = props;
9
+ return (
10
+ <>
11
+ {props.open ?
12
+ <div className='modal'>
13
+ <div className='model-content'>
14
+ {backDropClick
15
+ ? <OutsideAlerter onClose={onClose}>{props.children}</OutsideAlerter>
16
+ : <>{props.children}</>}
17
+ </div>
18
+ </div>
19
+ : null}
20
+ <style jsx>{`
21
+ .modal {
22
+ display: flex;
23
+ align-items: center;
24
+ justify-content: center;
25
+ position: fixed;
26
+ left: 0;
27
+ top: 0;
28
+ width: 100%;
29
+ height: 100vh;
30
+ overflow: auto;
31
+ background-color: var(--modal-backdrop);
32
+ }
33
+ .model-content {
34
+ width: ${modelWidth || '70vw'};
35
+ max-width: 70vw;
36
+ max-height: 90vh;
37
+ border-radius: 12px;
38
+ overflow: hidden;
39
+ // box-shadow: 0px 11px 15px -7px rgb(0 0 0 / 20%), 0px 24px 38px 3px rgb(0 0 0 / 14%), 0px 9px 46px 8px rgb(0 0 0 / 12%);
40
+ animation: popup 0.5s;
41
+ }
42
+ @keyframes popup {
43
+ 0%{
44
+ transform: scale(0.8);
45
+ }
46
+ 100%{
47
+ transform: scale(1);
48
+ }
49
+ }
50
+ @media(max-width: 576px) {
51
+ .model-content {
52
+ width: 90%;
53
+ }
54
+ }
55
+ `}</style>
56
+ </>
57
+ )
58
+ }
59
+
60
+ export default CustomModal;
@@ -0,0 +1,10 @@
1
+ import Icons from "../assets/icons";
2
+
3
+ const allIcons = Icons;
4
+
5
+ const Icon = ({ id, ...props }) => {
6
+ const selectedIcon = allIcons[id];
7
+ return selectedIcon ? selectedIcon(props) : null;
8
+ };
9
+
10
+ export default Icon;
@@ -0,0 +1,24 @@
1
+ import React from "react";
2
+ import { APP_NAME } from "../utils/global";
3
+
4
+ const ImageComponent = (props) => {
5
+ const { src, className, height, width, alt, loading, ...other } = props;
6
+
7
+ return (
8
+ <img
9
+ height={height || ""}
10
+ width={width || ""}
11
+ alt={alt || APP_NAME}
12
+ src={props.src}
13
+ loading={loading || "lazy"}
14
+ className={className}
15
+ {...other}
16
+ // onError={(e) => {
17
+ // e.target.onerror = null;
18
+ // e.target.src = "";
19
+ // }}
20
+ />
21
+ );
22
+ };
23
+
24
+ export default ImageComponent;