stream-chat-react-native-core 5.29.1-beta.4 → 5.30.0-beta.2

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 (209) hide show
  1. package/lib/commonjs/components/Channel/Channel.js +4 -2
  2. package/lib/commonjs/components/Channel/Channel.js.map +1 -1
  3. package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js +2 -2
  4. package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
  5. package/lib/commonjs/components/ChannelPreview/hooks/useLatestMessagePreview.js +1 -1
  6. package/lib/commonjs/components/ChannelPreview/hooks/useLatestMessagePreview.js.map +1 -1
  7. package/lib/commonjs/components/ImageGallery/components/ImageGalleryHeader.js +6 -14
  8. package/lib/commonjs/components/ImageGallery/components/ImageGalleryHeader.js.map +1 -1
  9. package/lib/commonjs/components/Message/Message.js +11 -0
  10. package/lib/commonjs/components/Message/Message.js.map +1 -1
  11. package/lib/commonjs/components/Message/MessageSimple/MessageContent.js +12 -27
  12. package/lib/commonjs/components/Message/MessageSimple/MessageContent.js.map +1 -1
  13. package/lib/commonjs/components/Message/MessageSimple/MessageDeleted.js +10 -12
  14. package/lib/commonjs/components/Message/MessageSimple/MessageDeleted.js.map +1 -1
  15. package/lib/commonjs/components/Message/MessageSimple/MessageEditedTimestamp.js +55 -0
  16. package/lib/commonjs/components/Message/MessageSimple/MessageEditedTimestamp.js.map +1 -0
  17. package/lib/commonjs/components/Message/MessageSimple/MessageFooter.js +94 -58
  18. package/lib/commonjs/components/Message/MessageSimple/MessageFooter.js.map +1 -1
  19. package/lib/commonjs/components/Message/MessageSimple/MessageSimple.js +6 -0
  20. package/lib/commonjs/components/Message/MessageSimple/MessageSimple.js.map +1 -1
  21. package/lib/commonjs/components/Message/MessageSimple/MessageTimestamp.js +48 -0
  22. package/lib/commonjs/components/Message/MessageSimple/MessageTimestamp.js.map +1 -0
  23. package/lib/commonjs/components/Message/hooks/useCreateMessageContext.js +5 -1
  24. package/lib/commonjs/components/Message/hooks/useCreateMessageContext.js.map +1 -1
  25. package/lib/commonjs/components/MessageInput/hooks/useAudioController.js +7 -10
  26. package/lib/commonjs/components/MessageInput/hooks/useAudioController.js.map +1 -1
  27. package/lib/commonjs/components/MessageList/InlineDateSeparator.js +6 -2
  28. package/lib/commonjs/components/MessageList/InlineDateSeparator.js.map +1 -1
  29. package/lib/commonjs/components/MessageList/MessageList.js +9 -6
  30. package/lib/commonjs/components/MessageList/MessageList.js.map +1 -1
  31. package/lib/commonjs/components/MessageList/MessageSystem.js +30 -27
  32. package/lib/commonjs/components/MessageList/MessageSystem.js.map +1 -1
  33. package/lib/commonjs/components/MessageList/utils/getGroupStyles.js +3 -2
  34. package/lib/commonjs/components/MessageList/utils/getGroupStyles.js.map +1 -1
  35. package/lib/commonjs/components/index.js +11 -0
  36. package/lib/commonjs/components/index.js.map +1 -1
  37. package/lib/commonjs/contexts/messageContext/MessageContext.js.map +1 -1
  38. package/lib/commonjs/contexts/messagesContext/MessagesContext.js.map +1 -1
  39. package/lib/commonjs/contexts/themeContext/utils/theme.js +3 -0
  40. package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
  41. package/lib/commonjs/i18n/en.json +1 -0
  42. package/lib/commonjs/i18n/es.json +14 -13
  43. package/lib/commonjs/i18n/fr.json +14 -13
  44. package/lib/commonjs/i18n/he.json +14 -13
  45. package/lib/commonjs/i18n/hi.json +14 -13
  46. package/lib/commonjs/i18n/it.json +14 -13
  47. package/lib/commonjs/i18n/ja.json +14 -13
  48. package/lib/commonjs/i18n/ko.json +14 -13
  49. package/lib/commonjs/i18n/nl.json +14 -13
  50. package/lib/commonjs/i18n/pt-BR.json +14 -13
  51. package/lib/commonjs/i18n/ru.json +14 -13
  52. package/lib/commonjs/i18n/tr.json +14 -13
  53. package/lib/commonjs/utils/getDateString.js +31 -0
  54. package/lib/commonjs/utils/getDateString.js.map +1 -0
  55. package/lib/commonjs/utils/utils.js +5 -1
  56. package/lib/commonjs/utils/utils.js.map +1 -1
  57. package/lib/commonjs/version.json +1 -1
  58. package/lib/module/components/Channel/Channel.js +4 -2
  59. package/lib/module/components/Channel/Channel.js.map +1 -1
  60. package/lib/module/components/Channel/hooks/useCreateMessagesContext.js +2 -2
  61. package/lib/module/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
  62. package/lib/module/components/ChannelPreview/hooks/useLatestMessagePreview.js +1 -1
  63. package/lib/module/components/ChannelPreview/hooks/useLatestMessagePreview.js.map +1 -1
  64. package/lib/module/components/ImageGallery/components/ImageGalleryHeader.js +6 -14
  65. package/lib/module/components/ImageGallery/components/ImageGalleryHeader.js.map +1 -1
  66. package/lib/module/components/Message/Message.js +11 -0
  67. package/lib/module/components/Message/Message.js.map +1 -1
  68. package/lib/module/components/Message/MessageSimple/MessageContent.js +12 -27
  69. package/lib/module/components/Message/MessageSimple/MessageContent.js.map +1 -1
  70. package/lib/module/components/Message/MessageSimple/MessageDeleted.js +10 -12
  71. package/lib/module/components/Message/MessageSimple/MessageDeleted.js.map +1 -1
  72. package/lib/module/components/Message/MessageSimple/MessageEditedTimestamp.js +55 -0
  73. package/lib/module/components/Message/MessageSimple/MessageEditedTimestamp.js.map +1 -0
  74. package/lib/module/components/Message/MessageSimple/MessageFooter.js +94 -58
  75. package/lib/module/components/Message/MessageSimple/MessageFooter.js.map +1 -1
  76. package/lib/module/components/Message/MessageSimple/MessageSimple.js +6 -0
  77. package/lib/module/components/Message/MessageSimple/MessageSimple.js.map +1 -1
  78. package/lib/module/components/Message/MessageSimple/MessageTimestamp.js +48 -0
  79. package/lib/module/components/Message/MessageSimple/MessageTimestamp.js.map +1 -0
  80. package/lib/module/components/Message/hooks/useCreateMessageContext.js +5 -1
  81. package/lib/module/components/Message/hooks/useCreateMessageContext.js.map +1 -1
  82. package/lib/module/components/MessageInput/hooks/useAudioController.js +7 -10
  83. package/lib/module/components/MessageInput/hooks/useAudioController.js.map +1 -1
  84. package/lib/module/components/MessageList/InlineDateSeparator.js +6 -2
  85. package/lib/module/components/MessageList/InlineDateSeparator.js.map +1 -1
  86. package/lib/module/components/MessageList/MessageList.js +9 -6
  87. package/lib/module/components/MessageList/MessageList.js.map +1 -1
  88. package/lib/module/components/MessageList/MessageSystem.js +30 -27
  89. package/lib/module/components/MessageList/MessageSystem.js.map +1 -1
  90. package/lib/module/components/MessageList/utils/getGroupStyles.js +3 -2
  91. package/lib/module/components/MessageList/utils/getGroupStyles.js.map +1 -1
  92. package/lib/module/components/index.js +11 -0
  93. package/lib/module/components/index.js.map +1 -1
  94. package/lib/module/contexts/messageContext/MessageContext.js.map +1 -1
  95. package/lib/module/contexts/messagesContext/MessagesContext.js.map +1 -1
  96. package/lib/module/contexts/themeContext/utils/theme.js +3 -0
  97. package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
  98. package/lib/module/i18n/en.json +1 -0
  99. package/lib/module/i18n/es.json +14 -13
  100. package/lib/module/i18n/fr.json +14 -13
  101. package/lib/module/i18n/he.json +14 -13
  102. package/lib/module/i18n/hi.json +14 -13
  103. package/lib/module/i18n/it.json +14 -13
  104. package/lib/module/i18n/ja.json +14 -13
  105. package/lib/module/i18n/ko.json +14 -13
  106. package/lib/module/i18n/nl.json +14 -13
  107. package/lib/module/i18n/pt-BR.json +14 -13
  108. package/lib/module/i18n/ru.json +14 -13
  109. package/lib/module/i18n/tr.json +14 -13
  110. package/lib/module/utils/getDateString.js +31 -0
  111. package/lib/module/utils/getDateString.js.map +1 -0
  112. package/lib/module/utils/utils.js +5 -1
  113. package/lib/module/utils/utils.js.map +1 -1
  114. package/lib/module/version.json +1 -1
  115. package/lib/typescript/components/Channel/Channel.d.ts +1 -1
  116. package/lib/typescript/components/Channel/Channel.d.ts.map +1 -1
  117. package/lib/typescript/components/Channel/hooks/useCreateMessagesContext.d.ts +1 -1
  118. package/lib/typescript/components/ImageGallery/components/ImageGalleryHeader.d.ts.map +1 -1
  119. package/lib/typescript/components/Message/Message.d.ts.map +1 -1
  120. package/lib/typescript/components/Message/MessageSimple/MessageContent.d.ts +1 -1
  121. package/lib/typescript/components/Message/MessageSimple/MessageContent.d.ts.map +1 -1
  122. package/lib/typescript/components/Message/MessageSimple/MessageDeleted.d.ts +8 -8
  123. package/lib/typescript/components/Message/MessageSimple/MessageDeleted.d.ts.map +1 -1
  124. package/lib/typescript/components/Message/MessageSimple/MessageEditedTimestamp.d.ts +7 -0
  125. package/lib/typescript/components/Message/MessageSimple/MessageEditedTimestamp.d.ts.map +1 -0
  126. package/lib/typescript/components/Message/MessageSimple/MessageFooter.d.ts +1 -1
  127. package/lib/typescript/components/Message/MessageSimple/MessageFooter.d.ts.map +1 -1
  128. package/lib/typescript/components/Message/MessageSimple/MessageSimple.d.ts +1 -1
  129. package/lib/typescript/components/Message/MessageSimple/MessageSimple.d.ts.map +1 -1
  130. package/lib/typescript/components/Message/MessageSimple/MessageTimestamp.d.ts +22 -0
  131. package/lib/typescript/components/Message/MessageSimple/MessageTimestamp.d.ts.map +1 -0
  132. package/lib/typescript/components/Message/hooks/useCreateMessageContext.d.ts +1 -1
  133. package/lib/typescript/components/Message/hooks/useCreateMessageContext.d.ts.map +1 -1
  134. package/lib/typescript/components/MessageInput/hooks/useAudioController.d.ts.map +1 -1
  135. package/lib/typescript/components/MessageList/DateHeader.d.ts +1 -1
  136. package/lib/typescript/components/MessageList/DateHeader.d.ts.map +1 -1
  137. package/lib/typescript/components/MessageList/InlineDateSeparator.d.ts.map +1 -1
  138. package/lib/typescript/components/MessageList/MessageList.d.ts.map +1 -1
  139. package/lib/typescript/components/MessageList/MessageSystem.d.ts +0 -8
  140. package/lib/typescript/components/MessageList/MessageSystem.d.ts.map +1 -1
  141. package/lib/typescript/components/MessageList/utils/getGroupStyles.d.ts.map +1 -1
  142. package/lib/typescript/components/index.d.ts +1 -0
  143. package/lib/typescript/components/index.d.ts.map +1 -1
  144. package/lib/typescript/contexts/channelContext/ChannelContext.d.ts +1 -1
  145. package/lib/typescript/contexts/channelContext/ChannelContext.d.ts.map +1 -1
  146. package/lib/typescript/contexts/messageContext/MessageContext.d.ts +5 -1
  147. package/lib/typescript/contexts/messageContext/MessageContext.d.ts.map +1 -1
  148. package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts +6 -5
  149. package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts.map +1 -1
  150. package/lib/typescript/contexts/themeContext/utils/theme.d.ts +3 -0
  151. package/lib/typescript/contexts/themeContext/utils/theme.d.ts.map +1 -1
  152. package/lib/typescript/i18n/en.json +1 -0
  153. package/lib/typescript/i18n/es.json +14 -13
  154. package/lib/typescript/i18n/fr.json +14 -13
  155. package/lib/typescript/i18n/he.json +14 -13
  156. package/lib/typescript/i18n/hi.json +14 -13
  157. package/lib/typescript/i18n/it.json +14 -13
  158. package/lib/typescript/i18n/ja.json +14 -13
  159. package/lib/typescript/i18n/ko.json +14 -13
  160. package/lib/typescript/i18n/nl.json +14 -13
  161. package/lib/typescript/i18n/pt-BR.json +14 -13
  162. package/lib/typescript/i18n/ru.json +14 -13
  163. package/lib/typescript/i18n/tr.json +14 -13
  164. package/lib/typescript/utils/Streami18n.d.ts +6 -0
  165. package/lib/typescript/utils/Streami18n.d.ts.map +1 -1
  166. package/lib/typescript/utils/getDateString.d.ts +30 -0
  167. package/lib/typescript/utils/getDateString.d.ts.map +1 -0
  168. package/lib/typescript/utils/utils.d.ts +6 -0
  169. package/lib/typescript/utils/utils.d.ts.map +1 -1
  170. package/package.json +2 -2
  171. package/src/components/Channel/Channel.tsx +4 -3
  172. package/src/components/Channel/hooks/useCreateMessagesContext.ts +2 -2
  173. package/src/components/ChannelPreview/hooks/useLatestMessagePreview.ts +1 -1
  174. package/src/components/ImageGallery/components/ImageGalleryHeader.tsx +3 -31
  175. package/src/components/Message/Message.tsx +7 -0
  176. package/src/components/Message/MessageSimple/MessageContent.tsx +13 -33
  177. package/src/components/Message/MessageSimple/MessageDeleted.tsx +13 -31
  178. package/src/components/Message/MessageSimple/MessageEditedTimestamp.tsx +56 -0
  179. package/src/components/Message/MessageSimple/MessageFooter.tsx +104 -63
  180. package/src/components/Message/MessageSimple/MessageSimple.tsx +14 -2
  181. package/src/components/Message/MessageSimple/MessageTimestamp.tsx +64 -0
  182. package/src/components/Message/hooks/useCreateMessageContext.ts +5 -0
  183. package/src/components/MessageInput/hooks/useAudioController.tsx +3 -5
  184. package/src/components/MessageList/DateHeader.tsx +1 -1
  185. package/src/components/MessageList/InlineDateSeparator.tsx +8 -8
  186. package/src/components/MessageList/MessageList.tsx +9 -9
  187. package/src/components/MessageList/MessageSystem.tsx +35 -43
  188. package/src/components/MessageList/utils/getGroupStyles.ts +7 -4
  189. package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +20 -12
  190. package/src/components/index.ts +1 -0
  191. package/src/contexts/channelContext/ChannelContext.tsx +1 -1
  192. package/src/contexts/messageContext/MessageContext.tsx +4 -0
  193. package/src/contexts/messagesContext/MessagesContext.tsx +6 -5
  194. package/src/contexts/themeContext/utils/theme.ts +6 -0
  195. package/src/i18n/en.json +1 -0
  196. package/src/i18n/es.json +14 -13
  197. package/src/i18n/fr.json +14 -13
  198. package/src/i18n/he.json +14 -13
  199. package/src/i18n/hi.json +14 -13
  200. package/src/i18n/it.json +14 -13
  201. package/src/i18n/ja.json +14 -13
  202. package/src/i18n/ko.json +14 -13
  203. package/src/i18n/nl.json +14 -13
  204. package/src/i18n/pt-BR.json +14 -13
  205. package/src/i18n/ru.json +14 -13
  206. package/src/i18n/tr.json +14 -13
  207. package/src/utils/getDateString.ts +67 -0
  208. package/src/utils/utils.ts +11 -0
  209. package/src/version.json +1 -1
