stream-chat-react-native-core 6.0.2-beta.1 → 6.1.0-beta.1

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 (216) hide show
  1. package/README.md +1 -1
  2. package/lib/commonjs/components/Channel/Channel.js +371 -279
  3. package/lib/commonjs/components/Channel/Channel.js.map +1 -1
  4. package/lib/commonjs/components/Channel/hooks/useChannelDataState.js +8 -0
  5. package/lib/commonjs/components/Channel/hooks/useChannelDataState.js.map +1 -1
  6. package/lib/commonjs/components/Channel/hooks/useCreateChannelContext.js +10 -1
  7. package/lib/commonjs/components/Channel/hooks/useCreateChannelContext.js.map +1 -1
  8. package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js +4 -0
  9. package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
  10. package/lib/commonjs/components/Channel/hooks/useMessageListPagination.js +161 -69
  11. package/lib/commonjs/components/Channel/hooks/useMessageListPagination.js.map +1 -1
  12. package/lib/commonjs/components/Channel/hooks/useTargetedMessage.js +10 -0
  13. package/lib/commonjs/components/Channel/hooks/useTargetedMessage.js.map +1 -1
  14. package/lib/commonjs/components/Chat/hooks/handleEventToSyncDB.js +81 -54
  15. package/lib/commonjs/components/Chat/hooks/handleEventToSyncDB.js.map +1 -1
  16. package/lib/commonjs/components/Message/Message.js +6 -0
  17. package/lib/commonjs/components/Message/Message.js.map +1 -1
  18. package/lib/commonjs/components/Message/hooks/useMessageActionHandlers.js +117 -79
  19. package/lib/commonjs/components/Message/hooks/useMessageActionHandlers.js.map +1 -1
  20. package/lib/commonjs/components/Message/hooks/useMessageActions.js +32 -14
  21. package/lib/commonjs/components/Message/hooks/useMessageActions.js.map +1 -1
  22. package/lib/commonjs/components/Message/utils/messageActions.js +4 -0
  23. package/lib/commonjs/components/Message/utils/messageActions.js.map +1 -1
  24. package/lib/commonjs/components/MessageList/InlineUnreadIndicator.js +19 -55
  25. package/lib/commonjs/components/MessageList/InlineUnreadIndicator.js.map +1 -1
  26. package/lib/commonjs/components/MessageList/MessageList.js +249 -211
  27. package/lib/commonjs/components/MessageList/MessageList.js.map +1 -1
  28. package/lib/commonjs/components/MessageList/UnreadMessagesNotification.js +148 -0
  29. package/lib/commonjs/components/MessageList/UnreadMessagesNotification.js.map +1 -0
  30. package/lib/commonjs/components/MessageMenu/MessageActionListItem.js.map +1 -1
  31. package/lib/commonjs/contexts/channelContext/ChannelContext.js.map +1 -1
  32. package/lib/commonjs/contexts/messagesContext/MessagesContext.js.map +1 -1
  33. package/lib/commonjs/contexts/themeContext/utils/theme.js +7 -1
  34. package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
  35. package/lib/commonjs/i18n/en.json +2 -0
  36. package/lib/commonjs/i18n/es.json +2 -0
  37. package/lib/commonjs/i18n/fr.json +2 -0
  38. package/lib/commonjs/i18n/he.json +2 -0
  39. package/lib/commonjs/i18n/hi.json +2 -0
  40. package/lib/commonjs/i18n/it.json +2 -0
  41. package/lib/commonjs/i18n/ja.json +2 -0
  42. package/lib/commonjs/i18n/ko.json +2 -0
  43. package/lib/commonjs/i18n/nl.json +2 -0
  44. package/lib/commonjs/i18n/pt-br.json +2 -0
  45. package/lib/commonjs/i18n/ru.json +2 -0
  46. package/lib/commonjs/i18n/tr.json +2 -0
  47. package/lib/commonjs/icons/UnreadIndicator.js +30 -0
  48. package/lib/commonjs/icons/UnreadIndicator.js.map +1 -0
  49. package/lib/commonjs/icons/index.js +11 -0
  50. package/lib/commonjs/icons/index.js.map +1 -1
  51. package/lib/commonjs/store/SqliteClient.js +1 -1
  52. package/lib/commonjs/store/schema.js +1 -0
  53. package/lib/commonjs/store/schema.js.map +1 -1
  54. package/lib/commonjs/types/types.js.map +1 -1
  55. package/lib/commonjs/utils/utils.js +35 -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 +371 -279
  59. package/lib/module/components/Channel/Channel.js.map +1 -1
  60. package/lib/module/components/Channel/hooks/useChannelDataState.js +8 -0
  61. package/lib/module/components/Channel/hooks/useChannelDataState.js.map +1 -1
  62. package/lib/module/components/Channel/hooks/useCreateChannelContext.js +10 -1
  63. package/lib/module/components/Channel/hooks/useCreateChannelContext.js.map +1 -1
  64. package/lib/module/components/Channel/hooks/useCreateMessagesContext.js +4 -0
  65. package/lib/module/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
  66. package/lib/module/components/Channel/hooks/useMessageListPagination.js +161 -69
  67. package/lib/module/components/Channel/hooks/useMessageListPagination.js.map +1 -1
  68. package/lib/module/components/Channel/hooks/useTargetedMessage.js +10 -0
  69. package/lib/module/components/Channel/hooks/useTargetedMessage.js.map +1 -1
  70. package/lib/module/components/Chat/hooks/handleEventToSyncDB.js +81 -54
  71. package/lib/module/components/Chat/hooks/handleEventToSyncDB.js.map +1 -1
  72. package/lib/module/components/Message/Message.js +6 -0
  73. package/lib/module/components/Message/Message.js.map +1 -1
  74. package/lib/module/components/Message/hooks/useMessageActionHandlers.js +117 -79
  75. package/lib/module/components/Message/hooks/useMessageActionHandlers.js.map +1 -1
  76. package/lib/module/components/Message/hooks/useMessageActions.js +32 -14
  77. package/lib/module/components/Message/hooks/useMessageActions.js.map +1 -1
  78. package/lib/module/components/Message/utils/messageActions.js +4 -0
  79. package/lib/module/components/Message/utils/messageActions.js.map +1 -1
  80. package/lib/module/components/MessageList/InlineUnreadIndicator.js +19 -55
  81. package/lib/module/components/MessageList/InlineUnreadIndicator.js.map +1 -1
  82. package/lib/module/components/MessageList/MessageList.js +249 -211
  83. package/lib/module/components/MessageList/MessageList.js.map +1 -1
  84. package/lib/module/components/MessageList/UnreadMessagesNotification.js +148 -0
  85. package/lib/module/components/MessageList/UnreadMessagesNotification.js.map +1 -0
  86. package/lib/module/components/MessageMenu/MessageActionListItem.js.map +1 -1
  87. package/lib/module/contexts/channelContext/ChannelContext.js.map +1 -1
  88. package/lib/module/contexts/messagesContext/MessagesContext.js.map +1 -1
  89. package/lib/module/contexts/themeContext/utils/theme.js +7 -1
  90. package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
  91. package/lib/module/i18n/en.json +2 -0
  92. package/lib/module/i18n/es.json +2 -0
  93. package/lib/module/i18n/fr.json +2 -0
  94. package/lib/module/i18n/he.json +2 -0
  95. package/lib/module/i18n/hi.json +2 -0
  96. package/lib/module/i18n/it.json +2 -0
  97. package/lib/module/i18n/ja.json +2 -0
  98. package/lib/module/i18n/ko.json +2 -0
  99. package/lib/module/i18n/nl.json +2 -0
  100. package/lib/module/i18n/pt-br.json +2 -0
  101. package/lib/module/i18n/ru.json +2 -0
  102. package/lib/module/i18n/tr.json +2 -0
  103. package/lib/module/icons/UnreadIndicator.js +30 -0
  104. package/lib/module/icons/UnreadIndicator.js.map +1 -0
  105. package/lib/module/icons/index.js +11 -0
  106. package/lib/module/icons/index.js.map +1 -1
  107. package/lib/module/store/SqliteClient.js +1 -1
  108. package/lib/module/store/schema.js +1 -0
  109. package/lib/module/store/schema.js.map +1 -1
  110. package/lib/module/types/types.js.map +1 -1
  111. package/lib/module/utils/utils.js +35 -1
  112. package/lib/module/utils/utils.js.map +1 -1
  113. package/lib/module/version.json +1 -1
  114. package/lib/typescript/components/Channel/Channel.d.ts +15 -3
  115. package/lib/typescript/components/Channel/Channel.d.ts.map +1 -1
  116. package/lib/typescript/components/Channel/hooks/useChannelDataState.d.ts +1 -0
  117. package/lib/typescript/components/Channel/hooks/useChannelDataState.d.ts.map +1 -1
  118. package/lib/typescript/components/Channel/hooks/useCreateChannelContext.d.ts +1 -1
  119. package/lib/typescript/components/Channel/hooks/useCreateChannelContext.d.ts.map +1 -1
  120. package/lib/typescript/components/Channel/hooks/useCreateMessagesContext.d.ts +4 -2
  121. package/lib/typescript/components/Channel/hooks/useCreateMessagesContext.d.ts.map +1 -1
  122. package/lib/typescript/components/Channel/hooks/useMessageListPagination.d.ts +4 -1
  123. package/lib/typescript/components/Channel/hooks/useMessageListPagination.d.ts.map +1 -1
  124. package/lib/typescript/components/Channel/hooks/useTargetedMessage.d.ts +2 -1
  125. package/lib/typescript/components/Channel/hooks/useTargetedMessage.d.ts.map +1 -1
  126. package/lib/typescript/components/Chat/hooks/handleEventToSyncDB.d.ts.map +1 -1
  127. package/lib/typescript/components/Message/Message.d.ts +2 -1
  128. package/lib/typescript/components/Message/Message.d.ts.map +1 -1
  129. package/lib/typescript/components/Message/hooks/useMessageActionHandlers.d.ts +2 -1
  130. package/lib/typescript/components/Message/hooks/useMessageActionHandlers.d.ts.map +1 -1
  131. package/lib/typescript/components/Message/hooks/useMessageActions.d.ts +3 -2
  132. package/lib/typescript/components/Message/hooks/useMessageActions.d.ts.map +1 -1
  133. package/lib/typescript/components/Message/hooks/useMessageData.d.ts +1 -1
  134. package/lib/typescript/components/Message/utils/messageActions.d.ts +2 -1
  135. package/lib/typescript/components/Message/utils/messageActions.d.ts.map +1 -1
  136. package/lib/typescript/components/MessageList/InlineUnreadIndicator.d.ts.map +1 -1
  137. package/lib/typescript/components/MessageList/MessageList.d.ts +1 -1
  138. package/lib/typescript/components/MessageList/MessageList.d.ts.map +1 -1
  139. package/lib/typescript/components/MessageList/UnreadMessagesNotification.d.ts +13 -0
  140. package/lib/typescript/components/MessageList/UnreadMessagesNotification.d.ts.map +1 -0
  141. package/lib/typescript/components/MessageMenu/MessageActionListItem.d.ts +2 -2
  142. package/lib/typescript/components/MessageMenu/MessageActionListItem.d.ts.map +1 -1
  143. package/lib/typescript/contexts/channelContext/ChannelContext.d.ts +25 -8
  144. package/lib/typescript/contexts/channelContext/ChannelContext.d.ts.map +1 -1
  145. package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts +5 -0
  146. package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts.map +1 -1
  147. package/lib/typescript/contexts/themeContext/utils/theme.d.ts +6 -0
  148. package/lib/typescript/contexts/themeContext/utils/theme.d.ts.map +1 -1
  149. package/lib/typescript/i18n/en.json +2 -0
  150. package/lib/typescript/i18n/es.json +2 -0
  151. package/lib/typescript/i18n/fr.json +2 -0
  152. package/lib/typescript/i18n/he.json +2 -0
  153. package/lib/typescript/i18n/hi.json +2 -0
  154. package/lib/typescript/i18n/it.json +2 -0
  155. package/lib/typescript/i18n/ja.json +2 -0
  156. package/lib/typescript/i18n/ko.json +2 -0
  157. package/lib/typescript/i18n/nl.json +2 -0
  158. package/lib/typescript/i18n/pt-br.json +2 -0
  159. package/lib/typescript/i18n/ru.json +2 -0
  160. package/lib/typescript/i18n/tr.json +2 -0
  161. package/lib/typescript/icons/UnreadIndicator.d.ts +8 -0
  162. package/lib/typescript/icons/UnreadIndicator.d.ts.map +1 -0
  163. package/lib/typescript/icons/index.d.ts +1 -0
  164. package/lib/typescript/icons/index.d.ts.map +1 -1
  165. package/lib/typescript/store/mappers/mapStorableToChannel.d.ts +1 -1
  166. package/lib/typescript/store/schema.d.ts +1 -0
  167. package/lib/typescript/store/schema.d.ts.map +1 -1
  168. package/lib/typescript/types/types.d.ts +2 -1
  169. package/lib/typescript/types/types.d.ts.map +1 -1
  170. package/lib/typescript/utils/i18n/Streami18n.d.ts +2 -0
  171. package/lib/typescript/utils/i18n/Streami18n.d.ts.map +1 -1
  172. package/lib/typescript/utils/utils.d.ts +21 -1
  173. package/lib/typescript/utils/utils.d.ts.map +1 -1
  174. package/package.json +1 -1
  175. package/src/components/Channel/Channel.tsx +101 -24
  176. package/src/components/Channel/__tests__/Channel.test.js +109 -58
  177. package/src/components/Channel/__tests__/ownCapabilities.test.js +26 -0
  178. package/src/components/Channel/__tests__/useMessageListPagination.test.js +234 -37
  179. package/src/components/Channel/hooks/useChannelDataState.ts +8 -0
  180. package/src/components/Channel/hooks/useCreateChannelContext.ts +11 -0
  181. package/src/components/Channel/hooks/useCreateMessagesContext.ts +4 -0
  182. package/src/components/Channel/hooks/useMessageListPagination.tsx +134 -64
  183. package/src/components/Channel/hooks/useTargetedMessage.ts +9 -2
  184. package/src/components/Chat/hooks/handleEventToSyncDB.ts +23 -1
  185. package/src/components/Message/Message.tsx +8 -0
  186. package/src/components/Message/hooks/useMessageActionHandlers.ts +54 -40
  187. package/src/components/Message/hooks/useMessageActions.tsx +31 -14
  188. package/src/components/Message/utils/messageActions.ts +6 -0
  189. package/src/components/MessageList/InlineUnreadIndicator.tsx +17 -26
  190. package/src/components/MessageList/MessageList.tsx +197 -231
  191. package/src/components/MessageList/UnreadMessagesNotification.tsx +107 -0
  192. package/src/components/MessageList/__tests__/MessageList.test.js +213 -0
  193. package/src/components/MessageMenu/MessageActionListItem.tsx +2 -1
  194. package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +669 -679
  195. package/src/contexts/channelContext/ChannelContext.tsx +35 -9
  196. package/src/contexts/messagesContext/MessagesContext.tsx +7 -2
  197. package/src/contexts/themeContext/utils/theme.ts +12 -0
  198. package/src/i18n/en.json +2 -0
  199. package/src/i18n/es.json +2 -0
  200. package/src/i18n/fr.json +2 -0
  201. package/src/i18n/he.json +2 -0
  202. package/src/i18n/hi.json +2 -0
  203. package/src/i18n/it.json +2 -0
  204. package/src/i18n/ja.json +2 -0
  205. package/src/i18n/ko.json +2 -0
  206. package/src/i18n/nl.json +2 -0
  207. package/src/i18n/pt-br.json +2 -0
  208. package/src/i18n/ru.json +2 -0
  209. package/src/i18n/tr.json +2 -0
  210. package/src/icons/UnreadIndicator.tsx +18 -0
  211. package/src/icons/index.ts +1 -0
  212. package/src/store/SqliteClient.ts +1 -1
  213. package/src/store/schema.ts +2 -0
  214. package/src/types/types.ts +5 -2
  215. package/src/utils/utils.ts +61 -1
  216. package/src/version.json +1 -1
