@ethora/chat-component-rn 26.5.11 → 26.5.12

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 (135) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +1 -0
  3. package/lib/commonjs/assets/icons.js +7 -1
  4. package/lib/commonjs/assets/icons.js.map +1 -1
  5. package/lib/commonjs/components/MainComponents/ChatRoom.js +17 -1
  6. package/lib/commonjs/components/MainComponents/ChatRoom.js.map +1 -1
  7. package/lib/commonjs/components/MainComponents/MediaMessage.js +288 -5
  8. package/lib/commonjs/components/MainComponents/MediaMessage.js.map +1 -1
  9. package/lib/commonjs/components/MessageBubble/MessageInteractions.js +23 -3
  10. package/lib/commonjs/components/MessageBubble/MessageInteractions.js.map +1 -1
  11. package/lib/commonjs/components/Modals/FilePreviewModal/DocumentViewer.js +5 -44
  12. package/lib/commonjs/components/Modals/FilePreviewModal/DocumentViewer.js.map +1 -1
  13. package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js +36 -3
  14. package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
  15. package/lib/commonjs/components/Modals/FilePreviewModal/GViewWebView.js +149 -0
  16. package/lib/commonjs/components/Modals/FilePreviewModal/GViewWebView.js.map +1 -0
  17. package/lib/commonjs/components/Modals/FilePreviewModal/PdfView.js +4 -17
  18. package/lib/commonjs/components/Modals/FilePreviewModal/PdfView.js.map +1 -1
  19. package/lib/commonjs/components/RoomComponents/styled/LastAudioMessage.js +19 -33
  20. package/lib/commonjs/components/RoomComponents/styled/LastAudioMessage.js.map +1 -1
  21. package/lib/commonjs/components/styled/AudioMessage.js +643 -66
  22. package/lib/commonjs/components/styled/AudioMessage.js.map +1 -1
  23. package/lib/commonjs/components/styled/Button.js +9 -3
  24. package/lib/commonjs/components/styled/Button.js.map +1 -1
  25. package/lib/commonjs/components/styled/SendInput.js +239 -40
  26. package/lib/commonjs/components/styled/SendInput.js.map +1 -1
  27. package/lib/commonjs/components/styled/StyledInputComponents/MediaComponents.js +31 -18
  28. package/lib/commonjs/components/styled/StyledInputComponents/MediaComponents.js.map +1 -1
  29. package/lib/commonjs/components/styled/UnsupportedType.js +47 -5
  30. package/lib/commonjs/components/styled/UnsupportedType.js.map +1 -1
  31. package/lib/commonjs/context/xmppProvider.js +5 -2
  32. package/lib/commonjs/context/xmppProvider.js.map +1 -1
  33. package/lib/commonjs/helpers/keyboardLayout.js +5 -3
  34. package/lib/commonjs/helpers/keyboardLayout.js.map +1 -1
  35. package/lib/commonjs/helpers/mimeToExtension.js +70 -3
  36. package/lib/commonjs/helpers/mimeToExtension.js.map +1 -1
  37. package/lib/commonjs/hooks/useEventHandlers.js +1 -1
  38. package/lib/commonjs/hooks/useEventHandlers.js.map +1 -1
  39. package/lib/commonjs/hooks/useSendMessage.js +6 -3
  40. package/lib/commonjs/hooks/useSendMessage.js.map +1 -1
  41. package/lib/commonjs/roomStore/roomsSlice.js +6 -0
  42. package/lib/commonjs/roomStore/roomsSlice.js.map +1 -1
  43. package/lib/module/assets/icons.js +7 -1
  44. package/lib/module/assets/icons.js.map +1 -1
  45. package/lib/module/components/MainComponents/ChatRoom.js +18 -2
  46. package/lib/module/components/MainComponents/ChatRoom.js.map +1 -1
  47. package/lib/module/components/MainComponents/MediaMessage.js +290 -7
  48. package/lib/module/components/MainComponents/MediaMessage.js.map +1 -1
  49. package/lib/module/components/MessageBubble/MessageInteractions.js +24 -4
  50. package/lib/module/components/MessageBubble/MessageInteractions.js.map +1 -1
  51. package/lib/module/components/Modals/FilePreviewModal/DocumentViewer.js +5 -45
  52. package/lib/module/components/Modals/FilePreviewModal/DocumentViewer.js.map +1 -1
  53. package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js +36 -3
  54. package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
  55. package/lib/module/components/Modals/FilePreviewModal/GViewWebView.js +144 -0
  56. package/lib/module/components/Modals/FilePreviewModal/GViewWebView.js.map +1 -0
  57. package/lib/module/components/Modals/FilePreviewModal/PdfView.js +3 -17
  58. package/lib/module/components/Modals/FilePreviewModal/PdfView.js.map +1 -1
  59. package/lib/module/components/RoomComponents/styled/LastAudioMessage.js +20 -34
  60. package/lib/module/components/RoomComponents/styled/LastAudioMessage.js.map +1 -1
  61. package/lib/module/components/styled/AudioMessage.js +644 -67
  62. package/lib/module/components/styled/AudioMessage.js.map +1 -1
  63. package/lib/module/components/styled/Button.js +9 -3
  64. package/lib/module/components/styled/Button.js.map +1 -1
  65. package/lib/module/components/styled/SendInput.js +240 -42
  66. package/lib/module/components/styled/SendInput.js.map +1 -1
  67. package/lib/module/components/styled/StyledInputComponents/MediaComponents.js +31 -18
  68. package/lib/module/components/styled/StyledInputComponents/MediaComponents.js.map +1 -1
  69. package/lib/module/components/styled/UnsupportedType.js +47 -5
  70. package/lib/module/components/styled/UnsupportedType.js.map +1 -1
  71. package/lib/module/context/xmppProvider.js +5 -2
  72. package/lib/module/context/xmppProvider.js.map +1 -1
  73. package/lib/module/helpers/keyboardLayout.js +4 -2
  74. package/lib/module/helpers/keyboardLayout.js.map +1 -1
  75. package/lib/module/helpers/mimeToExtension.js +67 -3
  76. package/lib/module/helpers/mimeToExtension.js.map +1 -1
  77. package/lib/module/hooks/useEventHandlers.js +1 -1
  78. package/lib/module/hooks/useEventHandlers.js.map +1 -1
  79. package/lib/module/hooks/useSendMessage.js +6 -3
  80. package/lib/module/hooks/useSendMessage.js.map +1 -1
  81. package/lib/module/roomStore/roomsSlice.js +6 -0
  82. package/lib/module/roomStore/roomsSlice.js.map +1 -1
  83. package/lib/typescript/assets/icons.d.ts.map +1 -1
  84. package/lib/typescript/components/MainComponents/ChatRoom.d.ts.map +1 -1
  85. package/lib/typescript/components/MainComponents/MediaMessage.d.ts.map +1 -1
  86. package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts.map +1 -1
  87. package/lib/typescript/components/Modals/FilePreviewModal/DocumentViewer.d.ts +0 -7
  88. package/lib/typescript/components/Modals/FilePreviewModal/DocumentViewer.d.ts.map +1 -1
  89. package/lib/typescript/components/Modals/FilePreviewModal/FilePreviewModal.d.ts.map +1 -1
  90. package/lib/typescript/components/Modals/FilePreviewModal/GViewWebView.d.ts +8 -0
  91. package/lib/typescript/components/Modals/FilePreviewModal/GViewWebView.d.ts.map +1 -0
  92. package/lib/typescript/components/Modals/FilePreviewModal/PdfView.d.ts.map +1 -1
  93. package/lib/typescript/components/RoomComponents/styled/LastAudioMessage.d.ts.map +1 -1
  94. package/lib/typescript/components/styled/AudioMessage.d.ts +8 -2
  95. package/lib/typescript/components/styled/AudioMessage.d.ts.map +1 -1
  96. package/lib/typescript/components/styled/Button.d.ts.map +1 -1
  97. package/lib/typescript/components/styled/SendInput.d.ts.map +1 -1
  98. package/lib/typescript/components/styled/StyledInputComponents/MediaComponents.d.ts +5 -1
  99. package/lib/typescript/components/styled/StyledInputComponents/MediaComponents.d.ts.map +1 -1
  100. package/lib/typescript/components/styled/UnsupportedType.d.ts +5 -0
  101. package/lib/typescript/components/styled/UnsupportedType.d.ts.map +1 -1
  102. package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
  103. package/lib/typescript/helpers/keyboardLayout.d.ts +3 -1
  104. package/lib/typescript/helpers/keyboardLayout.d.ts.map +1 -1
  105. package/lib/typescript/helpers/mimeToExtension.d.ts +31 -1
  106. package/lib/typescript/helpers/mimeToExtension.d.ts.map +1 -1
  107. package/lib/typescript/hooks/useSendMessage.d.ts.map +1 -1
  108. package/lib/typescript/roomStore/roomsSlice.d.ts.map +1 -1
  109. package/lib/typescript/types/models/modal.model.d.ts +3 -0
  110. package/lib/typescript/types/models/modal.model.d.ts.map +1 -1
  111. package/lib/typescript/types/types.d.ts +13 -0
  112. package/lib/typescript/types/types.d.ts.map +1 -1
  113. package/package.json +5 -1
  114. package/src/assets/icons.tsx +30 -25
  115. package/src/components/MainComponents/ChatRoom.tsx +21 -0
  116. package/src/components/MainComponents/MediaMessage.tsx +295 -5
  117. package/src/components/MessageBubble/MessageInteractions.tsx +35 -3
  118. package/src/components/Modals/FilePreviewModal/DocumentViewer.tsx +3 -40
  119. package/src/components/Modals/FilePreviewModal/FilePreviewModal.tsx +39 -3
  120. package/src/components/Modals/FilePreviewModal/GViewWebView.tsx +142 -0
  121. package/src/components/Modals/FilePreviewModal/PdfView.tsx +2 -18
  122. package/src/components/RoomComponents/styled/LastAudioMessage.tsx +20 -35
  123. package/src/components/styled/AudioMessage.tsx +724 -59
  124. package/src/components/styled/Button.tsx +20 -11
  125. package/src/components/styled/SendInput.tsx +255 -46
  126. package/src/components/styled/StyledInputComponents/MediaComponents.tsx +29 -18
  127. package/src/components/styled/UnsupportedType.tsx +60 -6
  128. package/src/context/xmppProvider.tsx +6 -2
  129. package/src/helpers/keyboardLayout.ts +5 -1
  130. package/src/helpers/mimeToExtension.ts +116 -2
  131. package/src/hooks/useEventHandlers.tsx +1 -1
  132. package/src/hooks/useSendMessage.tsx +12 -6
  133. package/src/roomStore/roomsSlice.ts +7 -0
  134. package/src/types/models/modal.model.ts +3 -0
  135. package/src/types/types.ts +13 -0
