@ethora/chat-component-rn 26.5.4 → 26.5.7

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 (238) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/README.md +25 -4
  3. package/lib/commonjs/components/ContextMenu/ContextMenuComponents.js +1 -7
  4. package/lib/commonjs/components/ContextMenu/ContextMenuComponents.js.map +1 -1
  5. package/lib/commonjs/components/MainComponents/ChatHeader.js +7 -1
  6. package/lib/commonjs/components/MainComponents/ChatHeader.js.map +1 -1
  7. package/lib/commonjs/components/MainComponents/ChatRoom.js +8 -2
  8. package/lib/commonjs/components/MainComponents/ChatRoom.js.map +1 -1
  9. package/lib/commonjs/components/MainComponents/ChatWrapper.js +2 -1
  10. package/lib/commonjs/components/MainComponents/ChatWrapper.js.map +1 -1
  11. package/lib/commonjs/components/MainComponents/MediaMessage.js +11 -5
  12. package/lib/commonjs/components/MainComponents/MediaMessage.js.map +1 -1
  13. package/lib/commonjs/components/MainComponents/MessageList.js +10 -2
  14. package/lib/commonjs/components/MainComponents/MessageList.js.map +1 -1
  15. package/lib/commonjs/components/MessageBubble/Message.js +60 -7
  16. package/lib/commonjs/components/MessageBubble/Message.js.map +1 -1
  17. package/lib/commonjs/components/MessageBubble/MessageInteractions.js +1 -38
  18. package/lib/commonjs/components/MessageBubble/MessageInteractions.js.map +1 -1
  19. package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js +20 -28
  20. package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
  21. package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js +35 -16
  22. package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
  23. package/lib/commonjs/components/Modals/ModalWrapper/ModalWrapper.js +11 -2
  24. package/lib/commonjs/components/Modals/ModalWrapper/ModalWrapper.js.map +1 -1
  25. package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js +1 -1
  26. package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
  27. package/lib/commonjs/components/RoomComponents/styled/LastMessageEmoji.js +9 -6
  28. package/lib/commonjs/components/RoomComponents/styled/LastMessageEmoji.js.map +1 -1
  29. package/lib/commonjs/components/UsersList/Checkbox.js +68 -0
  30. package/lib/commonjs/components/UsersList/Checkbox.js.map +1 -0
  31. package/lib/commonjs/components/UsersList/StyledComponents.js +1 -7
  32. package/lib/commonjs/components/UsersList/StyledComponents.js.map +1 -1
  33. package/lib/commonjs/components/UsersList/UsersList.js +3 -1
  34. package/lib/commonjs/components/UsersList/UsersList.js.map +1 -1
  35. package/lib/commonjs/components/styled/MediaFilePreview.js +96 -5
  36. package/lib/commonjs/components/styled/MediaFilePreview.js.map +1 -1
  37. package/lib/commonjs/components/styled/MessageImage.js +1 -2
  38. package/lib/commonjs/components/styled/MessageImage.js.map +1 -1
  39. package/lib/commonjs/components/styled/SendInput.js +4 -2
  40. package/lib/commonjs/components/styled/SendInput.js.map +1 -1
  41. package/lib/commonjs/components/styled/VideoMessage.js +2 -10
  42. package/lib/commonjs/components/styled/VideoMessage.js.map +1 -1
  43. package/lib/commonjs/context/xmppProvider.js +71 -2
  44. package/lib/commonjs/context/xmppProvider.js.map +1 -1
  45. package/lib/commonjs/helpers/mimeToExtension.js +131 -0
  46. package/lib/commonjs/helpers/mimeToExtension.js.map +1 -0
  47. package/lib/commonjs/helpers/resolveInitBeforeLoadUser.js +73 -1
  48. package/lib/commonjs/helpers/resolveInitBeforeLoadUser.js.map +1 -1
  49. package/lib/commonjs/hooks/useChatWrapperInit.js +22 -10
  50. package/lib/commonjs/hooks/useChatWrapperInit.js.map +1 -1
  51. package/lib/commonjs/hooks/useEventHandlers.js +9 -1
  52. package/lib/commonjs/hooks/useEventHandlers.js.map +1 -1
  53. package/lib/commonjs/hooks/useMessageHeapState.js +6 -2
  54. package/lib/commonjs/hooks/useMessageHeapState.js.map +1 -1
  55. package/lib/commonjs/hooks/useSendMessage.js +48 -4
  56. package/lib/commonjs/hooks/useSendMessage.js.map +1 -1
  57. package/lib/commonjs/networking/api-requests/auth.api.js +7 -1
  58. package/lib/commonjs/networking/api-requests/auth.api.js.map +1 -1
  59. package/lib/commonjs/networking/xmppClient.js +87 -1
  60. package/lib/commonjs/networking/xmppClient.js.map +1 -1
  61. package/lib/commonjs/roomStore/roomHeapSlice.js +26 -8
  62. package/lib/commonjs/roomStore/roomHeapSlice.js.map +1 -1
  63. package/lib/module/components/ContextMenu/ContextMenuComponents.js +0 -6
  64. package/lib/module/components/ContextMenu/ContextMenuComponents.js.map +1 -1
  65. package/lib/module/components/MainComponents/ChatHeader.js +7 -1
  66. package/lib/module/components/MainComponents/ChatHeader.js.map +1 -1
  67. package/lib/module/components/MainComponents/ChatRoom.js +8 -2
  68. package/lib/module/components/MainComponents/ChatRoom.js.map +1 -1
  69. package/lib/module/components/MainComponents/ChatWrapper.js +2 -1
  70. package/lib/module/components/MainComponents/ChatWrapper.js.map +1 -1
  71. package/lib/module/components/MainComponents/MediaMessage.js +11 -5
  72. package/lib/module/components/MainComponents/MediaMessage.js.map +1 -1
  73. package/lib/module/components/MainComponents/MessageList.js +11 -3
  74. package/lib/module/components/MainComponents/MessageList.js.map +1 -1
  75. package/lib/module/components/MessageBubble/Message.js +60 -7
  76. package/lib/module/components/MessageBubble/Message.js.map +1 -1
  77. package/lib/module/components/MessageBubble/MessageInteractions.js +3 -40
  78. package/lib/module/components/MessageBubble/MessageInteractions.js.map +1 -1
  79. package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js +21 -29
  80. package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
  81. package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js +36 -17
  82. package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
  83. package/lib/module/components/Modals/ModalWrapper/ModalWrapper.js +11 -2
  84. package/lib/module/components/Modals/ModalWrapper/ModalWrapper.js.map +1 -1
  85. package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js +1 -1
  86. package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
  87. package/lib/module/components/RoomComponents/styled/LastMessageEmoji.js +9 -6
  88. package/lib/module/components/RoomComponents/styled/LastMessageEmoji.js.map +1 -1
  89. package/lib/module/components/UsersList/Checkbox.js +63 -0
  90. package/lib/module/components/UsersList/Checkbox.js.map +1 -0
  91. package/lib/module/components/UsersList/StyledComponents.js +0 -6
  92. package/lib/module/components/UsersList/StyledComponents.js.map +1 -1
  93. package/lib/module/components/UsersList/UsersList.js +2 -1
  94. package/lib/module/components/UsersList/UsersList.js.map +1 -1
  95. package/lib/module/components/styled/MediaFilePreview.js +97 -6
  96. package/lib/module/components/styled/MediaFilePreview.js.map +1 -1
  97. package/lib/module/components/styled/MessageImage.js +1 -2
  98. package/lib/module/components/styled/MessageImage.js.map +1 -1
  99. package/lib/module/components/styled/SendInput.js +4 -2
  100. package/lib/module/components/styled/SendInput.js.map +1 -1
  101. package/lib/module/components/styled/VideoMessage.js +2 -10
  102. package/lib/module/components/styled/VideoMessage.js.map +1 -1
  103. package/lib/module/context/xmppProvider.js +73 -3
  104. package/lib/module/context/xmppProvider.js.map +1 -1
  105. package/lib/module/helpers/mimeToExtension.js +124 -0
  106. package/lib/module/helpers/mimeToExtension.js.map +1 -0
  107. package/lib/module/helpers/resolveInitBeforeLoadUser.js +71 -0
  108. package/lib/module/helpers/resolveInitBeforeLoadUser.js.map +1 -1
  109. package/lib/module/hooks/useChatWrapperInit.js +22 -10
  110. package/lib/module/hooks/useChatWrapperInit.js.map +1 -1
  111. package/lib/module/hooks/useEventHandlers.js +9 -1
  112. package/lib/module/hooks/useEventHandlers.js.map +1 -1
  113. package/lib/module/hooks/useMessageHeapState.js +6 -2
  114. package/lib/module/hooks/useMessageHeapState.js.map +1 -1
  115. package/lib/module/hooks/useSendMessage.js +49 -5
  116. package/lib/module/hooks/useSendMessage.js.map +1 -1
  117. package/lib/module/networking/api-requests/auth.api.js +7 -1
  118. package/lib/module/networking/api-requests/auth.api.js.map +1 -1
  119. package/lib/module/networking/xmppClient.js +87 -1
  120. package/lib/module/networking/xmppClient.js.map +1 -1
  121. package/lib/module/roomStore/roomHeapSlice.js +24 -7
  122. package/lib/module/roomStore/roomHeapSlice.js.map +1 -1
  123. package/lib/typescript/components/ContextMenu/ContextMenuComponents.d.ts +0 -1
  124. package/lib/typescript/components/ContextMenu/ContextMenuComponents.d.ts.map +1 -1
  125. package/lib/typescript/components/MainComponents/ChatHeader.d.ts.map +1 -1
  126. package/lib/typescript/components/MainComponents/ChatRoom.d.ts.map +1 -1
  127. package/lib/typescript/components/MainComponents/ChatWrapper.d.ts.map +1 -1
  128. package/lib/typescript/components/MainComponents/MediaMessage.d.ts.map +1 -1
  129. package/lib/typescript/components/MainComponents/MessageList.d.ts.map +1 -1
  130. package/lib/typescript/components/MessageBubble/Message.d.ts.map +1 -1
  131. package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts.map +1 -1
  132. package/lib/typescript/components/Modals/ChatProfileModal/ChatProfileModal.d.ts.map +1 -1
  133. package/lib/typescript/components/Modals/FilePreviewModal/FilePreviewModal.d.ts.map +1 -1
  134. package/lib/typescript/components/Modals/ModalWrapper/ModalWrapper.d.ts +6 -0
  135. package/lib/typescript/components/Modals/ModalWrapper/ModalWrapper.d.ts.map +1 -1
  136. package/lib/typescript/components/RoomComponents/styled/LastMessageEmoji.d.ts +8 -0
  137. package/lib/typescript/components/RoomComponents/styled/LastMessageEmoji.d.ts.map +1 -1
  138. package/lib/typescript/components/UsersList/Checkbox.d.ts +16 -0
  139. package/lib/typescript/components/UsersList/Checkbox.d.ts.map +1 -0
  140. package/lib/typescript/components/UsersList/StyledComponents.d.ts +0 -1
  141. package/lib/typescript/components/UsersList/StyledComponents.d.ts.map +1 -1
  142. package/lib/typescript/components/styled/MediaFilePreview.d.ts.map +1 -1
  143. package/lib/typescript/components/styled/MessageImage.d.ts.map +1 -1
  144. package/lib/typescript/components/styled/SendInput.d.ts.map +1 -1
  145. package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
  146. package/lib/typescript/helpers/mimeToExtension.d.ts +37 -0
  147. package/lib/typescript/helpers/mimeToExtension.d.ts.map +1 -0
  148. package/lib/typescript/helpers/resolveInitBeforeLoadUser.d.ts +18 -0
  149. package/lib/typescript/helpers/resolveInitBeforeLoadUser.d.ts.map +1 -1
  150. package/lib/typescript/hooks/useChatWrapperInit.d.ts.map +1 -1
  151. package/lib/typescript/hooks/useEventHandlers.d.ts +6 -0
  152. package/lib/typescript/hooks/useEventHandlers.d.ts.map +1 -1
  153. package/lib/typescript/hooks/useMessageHeapState.d.ts +2 -0
  154. package/lib/typescript/hooks/useMessageHeapState.d.ts.map +1 -1
  155. package/lib/typescript/hooks/useSendMessage.d.ts +2 -1
  156. package/lib/typescript/hooks/useSendMessage.d.ts.map +1 -1
  157. package/lib/typescript/networking/api-requests/auth.api.d.ts.map +1 -1
  158. package/lib/typescript/networking/xmppClient.d.ts +25 -1
  159. package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
  160. package/lib/typescript/roomStore/roomHeapSlice.d.ts +22 -1
  161. package/lib/typescript/roomStore/roomHeapSlice.d.ts.map +1 -1
  162. package/lib/typescript/types/types.d.ts +6 -0
  163. package/lib/typescript/types/types.d.ts.map +1 -1
  164. package/metro.js +17 -57
  165. package/package.json +1 -1
  166. package/src/components/ContextMenu/ContextMenuComponents.tsx +0 -7
  167. package/src/components/MainComponents/ChatHeader.tsx +5 -1
  168. package/src/components/MainComponents/ChatRoom.tsx +6 -1
  169. package/src/components/MainComponents/ChatWrapper.tsx +1 -0
  170. package/src/components/MainComponents/MediaMessage.tsx +15 -8
  171. package/src/components/MainComponents/MessageList.tsx +10 -3
  172. package/src/components/MessageBubble/Message.tsx +64 -10
  173. package/src/components/MessageBubble/MessageInteractions.tsx +2 -105
  174. package/src/components/Modals/ChatProfileModal/ChatProfileModal.tsx +20 -41
  175. package/src/components/Modals/FilePreviewModal/FilePreviewModal.tsx +30 -12
  176. package/src/components/Modals/ModalWrapper/ModalWrapper.tsx +22 -1
  177. package/src/components/Modals/UserProfileModal/UserProfileModal.tsx +1 -1
  178. package/src/components/RoomComponents/styled/LastMessageEmoji.tsx +9 -7
  179. package/src/components/UsersList/Checkbox.tsx +68 -0
  180. package/src/components/UsersList/StyledComponents.ts +0 -8
  181. package/src/components/UsersList/UsersList.tsx +1 -1
  182. package/src/components/styled/MediaFilePreview.tsx +91 -5
  183. package/src/components/styled/MessageImage.tsx +1 -2
  184. package/src/components/styled/SendInput.tsx +3 -0
  185. package/src/components/styled/VideoMessage.tsx +3 -10
  186. package/src/context/xmppProvider.tsx +90 -2
  187. package/src/helpers/mimeToExtension.ts +135 -0
  188. package/src/helpers/resolveInitBeforeLoadUser.ts +79 -0
  189. package/src/hooks/useChatWrapperInit.ts +51 -46
  190. package/src/hooks/useEventHandlers.tsx +24 -1
  191. package/src/hooks/useMessageHeapState.tsx +6 -2
  192. package/src/hooks/useSendMessage.tsx +75 -4
  193. package/src/networking/api-requests/auth.api.ts +5 -1
  194. package/src/networking/xmppClient.ts +95 -1
  195. package/src/roomStore/roomHeapSlice.ts +47 -4
  196. package/src/types/types.ts +10 -0
  197. package/lib/commonjs/components/InputComponents/AudioInput.js +0 -23
  198. package/lib/commonjs/components/InputComponents/AudioInput.js.map +0 -1
  199. package/lib/commonjs/components/InputComponents/AudioRecorder.js +0 -101
  200. package/lib/commonjs/components/InputComponents/AudioRecorder.js.map +0 -1
  201. package/lib/commonjs/components/InputComponents/MediaInput.js +0 -98
  202. package/lib/commonjs/components/InputComponents/MediaInput.js.map +0 -1
  203. package/lib/commonjs/components/InputComponents/RecordingIndicator.js +0 -70
  204. package/lib/commonjs/components/InputComponents/RecordingIndicator.js.map +0 -1
  205. package/lib/commonjs/components/Modals/ModalSelectMedia/ModalSelectMedia.js +0 -207
  206. package/lib/commonjs/components/Modals/ModalSelectMedia/ModalSelectMedia.js.map +0 -1
  207. package/lib/commonjs/components/OperationalModal/OperationalModal.js +0 -83
  208. package/lib/commonjs/components/OperationalModal/OperationalModal.js.map +0 -1
  209. package/lib/module/components/InputComponents/AudioInput.js +0 -18
  210. package/lib/module/components/InputComponents/AudioInput.js.map +0 -1
  211. package/lib/module/components/InputComponents/AudioRecorder.js +0 -95
  212. package/lib/module/components/InputComponents/AudioRecorder.js.map +0 -1
  213. package/lib/module/components/InputComponents/MediaInput.js +0 -92
  214. package/lib/module/components/InputComponents/MediaInput.js.map +0 -1
  215. package/lib/module/components/InputComponents/RecordingIndicator.js +0 -65
  216. package/lib/module/components/InputComponents/RecordingIndicator.js.map +0 -1
  217. package/lib/module/components/Modals/ModalSelectMedia/ModalSelectMedia.js +0 -200
  218. package/lib/module/components/Modals/ModalSelectMedia/ModalSelectMedia.js.map +0 -1
  219. package/lib/module/components/OperationalModal/OperationalModal.js +0 -77
  220. package/lib/module/components/OperationalModal/OperationalModal.js.map +0 -1
  221. package/lib/typescript/components/InputComponents/AudioInput.d.ts +0 -9
  222. package/lib/typescript/components/InputComponents/AudioInput.d.ts.map +0 -1
  223. package/lib/typescript/components/InputComponents/AudioRecorder.d.ts +0 -9
  224. package/lib/typescript/components/InputComponents/AudioRecorder.d.ts.map +0 -1
  225. package/lib/typescript/components/InputComponents/MediaInput.d.ts +0 -16
  226. package/lib/typescript/components/InputComponents/MediaInput.d.ts.map +0 -1
  227. package/lib/typescript/components/InputComponents/RecordingIndicator.d.ts +0 -4
  228. package/lib/typescript/components/InputComponents/RecordingIndicator.d.ts.map +0 -1
  229. package/lib/typescript/components/Modals/ModalSelectMedia/ModalSelectMedia.d.ts +0 -9
  230. package/lib/typescript/components/Modals/ModalSelectMedia/ModalSelectMedia.d.ts.map +0 -1
  231. package/lib/typescript/components/OperationalModal/OperationalModal.d.ts +0 -9
  232. package/lib/typescript/components/OperationalModal/OperationalModal.d.ts.map +0 -1
  233. package/src/components/InputComponents/AudioInput.tsx +0 -24
  234. package/src/components/InputComponents/AudioRecorder.tsx +0 -100
  235. package/src/components/InputComponents/MediaInput.tsx +0 -113
  236. package/src/components/InputComponents/RecordingIndicator.tsx +0 -77
  237. package/src/components/Modals/ModalSelectMedia/ModalSelectMedia.tsx +0 -283
  238. package/src/components/OperationalModal/OperationalModal.tsx +0 -78