@@ -2,16 +2,21 @@ import { useEffect, useRef, useState } from 'react';
2
2
 
3
3
  export const useTargetedMessage = (messageId?: string) => {
4
4
  const clearTargetedMessageCall = useRef<ReturnType<typeof setTimeout>>();
5
- const [targetedMessage, setTargetedMessage] = useState(messageId);
5
+ const [targetedMessage, setTargetedMessage] = useState<string | undefined>(messageId);
6
+ const [highlightedMessageId, setHighlightedMessageId] = useState<string | undefined>();
6
7
  const prevTargetedMessageRef = useRef<string>();
7
8
 
8
9
  useEffect(() => {
9
10
  prevTargetedMessageRef.current = targetedMessage;
11
+ if (targetedMessage) {
12
+ setHighlightedMessageId(targetedMessage);
13
+ }
10
14
  }, [targetedMessage]);
11
15
 
12
16
  useEffect(() => {
13
17
  clearTargetedMessageCall.current = setTimeout(() => {
14
18
  setTargetedMessage(undefined);
19
+ setHighlightedMessageId(undefined);
15
20
  }, 3000);
16
21
 
17
22
  return () => {
@@ -19,17 +24,19 @@ export const useTargetedMessage = (messageId?: string) => {
19
24
  };
20
25
  }, []);
21
26
 
22
- const setTargetedMessageTimeoutRef = useRef((messageId: string) => {
27
+ const setTargetedMessageTimeoutRef = useRef((messageId: string | undefined) => {
23
28
  clearTargetedMessageCall.current && clearTimeout(clearTargetedMessageCall.current);
24
29
 
25
30
  clearTargetedMessageCall.current = setTimeout(() => {
26
31
  setTargetedMessage(undefined);
32
+ setHighlightedMessageId(undefined);
27
33
  }, 3000);
28
34
 
29
35
  setTargetedMessage(messageId);
30
36
  });
31
37
 
32
38
  return {
39
+ highlightedMessageId,
33
40
  prevTargetedMessage: prevTargetedMessageRef.current,
34
41
  setTargetedMessage: setTargetedMessageTimeoutRef.current,
35
42
  targetedMessage,
@@ -77,7 +77,7 @@ export const handleEventToSyncDB = async <
77
77
  return createQueries(flush);
78
78
  };
79
79
 
80
- if (type === 'message.read') {
80
+ if (type === 'message.read' || type === 'notification.mark_read') {
81
81
  const cid = event.cid;
82
82
  const user = event.user;
83
83
  if (user?.id && cid) {
@@ -88,6 +88,7 @@ export const handleEventToSyncDB = async <
88
88
  reads: [
89
89
  {
90
90
  last_read: event.received_at as string,
91
+ last_read_message_id: event.last_read_message_id,
91
92
  unread_messages: 0,
92
93
  user,
93
94
  },
@@ -97,6 +98,27 @@ export const handleEventToSyncDB = async <
97
98
  }
98
99
  }
99
100
 
101
+ if (type === 'notification.mark_unread') {
102
+ const cid = event.cid;
103
+ const user = event.user;
104
+ if (user?.id && cid) {
105
+ return await queriesWithChannelGuard((flushOverride) =>
106
+ upsertReads({
107
+ cid,
108
+ flush: flushOverride,
109
+ reads: [
110
+ {
111
+ last_read: event.received_at as string,
112
+ last_read_message_id: event.last_read_message_id,
113
+ unread_messages: event.unread_messages,
114
+ user,
115
+ },
116
+ ],
117
+ }),
118
+ );
119
+ }
120
+ }
121
+
100
122
  if (type === 'message.new') {
101
123
  const message = event.message;
102
124
 
@@ -110,6 +110,7 @@ export type MessageActionHandlers<
110
110
  deleteMessage: () => void;
111
111
  editMessage: () => void;
112
112
  flagMessage: () => void;
113
+ markUnread: () => Promise<void>;
113
114
  pinMessage: () => Promise<void>;
114
115
  quotedReply: () => void;
115
116
  resendMessage: () => Promise<void>;
@@ -145,6 +146,7 @@ export type MessagePropsWithContext<
145
146
  | 'handleDelete'
146
147
  | 'handleEdit'
147
148
  | 'handleFlag'
149
+ | 'handleMarkUnread'
148
150
  | 'handleMute'
149
151
  | 'handlePinMessage'
150
152
  | 'handleQuotedReply'
@@ -223,6 +225,7 @@ const MessageWithContext = <
223
225
  handleDelete,
224
226
  handleEdit,
225
227
  handleFlag,
228
+ handleMarkUnread,
226
229
  handleMute,
227
230
  handlePinMessage,
228
231
  handleQuotedReply,
@@ -472,6 +475,7 @@ const MessageWithContext = <
472
475
  handleDeleteMessage,
473
476
  handleEditMessage,
474
477
  handleFlagMessage,
478
+ handleMarkUnreadMessage,
475
479
  handleQuotedReplyMessage,
476
480
  handleResendMessage,
477
481
  handleToggleBanUser,
@@ -499,6 +503,7 @@ const MessageWithContext = <
499
503
  editMessage,
500
504
  flagMessage,
501
505
  handleReaction,
506
+ markUnread,
502
507
  muteUser,
503
508
  pinMessage,
504
509
  quotedReply,
@@ -517,6 +522,7 @@ const MessageWithContext = <
517
522
  handleDelete,
518
523
  handleEdit,
519
524
  handleFlag,
525
+ handleMarkUnread,
520
526
  handleMute,
521
527
  handlePinMessage,
522
528
  handleQuotedReply,
@@ -552,6 +558,7 @@ const MessageWithContext = <
552
558
  flagMessage,
553
559
  isMyMessage,
554
560
  isThreadMessage,
561
+ markUnread,
555
562
  message,
556
563
  muteUser,
557
564
  ownCapabilities,
@@ -568,6 +575,7 @@ const MessageWithContext = <
568
575
  deleteMessage: handleDeleteMessage,
569
576
  editMessage: handleEditMessage,
570
577
  flagMessage: handleFlagMessage,
578
+ markUnread: handleMarkUnreadMessage,
571
579
  pinMessage: handleTogglePinMessage,
572
580
  quotedReply: handleQuotedReplyMessage,
573
581
  resendMessage: handleResendMessage,
@@ -48,27 +48,27 @@ export const useMessageActionHandlers = <
48
48
  );
49
49
 
50
50
  const handleCopyMessage = () => {
51
- setClipboardString(message.text || '');
51
+ if (!message.text) return;
52
+ setClipboardString(message.text);
52
53
  };
53
54
 
54
55
  const handleDeleteMessage = () => {
55
- if (message.id) {
56
- Alert.alert(
57
- t('Delete Message'),
58
- t('Are you sure you want to permanently delete this message?'),
59
- [
60
- { style: 'cancel', text: t('Cancel') },
61
- {
62
- onPress: async () => {
63
- await deleteMessage(message as MessageResponse<StreamChatGenerics>);
64
- },
65
- style: 'destructive',
66
- text: t('Delete'),
56
+ if (!message.id) return;
57
+ Alert.alert(
58
+ t('Delete Message'),
59
+ t('Are you sure you want to permanently delete this message?'),
60
+ [
61
+ { style: 'cancel', text: t('Cancel') },
62
+ {
63
+ onPress: async () => {
64
+ await deleteMessage(message as MessageResponse<StreamChatGenerics>);
67
65
  },
68
- ],
69
- { cancelable: false },
70
- );
71
- }
66
+ style: 'destructive',
67
+ text: t('Delete'),
68
+ },
69
+ ],
70
+ { cancelable: false },
71
+ );
72
72
  };
73
73
 
74
74
  const handleToggleMuteUser = async () => {
@@ -110,31 +110,44 @@ export const useMessageActionHandlers = <
110
110
  };
111
111
 
112
112
  const handleFlagMessage = () => {
113
+ if (!message.id) return;
114
+ Alert.alert(
115
+ t('Flag Message'),
116
+ t('Do you want to send a copy of this message to a moderator for further investigation?'),
117
+ [
118
+ { style: 'cancel', text: t('Cancel') },
119
+ {
120
+ onPress: async () => {
121
+ try {
122
+ await client.flagMessage(message.id);
123
+ Alert.alert(t('Message flagged'), t('The message has been reported to a moderator.'));
124
+ } catch (error) {
125
+ console.log('Error flagging message:', error);
126
+ Alert.alert(
127
+ t('Cannot Flag Message'),
128
+ t(
129
+ 'Flag action failed either due to a network issue or the message is already flagged',
130
+ ),
131
+ );
132
+ }
133
+ },
134
+ text: t('Flag'),
135
+ },
136
+ ],
137
+ { cancelable: false },
138
+ );
139
+ };
140
+
141
+ const handleMarkUnreadMessage = async () => {
142
+ if (!message.id) return;
113
143
  try {
114
- if (message.id) {
115
- Alert.alert(
116
- t('Flag Message'),
117
- t('Do you want to send a copy of this message to a moderator for further investigation?'),
118
- [
119
- { style: 'cancel', text: t('Cancel') },
120
- {
121
- onPress: async () => {
122
- await client.flagMessage(message.id);
123
- Alert.alert(
124
- t('Message flagged'),
125
- t('The message has been reported to a moderator.'),
126
- );
127
- },
128
- text: t('Flag'),
129
- },
130
- ],
131
- { cancelable: false },
132
- );
133
- }
134
- } catch (_) {
144
+ await channel.markUnread({ message_id: message.id });
145
+ } catch (error) {
146
+ console.log('Error marking message as unread:', error);
135
147
  Alert.alert(
136
- t('Cannot Flag Message'),
137
- t('Flag action failed either due to a network issue or the message is already flagged'),
148
+ t(
149
+ 'Error marking message unread. Cannot mark unread messages older than the newest 100 channel messages.',
150
+ ),
138
151
  );
139
152
  }
140
153
  };
@@ -173,6 +186,7 @@ export const useMessageActionHandlers = <
173
186
  handleDeleteMessage,
174
187
  handleEditMessage,
175
188
  handleFlagMessage,
189
+ handleMarkUnreadMessage,
176
190
  handleQuotedReplyMessage,
177
191
  handleResendMessage,
178
192
  handleToggleBanUser,
@@ -20,6 +20,7 @@ import {
20
20
  Resend,
21
21
  ThreadReply,
22
22
  Unpin,
23
+ UnreadIndicator,
23
24
  UserDelete,
24
25
  } from '../../../icons';
25
26
  import type { DefaultStreamChatGenerics } from '../../../types/types';
@@ -41,6 +42,7 @@ export type MessageActionsHookProps<
41
42
  | 'handleEdit'
42
43
  | 'handleFlag'
43
44
  | 'handleQuotedReply'
45
+ | 'handleMarkUnread'
44
46
  | 'handleMute'
45
47
  | 'handlePinMessage'
46
48
  | 'handleRetry'
@@ -77,6 +79,7 @@ export const useMessageActions = <
77
79
  handleDelete,
78
80
  handleEdit,
79
81
  handleFlag,
82
+ handleMarkUnread,
80
83
  handleMute,
81
84
  handlePinMessage,
82
85
  handleQuotedReply,
@@ -104,6 +107,7 @@ export const useMessageActions = <
104
107
  handleDeleteMessage,
105
108
  handleEditMessage,
106
109
  handleFlagMessage,
110
+ handleMarkUnreadMessage,
107
111
  handleQuotedReplyMessage,
108
112
  handleResendMessage,
109
113
  handleToggleBanUser,
@@ -195,6 +199,32 @@ export const useMessageActions = <
195
199
  title: t('Edit Message'),
196
200
  };
197
201
 
202
+ const flagMessage: MessageActionType = {
203
+ action: () => {
204
+ dismissOverlay();
205
+ if (handleFlag) {
206
+ handleFlag(message);
207
+ }
208
+ handleFlagMessage();
209
+ },
210
+ actionType: 'flagMessage',
211
+ icon: <MessageFlag pathFill={grey} />,
212
+ title: t('Flag Message'),
213
+ };
214
+
215
+ const markUnread: MessageActionType = {
216
+ action: () => {
217
+ dismissOverlay();
218
+ if (handleMarkUnread) {
219
+ handleMarkUnread(message);
220
+ }
221
+ handleMarkUnreadMessage();
222
+ },
223
+ actionType: 'markUnread',
224
+ icon: <UnreadIndicator fill={grey} size={24} />,
225
+ title: t('Mark as Unread'),
226
+ };
227
+
198
228
  const pinMessage: MessageActionType = {
199
229
  action: () => {
200
230
  dismissOverlay();
@@ -221,20 +251,6 @@ export const useMessageActions = <
221
251
  title: t('Unpin from Conversation'),
222
252
  };
223
253
 
224
- const flagMessage: MessageActionType = {
225
- action: () => {
226
- dismissOverlay();
227
- if (handleFlag) {
228
- handleFlag(message);
229
- }
230
-
231
- handleFlagMessage();
232
- },
233
- actionType: 'flagMessage',
234
- icon: <MessageFlag pathFill={grey} />,
235
- title: t('Flag Message'),
236
- };
237
-
238
254
  const handleReaction = !error
239
255
  ? selectReaction
240
256
  ? selectReaction(message)
@@ -311,6 +327,7 @@ export const useMessageActions = <
311
327
  editMessage,
312
328
  flagMessage,
313
329
  handleReaction,
330
+ markUnread,
314
331
  muteUser,
315
332
  pinMessage,
316
333
  quotedReply,
@@ -15,6 +15,7 @@ export type MessageActionsParams<
15
15
  error: boolean | Error;
16
16
  flagMessage: MessageActionType;
17
17
  isThreadMessage: boolean;
18
+ markUnread: MessageActionType;
18
19
  muteUser: MessageActionType;
19
20
  ownCapabilities: OwnCapabilitiesContextValue;
20
21
  pinMessage: MessageActionType;
@@ -43,6 +44,7 @@ export const messageActions = <
43
44
  flagMessage,
44
45
  isMyMessage,
45
46
  isThreadMessage,
47
+ markUnread,
46
48
  message,
47
49
  ownCapabilities,
48
50
  pinMessage,
@@ -77,6 +79,10 @@ export const messageActions = <
77
79
  actions.push(editMessage);
78
80
  }
79
81
 
82
+ if (ownCapabilities.readEvents && !error && !isThreadMessage) {
83
+ actions.push(markUnread);
84
+ }
85
+
80
86
  if (isClipboardAvailable() && message.text && !error) {
81
87
  actions.push(copyMessage);
82
88
  }
@@ -1,47 +1,38 @@
1
1
  import React from 'react';
2
2
  import { StyleSheet, Text, View } from 'react-native';
3
- import Svg, { Defs, LinearGradient, Rect, Stop } from 'react-native-svg';
4
3
 
5
4
  import { useTheme } from '../../contexts/themeContext/ThemeContext';
6
5
  import { useTranslationContext } from '../../contexts/translationContext/TranslationContext';
7
- import { useViewport } from '../../hooks/useViewport';
8
-
9
- const styles = StyleSheet.create({
10
- container: {
11
- alignItems: 'center',
12
- justifyContent: 'center',
13
- padding: 10,
14
- width: '100%',
15
- },
16
- text: {
17
- fontSize: 12,
18
- },
19
- });
20
6
 
21
7
  export const InlineUnreadIndicator = () => {
22
8
  const {
23
9
  theme: {
24
- colors: { bg_gradient_end, bg_gradient_start, grey },
10
+ colors: { grey, light_gray },
25
11
  messageList: {
26
12
  inlineUnreadIndicator: { container, text },
27
13
  },
28
14
  },
29
15
  } = useTheme();
30
16
  const { t } = useTranslationContext();
31
- const { vw } = useViewport();
32
17
 
33
18
  return (
34
- <View style={[styles.container, container]}>
35
- <Svg height={24} style={{ position: 'absolute' }} width={vw(100)}>
36
- <Rect fill='url(#gradient)' height={24} width={vw(100)} x={0} y={0} />
37
- <Defs>
38
- <LinearGradient gradientUnits='userSpaceOnUse' id='gradient' x1={0} x2={0} y1={24} y2={0}>
39
- <Stop offset={1} stopColor={bg_gradient_end} stopOpacity={1} />
40
- <Stop offset={0} stopColor={bg_gradient_start} stopOpacity={1} />
41
- </LinearGradient>
42
- </Defs>
43
- </Svg>
19
+ <View
20
+ accessibilityLabel='Inline unread indicator'
21
+ style={[styles.container, { backgroundColor: light_gray }, container]}
22
+ >
44
23
  <Text style={[styles.text, { color: grey }, text]}>{t<string>('Unread Messages')}</Text>
45
24
  </View>
46
25
  );
47
26
  };
27
+
28
+ const styles = StyleSheet.create({
29
+ container: {
30
+ alignItems: 'center',
31
+ justifyContent: 'center',
32
+ marginTop: 2,
33
+ padding: 10,
34
+ },
35
+ text: {
36
+ fontSize: 12,
37
+ },
38
+ });