@ethora/chat-component-rn 26.5.11 → 26.5.13

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 (154) 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 +58 -22
  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/MainComponents/ReduxWrapper.js +24 -15
  10. package/lib/commonjs/components/MainComponents/ReduxWrapper.js.map +1 -1
  11. package/lib/commonjs/components/MessageBubble/MessageInteractions.js +23 -3
  12. package/lib/commonjs/components/MessageBubble/MessageInteractions.js.map +1 -1
  13. package/lib/commonjs/components/Modals/FilePreviewModal/DocumentViewer.js +5 -44
  14. package/lib/commonjs/components/Modals/FilePreviewModal/DocumentViewer.js.map +1 -1
  15. package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js +36 -3
  16. package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
  17. package/lib/commonjs/components/Modals/FilePreviewModal/GViewWebView.js +149 -0
  18. package/lib/commonjs/components/Modals/FilePreviewModal/GViewWebView.js.map +1 -0
  19. package/lib/commonjs/components/Modals/FilePreviewModal/PdfView.js +4 -17
  20. package/lib/commonjs/components/Modals/FilePreviewModal/PdfView.js.map +1 -1
  21. package/lib/commonjs/components/RoomComponents/styled/LastAudioMessage.js +19 -33
  22. package/lib/commonjs/components/RoomComponents/styled/LastAudioMessage.js.map +1 -1
  23. package/lib/commonjs/components/styled/AudioMessage.js +643 -66
  24. package/lib/commonjs/components/styled/AudioMessage.js.map +1 -1
  25. package/lib/commonjs/components/styled/Button.js +9 -3
  26. package/lib/commonjs/components/styled/Button.js.map +1 -1
  27. package/lib/commonjs/components/styled/SendInput.js +239 -40
  28. package/lib/commonjs/components/styled/SendInput.js.map +1 -1
  29. package/lib/commonjs/components/styled/StyledInputComponents/MediaComponents.js +31 -18
  30. package/lib/commonjs/components/styled/StyledInputComponents/MediaComponents.js.map +1 -1
  31. package/lib/commonjs/components/styled/UnsupportedType.js +47 -5
  32. package/lib/commonjs/components/styled/UnsupportedType.js.map +1 -1
  33. package/lib/commonjs/context/xmppProvider.js +68 -2
  34. package/lib/commonjs/context/xmppProvider.js.map +1 -1
  35. package/lib/commonjs/helpers/keyboardLayout.js +5 -3
  36. package/lib/commonjs/helpers/keyboardLayout.js.map +1 -1
  37. package/lib/commonjs/helpers/mimeToExtension.js +70 -3
  38. package/lib/commonjs/helpers/mimeToExtension.js.map +1 -1
  39. package/lib/commonjs/hooks/useEventHandlers.js +1 -1
  40. package/lib/commonjs/hooks/useEventHandlers.js.map +1 -1
  41. package/lib/commonjs/hooks/useSendMessage.js +6 -3
  42. package/lib/commonjs/hooks/useSendMessage.js.map +1 -1
  43. package/lib/commonjs/networking/xmppClient.js +26 -1
  44. package/lib/commonjs/networking/xmppClient.js.map +1 -1
  45. package/lib/commonjs/roomStore/Middleware/unreadMidlleware.js +10 -10
  46. package/lib/commonjs/roomStore/Middleware/unreadMidlleware.js.map +1 -1
  47. package/lib/commonjs/roomStore/roomsSlice.js +65 -4
  48. package/lib/commonjs/roomStore/roomsSlice.js.map +1 -1
  49. package/lib/module/assets/icons.js +7 -1
  50. package/lib/module/assets/icons.js.map +1 -1
  51. package/lib/module/components/MainComponents/ChatRoom.js +59 -23
  52. package/lib/module/components/MainComponents/ChatRoom.js.map +1 -1
  53. package/lib/module/components/MainComponents/MediaMessage.js +290 -7
  54. package/lib/module/components/MainComponents/MediaMessage.js.map +1 -1
  55. package/lib/module/components/MainComponents/ReduxWrapper.js +24 -15
  56. package/lib/module/components/MainComponents/ReduxWrapper.js.map +1 -1
  57. package/lib/module/components/MessageBubble/MessageInteractions.js +24 -4
  58. package/lib/module/components/MessageBubble/MessageInteractions.js.map +1 -1
  59. package/lib/module/components/Modals/FilePreviewModal/DocumentViewer.js +5 -45
  60. package/lib/module/components/Modals/FilePreviewModal/DocumentViewer.js.map +1 -1
  61. package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js +36 -3
  62. package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
  63. package/lib/module/components/Modals/FilePreviewModal/GViewWebView.js +144 -0
  64. package/lib/module/components/Modals/FilePreviewModal/GViewWebView.js.map +1 -0
  65. package/lib/module/components/Modals/FilePreviewModal/PdfView.js +3 -17
  66. package/lib/module/components/Modals/FilePreviewModal/PdfView.js.map +1 -1
  67. package/lib/module/components/RoomComponents/styled/LastAudioMessage.js +20 -34
  68. package/lib/module/components/RoomComponents/styled/LastAudioMessage.js.map +1 -1
  69. package/lib/module/components/styled/AudioMessage.js +644 -67
  70. package/lib/module/components/styled/AudioMessage.js.map +1 -1
  71. package/lib/module/components/styled/Button.js +9 -3
  72. package/lib/module/components/styled/Button.js.map +1 -1
  73. package/lib/module/components/styled/SendInput.js +240 -42
  74. package/lib/module/components/styled/SendInput.js.map +1 -1
  75. package/lib/module/components/styled/StyledInputComponents/MediaComponents.js +31 -18
  76. package/lib/module/components/styled/StyledInputComponents/MediaComponents.js.map +1 -1
  77. package/lib/module/components/styled/UnsupportedType.js +47 -5
  78. package/lib/module/components/styled/UnsupportedType.js.map +1 -1
  79. package/lib/module/context/xmppProvider.js +70 -4
  80. package/lib/module/context/xmppProvider.js.map +1 -1
  81. package/lib/module/helpers/keyboardLayout.js +4 -2
  82. package/lib/module/helpers/keyboardLayout.js.map +1 -1
  83. package/lib/module/helpers/mimeToExtension.js +67 -3
  84. package/lib/module/helpers/mimeToExtension.js.map +1 -1
  85. package/lib/module/hooks/useEventHandlers.js +1 -1
  86. package/lib/module/hooks/useEventHandlers.js.map +1 -1
  87. package/lib/module/hooks/useSendMessage.js +6 -3
  88. package/lib/module/hooks/useSendMessage.js.map +1 -1
  89. package/lib/module/networking/xmppClient.js +26 -1
  90. package/lib/module/networking/xmppClient.js.map +1 -1
  91. package/lib/module/roomStore/Middleware/unreadMidlleware.js +10 -10
  92. package/lib/module/roomStore/Middleware/unreadMidlleware.js.map +1 -1
  93. package/lib/module/roomStore/roomsSlice.js +63 -3
  94. package/lib/module/roomStore/roomsSlice.js.map +1 -1
  95. package/lib/typescript/assets/icons.d.ts.map +1 -1
  96. package/lib/typescript/components/MainComponents/ChatRoom.d.ts.map +1 -1
  97. package/lib/typescript/components/MainComponents/MediaMessage.d.ts.map +1 -1
  98. package/lib/typescript/components/MainComponents/ReduxWrapper.d.ts.map +1 -1
  99. package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts.map +1 -1
  100. package/lib/typescript/components/Modals/FilePreviewModal/DocumentViewer.d.ts +0 -7
  101. package/lib/typescript/components/Modals/FilePreviewModal/DocumentViewer.d.ts.map +1 -1
  102. package/lib/typescript/components/Modals/FilePreviewModal/FilePreviewModal.d.ts.map +1 -1
  103. package/lib/typescript/components/Modals/FilePreviewModal/GViewWebView.d.ts +8 -0
  104. package/lib/typescript/components/Modals/FilePreviewModal/GViewWebView.d.ts.map +1 -0
  105. package/lib/typescript/components/Modals/FilePreviewModal/PdfView.d.ts.map +1 -1
  106. package/lib/typescript/components/RoomComponents/styled/LastAudioMessage.d.ts.map +1 -1
  107. package/lib/typescript/components/styled/AudioMessage.d.ts +8 -2
  108. package/lib/typescript/components/styled/AudioMessage.d.ts.map +1 -1
  109. package/lib/typescript/components/styled/Button.d.ts.map +1 -1
  110. package/lib/typescript/components/styled/SendInput.d.ts.map +1 -1
  111. package/lib/typescript/components/styled/StyledInputComponents/MediaComponents.d.ts +5 -1
  112. package/lib/typescript/components/styled/StyledInputComponents/MediaComponents.d.ts.map +1 -1
  113. package/lib/typescript/components/styled/UnsupportedType.d.ts +5 -0
  114. package/lib/typescript/components/styled/UnsupportedType.d.ts.map +1 -1
  115. package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
  116. package/lib/typescript/helpers/keyboardLayout.d.ts +3 -1
  117. package/lib/typescript/helpers/keyboardLayout.d.ts.map +1 -1
  118. package/lib/typescript/helpers/mimeToExtension.d.ts +31 -1
  119. package/lib/typescript/helpers/mimeToExtension.d.ts.map +1 -1
  120. package/lib/typescript/hooks/useSendMessage.d.ts.map +1 -1
  121. package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
  122. package/lib/typescript/roomStore/Middleware/unreadMidlleware.d.ts.map +1 -1
  123. package/lib/typescript/roomStore/roomsSlice.d.ts +18 -1
  124. package/lib/typescript/roomStore/roomsSlice.d.ts.map +1 -1
  125. package/lib/typescript/types/models/modal.model.d.ts +3 -0
  126. package/lib/typescript/types/models/modal.model.d.ts.map +1 -1
  127. package/lib/typescript/types/types.d.ts +15 -0
  128. package/lib/typescript/types/types.d.ts.map +1 -1
  129. package/package.json +5 -1
  130. package/src/assets/icons.tsx +30 -25
  131. package/src/components/MainComponents/ChatRoom.tsx +61 -23
  132. package/src/components/MainComponents/MediaMessage.tsx +295 -5
  133. package/src/components/MainComponents/ReduxWrapper.tsx +23 -9
  134. package/src/components/MessageBubble/MessageInteractions.tsx +35 -3
  135. package/src/components/Modals/FilePreviewModal/DocumentViewer.tsx +3 -40
  136. package/src/components/Modals/FilePreviewModal/FilePreviewModal.tsx +39 -3
  137. package/src/components/Modals/FilePreviewModal/GViewWebView.tsx +142 -0
  138. package/src/components/Modals/FilePreviewModal/PdfView.tsx +2 -18
  139. package/src/components/RoomComponents/styled/LastAudioMessage.tsx +20 -35
  140. package/src/components/styled/AudioMessage.tsx +724 -59
  141. package/src/components/styled/Button.tsx +20 -11
  142. package/src/components/styled/SendInput.tsx +255 -46
  143. package/src/components/styled/StyledInputComponents/MediaComponents.tsx +29 -18
  144. package/src/components/styled/UnsupportedType.tsx +60 -6
  145. package/src/context/xmppProvider.tsx +61 -3
  146. package/src/helpers/keyboardLayout.ts +5 -1
  147. package/src/helpers/mimeToExtension.ts +116 -2
  148. package/src/hooks/useEventHandlers.tsx +1 -1
  149. package/src/hooks/useSendMessage.tsx +12 -6
  150. package/src/networking/xmppClient.ts +24 -1
  151. package/src/roomStore/Middleware/unreadMidlleware.tsx +11 -8
  152. package/src/roomStore/roomsSlice.ts +66 -2
  153. package/src/types/models/modal.model.ts +3 -0
  154. package/src/types/types.ts +32 -0