@@ -0,0 +1,142 @@
1
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { ActivityIndicator, StyleSheet, View } from 'react-native';
3
+ import { WebView } from 'react-native-webview';
4
+
5
+ interface GViewWebViewProps {
6
+ url: string;
7
+ onError?: () => void;
8
+ }
9
+
10
+ const MAX_ATTEMPTS = 6;
11
+ const LOAD_BUDGET_MS = 8000;
12
+ const ATTEMPT_TIMEOUT_MS = 3000;
13
+
14
+ const RENDER_POLLER = `
15
+ (function () {
16
+ if (window.__ethoraGviewProbe) { return; }
17
+ window.__ethoraGviewProbe = true;
18
+ var tries = 0;
19
+ function rendered() {
20
+ try {
21
+ var imgs = document.querySelectorAll('img');
22
+ for (var i = 0; i < imgs.length; i++) {
23
+ // naturalHeight is readable even for cross-origin images; gview's
24
+ // page images are tall, the preparing page has none.
25
+ if (imgs[i].naturalHeight > 80) { return true; }
26
+ }
27
+ // Some gview render paths paint pages into <canvas> instead.
28
+ var canvases = document.querySelectorAll('canvas');
29
+ for (var j = 0; j < canvases.length; j++) {
30
+ if (canvases[j].height > 80) { return true; }
31
+ }
32
+ var txt = ((document.body && document.body.innerText) || '').trim();
33
+ return txt.length > 80;
34
+ } catch (e) {
35
+ return false;
36
+ }
37
+ }
38
+ function tick() {
39
+ tries++;
40
+ if (rendered()) {
41
+ try {
42
+ window.ReactNativeWebView.postMessage(JSON.stringify({ rendered: true }));
43
+ } catch (e) {}
44
+ return;
45
+ }
46
+ if (tries < 40) { setTimeout(tick, 500); }
47
+ }
48
+ tick();
49
+ })();
50
+ true;
51
+ `;
52
+
53
+ const GViewWebView: React.FC<GViewWebViewProps> = ({ url, onError }) => {
54
+ const [attempt, setAttempt] = useState(0);
55
+ const [ready, setReady] = useState(false);
56
+ const readyRef = useRef(false);
57
+ const attemptRef = useRef(0);
58
+ const watchdog = useRef<ReturnType<typeof setTimeout> | null>(null);
59
+
60
+ const viewerUrl = `https://docs.google.com/gview?embedded=true&url=${encodeURIComponent(
61
+ url
62
+ )}`;
63
+
64
+ const clearWatchdog = () => {
65
+ if (watchdog.current) {
66
+ clearTimeout(watchdog.current);
67
+ watchdog.current = null;
68
+ }
69
+ };
70
+
71
+ const giveUpAttempt = useCallback(() => {
72
+ if (readyRef.current) {return;}
73
+ if (attemptRef.current < MAX_ATTEMPTS - 1) {
74
+ attemptRef.current += 1;
75
+ setAttempt(attemptRef.current);
76
+ } else {
77
+ readyRef.current = true;
78
+ setReady(true);
79
+ }
80
+ }, []);
81
+
82
+ useEffect(() => {
83
+ if (readyRef.current) {return;}
84
+ clearWatchdog();
85
+ watchdog.current = setTimeout(giveUpAttempt, LOAD_BUDGET_MS);
86
+ return clearWatchdog;
87
+ }, [attempt, giveUpAttempt]);
88
+
89
+ const handleLoadEnd = useCallback(() => {
90
+ if (readyRef.current) {return;}
91
+ clearWatchdog();
92
+ watchdog.current = setTimeout(giveUpAttempt, ATTEMPT_TIMEOUT_MS);
93
+ }, [giveUpAttempt]);
94
+
95
+ const handleMessage = useCallback((e: any) => {
96
+ let isRendered = false;
97
+ try {
98
+ isRendered = !!JSON.parse(e.nativeEvent.data)?.rendered;
99
+ } catch {
100
+ isRendered = false;
101
+ }
102
+ if (isRendered && !readyRef.current) {
103
+ clearWatchdog();
104
+ readyRef.current = true;
105
+ setReady(true);
106
+ }
107
+ }, []);
108
+
109
+ return (
110
+ <View style={styles.container}>
111
+ <WebView
112
+ key={attempt}
113
+ source={{ uri: viewerUrl }}
114
+ style={styles.webview}
115
+ originWhitelist={['*']}
116
+ injectedJavaScript={RENDER_POLLER}
117
+ onLoadEnd={handleLoadEnd}
118
+ onMessage={handleMessage}
119
+ onError={onError}
120
+ onHttpError={onError}
121
+ />
122
+ {!ready && (
123
+ <View style={styles.loadingOverlay} pointerEvents="none">
124
+ <ActivityIndicator size="large" />
125
+ </View>
126
+ )}
127
+ </View>
128
+ );
129
+ };
130
+
131
+ export default GViewWebView;
132
+
133
+ const styles = StyleSheet.create({
134
+ container: { flex: 1, width: '100%', backgroundColor: '#fff' },
135
+ webview: { flex: 1, backgroundColor: '#fff' },
136
+ loadingOverlay: {
137
+ ...StyleSheet.absoluteFillObject,
138
+ justifyContent: 'center',
139
+ alignItems: 'center',
140
+ backgroundColor: '#ffffff',
141
+ },
142
+ });
@@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react';
2
2
  import { ActivityIndicator, Platform, StyleSheet, Text, View } from 'react-native';
