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,178 @@
1
+ import React, { useRef, useState } from 'react';
2
+ import styled from 'styled-components';
3
+ import ImageComponent from '../../../components/ImageComponent';
4
+ import client from '../../../utils/chatSdk';
5
+ import { getMediaUrl, uploadPicturePresignedURl, userProfilePicturePlaceholder, checkFileSize, checkLetterUppercase } from '../../../lib/helpers';
6
+ import OutsideAlerter from '../../../components/OutsideAlerter/OutsideAlerter';
7
+ import TakeProfilePhoto from './TakeProfilePhoto';
8
+ import Toaster from '../Toaster/Toaster';
9
+ import ProfilePictureUploadPreview from '../../../components/Modal/ProfilePictureUploadPreview';
10
+ import CustomModal from '../../../components/CustomModal';
11
+
12
+
13
+ const ProfilePictureTextContainer = styled.div`
14
+ position: absolute;
15
+ top: 0;
16
+ width: 200px;
17
+ height: 200px;
18
+ border-radius: 50%;
19
+ background: var(--photopicker_overlay_background);
20
+ justify-content: center;
21
+ cursor: pointer;
22
+ `;
23
+
24
+ const ProfilePictureText = styled.p`
25
+ text-transform: uppercase;
26
+ color: #fff;
27
+ font-size: 0.8rem;
28
+ overflow-wrap: break-word;
29
+ margin-bottom: 0;
30
+ margin-top: 5px;
31
+ text-align: center;
32
+ `;
33
+
34
+ const ProfilePictureTextImageContainer = styled.div`
35
+ max-width: 60px;
36
+ display: flex;
37
+ flex-direction: column;
38
+ align-items: center;
39
+ justify-content: center;
40
+ .camera_icon{
41
+ width: 30px;
42
+ height: 30px;
43
+ }
44
+ `;
45
+
46
+ const ProfileModalContainer = styled.div`
47
+ background-color: var(--modal_color);
48
+ color: var(--black);
49
+ position: absolute;
50
+ top: 50%;
51
+ left: 50%;
52
+ z-index: 999;
53
+ -webkit-transform: translate(0%,0%);
54
+ -ms-transform: translate(0%,0%);
55
+ transform: translate(0%,0%);
56
+ padding: 20px;
57
+ box-shadow: 0 4px 8px 0 rgb(0 0 0 / 20%), 0 6px 20px 0 rgb(0 0 0 / 19%);
58
+ border-radius: 3px;
59
+ display: flex;
60
+ flex-direction: column;
61
+ gap: 10px;
62
+
63
+ `;
64
+
65
+ const ProfileModalOptionText = styled.p`
66
+ color: var(--black);
67
+ margin-bottom: 0px;
68
+ cursor: pointer;
69
+ `;
70
+
71
+ const ProfileUpdate = (props) => {
72
+ const { setUpdateUserDetails, updateUserProfile, showImageUploaderOption, setUserDetails, setShowProfilePicture, theme, updateUserDetails, setShowUsernameInvalid, setNameDisable } = props;
73
+ const [showProfileModal, setShowProfileModal] = useState(false);
74
+ const [isTakePhotoModal, setIsTakePhotoModal] = useState(false);
75
+ const [toastStatus, setToastStatus] = useState({open: false, message: '', variant: ''});
76
+ const [getUploadedProfilePictureLink, setGetUploadedProfilePictureLink] = useState('');
77
+ const uploadFileRef = useRef(null);
78
+ const profileOptions = [{ id: 1, title: 'View Photo' }, { id: 2, title: 'Take Photo' }, { id: 3, title: 'Upload Photo' }, { id: 4, title: 'Remove Photo' }];
79
+
80
+ const uploadProfileData = (data) => {
81
+ if (data.id === 3) {
82
+ uploadFileRef.current.click();
83
+ }else if (data.id === 4) {
84
+ updateProfileImageRequest(userProfilePicturePlaceholder);
85
+ }else if (data.id === 1) {
86
+ setShowProfilePicture({showProfile: true, userName: updateUserDetails.userName , userImageSrc: updateUserDetails.userProfileImageUrl, theme: theme});
87
+ }else if( data.id === 2){
88
+ setIsTakePhotoModal(true);
89
+ }
90
+ setShowProfileModal(false);
91
+ }
92
+
93
+ const updateProfileImageRequest = (mediaUrl) => {
94
+ setUpdateUserDetails((prev) => {
95
+ return{
96
+ ...prev,
97
+ userName: updateUserDetails?.userName,
98
+ userProfileImageUrl: mediaUrl
99
+ }
100
+ })
101
+ setUserDetails((prev) => {
102
+ return{
103
+ ...prev,
104
+ userName: updateUserDetails?.userName,
105
+ userProfileImageUrl: mediaUrl
106
+ }
107
+ })
108
+ const body = {
109
+ userName: updateUserDetails?.userName,
110
+ userProfileImageUrl: mediaUrl
111
+ };
112
+ try {
113
+ const res = client.user.patchUser(body);
114
+ setToastStatus({open: true, variant:"success", message: 'Profile updated successfully' });
115
+ setNameDisable(true);
116
+ } catch (error) {
117
+ setToastStatus({open: true, variant:"error", message: 'Profile updated fail!' });
118
+ }
119
+
120
+ }
121
+
122
+ const uploadMediaChange = async (e) => {
123
+ setShowProfileModal(false);
124
+ const file = e.target.files[0];
125
+ setGetUploadedProfilePictureLink(URL.createObjectURL(file));
126
+ e.target.value = null;
127
+ }
128
+
129
+ return (
130
+ <>
131
+ <ProfilePictureTextContainer className='profile_picture_uploader' showImageUploaderOption={showImageUploaderOption} onClick={() => setShowProfileModal(true)} >
132
+ <ProfilePictureTextImageContainer>
133
+ <ImageComponent className={'camera_icon'} src={'https://www.shutterstock.com/image-vector/photo-camera-lens-button3d-vector-600w-2087249068.jpg'} alt="camera_icon" />
134
+ <ProfilePictureText>{'Change Profile Photo'}</ProfilePictureText>
135
+ </ProfilePictureTextImageContainer>
136
+ <input ref={uploadFileRef} onChange={uploadMediaChange} type='file' style={{ display: 'none' }} accept="image/png, image/gif, image/jpeg" />
137
+ </ProfilePictureTextContainer>
138
+ {
139
+ showProfileModal &&
140
+ <OutsideAlerter onClose={() => setShowProfileModal(false)} >
141
+ <ProfileModalContainer>
142
+ {
143
+ profileOptions.map((data, index) => (
144
+ <ProfileModalOptionText key={data.id}
145
+ onClick={() => uploadProfileData(data)}
146
+ >{data.title}</ProfileModalOptionText>
147
+ ))
148
+ }
149
+ </ProfileModalContainer>
150
+ </OutsideAlerter>
151
+ }
152
+ {
153
+ getUploadedProfilePictureLink.length > 0 &&
154
+ <CustomModal backDropClick={true} open={getUploadedProfilePictureLink.length} onClose={() => setGetUploadedProfilePictureLink('')}>
155
+ <ProfilePictureUploadPreview theme={theme}
156
+ imageUrl={getUploadedProfilePictureLink}
157
+ isActive={getUploadedProfilePictureLink.length} updateProfileImageRequest={updateProfileImageRequest}
158
+ onClose={() => setGetUploadedProfilePictureLink('')}
159
+ updateUserDetails={updateUserDetails}
160
+ setToastStatus={setToastStatus}
161
+ uploadFileRef={uploadFileRef}
162
+ />
163
+ </CustomModal>
164
+ }
165
+
166
+ {
167
+ isTakePhotoModal &&
168
+ <TakeProfilePhoto isTakePhotoModal={isTakePhotoModal} theme={theme} onClose={() => setIsTakePhotoModal(false)} updateProfileImageRequest={updateProfileImageRequest} setIsTakePhotoModal={setIsTakePhotoModal} setShowUsernameInvalid={setShowUsernameInvalid} updateUserDetails={updateUserDetails} setNameDisable={setNameDisable} />
169
+ }
170
+
171
+ {
172
+ <Toaster message={toastStatus.message} variant={toastStatus.variant} open={toastStatus.open} onClose={() => setToastStatus({open: false})} theme={theme} />
173
+ }
174
+ </>
175
+ )
176
+ }
177
+
178
+ export default ProfileUpdate;
@@ -0,0 +1,391 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import styled, { css } from 'styled-components';
3
+ import OutsideAlerter from '../../../components/OutsideAlerter/OutsideAlerter';
4
+ import ImageComponent from '../../../components/ImageComponent';
5
+ import { CAMERA_RETAKE, CAMERA_SWITCH, CLOSE_ICON, CORRECT_ICON } from '../../../utils/global';
6
+ import { checkFileSize, checkLetterUppercase, dataURLtoFile, getMediaUrl, uploadPicturePresignedURl } from '../../../lib/helpers';
7
+ import Loader from '../Loader/Loader';
8
+ import CustomModal from '../../../components/CustomModal';
9
+ import CameraPermissionBlockedModal from '../../../components/Modal/CameraPermissionBlockedModal';
10
+ import CameraPermissionRequestModal from '../../../components/Modal/CameraPermissionRequestModal';
11
+ import Toaster from '../Toaster/Toaster';
12
+ import { mobile } from '../../../utils/media';
13
+ import useDeviceType from '../../../hooks/useDeviceType';
14
+ import ImageCropper from '../ImageCropper/ImageCropper';
15
+
16
+ const TakeProfilePhotoWrapper = styled.div`
17
+ height: 100vh;
18
+ width: 100vw;
19
+ top: 0;
20
+ left: 0;
21
+ background-color: var(--modal-backdrop);
22
+ position: fixed;
23
+ border: none;
24
+ z-index: 1001;
25
+ cursor: default;
26
+ visibility: hidden;
27
+ ${(props) =>
28
+ props.isActive &&
29
+ css`
30
+ visibility: visible;
31
+ opacity: 1;
32
+ transform: translateY(0);
33
+ `}
34
+
35
+ .cross_icon{
36
+ width: 24px;
37
+ height: 24px;
38
+ }
39
+ `;
40
+
41
+ const TakePhotoContainer = styled.div`
42
+ background-color: var(--modal_color);
43
+ color: var(--black);
44
+ position: absolute;
45
+ max-width: 500px;
46
+ max-height: 700px;
47
+ top: 50%;
48
+ left: 50%;
49
+ -webkit-transform: translate(-50%,-50%);
50
+ -ms-transform: translate(-50%,-50%);
51
+ transform: translate(-50%,-50%);
52
+ padding: ${props => props.isPadding ? '0 2rem' : 'unset'};
53
+ padding-bottom: 3rem;
54
+ visibility: hidden;
55
+ ${(props) =>
56
+ props.isActive &&
57
+ css`
58
+ visibility: visible;
59
+ opacity: 1;
60
+ `}
61
+ ${mobile(css`
62
+ width: 100%;
63
+ height: 80%;
64
+ `)}
65
+
66
+ .video_play{
67
+ width: 500px;
68
+ height: 375px;
69
+ max-width: 500px;
70
+ max-height: 500px;
71
+ ${mobile(css`
72
+ width: 100%;
73
+ height: 100%;
74
+ max-height: 480px;
75
+ `)}
76
+ }
77
+
78
+ .user_clicked_pic{
79
+ width: 500px;
80
+ height: 400px;
81
+ border-radius: 0;
82
+ ${mobile(css`
83
+ width: 100%;
84
+ `)}
85
+ }
86
+ `;
87
+
88
+ const CameraIconContainer = styled.div`
89
+ width: 60px;
90
+ height: 60px;
91
+ border-radius: 50%;
92
+ background-color: var(--profile-name);
93
+ display: ${props => !props.isActive ? 'flex' : 'none'};
94
+ justify-content: center;
95
+ align-items: center;
96
+ position: absolute;
97
+ left: 50%;
98
+ transform: translate(-50%, 0%);
99
+ bottom: -20px;
100
+ cursor: pointer;
101
+
102
+ ${mobile(css`
103
+ bottom: 0;
104
+ `)}
105
+
106
+ .camera_icon{
107
+ width: 24px;
108
+ height: 24px;
109
+ }
110
+ `;
111
+
112
+ const TakePhotoHeader = styled.div`
113
+ width: 100%;
114
+ display: flex;
115
+ justify-content: space-between;
116
+ padding: 1rem 2rem;
117
+ ${mobile(css`
118
+ padding: 1rem;
119
+ `)}
120
+ .header_wrapper{
121
+ display: flex;
122
+ }
123
+ `;
124
+
125
+ const TakePhotoHeaderText = styled.p`
126
+ margin-bottom: 0;
127
+ color: var(--black);
128
+ margin-left: 1rem;
129
+ padding-top:${props => props.isPaddingTop ? '2rem' : 'unset'};
130
+ `;
131
+
132
+ const ClickedImageWrapper = styled.div`
133
+ position: relative;
134
+ ${mobile(css`
135
+ height: 100%;
136
+ display: flex;
137
+ align-items: center;
138
+ `)}
139
+ `;
140
+
141
+ const CorrectIconWrapper = styled.div`
142
+ width: 60px;
143
+ height: 60px;
144
+ border-radius: 50%;
145
+ background-color: var(--profile-name);
146
+ display: flex;
147
+ justify-content: center;
148
+ align-items: center;
149
+ position: absolute;
150
+ right: 50px;
151
+ bottom: -30px;
152
+
153
+ ${mobile(css`
154
+ bottom: 0;
155
+ `)}
156
+
157
+ img{
158
+ width: 30px;
159
+ height: 30px;
160
+ }
161
+ `;
162
+
163
+ const VideoWrapper = styled.div`
164
+ display: ${props => !props.isActive ? 'block' : 'none'};
165
+ ${mobile(css`
166
+ height: 100%;
167
+ `)}
168
+ `
169
+
170
+ const LoaderWrapper = styled.div`
171
+ display: ${props => props.isActive ? 'block' : 'none'};
172
+ `;
173
+
174
+ const LoaderVideoContainer = styled.div`
175
+ position: relative;
176
+ ${mobile(css`
177
+ height: 100%;
178
+ `)}
179
+ `;
180
+
181
+ const ModalAllowCameraCTA = styled.button`
182
+ border: none;
183
+ padding: 10px 20px;
184
+ background: var(--profile-name);
185
+ color: #fff;
186
+ border-radius: 45px;
187
+ margin: 2rem 0 0;
188
+ `;
189
+
190
+ const ModalHeaderTitle = styled.h3`
191
+ font-size: 2rem;
192
+ color: var(--black);
193
+ padding-top: 2rem;
194
+ margin-left: 1rem;
195
+ margin-bottom: 1rem;
196
+ `;
197
+
198
+ const CameraSwitchContainer = styled.div`
199
+ display: flex;
200
+ align-items: center;
201
+
202
+ .camera_switch{
203
+ width: 20px;
204
+ height: 20px;
205
+ filter: ${props => props.theme ? ' invert(1) ' : ''} ;
206
+ }
207
+ `;
208
+
209
+ const TakeProfilePhoto = (props) => {
210
+ const { isTakePhotoModal, onClose, updateProfileImageRequest, setIsTakePhotoModal, setShowUsernameInvalid, updateUserDetails, setNameDisable, theme } = props;
211
+ const [getClickedPictureUrl, setGetClickedPictureUrl] = useState('');
212
+ const [takePhoto, setTakePhoto] = useState(true);
213
+ const [currentStream, setCurrentStream] = useState('');
214
+ const [loaderStatus, setLoaderStatus] = useState(true);
215
+ const [notAllowCameraPermission, setNotAllowCameraPermission] = useState(false);
216
+ const [accessCamera, setAccessCamera] = useState(false);
217
+ const [toastStatus, setToastStatus] = useState({ open: false, message: '', variant: '' });
218
+ const [isCameraSwitch, setIsCameraSwitch] = useState(false);
219
+ const [rotateCameraIcon, setRotateCameraIcon] = useState(true);
220
+ const [croppedImg, setCroppedImg] = useState("");
221
+ const isMobile = useDeviceType();
222
+
223
+
224
+ const closeStream = (stream) => {
225
+ setRotateCameraIcon(false);
226
+ const tracks = stream.getTracks();
227
+ tracks.forEach(function (track) {
228
+ track.stop();
229
+ });
230
+ }
231
+
232
+ useEffect(() => {
233
+ if (!takePhoto) return;
234
+ let newFacingMode;
235
+ if (isCameraSwitch) {
236
+ const videoTrack = currentStream.getVideoTracks()[0];
237
+ const currentFacingMode = videoTrack.getSettings().facingMode;
238
+ newFacingMode = currentFacingMode === 'user' ? 'environment' : 'user';
239
+ videoTrack.stop();
240
+ }
241
+ setLoaderStatus(true);
242
+ const video = document.querySelector("video");
243
+ const canvas = document.createElement("canvas");
244
+ const ctx = canvas.getContext("2d");
245
+ const takePictureButton = document.querySelector("#take-picture");
246
+ setAccessCamera(true);
247
+ navigator.mediaDevices
248
+ .getUserMedia({ video: isCameraSwitch ? { facingMode: newFacingMode } : true })
249
+ .then((stream) => {
250
+ setAccessCamera(false);
251
+ video.srcObject = stream;
252
+ video.play();
253
+ setCurrentStream(stream);
254
+ takePictureButton.addEventListener('click', () => closeStream(stream));
255
+ })
256
+ .catch((err) => {
257
+ setAccessCamera(false);
258
+ setNotAllowCameraPermission(true);
259
+ console.error(err);
260
+ });
261
+
262
+ takePictureButton.addEventListener("click", () => {
263
+ // Set the canvas dimensions to match the video dimensions
264
+ canvas.width = video.videoWidth;
265
+ canvas.height = video.videoHeight;
266
+
267
+ // Draw the current video frame onto the canvas
268
+ ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
269
+
270
+ // Convert the canvas image data to a base64-encoded URL
271
+ const imageDataUrl = canvas.toDataURL();
272
+ setTakePhoto(false);
273
+ setGetClickedPictureUrl(imageDataUrl);
274
+ });
275
+ setTimeout(() => {
276
+ setLoaderStatus(false);
277
+ }, 900);
278
+ }, [takePhoto, isCameraSwitch]);
279
+
280
+ const submitHandler = async () => {
281
+ const file = dataURLtoFile(croppedImg, 'myimage.png');
282
+ const { valid, error } = checkFileSize(file);
283
+ const isValidUsername = checkLetterUppercase(updateUserDetails?.userName);
284
+ if (valid && isValidUsername) {
285
+ const response = await uploadPicturePresignedURl(file.type);
286
+ if (response?.presignedUrl) {
287
+ onClose();
288
+ const uploadImage = await getMediaUrl(response?.presignedUrl, file, file.type);
289
+ updateProfileImageRequest(response?.mediaUrl);
290
+ }
291
+ } else {
292
+ setShowUsernameInvalid(true);
293
+ allowCameraModalHandler();
294
+ if (isValidUsername) {
295
+ setToastStatus({ open: true, message: error, variant: 'error' });
296
+ }
297
+ }
298
+ }
299
+
300
+ const closeModalCameraAccessHandler = () => {
301
+ currentStream && closeStream(currentStream);
302
+ onClose();
303
+ }
304
+
305
+ const allowCameraModalHandler = () => {
306
+ onClose();
307
+ }
308
+ return (
309
+ <>
310
+ <TakeProfilePhotoWrapper isActive={isTakePhotoModal} className="App">
311
+ <OutsideAlerter onClose={closeModalCameraAccessHandler}>
312
+ <TakePhotoContainer isActive={!notAllowCameraPermission && !accessCamera}>
313
+ <TakePhotoHeader>
314
+ <div className='header_wrapper'>
315
+ <ImageComponent
316
+ id="takePhotoModal"
317
+ onClick={closeModalCameraAccessHandler}
318
+ src={CLOSE_ICON}
319
+ className={`${props?.theme ? "darkicons" : "lighticons"} cross_icon`}
320
+ />
321
+ <TakePhotoHeaderText>{getClickedPictureUrl.length ? 'Drag the image to adjust' : 'Take Photo'}</TakePhotoHeaderText>
322
+ </div>
323
+ {
324
+ getClickedPictureUrl.length > 0 &&
325
+ <div onClick={() => {
326
+ setGetClickedPictureUrl('');
327
+ setTakePhoto(true);
328
+ setRotateCameraIcon(true);
329
+ }} className='header_wrapper pointer'>
330
+ <ImageComponent
331
+ src={CAMERA_RETAKE}
332
+ className={`${props?.theme ? "darkicons" : "lighticons"} cross_icon`}
333
+ />
334
+ <TakePhotoHeaderText>{'Retake'}</TakePhotoHeaderText>
335
+ </div>
336
+ }
337
+
338
+ {
339
+ rotateCameraIcon && isMobile &&
340
+ <CameraSwitchContainer theme={theme}>
341
+ <ImageComponent className="camera_switch" src={CAMERA_SWITCH} alt="camera_switch" />
342
+ <TakePhotoHeaderText onClick={() => setIsCameraSwitch(!isCameraSwitch)}>{'Rotate camera'}</TakePhotoHeaderText>
343
+ </CameraSwitchContainer>
344
+ }
345
+
346
+ </TakePhotoHeader>
347
+ <>
348
+ {
349
+ getClickedPictureUrl?.length > 0 &&
350
+ <>
351
+ <ClickedImageWrapper >
352
+ <ImageCropper setCroppedImg={setCroppedImg} imageUrl={getClickedPictureUrl} />
353
+ <CorrectIconWrapper>
354
+ <ImageComponent onClick={submitHandler} className={`darkicons`} src={CORRECT_ICON} alt={"correct_icon"} />
355
+ </CorrectIconWrapper>
356
+ </ClickedImageWrapper>
357
+
358
+ </>
359
+ }
360
+ <LoaderVideoContainer>
361
+ <VideoWrapper isActive={getClickedPictureUrl}>
362
+ <video className='video_play'></video>
363
+ <CameraIconContainer isActive={getClickedPictureUrl} id='take-picture'>
364
+ <ImageComponent className={'camera_icon'} src={'https://www.shutterstock.com/image-vector/photo-camera-lens-button3d-vector-600w-2087249068.jpg'} alt={'camera_icon'} />
365
+ </CameraIconContainer>
366
+ </VideoWrapper>
367
+ </LoaderVideoContainer>
368
+ </>
369
+ </TakePhotoContainer>
370
+ </OutsideAlerter>
371
+ </TakeProfilePhotoWrapper>
372
+ {
373
+ notAllowCameraPermission &&
374
+ <CustomModal open={notAllowCameraPermission} backDropClick={true} onClose={allowCameraModalHandler} >
375
+ <CameraPermissionBlockedModal onClick={allowCameraModalHandler} />
376
+ </CustomModal>
377
+ }
378
+ {
379
+ accessCamera &&
380
+ <CustomModal open={accessCamera} backDropClick={true} onClose={allowCameraModalHandler} >
381
+ <CameraPermissionRequestModal onClick={allowCameraModalHandler} />
382
+ </CustomModal>
383
+ }
384
+ {
385
+ <Toaster message={toastStatus.message} variant={toastStatus.variant} open={toastStatus.open} onClose={() => setToastStatus({ open: false })} theme={theme} />
386
+ }
387
+ </>
388
+ );
389
+ }
390
+
391
+ export default TakeProfilePhoto;