@@ -240,6 +240,30 @@ const FilePreviewModal: React.FC<FilePreviewModalProps> = ({
240
240
  );
241
241
  case activeFile.mimetype.startsWith('video/'):
242
242
  return <ModalVideo uri={activeFile.fileURL} />;
243
+ case activeFile.mimetype.includes('application/octet-stream'):
244
+ return (
245
+ <View
246
+ style={{
247
+ width: '100%',
248
+ padding: 20,
249
+ gap: 12,
250
+ backgroundColor: '#FFF8ED',
251
+ borderRadius: 16,
252
+ }}
253
+ >
254
+ <Text style={{ fontSize: 16, fontWeight: '600' }}>
255
+ Voice message
256
+ </Text>
257
+ <AudioMessage
258
+ src={activeFile.fileURL}
259
+ mimeType={activeFile.mimetype}
260
+ fileName={activeFile.fileName}
261
+ originalName={activeFile.originalName}
262
+ duration={activeFile.duration}
263
+ waveForm={activeFile.waveForm}
264
+ />
265
+ </View>
266
+ );
243
267
  // Mirrors the MediaMessage heuristic: treat octet-stream voicemails
244
268
  // with audio-shaped filenames / URLs as audio so the preview shows
245
269
  // the player instead of an "Unsupported" card. Customer-reported
@@ -247,7 +271,12 @@ const FilePreviewModal: React.FC<FilePreviewModalProps> = ({
247
271
  case isLikelyAudio(
248
272
  activeFile.mimetype,
249
273
  activeFile.fileName,
250
- activeFile.fileURL
274
+ activeFile.fileURL,
275
+ {
276
+ duration: activeFile.duration,
277
+ waveForm: activeFile.waveForm,
278
+ originalName: activeFile.originalName,
279
+ }
251
280
  ):
252
281
  return (
253
282
  <View
@@ -261,11 +290,18 @@ const FilePreviewModal: React.FC<FilePreviewModalProps> = ({
261
290
  >
262
291
  <Text style={{ fontSize: 16, fontWeight: '600' }}>
263
292
  {ensureFilenameHasExtension(
264
- activeFile.fileName,
293
+ activeFile.originalName || activeFile.fileName,
265
294
  activeFile.mimetype
266
295
  )}
267
296
  </Text>
268
- <AudioMessage src={activeFile.fileURL} />
297
+ <AudioMessage
298
+ src={activeFile.fileURL}
299
+ mimeType={activeFile.mimetype}
300
+ fileName={activeFile.fileName}
301
+ originalName={activeFile.originalName}
302
+ duration={activeFile.duration}
303
+ waveForm={activeFile.waveForm}
304
+ />
269
305
  </View>
270
306
  );
271
307
  case activeFile.mimetype === 'application/pdf':
@@ -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
  };