3
3
  import { WebView } from 'react-native-webview';
4
4
  import * as FileSystem from 'expo-file-system/legacy';
5
+ import GViewWebView from './GViewWebView';
5
6
 
6
7
  interface PdfViewerProps {
7
8
  pdfUrl: string;
@@ -40,24 +41,7 @@ const PdfViewer: React.FC<PdfViewerProps> = ({ pdfUrl }) => {
40
41
  }, [pdfUrl, isAndroid]);
41
42
 
42
43
  if (isAndroid) {
43
- const gviewUrl = `https://docs.google.com/gview?embedded=true&url=${encodeURIComponent(
44
- pdfUrl
45
- )}`;
46
- return (
47
- <View style={styles.container}>
48
- <WebView
49
- source={{ uri: gviewUrl }}
50
- style={styles.webview}
51
- originWhitelist={['*']}
52
- startInLoadingState
53
- renderLoading={() => (
54
- <View style={styles.center}>
55
- <ActivityIndicator size="large" />
56
- </View>
57
- )}
58
- />
59
- </View>
60
- );
44
+ return <GViewWebView url={pdfUrl} />;
61
45
  }
62
46
 
63
47
  if (error) {
@@ -3,58 +3,43 @@ import {
3
3
  LastRoomMessageContainer,
4
4
  LastRoomMessageName,
5
5
  LastRoomMessageText,
6
- ShadeWrapper,
7
6
  } from './StyledRoomComponents';
8
7
  import { LastMessage } from '../../../types/types';
9
8
  import styled from 'styled-components/native';
10
- import { Text, View } from 'react-native';
9
+ import { View } from 'react-native';
10
+ import { PlayIcon } from '../../../assets/icons';
11
11
 
12
12
  interface LastMessageEmojiProps extends Pick<LastMessage, 'user' | 'body'> {}
13
13
 
14
14
  const PlayButton = styled.View`
15
- position: absolute;
16
- width: 8px;
17
- height: 9px;
18
- border-radius: 50%;
15
+ width: 20px;
16
+ height: 20px;
17
+ border-radius: 10px;
19
18
  display: flex;
20
19
  justify-content: center;
21
20
  align-items: center;
22
- color: white;
23
- font-size: 10px;
24
- pointer-events: none;
25
- z-index: 100;
21
+ background-color: #d8ecff;
22
+ margin-top: 1px;
26
23
  `;
27
24
 
28
- const PhotoContainer = styled.View`
29
- position: relative;
30
- width: 20px;
31
- height: 20px;
32
- overflow: hidden;
33
- border-radius: 8px;
34
- width: 20px;
35
- height: 20px;
36
- object-fit: cover;
37
- pointer-events: none;
25
+ const AudioRow = styled.View`
26
+ flex-direction: row;
27
+ align-items: center;
28
+ gap: 6px;
38
29
  `;
39
30
 
40
31
  const LastAudioMessage: FC<LastMessageEmojiProps> = ({ user, body }) => {
41
32
  return (
42
33
  <LastRoomMessageContainer>
43
- <LastRoomMessageName>{user?.name ?? ''}</LastRoomMessageName>
44
- <View
45
- style={{
46
- display: 'flex',
47
- flexDirection: 'row',
48
- gap: '4px',
49
- }}
50
- >
51
- <PhotoContainer>
52
- <ShadeWrapper>
53
- <PlayButton><Text>▶</Text></PlayButton>
54
- </ShadeWrapper>
55
- </PhotoContainer>
56
- <LastRoomMessageText>audio</LastRoomMessageText>
57
- </View>
34
+ <LastRoomMessageName numberOfLines={1}>{user?.name ?? ''}</LastRoomMessageName>
35
+ <AudioRow>
36
+ <PlayButton>
37
+ <PlayIcon width={10} height={10} color="#1F2937" />
38
+ </PlayButton>
39
+ <LastRoomMessageText numberOfLines={1}>
40
+ {body?.trim() ? body : 'audio'}
41
+ </LastRoomMessageText>
42
+ </AudioRow>
58
43
  </LastRoomMessageContainer>
59
44
  );
60
45
  };