@@ -3,11 +3,9 @@ import { LayoutChangeEvent, StyleSheet, View } from 'react-native';
3
3
 
4
4
  import merge from 'lodash/merge';
5
5
 
6
- import type { MessageFooterProps } from './MessageFooter';
7
6
  import { MessageTextContainer } from './MessageTextContainer';
8
7
 
9
8
  import {
10
- Alignment,
11
9
  MessageContextValue,
12
10
  useMessageContext,
13
11
  } from '../../../contexts/messageContext/MessageContext';
@@ -16,13 +14,9 @@ import {
16
14
  useMessagesContext,
17
15
  } from '../../../contexts/messagesContext/MessagesContext';
18
16
  import { useTheme } from '../../../contexts/themeContext/ThemeContext';
19
- import {
20
- TranslationContextValue,
21
- useTranslationContext,
22
- } from '../../../contexts/translationContext/TranslationContext';
17
+ import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext';
23
18
 
24
19
  import type { DefaultStreamChatGenerics } from '../../../types/types';
25
- import type { MessageType } from '../../MessageList/hooks/useMessageList';
26
20
 
27
21
  const styles = StyleSheet.create({
28
22
  containerInner: {
@@ -40,17 +34,16 @@ const styles = StyleSheet.create({
40
34
  });
41
35
 
42
36
  type MessageDeletedComponentProps = {
43
- formattedDate: string | Date;
44
37
  groupStyle: string;
45
38
  noBorder: boolean;
46
39
  onLayout: (event: LayoutChangeEvent) => void;
40
+ date?: string | Date;
47
41
  };
48
42
 
49
43
  type MessageDeletedPropsWithContext<
50
44
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
51
45
  > = Pick<MessageContextValue<StreamChatGenerics>, 'alignment' | 'message'> &
52
46
  Pick<MessagesContextValue<StreamChatGenerics>, 'MessageFooter'> &
53
- Pick<TranslationContextValue, 't'> &
54
47
  MessageDeletedComponentProps;
55
48
 
56
49
  const MessageDeletedWithContext = <
@@ -58,8 +51,7 @@ const MessageDeletedWithContext = <
58
51
  >(
59
52
  props: MessageDeletedPropsWithContext<StreamChatGenerics>,
60
53
  ) => {
61
- const { alignment, formattedDate, groupStyle, message, MessageFooter, noBorder, onLayout, t } =
62
- props;
54
+ const { alignment, date, groupStyle, message, MessageFooter, noBorder, onLayout } = props;
63
55
 
64
56
  const {
65
57
  theme: {
@@ -74,6 +66,7 @@ const MessageDeletedWithContext = <
74
66
  },
75
67
  },
76
68
  } = useTheme();
69
+ const { t } = useTranslationContext();
77
70
 
78
71
  return (
79
72
  <View
@@ -108,7 +101,7 @@ const MessageDeletedWithContext = <
108
101
  message={{ ...message, text: `_${t('Message deleted')}_` }}
109
102
  />
110
103
  </View>
111
- <MessageFooter formattedDate={formattedDate} isDeleted />
104
+ <MessageFooter date={date} isDeleted />
112
105
  </View>
113
106
  );
114
107
  };
@@ -117,16 +110,8 @@ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = Default
117
110
  prevProps: MessageDeletedPropsWithContext<StreamChatGenerics>,
118
111
  nextProps: MessageDeletedPropsWithContext<StreamChatGenerics>,
119
112
  ) => {
120
- const {
121
- alignment: prevAlignment,
122
- formattedDate: prevFormattedDate,
123
- message: prevMessage,
124
- } = prevProps;
125
- const {
126
- alignment: nextAlignment,
127
- formattedDate: nextFormattedDate,
128
- message: nextMessage,
129
- } = nextProps;
113
+ const { alignment: prevAlignment, date: prevDate, message: prevMessage } = prevProps;
114
+ const { alignment: nextAlignment, date: nextDate, message: nextMessage } = nextProps;
130
115
 
131
116
  const alignmentEqual = prevAlignment === nextAlignment;
132
117
  if (!alignmentEqual) return false;
@@ -142,8 +127,8 @@ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = Default
142
127
  prevMessage.pinned === nextMessage.pinned;
143
128
  if (!messageEqual) return false;
144
129
 
145
- const formattedDateEqual = prevFormattedDate === nextFormattedDate;
146
- if (!formattedDateEqual) return false;
130
+ const dateEqual = prevDate === nextDate;
131
+ if (!dateEqual) return false;
147
132
 
148
133
  return true;
149
134
  };
@@ -155,10 +140,10 @@ const MemoizedMessageDeleted = React.memo(
155
140
 
156
141
  export type MessageDeletedProps<
157
142
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
158
- > = MessageDeletedComponentProps & {
159
- alignment?: Alignment;
160
- message?: MessageType<StreamChatGenerics>;
161
- MessageFooter?: React.ComponentType<MessageFooterProps<StreamChatGenerics>>;
143
+ > = Partial<MessageDeletedPropsWithContext<StreamChatGenerics>> & {
144
+ groupStyle: string;
145
+ noBorder: boolean;
146
+ onLayout: (event: LayoutChangeEvent) => void;
162
147
  };
163
148
 
164
149
  export const MessageDeleted = <
@@ -170,15 +155,12 @@ export const MessageDeleted = <
170
155
 
171
156
  const { MessageFooter } = useMessagesContext<StreamChatGenerics>();
172
157
 
173
- const { t } = useTranslationContext();
174
-
175
158
  return (
176
159
  <MemoizedMessageDeleted
177
160
  {...{
178
161
  alignment,
179
162
  message,
180
163
  MessageFooter,
181
- t,
182
164
  }}
183
165
  {...props}
184
166
  />
@@ -0,0 +1,56 @@
1
+ import React from 'react';
2
+ import { StyleSheet, Text, View } from 'react-native';
3
+
4
+ import { MessageTimestamp, MessageTimestampProps } from './MessageTimestamp';
5
+
6
+ import {
7
+ MessageContextValue,
8
+ useMessageContext,
9
+ } from '../../../contexts/messageContext/MessageContext';
10
+ import { useTheme } from '../../../contexts/themeContext/ThemeContext';
11
+ import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext';
12
+ import { DefaultStreamChatGenerics } from '../../../types/types';
13
+ import { isEditedMessage } from '../../../utils/utils';
14
+
15
+ export type MessageEditedTimestampProps<
16
+ StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
17
+ > = Partial<Pick<MessageContextValue<StreamChatGenerics>, 'message'>> & MessageTimestampProps;
18
+
19
+ export const MessageEditedTimestamp = <
20
+ StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
21
+ >(
22
+ props: MessageEditedTimestampProps<StreamChatGenerics>,
23
+ ) => {
24
+ const { message: propMessage, timestamp } = props;
25
+ const {
26
+ theme: {
27
+ colors: { grey },
28
+ messageSimple: {
29
+ content: { editedLabel, editedTimestampContainer },
30
+ },
31
+ },
32
+ } = useTheme();
33
+ const { t } = useTranslationContext();
34
+ const { message: contextMessage } = useMessageContext<StreamChatGenerics>();
35
+ const message = propMessage || contextMessage;
36
+
37
+ if (!isEditedMessage(message)) {
38
+ return null;
39
+ }
40
+
41
+ return (
42
+ <View style={[styles.container, editedTimestampContainer]}>
43
+ <Text style={[styles.text, { color: grey }, editedLabel]}>{t<string>('Edited') + ' '}</Text>
44
+ <MessageTimestamp calendar={true} timestamp={timestamp} />
45
+ </View>
46
+ );
47
+ };
48
+
49
+ const styles = StyleSheet.create({
50
+ container: {
51
+ flexDirection: 'row',
52
+ },
53
+ text: {
54
+ fontSize: 12,
55
+ },
56
+ });
@@ -5,6 +5,8 @@ import type { Attachment } from 'stream-chat';
5
5
 
6
6
  import type { MessageStatusProps } from './MessageStatus';
7
7
 
8
+ import { MessageTimestamp } from './MessageTimestamp';
9
+
8
10
  import type { ChannelContextValue } from '../../../contexts/channelContext/ChannelContext';
9
11
  import {
10
12
  Alignment,
@@ -21,11 +23,11 @@ import { useTranslationContext } from '../../../contexts/translationContext/Tran
21
23
  import { Eye } from '../../../icons';
22
24
 
23
25
  import type { DefaultStreamChatGenerics } from '../../../types/types';
24
- import { MessageStatusTypes } from '../../../utils/utils';
26
+ import { isEditedMessage, MessageStatusTypes } from '../../../utils/utils';
25
27
  import type { MessageType } from '../../MessageList/hooks/useMessageList';
26
28
 
27
29
  type MessageFooterComponentProps = {
28
- formattedDate: string | Date;
30
+ date?: string | Date;
29
31
  isDeleted?: boolean;
30
32
  };
31
33
 
@@ -34,6 +36,7 @@ type MessageFooterPropsWithContext<
34
36
  > = Pick<
35
37
  MessageContextValue<StreamChatGenerics>,
36
38
  | 'alignment'
39
+ | 'isEditedMessageOpen'
37
40
  | 'members'
38
41
  | 'message'
39
42
  | 'otherAttachments'
@@ -42,10 +45,41 @@ type MessageFooterPropsWithContext<
42
45
  > &
43
46
  Pick<
44
47
  MessagesContextValue<StreamChatGenerics>,
45
- 'deletedMessagesVisibilityType' | 'MessageStatus'
48
+ 'deletedMessagesVisibilityType' | 'MessageEditedTimestamp' | 'MessageStatus'
46
49
  > &
47
50
  MessageFooterComponentProps;
48
51
 
52
+ const OnlyVisibleToYouComponent = ({ alignment }: { alignment: Alignment }) => {
53
+ const {
54
+ theme: {
55
+ colors: { grey_dark },
56
+ messageSimple: {
57
+ content: { deletedMetaText, eyeIcon, metaText },
58
+ },
59
+ },
60
+ } = useTheme();
61
+ const { t } = useTranslationContext();
62
+
63
+ return (
64
+ <>
65
+ <Eye pathFill={grey_dark} {...eyeIcon} />
66
+ <Text
67
+ style={[
68
+ {
69
+ color: grey_dark,
70
+ textAlign: alignment,
71
+ },
72
+ metaText,
73
+ deletedMetaText,
74
+ ]}
75
+ testID='only-visible-to-you'
76
+ >
77
+ {t<string>('Only visible to you')}
78
+ </Text>
79
+ </>
80
+ );
81
+ };
82
+
49
83
  const MessageFooterWithContext = <
50
84
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
51
85
  >(
@@ -53,12 +87,14 @@ const MessageFooterWithContext = <
53
87
  ) => {
54
88
  const {
55
89
  alignment,
90
+ date,
56
91
  deletedMessagesVisibilityType,
57
- formattedDate,
58
92
  isDeleted,
93
+ isEditedMessageOpen,
59
94
  lastGroupMessage,
60
95
  members,
61
96
  message,
97
+ MessageEditedTimestamp,
62
98
  MessageStatus,
63
99
  otherAttachments,
64
100
  showMessageStatus,
@@ -66,9 +102,9 @@ const MessageFooterWithContext = <
66
102
 
67
103
  const {
68
104
  theme: {
69
- colors: { grey, grey_dark },
105
+ colors: { grey },
70
106
  messageSimple: {
71
- content: { deletedMetaText, eyeIcon, messageUser, metaContainer, metaText },
107
+ content: { editedLabel, messageUser, metaContainer, metaText },
72
108
  },
73
109
  },
74
110
  } = useTheme();
@@ -78,69 +114,51 @@ const MessageFooterWithContext = <
78
114
  return (
79
115
  <View style={[styles.container, metaContainer]} testID='message-deleted'>
80
116
  {deletedMessagesVisibilityType === 'sender' && (
117
+ <OnlyVisibleToYouComponent alignment={alignment} />
118
+ )}
119
+ <MessageTimestamp format='LT' timestamp={date} />
120
+ </View>
121
+ );
122
+ }
123
+
124
+ if (lastGroupMessage === false && message.status === MessageStatusTypes.RECEIVED) {
125
+ return null;
126
+ }
127
+
128
+ return (
129
+ <>
130
+ <View style={[styles.container, metaContainer]} testID='message-status-time'>
131
+ {otherAttachments.length && otherAttachments[0].actions ? (
132
+ <OnlyVisibleToYouComponent alignment={alignment} />
133
+ ) : null}
134
+ {Object.keys(members).length > 2 && alignment === 'left' && message.user?.name ? (
135
+ <Text style={[styles.text, { color: grey }, messageUser]}>{message.user.name}</Text>
136
+ ) : null}
137
+ {showMessageStatus && <MessageStatus />}
138
+ <MessageTimestamp format='LT' timestamp={date} />
139
+
140
+ {isEditedMessage(message) && !isEditedMessageOpen && (
81
141
  <>
82
- <Eye pathFill={grey_dark} {...eyeIcon} />
83
142
  <Text
84
143
  style={[
144
+ styles.dotText,
85
145
  {
86
- color: grey_dark,
146
+ color: grey,
87
147
  textAlign: alignment,
88
148
  },
89
149
  metaText,
90
- deletedMetaText,
91
150
  ]}
92
- testID='only-visible-to-you'
93
151
  >
94
- {t<string>('Only visible to you')}
152
+
153
+ </Text>
154
+ <Text style={[styles.text, { color: grey, textAlign: alignment }, editedLabel]}>
155
+ {t<string>('Edited')}
95
156
  </Text>
96
157
  </>
97
158
  )}
98
- <Text
99
- style={[
100
- {
101
- color: grey,
102
- textAlign: alignment,
103
- },
104
- metaText,
105
- ]}
106
- >
107
- {formattedDate.toString()}
108
- </Text>
109
159
  </View>
110
- );
111
- }
112
-
113
- if (lastGroupMessage === false && message.status === MessageStatusTypes.RECEIVED) {
114
- return null;
115
- }
116
-
117
- return (
118
- <View style={[styles.container, metaContainer]} testID='message-status-time'>
119
- {otherAttachments.length && otherAttachments[0].actions ? (
120
- <>
121
- <Eye pathFill={grey_dark} {...eyeIcon} />
122
- <Text
123
- style={[
124
- {
125
- color: grey_dark,
126
- textAlign: alignment,
127
- },
128
- metaText,
129
- deletedMetaText,
130
- ]}
131
- >
132
- {t<string>('Only visible to you')}
133
- </Text>
134
- </>
135
- ) : null}
136
- {Object.keys(members).length > 2 && alignment === 'left' && message.user?.name ? (
137
- <Text style={[{ color: grey }, messageUser]}>{message.user.name}</Text>
138
- ) : null}
139
- {showMessageStatus && <MessageStatus />}
140
- <Text style={[{ color: grey, textAlign: alignment }, metaText]}>
141
- {formattedDate.toString()}
142
- </Text>
143
- </View>
160
+ {isEditedMessageOpen && <MessageEditedTimestamp format='LT' timestamp={date} />}
161
+ </>
144
162
  );
145
163
  };
146
164
 
@@ -150,7 +168,8 @@ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = Default
150
168
  ) => {
151
169
  const {
152
170
  alignment: prevAlignment,
153
- formattedDate: prevFormattedDate,
171
+ date: prevDate,
172
+ isEditedMessageOpen: prevIsEditedMessageOpen,
154
173
  lastGroupMessage: prevLastGroupMessage,
155
174
  members: prevMembers,
156
175
  message: prevMessage,
@@ -159,7 +178,8 @@ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = Default
159
178
  } = prevProps;
160
179
  const {
161
180
  alignment: nextAlignment,
162
- formattedDate: nextFormattedDate,
181
+ date: nextDate,
182
+ isEditedMessageOpen: nextIsEditedMessageOpen,
163
183
  lastGroupMessage: nextLastGroupMessage,
164
184
  members: nextMembers,
165
185
  message: nextMessage,
@@ -170,6 +190,9 @@ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = Default
170
190
  const alignmentEqual = prevAlignment === nextAlignment;
171
191
  if (!alignmentEqual) return false;
172
192
 
193
+ const isEditedMessageOpenEqual = prevIsEditedMessageOpen === nextIsEditedMessageOpen;
194
+ if (!isEditedMessageOpenEqual) return false;
195
+
173
196
  const membersEqual = Object.keys(prevMembers).length === Object.keys(nextMembers).length;
174
197
  if (!membersEqual) return false;
175
198
 
@@ -200,8 +223,8 @@ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = Default
200
223
  const showMessageStatusEqual = prevShowMessageStatus === nextShowMessageStatus;
201
224
  if (!showMessageStatusEqual) return false;
202
225
 
203
- const formattedDateEqual = prevFormattedDate === nextFormattedDate;
204
- if (!formattedDateEqual) return false;
226
+ const dateEqual = prevDate === nextDate;
227
+ if (!dateEqual) return false;
205
228
 
206
229
  return true;
207
230
  };
@@ -228,19 +251,29 @@ export const MessageFooter = <
228
251
  >(
229
252
  props: MessageFooterProps<StreamChatGenerics>,
230
253
  ) => {
231
- const { alignment, lastGroupMessage, members, message, otherAttachments, showMessageStatus } =
232
- useMessageContext<StreamChatGenerics>();
254
+ const {
255
+ alignment,
256
+ isEditedMessageOpen,
257
+ lastGroupMessage,
258
+ members,
259
+ message,
260
+ otherAttachments,
261
+ showMessageStatus,
262
+ } = useMessageContext<StreamChatGenerics>();
233
263
 
234
- const { deletedMessagesVisibilityType, MessageStatus } = useMessagesContext<StreamChatGenerics>();
264
+ const { deletedMessagesVisibilityType, MessageEditedTimestamp, MessageStatus } =
265
+ useMessagesContext<StreamChatGenerics>();
235
266
 
236
267
  return (
237
268
  <MemoizedMessageFooter
238
269
  {...{
239
270
  alignment,
240
271
  deletedMessagesVisibilityType,
272
+ isEditedMessageOpen,
241
273
  lastGroupMessage,
242
274
  members,
243
275
  message,
276
+ MessageEditedTimestamp,
244
277
  MessageStatus,
245
278
  otherAttachments,
246
279
  showMessageStatus,
@@ -252,7 +285,15 @@ export const MessageFooter = <
252
285
 
253
286
  const styles = StyleSheet.create({
254
287
  container: {
288
+ alignItems: 'center',
255
289
  flexDirection: 'row',
290
+ justifyContent: 'center',
256
291
  marginTop: 4,
257
292
  },
293
+ dotText: {
294
+ paddingHorizontal: 4,
295
+ },
296
+ text: {
297
+ fontSize: 12,
298
+ },
258
299
  });
@@ -31,7 +31,13 @@ export type MessageSimplePropsWithContext<
31
31
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
32
32
  > = Pick<
33
33
  MessageContextValue<StreamChatGenerics>,
34
- 'alignment' | 'channel' | 'disabled' | 'groupStyles' | 'hasReactions' | 'message'
34
+ | 'alignment'
35
+ | 'channel'
36
+ | 'disabled'
37
+ | 'isEditedMessageOpen'
38
+ | 'groupStyles'
39
+ | 'hasReactions'
40
+ | 'message'
35
41
  > &
36
42
  Pick<
37
43
  MessagesContextValue<StreamChatGenerics>,
@@ -122,6 +128,7 @@ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = Default
122
128
  disabled: prevDisabled,
123
129
  groupStyles: prevGroupStyles,
124
130
  hasReactions: prevHasReactions,
131
+ isEditedMessageOpen: prevIsEditedMessageOpen,
125
132
  message: prevMessage,
126
133
  myMessageTheme: prevMyMessageTheme,
127
134
  } = prevProps;
@@ -130,6 +137,7 @@ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = Default
130
137
  disabled: nextDisabled,
131
138
  groupStyles: nextGroupStyles,
132
139
  hasReactions: nextHasReactions,
140
+ isEditedMessageOpen: nextIsEditedMessageOpen,
133
141
  message: nextMessage,
134
142
  myMessageTheme: nextMyMessageTheme,
135
143
  } = nextProps;
@@ -146,6 +154,9 @@ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = Default
146
154
  const groupStylesEqual = JSON.stringify(prevGroupStyles) === JSON.stringify(nextGroupStyles);
147
155
  if (!groupStylesEqual) return false;
148
156
 
157
+ const isEditedMessageOpenEqual = prevIsEditedMessageOpen === nextIsEditedMessageOpen;
158
+ if (!isEditedMessageOpenEqual) return false;
159
+
149
160
  const isPrevMessageTypeDeleted = prevMessage.type === 'deleted';
150
161
  const isNextMessageTypeDeleted = nextMessage.type === 'deleted';
151
162
 
@@ -219,7 +230,7 @@ export const MessageSimple = <
219
230
  >(
220
231
  props: MessageSimpleProps<StreamChatGenerics>,
221
232
  ) => {
222
- const { alignment, channel, disabled, groupStyles, hasReactions, message } =
233
+ const { alignment, channel, disabled, groupStyles, hasReactions, isEditedMessageOpen, message } =
223
234
  useMessageContext<StreamChatGenerics>();
224
235
  const {
225
236
  enableMessageGroupingByUser,
@@ -238,6 +249,7 @@ export const MessageSimple = <
238
249
  enableMessageGroupingByUser,
239
250
  groupStyles,
240
251
  hasReactions,
252
+ isEditedMessageOpen,
241
253
  message,
242
254
  MessageAvatar,
243
255
  MessageContent,
@@ -0,0 +1,64 @@
1
+ import React from 'react';
2
+ import { StyleSheet, Text } from 'react-native';
3
+
4
+ import { useTheme } from '../../../contexts/themeContext/ThemeContext';
5
+ import {
6
+ TDateTimeParserInput,
7
+ TranslationContextValue,
8
+ useTranslationContext,
9
+ } from '../../../contexts/translationContext/TranslationContext';
10
+ import { getDateString } from '../../../utils/getDateString';
11
+
12
+ export type MessageTimestampProps = Partial<Pick<TranslationContextValue, 'tDateTimeParser'>> & {
13
+ /**
14
+ * Whether to show the time in Calendar time format. Calendar time displays time relative to a today's date.
15
+ */
16
+ calendar?: boolean;
17
+ /**
18
+ * The format in which the date should be displayed.
19
+ */
20
+ format?: string;
21
+ /**
22
+ * A function to format the date.
23
+ */
24
+ formatDate?: (date: TDateTimeParserInput) => string;
25
+ /**
26
+ * The timestamp of the message.
27
+ */
28
+ timestamp?: string | Date;
29
+ };
30
+
31
+ export const MessageTimestamp = (props: MessageTimestampProps) => {
32
+ const { calendar, format, formatDate, tDateTimeParser: propsTDateTimeParser, timestamp } = props;
33
+ const {
34
+ theme: {
35
+ colors: { grey },
36
+ messageSimple: {
37
+ content: { timestampText },
38
+ },
39
+ },
40
+ } = useTheme();
41
+ const { tDateTimeParser: contextTDateTimeParser } = useTranslationContext();
42
+
43
+ if (!timestamp) return null;
44
+
45
+ const formattedDate = getDateString({
46
+ calendar,
47
+ date: timestamp,
48
+ format,
49
+ formatDate,
50
+ tDateTimeParser: propsTDateTimeParser || contextTDateTimeParser,
51
+ });
52
+
53
+ if (!formattedDate) return null;
54
+
55
+ return (
56
+ <Text style={[styles.text, { color: grey }, timestampText]}>{formattedDate.toString()}</Text>
57
+ );
58
+ };
59
+
60
+ const styles = StyleSheet.create({
61
+ text: {
62
+ fontSize: 12,
63
+ },
64
+ });
@@ -24,6 +24,7 @@ export const useCreateMessageContext = <
24
24
  handleToggleReaction,
25
25
  hasReactions,
26
26
  images,
27
+ isEditedMessageOpen,
27
28
  isMyMessage,
28
29
  lastGroupMessage,
29
30
  lastReceivedId,
@@ -39,6 +40,7 @@ export const useCreateMessageContext = <
39
40
  otherAttachments,
40
41
  preventPress,
41
42
  reactions,
43
+ setIsEditedMessageOpen,
42
44
  showAvatar,
43
45
  showMessageOverlay,
44
46
  showMessageStatus,
@@ -78,6 +80,7 @@ export const useCreateMessageContext = <
78
80
  handleToggleReaction,
79
81
  hasReactions,
80
82
  images,
83
+ isEditedMessageOpen,
81
84
  isMyMessage,
82
85
  lastGroupMessage,
83
86
  lastReceivedId,
@@ -93,6 +96,7 @@ export const useCreateMessageContext = <
93
96
  otherAttachments,
94
97
  preventPress,
95
98
  reactions,
99
+ setIsEditedMessageOpen,
96
100
  showAvatar,
97
101
  showMessageOverlay,
98
102
  showMessageStatus,
@@ -107,6 +111,7 @@ export const useCreateMessageContext = <
107
111
  goToMessage,
108
112
  groupStylesLength,
109
113
  hasReactions,
114
+ isEditedMessageOpen,
110
115
  lastGroupMessage,
111
116
  lastReceivedId,
112
117
  membersValue,
@@ -138,11 +138,9 @@ export const useAudioController = () => {
138
138
  await Audio.stopPlayer();
139
139
  }
140
140
  // For Expo CLI
141
- if (recording && typeof recording !== 'string') {
142
- if (soundRef.current?.stopAsync && soundRef.current?.unloadAsync) {
143
- await soundRef.current.stopAsync();
144
- await soundRef.current?.unloadAsync();
145
- }
141
+ if (soundRef.current?.stopAsync && soundRef.current?.unloadAsync) {
142
+ await soundRef.current.stopAsync();
143
+ await soundRef.current?.unloadAsync();
146
144
  }
147
145
  };
148
146
 
@@ -21,7 +21,7 @@ const styles = StyleSheet.create({
21
21
  });
22
22
 
23
23
  export type DateHeaderProps = {
24
- dateString: string;
24
+ dateString: string | number;
25
25
  };
26
26
 
27
27
  export const DateHeader = ({ dateString }: DateHeaderProps) => {
@@ -2,10 +2,8 @@ import React from 'react';
2
2
  import { StyleSheet, Text, View } from 'react-native';
3
3
 
4
4
  import { useTheme } from '../../contexts/themeContext/ThemeContext';
5
- import {
6
- isDayOrMoment,
7
- useTranslationContext,
8
- } from '../../contexts/translationContext/TranslationContext';
5
+ import { useTranslationContext } from '../../contexts/translationContext/TranslationContext';
6
+ import { getDateString } from '../../utils/getDateString';
9
7
 
10
8
  const styles = StyleSheet.create({
11
9
  container: {
@@ -42,10 +40,12 @@ export const InlineDateSeparator = ({ date }: InlineDateSeparatorProps) => {
42
40
  }
43
41
 
44
42
  const dateFormat = date.getFullYear() === new Date().getFullYear() ? 'MMM D' : 'MMM D, YYYY';
45
- const tDate = tDateTimeParser(date);
46
- const dateString = isDayOrMoment(tDate)
47
- ? tDate.format(dateFormat)
48
- : new Date(tDate).toDateString();
43
+
44
+ const dateString = getDateString({
45
+ date,
46
+ format: dateFormat,
47
+ tDateTimeParser,
48
+ });
49
49
 
50
50
  return (
51
51
  <View