@@ -1,100 +0,0 @@
1
- import React, { useState, useRef, useCallback, useEffect } from 'react';
2
- import {
3
- RecordContainer,
4
- Timer,
5
- } from '../styled/StyledInputComponents/StyledInputComponents';
6
- import { RecordIcon, RemoveIcon, SendIcon } from '../../assets/icons';
7
- import Button from '../styled/Button';
8
- import RecordingIndicator from './RecordingIndicator';
9
- import { Platform, View } from 'react-native';
10
- import AudioRecorderPlayer from 'react-native-audio-recorder-player';
11
- import RNFS from 'react-native-fs';
12
-
13
- interface AudioRecorderProps {
14
- setIsRecording: (state: boolean) => void;
15
- isRecording: boolean;
16
- handleSendClick: (audioBlob?: any) => void;
17
- }
18
-
19
- const AudioRecorder: React.FC<AudioRecorderProps> = ({
20
- setIsRecording,
21
- isRecording,
22
- handleSendClick,
23
- }) => {
24
- const audioRecorderPlayer = useRef(new AudioRecorderPlayer()).current;
25
- const [timer, setTimer] = useState('00:00');
26
- const [audioPath, setAudioPath] = useState<string | null>(null);
27
-
28
- useEffect(() => {
29
- return () => {
30
- audioRecorderPlayer.stopRecorder();
31
- audioRecorderPlayer.removeRecordBackListener();
32
- };
33
- }, [audioRecorderPlayer]);
34
-
35
- const startRecording = async () => {
36
- try {
37
- const path = Platform.select({
38
- ios: `${RNFS.DocumentDirectoryPath}/recording.m4a`,
39
- android: `${RNFS.CachesDirectoryPath}/recording.mp4`,
40
- });
41
- const uri = await audioRecorderPlayer.startRecorder(path);
42
- setAudioPath(uri);
43
-
44
- audioRecorderPlayer.addRecordBackListener((e: any) => {
45
- const minutes = Math.floor(e.currentPosition / 60000);
46
- const seconds = Math.floor((e.currentPosition % 60000) / 1000);
47
- setTimer(
48
- `${minutes.toString().padStart(2, '0')}:${seconds
49
- .toString()
50
- .padStart(2, '0')}`
51
- );
52
- });
53
-
54
- setIsRecording(true);
55
- } catch (error) {
56
- console.error('Error starting recording:', error);
57
- }
58
- };
59
-
60
- const stopRecording = async () => {
61
- try {
62
- await audioRecorderPlayer.stopRecorder();
63
- audioRecorderPlayer.removeRecordBackListener();
64
- setIsRecording(false);
65
- } catch (error) {
66
- console.error('Error stopping recording:', error);
67
- }
68
- };
69
-
70
- const sendAudio = () => {
71
- if (audioPath) {
72
- console.log('Audio sent:', audioPath);
73
- handleSendClick(audioPath);
74
- resetState();
75
- }
76
- };
77
-
78
- const resetState = () => {
79
- setAudioPath(null);
80
- setTimer('00:00');
81
- setIsRecording(false);
82
- };
83
- return isRecording ? (
84
- <RecordContainer>
85
- <View style={{ display: 'flex', alignItems: 'center' }}>
86
- {isRecording && <RecordingIndicator />}
87
- <Timer>{timer}</Timer>
88
- </View>
89
-
90
- <View style={{ display: 'flex', gap: 8 }}>
91
- <Button onPress={stopRecording} EndIcon={<RemoveIcon />} unstyled />
92
- <Button onPress={sendAudio} EndIcon={<SendIcon />} unstyled />
93
- </View>
94
- </RecordContainer>
95
- ) : (
96
- <Button onPress={startRecording} EndIcon={<RecordIcon />} />
97
- );
98
- };
99
-
100
- export default AudioRecorder;
@@ -1,113 +0,0 @@
1
- import React, { useCallback } from 'react';
2
- import { View, Image, TouchableOpacity } from 'react-native';
3
- import { Video, ResizeMode } from 'expo-av';
4
- import * as ImagePicker from 'expo-image-picker';
5
- import { AttachIcon, RemoveIcon } from '../../assets/icons';
6
- import Button from '../styled/Button';
7
- import { IConfig } from '../../types/types';
8
-
9
- interface FilePreview {
10
- uri: string;
11
- name: string;
12
- type: string;
13
- }
14
-
15
- interface MediaInputProps {
16
- filePreviews: FilePreview[];
17
- setFilePreviews: (
18
- update: FilePreview[] | ((prev: FilePreview[]) => FilePreview[])
19
- ) => void;
20
- handleSendClick: () => void;
21
- config?: IConfig;
22
- }
23
-
24
- const MediaInput: React.FC<MediaInputProps> = ({
25
- filePreviews,
26
- setFilePreviews,
27
- handleSendClick,
28
- config,
29
- }) => {
30
- const handleAttachClick = useCallback(async () => {
31
- const result = await ImagePicker.launchImageLibraryAsync({
32
- mediaTypes: ['images', 'videos'],
33
- allowsMultipleSelection: true,
34
- selectionLimit: 5,
35
- quality: 0.8,
36
- });
37
-
38
- if (!result.canceled && result.assets) {
39
- const newFiles = result.assets.map((asset) => ({
40
- uri: asset.uri,
41
- name: asset.fileName || asset.uri.split('/').pop() || `file_${Date.now()}`,
42
- type: asset.mimeType || 'application/octet-stream',
43
- }));
44
- setFilePreviews((prevFiles: FilePreview[]) =>
45
- [...prevFiles, ...newFiles].slice(0, 5)
46
- );
47
- }
48
- }, [setFilePreviews]);
49
-
50
- const handleRemoveFile = useCallback(
51
- (file: FilePreview) => {
52
- setFilePreviews((prevFiles: FilePreview[]) =>
53
- prevFiles.filter((f) => f.uri !== file.uri)
54
- );
55
- },
56
- [setFilePreviews]
57
- );
58
-
59
- const renderFilePreview = useCallback((file: FilePreview) => {
60
- if (file.type?.startsWith('image/')) {
61
- return (
62
- <Image source={{ uri: file.uri }} style={{ width: 50, height: 50 }} />
63
- );
64
- } else if (file.type?.startsWith('video/')) {
65
- return (
66
- <Video
67
- source={{ uri: file.uri }}
68
- style={{ width: 50, height: 50 }}
69
- useNativeControls
70
- resizeMode={ResizeMode.COVER}
71
- />
72
- );
73
- }
74
- return null;
75
- }, []);
76
-
77
- return (
78
- <View>
79
- <Button
80
- onPress={handleAttachClick}
81
- disabled={config?.disableMedia}
82
- EndIcon={<AttachIcon />}
83
- />
84
- {filePreviews.length > 0 && (
85
- <View>
86
- {filePreviews.map((file) => (
87
- <View key={file.uri} style={{ position: 'relative', margin: 8 }}>
88
- {renderFilePreview(file)}
89
- <TouchableOpacity
90
- onPress={() => handleRemoveFile(file)}
91
- style={{
92
- position: 'absolute',
93
- top: 4,
94
- right: 4,
95
- width: 20,
96
- height: 20,
97
- backgroundColor: 'rgba(0, 0, 0, 0.5)',
98
- justifyContent: 'center',
99
- alignItems: 'center',
100
- borderRadius: 10,
101
- }}
102
- >
103
- <RemoveIcon />
104
- </TouchableOpacity>
105
- </View>
106
- ))}
107
- </View>
108
- )}
109
- </View>
110
- );
111
- };
112
-
113
- export default MediaInput;
@@ -1,77 +0,0 @@
1
- import React, {useEffect, useRef} from 'react';
2
- import {View, StyleSheet, Animated} from 'react-native';
3
-
4
- const RecordingIndicator = () => {
5
- const scaleAnim = useRef(new Animated.Value(1)).current; // For scaling the circle
6
- const opacityAnim = useRef(new Animated.Value(1)).current; // For pulsating effect
7
-
8
- useEffect(() => {
9
- Animated.loop(
10
- Animated.sequence([
11
- Animated.parallel([
12
- Animated.timing(scaleAnim, {
13
- toValue: 1.3,
14
- duration: 750,
15
- useNativeDriver: true,
16
- }),
17
- Animated.timing(opacityAnim, {
18
- toValue: 0.6,
19
- duration: 750,
20
- useNativeDriver: true,
21
- }),
22
- ]),
23
- Animated.parallel([
24
- Animated.timing(scaleAnim, {
25
- toValue: 1,
26
- duration: 750,
27
- useNativeDriver: true,
28
- }),
29
- Animated.timing(opacityAnim, {
30
- toValue: 1,
31
- duration: 750,
32
- useNativeDriver: true,
33
- }),
34
- ]),
35
- ]),
36
- ).start();
37
- }, [scaleAnim, opacityAnim]);
38
-
39
- return (
40
- <View style={styles.wrapper}>
41
- <Animated.View
42
- style={[
43
- styles.outerCircle,
44
- {
45
- transform: [{scale: scaleAnim}],
46
- opacity: opacityAnim,
47
- },
48
- ]}
49
- />
50
- <View style={styles.innerCircle} />
51
- </View>
52
- );
53
- };
54
-
55
- const styles = StyleSheet.create({
56
- wrapper: {
57
- justifyContent: 'center',
58
- alignItems: 'center',
59
- marginRight: 10,
60
- },
61
- outerCircle: {
62
- width: 18,
63
- height: 18,
64
- borderRadius: 9,
65
- backgroundColor: 'rgba(255, 0, 0, 0.6)',
66
- position: 'absolute',
67
- },
68
- innerCircle: {
69
- width: 16,
70
- height: 16,
71
- borderRadius: 8,
72
- backgroundColor: 'red',
73
- position: 'relative',
74
- },
75
- });
76
-
77
- export default RecordingIndicator;
@@ -1,283 +0,0 @@
1
- import React, { FC, useMemo } from 'react';
2
- import { Alert, Linking, Platform } from 'react-native';
3
- import Button from '../../styled/Button';
4
- import DropdownMenu from '../../DropdownMenu/DropdownMenu';
5
- import DocumentPicker from 'react-native-document-picker';
6
- import ImagePicker from 'react-native-image-crop-picker';
7
- import {
8
- check,
9
- request,
10
- PERMISSIONS,
11
- RESULTS,
12
- Permission,
13
- } from 'react-native-permissions';
14
- import {
15
- AttachIcon,
16
- CameraIcon,
17
- DocumentIcon,
18
- MediaIcon,
19
- } from '../../../assets/icons';
20
- import { MediaFile } from '../../../types/types';
21
-
22
- interface ModalSelectMediaProps {
23
- onFileSelect: (files: MediaFile[]) => void;
24
- config?: any;
25
- }
26
-
27
- interface Permissions {
28
- UNAVAILABLE: 'unavailable';
29
- BLOCKED: 'blocked';
30
- DENIED: 'denied';
31
- GRANTED: 'granted';
32
- LIMITED: 'limited';
33
- }
34
-
35
- export const ModalSelectMedia: FC<ModalSelectMediaProps> = ({
36
- onFileSelect,
37
- config,
38
- }) => {
39
- const checkPermission = async (permission: Permission) => {
40
- const status = await check(permission);
41
-
42
- if (status === RESULTS.GRANTED) {
43
- return status;
44
- } else if (status === RESULTS.DENIED) {
45
- const requestStatus = await request(permission);
46
- if (requestStatus === RESULTS.GRANTED) {
47
- return requestStatus;
48
- } else if (requestStatus === RESULTS.DENIED) {
49
- return requestStatus;
50
- }
51
- } else if (status === RESULTS.UNAVAILABLE) {
52
- return status;
53
- } else {
54
- return status;
55
- }
56
- };
57
-
58
- const handleCameraSelection = async () => {
59
- const permission =
60
- Platform.OS === 'ios'
61
- ? PERMISSIONS.IOS.CAMERA
62
- : PERMISSIONS.ANDROID.CAMERA;
63
- const permissionStatus = await checkPermission(permission);
64
-
65
- if (permissionStatus !== RESULTS.GRANTED) {
66
- Alert.alert(
67
- 'Permission required',
68
- 'Camera permission is needed to take photos.',
69
- [
70
- {
71
- text: 'Cancel',
72
- onPress: () => console.log('Camera permission cancelled'),
73
- style: 'cancel',
74
- },
75
- {
76
- text: 'Open Settings',
77
- onPress: () => Linking.openSettings(),
78
- },
79
- ]
80
- );
81
- return;
82
- }
83
-
84
- try {
85
- const image = await ImagePicker.openCamera({
86
- width: 300,
87
- height: 400,
88
- cropping: true,
89
- });
90
-
91
- const originalName = image.path.split('/').pop();
92
- const file = {
93
- uri: image.path,
94
- type: image.mime,
95
- name: originalName || `camera_${Date.now()}.jpg`,
96
- };
97
- onFileSelect([file]);
98
- } catch (error: any) {
99
- const errorMessage = error?.message || String(error);
100
- const isSimulatorError =
101
- errorMessage.includes('simulator') ||
102
- errorMessage.includes('Cannot run camera') ||
103
- errorMessage.includes('Camera not available');
104
-
105
- if (isSimulatorError) {
106
- Alert.alert(
107
- 'Camera unavailable',
108
- 'Camera is not available on iOS Simulator. Please test on a real device.',
109
- [{ text: 'OK' }]
110
- );
111
- } else if (error?.code !== 'E_PICKER_CANCELLED') {
112
- console.error('Camera error:', error);
113
- Alert.alert(
114
- 'Camera error',
115
- errorMessage || 'Failed to open camera. Please try again.',
116
- [{ text: 'OK' }]
117
- );
118
- }
119
- }
120
- };
121
-
122
- const handleGallerySelection = async () => {
123
- try {
124
- let permission: Permission;
125
-
126
- if (Platform.OS === 'ios') {
127
- permission = PERMISSIONS.IOS.PHOTO_LIBRARY;
128
- } else if (Number(Platform.Version) >= 33) {
129
- permission = PERMISSIONS.ANDROID.READ_MEDIA_IMAGES;
130
- } else {
131
- permission = PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE;
132
- }
133
-
134
- console.log('handleGallerySelection - checking permission:', permission);
135
- const permissionStatus = await checkPermission(permission);
136
- console.log('handleGallerySelection - permission status:', permissionStatus);
137
-
138
- if (permissionStatus !== RESULTS.GRANTED) {
139
- console.log('handleGallerySelection - permission not granted, showing alert');
140
- Alert.alert(
141
- 'Permission required',
142
- 'Gallery permission is needed to select photos.',
143
- [
144
- {
145
- text: 'Cancel',
146
- onPress: () => console.log('Gallery permission cancelled'),
147
- style: 'cancel',
148
- },
149
- {
150
- text: 'Open Settings',
151
- onPress: () => Linking.openSettings(),
152
- },
153
- ]
154
- );
155
- return;
156
- }
157
-
158
- await new Promise(resolve => setTimeout(resolve, 300));
159
- const image = await ImagePicker.openPicker({
160
- multiple: false,
161
- mediaType: 'any',
162
- });
163
- console.log('handleGallerySelection - image selected:', image);
164
-
165
- const originalName = image.path.split('/').pop();
166
- const file = {
167
- uri: image.path,
168
- type: image.mime,
169
- name:
170
- originalName ||
171
- `gallery_${Date.now()}${
172
- image.mime.includes('video') ? '.mp4' : '.jpg'
173
- }`,
174
- };
175
-
176
- onFileSelect([file]);
177
- } catch (error: any) {
178
- if (error?.code === 'E_PICKER_CANCELLED') {
179
- return;
180
- }
181
-
182
- console.error('Gallery error:', error);
183
- console.error('Gallery error code:', error?.code);
184
- console.error('Gallery error message:', error?.message);
185
-
186
- const errorMessage = error?.message || String(error);
187
- Alert.alert(
188
- 'Gallery error',
189
- errorMessage || 'Failed to open gallery. Please try again.',
190
- [{ text: 'OK' }]
191
- );
192
- }
193
- };
194
-
195
- const handleFileSelection = async () => {
196
- try {
197
- const result = await DocumentPicker.pick({
198
- type: [DocumentPicker.types.allFiles],
199
- allowMultiSelection: false,
200
- });
201
-
202
- const files = result.map((file: any) => {
203
- const originalName = file.name;
204
- return {
205
- uri: file.uri,
206
- type: file.type || 'unknown',
207
- name: originalName || `file_${Date.now()}`,
208
- };
209
- });
210
-
211
- onFileSelect(files);
212
- } catch (err: any) {
213
- if (DocumentPicker.isCancel(err)) {
214
- console.log('User cancelled file picker');
215
- } else {
216
- console.error('DocumentPicker Error:', err);
217
- const errorMessage = err?.message || String(err);
218
- Alert.alert(
219
- 'File selection error',
220
- errorMessage || 'Failed to select file. Please try again.',
221
- [{ text: 'OK' }]
222
- );
223
- }
224
- }
225
- };
226
-
227
- const menuOptions = useMemo(
228
- () => [
229
- {
230
- label: 'Camera',
231
- icon: <CameraIcon />,
232
- onClick: async () => {
233
- setTimeout(async () => {
234
- await handleCameraSelection();
235
- }, 500);
236
- },
237
- },
238
- {
239
- label: 'Media File',
240
- icon: <MediaIcon />,
241
- onClick: async () => {
242
- await handleGallerySelection();
243
- },
244
- },
245
- {
246
- label: 'Document',
247
- icon: <DocumentIcon />,
248
- onClick: async () => {
249
- setTimeout(async () => {
250
- await handleFileSelection();
251
- }, 500);
252
- },
253
- },
254
- ],
255
- []
256
- );
257
-
258
- return (
259
- <DropdownMenu
260
- position="leftBottom"
261
- options={menuOptions}
262
- openButton={(onPress) => {
263
- return (
264
- <Button
265
- style={{
266
- padding: 0,
267
- height: 40,
268
- width: 40,
269
- justifyContent: 'center',
270
- alignItems: 'center',
271
- backgroundColor: 'transparent',
272
- margin: 0,
273
- }}
274
- EndIcon={<AttachIcon color={config?.colors?.primary || '#0052CD'} />}
275
- onPress={() => {
276
- onPress();
277
- }}
278
- />
279
- );
280
- }}
281
- />
282
- );
283
- };
@@ -1,78 +0,0 @@
1
- import React, { useState } from 'react';
2
- // import QRCode from 'react-qr-code';
3
- import { CloseButton } from '../Modals/styledModalComponents';
4
- import { Overlay, StyledModal } from '../styled/MediaModal';
5
- import { StyledInput } from '../styled/StyledInputComponents/StyledInputComponents';
6
- import Button from '../styled/Button';
7
- import { Text, View } from 'react-native';
8
- import { QRCODE_URL } from '../../helpers/constants/PLATFORM_CONSTANTS';
9
- import Clipboard from '@react-native-clipboard/clipboard';
10
-
11
- interface OperationalModalProps {
12
- isVisible: boolean;
13
- chatJid: string;
14
- setVisible: React.Dispatch<React.SetStateAction<boolean>>;
15
- }
16
-
17
- const OperationalModal: React.FC<OperationalModalProps> = ({
18
- isVisible,
19
- chatJid,
20
- setVisible,
21
- }) => {
22
- const handleCopyClick = () => {
23
- Clipboard.setString(`${QRCODE_URL}${chatJid}`);
24
- };
25
-
26
- return (
27
- isVisible && (
28
- <Overlay
29
- style={{
30
- position: 'absolute',
31
- }}
32
- >
33
- <StyledModal
34
- style={{
35
- borderRadius: 16,
36
- width: 'auto',
37
- height: 'auto',
38
- paddingHorizontal: 64,
39
- paddingVertical: 32,
40
- minWidth: 480,
41
- }}
42
- >
43
- <CloseButton onPress={() => setVisible(false)}>
44
- <Text style={{ fontSize: 24 }}>&times;</Text>
45
- </CloseButton>
46
- <View
47
- style={{
48
- display: 'flex',
49
- flexDirection: 'column',
50
- gap: 16,
51
- alignItems: 'center',
52
- }}
53
- >
54
- <View style={{ width: '70%', position: 'relative' }} />
55
-
56
- <View
57
- style={{
58
- display: 'flex',
59
- gap: 8,
60
- alignItems: 'center',
61
- minWidth: 400,
62
- }}
63
- >
64
- <StyledInput
65
- value={chatJid}
66
- editable={true}
67
- style={{ width: '80%' }}
68
- />
69
- <Button text="Copy" onPress={handleCopyClick} />
70
- </View>
71
- </View>
72
- </StyledModal>
73
- </Overlay>
74
- )
75
- );
76
- };
77
-
78
- export default OperationalModal;