stream-chat-react-native-core 5.31.2-beta.3 → 5.32.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.
- package/lib/commonjs/components/Channel/Channel.js +21 -20
- package/lib/commonjs/components/Channel/Channel.js.map +1 -1
- package/lib/commonjs/components/Chat/hooks/handleEventToSyncDB.js.map +1 -1
- package/lib/commonjs/components/Message/Message.js +9 -19
- package/lib/commonjs/components/Message/Message.js.map +1 -1
- package/lib/commonjs/components/Message/MessageSimple/MessageFooter.js +1 -2
- package/lib/commonjs/components/Message/MessageSimple/MessageFooter.js.map +1 -1
- package/lib/commonjs/components/Message/MessageSimple/ReactionList.js +54 -37
- package/lib/commonjs/components/Message/MessageSimple/ReactionList.js.map +1 -1
- package/lib/commonjs/components/Message/hooks/useCreateMessageContext.js +6 -11
- package/lib/commonjs/components/Message/hooks/useCreateMessageContext.js.map +1 -1
- package/lib/commonjs/components/Message/hooks/useProcessReactions.js +90 -0
- package/lib/commonjs/components/Message/hooks/useProcessReactions.js.map +1 -0
- package/lib/commonjs/components/MessageOverlay/MessageOverlay.js +3 -12
- package/lib/commonjs/components/MessageOverlay/MessageOverlay.js.map +1 -1
- package/lib/commonjs/components/MessageOverlay/OverlayReactions.js +47 -143
- package/lib/commonjs/components/MessageOverlay/OverlayReactions.js.map +1 -1
- package/lib/commonjs/components/MessageOverlay/OverlayReactionsItem.js +166 -0
- package/lib/commonjs/components/MessageOverlay/OverlayReactionsItem.js.map +1 -0
- package/lib/commonjs/components/MessageOverlay/hooks/useFetchReactions.js +144 -0
- package/lib/commonjs/components/MessageOverlay/hooks/useFetchReactions.js.map +1 -0
- package/lib/commonjs/contexts/messageContext/MessageContext.js.map +1 -1
- package/lib/commonjs/contexts/themeContext/utils/theme.js +0 -1
- package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
- package/lib/commonjs/i18n/es.json +13 -13
- package/lib/commonjs/i18n/fr.json +13 -13
- package/lib/commonjs/i18n/he.json +13 -13
- package/lib/commonjs/i18n/hi.json +13 -13
- package/lib/commonjs/i18n/it.json +13 -13
- package/lib/commonjs/i18n/ja.json +13 -13
- package/lib/commonjs/i18n/ko.json +13 -13
- package/lib/commonjs/i18n/nl.json +13 -13
- package/lib/commonjs/i18n/pt-BR.json +13 -13
- package/lib/commonjs/i18n/ru.json +13 -13
- package/lib/commonjs/i18n/tr.json +13 -13
- package/lib/commonjs/mock-builders/generator/message.js +2 -0
- package/lib/commonjs/mock-builders/generator/message.js.map +1 -1
- package/lib/commonjs/store/QuickSqliteClient.js +1 -1
- package/lib/commonjs/store/apis/getReactions.js +17 -0
- package/lib/commonjs/store/apis/getReactions.js.map +1 -0
- package/lib/commonjs/store/apis/getReactionsforFilterSort.js +30 -0
- package/lib/commonjs/store/apis/getReactionsforFilterSort.js.map +1 -0
- package/lib/commonjs/store/apis/insertReaction.js +8 -1
- package/lib/commonjs/store/apis/insertReaction.js.map +1 -1
- package/lib/commonjs/store/apis/queries/selectReactionsForMessages.js +1 -1
- package/lib/commonjs/store/apis/queries/selectReactionsForMessages.js.map +1 -1
- package/lib/commonjs/store/apis/updateReaction.js +6 -6
- package/lib/commonjs/store/apis/updateReaction.js.map +1 -1
- package/lib/commonjs/store/mappers/mapMessageToStorable.js +5 -3
- package/lib/commonjs/store/mappers/mapMessageToStorable.js.map +1 -1
- package/lib/commonjs/store/mappers/mapStorableToMessage.js +5 -3
- package/lib/commonjs/store/mappers/mapStorableToMessage.js.map +1 -1
- package/lib/commonjs/store/schema.js +2 -1
- package/lib/commonjs/store/schema.js.map +1 -1
- package/lib/commonjs/utils/addReactionToLocalState.js +25 -13
- package/lib/commonjs/utils/addReactionToLocalState.js.map +1 -1
- package/lib/commonjs/utils/removeReactionFromLocalState.js +11 -3
- package/lib/commonjs/utils/removeReactionFromLocalState.js.map +1 -1
- package/lib/commonjs/utils/removeReservedFields.js +1 -1
- package/lib/commonjs/utils/removeReservedFields.js.map +1 -1
- package/lib/commonjs/utils/utils.js +19 -5
- package/lib/commonjs/utils/utils.js.map +1 -1
- package/lib/commonjs/version.json +1 -1
- package/lib/module/components/Channel/Channel.js +21 -20
- package/lib/module/components/Channel/Channel.js.map +1 -1
- package/lib/module/components/Chat/hooks/handleEventToSyncDB.js.map +1 -1
- package/lib/module/components/Message/Message.js +9 -19
- package/lib/module/components/Message/Message.js.map +1 -1
- package/lib/module/components/Message/MessageSimple/MessageFooter.js +1 -2
- package/lib/module/components/Message/MessageSimple/MessageFooter.js.map +1 -1
- package/lib/module/components/Message/MessageSimple/ReactionList.js +54 -37
- package/lib/module/components/Message/MessageSimple/ReactionList.js.map +1 -1
- package/lib/module/components/Message/hooks/useCreateMessageContext.js +6 -11
- package/lib/module/components/Message/hooks/useCreateMessageContext.js.map +1 -1
- package/lib/module/components/Message/hooks/useProcessReactions.js +90 -0
- package/lib/module/components/Message/hooks/useProcessReactions.js.map +1 -0
- package/lib/module/components/MessageOverlay/MessageOverlay.js +3 -12
- package/lib/module/components/MessageOverlay/MessageOverlay.js.map +1 -1
- package/lib/module/components/MessageOverlay/OverlayReactions.js +47 -143
- package/lib/module/components/MessageOverlay/OverlayReactions.js.map +1 -1
- package/lib/module/components/MessageOverlay/OverlayReactionsItem.js +166 -0
- package/lib/module/components/MessageOverlay/OverlayReactionsItem.js.map +1 -0
- package/lib/module/components/MessageOverlay/hooks/useFetchReactions.js +144 -0
- package/lib/module/components/MessageOverlay/hooks/useFetchReactions.js.map +1 -0
- package/lib/module/contexts/messageContext/MessageContext.js.map +1 -1
- package/lib/module/contexts/themeContext/utils/theme.js +0 -1
- package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
- package/lib/module/i18n/es.json +13 -13
- package/lib/module/i18n/fr.json +13 -13
- package/lib/module/i18n/he.json +13 -13
- package/lib/module/i18n/hi.json +13 -13
- package/lib/module/i18n/it.json +13 -13
- package/lib/module/i18n/ja.json +13 -13
- package/lib/module/i18n/ko.json +13 -13
- package/lib/module/i18n/nl.json +13 -13
- package/lib/module/i18n/pt-BR.json +13 -13
- package/lib/module/i18n/ru.json +13 -13
- package/lib/module/i18n/tr.json +13 -13
- package/lib/module/mock-builders/generator/message.js +2 -0
- package/lib/module/mock-builders/generator/message.js.map +1 -1
- package/lib/module/store/QuickSqliteClient.js +1 -1
- package/lib/module/store/apis/getReactions.js +17 -0
- package/lib/module/store/apis/getReactions.js.map +1 -0
- package/lib/module/store/apis/getReactionsforFilterSort.js +30 -0
- package/lib/module/store/apis/getReactionsforFilterSort.js.map +1 -0
- package/lib/module/store/apis/insertReaction.js +8 -1
- package/lib/module/store/apis/insertReaction.js.map +1 -1
- package/lib/module/store/apis/queries/selectReactionsForMessages.js +1 -1
- package/lib/module/store/apis/queries/selectReactionsForMessages.js.map +1 -1
- package/lib/module/store/apis/updateReaction.js +6 -6
- package/lib/module/store/apis/updateReaction.js.map +1 -1
- package/lib/module/store/mappers/mapMessageToStorable.js +5 -3
- package/lib/module/store/mappers/mapMessageToStorable.js.map +1 -1
- package/lib/module/store/mappers/mapStorableToMessage.js +5 -3
- package/lib/module/store/mappers/mapStorableToMessage.js.map +1 -1
- package/lib/module/store/schema.js +2 -1
- package/lib/module/store/schema.js.map +1 -1
- package/lib/module/utils/addReactionToLocalState.js +25 -13
- package/lib/module/utils/addReactionToLocalState.js.map +1 -1
- package/lib/module/utils/removeReactionFromLocalState.js +11 -3
- package/lib/module/utils/removeReactionFromLocalState.js.map +1 -1
- package/lib/module/utils/removeReservedFields.js +1 -1
- package/lib/module/utils/removeReservedFields.js.map +1 -1
- package/lib/module/utils/utils.js +19 -5
- package/lib/module/utils/utils.js.map +1 -1
- package/lib/module/version.json +1 -1
- package/lib/typescript/components/Channel/Channel.d.ts.map +1 -1
- package/lib/typescript/components/Channel/hooks/useCreateInputMessageInputContext.d.ts +2 -2
- package/lib/typescript/components/Chat/hooks/handleEventToSyncDB.d.ts.map +1 -1
- package/lib/typescript/components/Message/Message.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageSimple/ReactionList.d.ts +11 -3
- package/lib/typescript/components/Message/MessageSimple/ReactionList.d.ts.map +1 -1
- package/lib/typescript/components/Message/hooks/useCreateMessageContext.d.ts.map +1 -1
- package/lib/typescript/components/Message/hooks/useMessageActionHandlers.d.ts +1 -1
- package/lib/typescript/components/Message/hooks/useMessageActions.d.ts +1 -1
- package/lib/typescript/components/Message/hooks/useProcessReactions.d.ts +38 -0
- package/lib/typescript/components/Message/hooks/useProcessReactions.d.ts.map +1 -0
- package/lib/typescript/components/MessageOverlay/MessageOverlay.d.ts.map +1 -1
- package/lib/typescript/components/MessageOverlay/OverlayReactions.d.ts +2 -1
- package/lib/typescript/components/MessageOverlay/OverlayReactions.d.ts.map +1 -1
- package/lib/typescript/components/MessageOverlay/OverlayReactionsItem.d.ts +11 -0
- package/lib/typescript/components/MessageOverlay/OverlayReactionsItem.d.ts.map +1 -0
- package/lib/typescript/components/MessageOverlay/hooks/useFetchReactions.d.ts +14 -0
- package/lib/typescript/components/MessageOverlay/hooks/useFetchReactions.d.ts.map +1 -0
- package/lib/typescript/contexts/messageContext/MessageContext.d.ts +3 -6
- package/lib/typescript/contexts/messageContext/MessageContext.d.ts.map +1 -1
- package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts +1 -1
- package/lib/typescript/contexts/themeContext/utils/theme.d.ts +0 -1
- package/lib/typescript/contexts/themeContext/utils/theme.d.ts.map +1 -1
- package/lib/typescript/i18n/es.json +13 -13
- package/lib/typescript/i18n/fr.json +13 -13
- package/lib/typescript/i18n/he.json +13 -13
- package/lib/typescript/i18n/hi.json +13 -13
- package/lib/typescript/i18n/it.json +13 -13
- package/lib/typescript/i18n/ja.json +13 -13
- package/lib/typescript/i18n/ko.json +13 -13
- package/lib/typescript/i18n/nl.json +13 -13
- package/lib/typescript/i18n/pt-BR.json +13 -13
- package/lib/typescript/i18n/ru.json +13 -13
- package/lib/typescript/i18n/tr.json +13 -13
- package/lib/typescript/store/apis/getReactions.d.ts +7 -0
- package/lib/typescript/store/apis/getReactions.d.ts.map +1 -0
- package/lib/typescript/store/apis/getReactionsforFilterSort.d.ts +14 -0
- package/lib/typescript/store/apis/getReactionsforFilterSort.d.ts.map +1 -0
- package/lib/typescript/store/apis/insertReaction.d.ts +3 -2
- package/lib/typescript/store/apis/insertReaction.d.ts.map +1 -1
- package/lib/typescript/store/apis/queries/selectReactionsForMessages.d.ts +4 -0
- package/lib/typescript/store/apis/queries/selectReactionsForMessages.d.ts.map +1 -1
- package/lib/typescript/store/apis/updateReaction.d.ts.map +1 -1
- package/lib/typescript/store/mappers/mapMessageToStorable.d.ts.map +1 -1
- package/lib/typescript/store/mappers/mapStorableToMessage.d.ts.map +1 -1
- package/lib/typescript/store/schema.d.ts +2 -1
- package/lib/typescript/store/schema.d.ts.map +1 -1
- package/lib/typescript/utils/addReactionToLocalState.d.ts.map +1 -1
- package/lib/typescript/utils/removeReactionFromLocalState.d.ts.map +1 -1
- package/lib/typescript/utils/removeReservedFields.d.ts.map +1 -1
- package/lib/typescript/utils/utils.d.ts +9 -3
- package/lib/typescript/utils/utils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/Channel/Channel.tsx +24 -34
- package/src/components/Chat/hooks/handleEventToSyncDB.ts +1 -2
- package/src/components/Message/Message.tsx +8 -26
- package/src/components/Message/MessageSimple/MessageFooter.tsx +1 -1
- package/src/components/Message/MessageSimple/ReactionList.tsx +72 -47
- package/src/components/Message/MessageSimple/__tests__/MessageContent.test.js +1 -1
- package/src/components/Message/hooks/useCreateMessageContext.ts +5 -10
- package/src/components/Message/hooks/useProcessReactions.ts +116 -0
- package/src/components/MessageOverlay/MessageOverlay.tsx +4 -17
- package/src/components/MessageOverlay/OverlayReactions.tsx +75 -176
- package/src/components/MessageOverlay/OverlayReactionsItem.tsx +188 -0
- package/src/components/MessageOverlay/hooks/useFetchReactions.ts +85 -0
- package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +139 -0
- package/src/contexts/messageContext/MessageContext.tsx +2 -6
- package/src/contexts/themeContext/utils/theme.ts +0 -2
- package/src/i18n/es.json +13 -13
- package/src/i18n/fr.json +13 -13
- package/src/i18n/he.json +13 -13
- package/src/i18n/hi.json +13 -13
- package/src/i18n/it.json +13 -13
- package/src/i18n/ja.json +13 -13
- package/src/i18n/ko.json +13 -13
- package/src/i18n/nl.json +13 -13
- package/src/i18n/pt-BR.json +13 -13
- package/src/i18n/ru.json +13 -13
- package/src/i18n/tr.json +13 -13
- package/src/mock-builders/generator/message.js +2 -0
- package/src/store/QuickSqliteClient.ts +1 -1
- package/src/store/apis/getReactions.ts +21 -0
- package/src/store/apis/getReactionsforFilterSort.ts +43 -0
- package/src/store/apis/insertReaction.ts +15 -5
- package/src/store/apis/queries/selectReactionsForMessages.ts +5 -1
- package/src/store/apis/updateReaction.ts +6 -18
- package/src/store/mappers/mapMessageToStorable.ts +4 -2
- package/src/store/mappers/mapStorableToMessage.ts +12 -2
- package/src/store/schema.ts +4 -2
- package/src/utils/addReactionToLocalState.ts +33 -17
- package/src/utils/removeReactionFromLocalState.ts +22 -2
- package/src/utils/removeReservedFields.ts +2 -0
- package/src/utils/utils.ts +19 -7
- package/src/version.json +1 -1
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { StyleSheet, TouchableOpacity, useWindowDimensions, View } from 'react-native';
|
|
2
|
+
import { StyleSheet, Text, TouchableOpacity, useWindowDimensions, View } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import Svg, { Circle } from 'react-native-svg';
|
|
5
5
|
|
|
6
|
+
import { ReactionGroupResponse, ReactionResponse } from 'stream-chat';
|
|
7
|
+
|
|
6
8
|
import {
|
|
7
9
|
MessageContextValue,
|
|
8
|
-
Reactions,
|
|
9
10
|
useMessageContext,
|
|
10
11
|
} from '../../../contexts/messageContext/MessageContext';
|
|
11
12
|
import {
|
|
@@ -19,26 +20,10 @@ import { Unknown } from '../../../icons/Unknown';
|
|
|
19
20
|
import type { IconProps } from '../../../icons/utils/base';
|
|
20
21
|
import type { DefaultStreamChatGenerics } from '../../../types/types';
|
|
21
22
|
import type { ReactionData } from '../../../utils/utils';
|
|
22
|
-
|
|
23
|
-
const styles = StyleSheet.create({
|
|
24
|
-
container: {
|
|
25
|
-
left: 0,
|
|
26
|
-
position: 'absolute',
|
|
27
|
-
top: 0,
|
|
28
|
-
},
|
|
29
|
-
reactionBubble: {
|
|
30
|
-
alignItems: 'center',
|
|
31
|
-
flexDirection: 'row',
|
|
32
|
-
justifyContent: 'space-evenly',
|
|
33
|
-
position: 'absolute',
|
|
34
|
-
},
|
|
35
|
-
reactionBubbleBackground: {
|
|
36
|
-
position: 'absolute',
|
|
37
|
-
},
|
|
38
|
-
});
|
|
23
|
+
import { ReactionSummary } from '../hooks/useProcessReactions';
|
|
39
24
|
|
|
40
25
|
export type MessageReactions = {
|
|
41
|
-
reactions:
|
|
26
|
+
reactions: ReactionSummary[];
|
|
42
27
|
supportedReactions?: ReactionData[];
|
|
43
28
|
};
|
|
44
29
|
|
|
@@ -76,7 +61,13 @@ export type ReactionListPropsWithContext<
|
|
|
76
61
|
messageContentWidth: number;
|
|
77
62
|
supportedReactions: ReactionData[];
|
|
78
63
|
fill?: string;
|
|
64
|
+
/** An array of the reaction objects to display in the list */
|
|
65
|
+
latest_reactions?: ReactionResponse<StreamChatGenerics>[];
|
|
66
|
+
/** An array of the own reaction objects to distinguish own reactions visually */
|
|
67
|
+
own_reactions?: ReactionResponse<StreamChatGenerics>[] | null;
|
|
79
68
|
radius?: number; // not recommended to change this
|
|
69
|
+
/** An object containing summary for each reaction type on a message */
|
|
70
|
+
reaction_groups?: Record<string, ReactionGroupResponse> | null;
|
|
80
71
|
reactionSize?: number;
|
|
81
72
|
stroke?: string;
|
|
82
73
|
strokeSize?: number; // not recommended to change this
|
|
@@ -110,6 +101,7 @@ const ReactionListWithContext = <
|
|
|
110
101
|
theme: {
|
|
111
102
|
colors: {
|
|
112
103
|
accent_blue,
|
|
104
|
+
black,
|
|
113
105
|
grey,
|
|
114
106
|
grey_gainsboro,
|
|
115
107
|
grey_whisper,
|
|
@@ -125,7 +117,6 @@ const ReactionListWithContext = <
|
|
|
125
117
|
middleIcon,
|
|
126
118
|
radius: themeRadius,
|
|
127
119
|
reactionBubble,
|
|
128
|
-
reactionBubbleBackground,
|
|
129
120
|
reactionSize: themeReactionSize,
|
|
130
121
|
strokeSize: themeStrokeSize,
|
|
131
122
|
},
|
|
@@ -200,21 +191,6 @@ const ReactionListWithContext = <
|
|
|
200
191
|
<Circle cx={x1} cy={y1} fill={alignmentLeft ? fill : white} r={radius} />
|
|
201
192
|
<Circle cx={x2} cy={y2} fill={alignmentLeft ? fill : white} r={radius * 2} />
|
|
202
193
|
</Svg>
|
|
203
|
-
<View
|
|
204
|
-
style={[
|
|
205
|
-
styles.reactionBubbleBackground,
|
|
206
|
-
{
|
|
207
|
-
backgroundColor: alignmentLeft ? fill : white,
|
|
208
|
-
borderColor: fill,
|
|
209
|
-
borderRadius: reactionSize,
|
|
210
|
-
borderWidth: strokeSize,
|
|
211
|
-
height: reactionSize,
|
|
212
|
-
left,
|
|
213
|
-
width: reactionSize * reactions.length,
|
|
214
|
-
},
|
|
215
|
-
reactionBubbleBackground,
|
|
216
|
-
]}
|
|
217
|
-
/>
|
|
218
194
|
<View pointerEvents='none' style={[StyleSheet.absoluteFill]}>
|
|
219
195
|
<Svg>
|
|
220
196
|
<Circle cx={x2} cy={y2} fill={alignmentLeft ? fill : white} r={radius * 2} />
|
|
@@ -252,24 +228,36 @@ const ReactionListWithContext = <
|
|
|
252
228
|
styles.reactionBubble,
|
|
253
229
|
{
|
|
254
230
|
backgroundColor: alignmentLeft ? fill : white,
|
|
255
|
-
|
|
231
|
+
borderColor: fill,
|
|
232
|
+
borderRadius: reactionSize,
|
|
233
|
+
borderWidth: strokeSize,
|
|
256
234
|
height: reactionSize - strokeSize * 2,
|
|
257
235
|
left: left + strokeSize,
|
|
258
236
|
top: strokeSize,
|
|
259
|
-
width: reactionSize * reactions.length - strokeSize * 2,
|
|
260
237
|
},
|
|
261
238
|
reactionBubble,
|
|
262
239
|
]}
|
|
263
240
|
>
|
|
264
|
-
{reactions.map((reaction) => (
|
|
265
|
-
<
|
|
241
|
+
{reactions.map((reaction, index) => (
|
|
242
|
+
<View
|
|
266
243
|
key={reaction.type}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
244
|
+
style={[
|
|
245
|
+
styles.reactionContainer,
|
|
246
|
+
{
|
|
247
|
+
marginRight: index < reactions.length - 1 ? 5 : 0,
|
|
248
|
+
},
|
|
249
|
+
]}
|
|
250
|
+
>
|
|
251
|
+
<Icon
|
|
252
|
+
key={reaction.type}
|
|
253
|
+
pathFill={reaction.own ? iconFillColor || accent_blue : grey}
|
|
254
|
+
size={reactionSize / 2}
|
|
255
|
+
style={middleIcon}
|
|
256
|
+
supportedReactions={supportedReactions}
|
|
257
|
+
type={reaction.type}
|
|
258
|
+
/>
|
|
259
|
+
<Text style={[styles.reactionCount, { color: black }]}>{reaction.count}</Text>
|
|
260
|
+
</View>
|
|
273
261
|
))}
|
|
274
262
|
</TouchableOpacity>
|
|
275
263
|
</View>
|
|
@@ -285,11 +273,13 @@ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = Default
|
|
|
285
273
|
const {
|
|
286
274
|
message: prevMessage,
|
|
287
275
|
messageContentWidth: prevMessageContentWidth,
|
|
276
|
+
reactions: prevReactions,
|
|
288
277
|
targetedMessage: prevTargetedMessage,
|
|
289
278
|
} = prevProps;
|
|
290
279
|
const {
|
|
291
280
|
message: nextMessage,
|
|
292
281
|
messageContentWidth: nextMessageContentWidth,
|
|
282
|
+
reactions: nextReactions,
|
|
293
283
|
targetedMessage: nextTargetedMessage,
|
|
294
284
|
} = nextProps;
|
|
295
285
|
|
|
@@ -313,6 +303,16 @@ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = Default
|
|
|
313
303
|
: prevMessage.latest_reactions === nextMessage.latest_reactions;
|
|
314
304
|
if (!latestReactionsEqual) return false;
|
|
315
305
|
|
|
306
|
+
const reactionsEqual =
|
|
307
|
+
Array.isArray(prevReactions) && Array.isArray(nextReactions)
|
|
308
|
+
? prevReactions.length === nextReactions.length &&
|
|
309
|
+
prevReactions.every(
|
|
310
|
+
({ type }, index) => type === nextMessage.latest_reactions?.[index].type,
|
|
311
|
+
)
|
|
312
|
+
: prevReactions === nextReactions;
|
|
313
|
+
|
|
314
|
+
if (!reactionsEqual) return false;
|
|
315
|
+
|
|
316
316
|
return true;
|
|
317
317
|
};
|
|
318
318
|
|
|
@@ -323,7 +323,7 @@ const MemoizedReactionList = React.memo(
|
|
|
323
323
|
|
|
324
324
|
export type ReactionListProps<
|
|
325
325
|
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
326
|
-
> = Partial<
|
|
326
|
+
> = Partial<ReactionListPropsWithContext<StreamChatGenerics>> &
|
|
327
327
|
Pick<ReactionListPropsWithContext<StreamChatGenerics>, 'messageContentWidth'>;
|
|
328
328
|
|
|
329
329
|
/**
|
|
@@ -364,3 +364,28 @@ export const ReactionList = <
|
|
|
364
364
|
/>
|
|
365
365
|
);
|
|
366
366
|
};
|
|
367
|
+
|
|
368
|
+
const styles = StyleSheet.create({
|
|
369
|
+
container: {
|
|
370
|
+
left: 0,
|
|
371
|
+
position: 'absolute',
|
|
372
|
+
top: 0,
|
|
373
|
+
},
|
|
374
|
+
reactionBubble: {
|
|
375
|
+
alignItems: 'center',
|
|
376
|
+
flexDirection: 'row',
|
|
377
|
+
justifyContent: 'space-evenly',
|
|
378
|
+
paddingHorizontal: 5,
|
|
379
|
+
position: 'absolute',
|
|
380
|
+
},
|
|
381
|
+
reactionContainer: {
|
|
382
|
+
alignItems: 'center',
|
|
383
|
+
flexDirection: 'row',
|
|
384
|
+
justifyContent: 'center',
|
|
385
|
+
},
|
|
386
|
+
reactionCount: {
|
|
387
|
+
fontSize: 12,
|
|
388
|
+
fontWeight: 'bold',
|
|
389
|
+
marginLeft: 2,
|
|
390
|
+
},
|
|
391
|
+
});
|
|
@@ -212,7 +212,7 @@ describe('MessageContent', () => {
|
|
|
212
212
|
const user = generateUser();
|
|
213
213
|
const reaction = generateReaction();
|
|
214
214
|
const message = generateMessage({
|
|
215
|
-
|
|
215
|
+
reaction_groups: { [reaction.type]: reaction },
|
|
216
216
|
user,
|
|
217
217
|
});
|
|
218
218
|
|
|
@@ -2,7 +2,7 @@ import { useMemo } from 'react';
|
|
|
2
2
|
|
|
3
3
|
import type { MessageContextValue } from '../../../contexts/messageContext/MessageContext';
|
|
4
4
|
import type { DefaultStreamChatGenerics } from '../../../types/types';
|
|
5
|
-
import {
|
|
5
|
+
import { stringifyMessage } from '../../../utils/utils';
|
|
6
6
|
|
|
7
7
|
export const useCreateMessageContext = <
|
|
8
8
|
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
@@ -48,14 +48,9 @@ export const useCreateMessageContext = <
|
|
|
48
48
|
videos,
|
|
49
49
|
}: MessageContextValue<StreamChatGenerics>) => {
|
|
50
50
|
const groupStylesLength = groupStyles.length;
|
|
51
|
-
const reactionsValue = reactions.map(({ own, type }) => `${own}${type}`).join();
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
const messageValue = `${
|
|
55
|
-
latestReactions ? latestReactions.map(({ type, user }) => `${type}${user?.id}`).join() : ''
|
|
56
|
-
}${message.updated_at}${message.deleted_at}${readBy}${message.status}${message.type}${
|
|
57
|
-
message.text
|
|
58
|
-
}${message.reply_count}`;
|
|
51
|
+
const reactionsValue = reactions.map(({ count, own, type }) => `${own}${type}${count}`).join();
|
|
52
|
+
const stringifiedMessage = stringifyMessage(message);
|
|
53
|
+
|
|
59
54
|
const membersValue = JSON.stringify(members);
|
|
60
55
|
const myMessageThemeString = useMemo(() => JSON.stringify(myMessageTheme), [myMessageTheme]);
|
|
61
56
|
|
|
@@ -115,7 +110,7 @@ export const useCreateMessageContext = <
|
|
|
115
110
|
lastGroupMessage,
|
|
116
111
|
lastReceivedId,
|
|
117
112
|
membersValue,
|
|
118
|
-
|
|
113
|
+
stringifiedMessage,
|
|
119
114
|
myMessageThemeString,
|
|
120
115
|
reactionsValue,
|
|
121
116
|
showAvatar,
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { ComponentType, useMemo } from 'react';
|
|
2
|
+
|
|
3
|
+
import { ReactionResponse } from 'stream-chat';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
MessagesContextValue,
|
|
7
|
+
useMessagesContext,
|
|
8
|
+
} from '../../../contexts/messagesContext/MessagesContext';
|
|
9
|
+
import { DefaultStreamChatGenerics } from '../../../types/types';
|
|
10
|
+
import { ReactionData } from '../../../utils/utils';
|
|
11
|
+
import { ReactionListProps } from '../MessageSimple/ReactionList';
|
|
12
|
+
|
|
13
|
+
export type ReactionSummary = {
|
|
14
|
+
own: boolean;
|
|
15
|
+
type: string;
|
|
16
|
+
count?: number;
|
|
17
|
+
firstReactionAt?: Date | null;
|
|
18
|
+
Icon?: ComponentType | null;
|
|
19
|
+
lastReactionAt?: Date | null;
|
|
20
|
+
latestReactedUserNames?: string[];
|
|
21
|
+
unlistedReactedUserCount?: number;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type ReactionsComparator = (a: ReactionSummary, b: ReactionSummary) => number;
|
|
25
|
+
|
|
26
|
+
type UseProcessReactionsParams<
|
|
27
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
28
|
+
> = Pick<
|
|
29
|
+
ReactionListProps<StreamChatGenerics>,
|
|
30
|
+
'own_reactions' | 'reaction_groups' | 'latest_reactions'
|
|
31
|
+
> &
|
|
32
|
+
Partial<Pick<MessagesContextValue<StreamChatGenerics>, 'supportedReactions'>> & {
|
|
33
|
+
sortReactions?: ReactionsComparator;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const defaultReactionsSort: ReactionsComparator = (a, b) => {
|
|
37
|
+
if (a.firstReactionAt && b.firstReactionAt) {
|
|
38
|
+
return +a.firstReactionAt - +b.firstReactionAt;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return a.type.localeCompare(b.type, 'en');
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const isOwnReaction = <
|
|
45
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
46
|
+
>(
|
|
47
|
+
reactionType: string,
|
|
48
|
+
ownReactions?: ReactionResponse<StreamChatGenerics>[] | null,
|
|
49
|
+
) => (ownReactions ? ownReactions.some((reaction) => reaction.type === reactionType) : false);
|
|
50
|
+
|
|
51
|
+
const isSupportedReaction = (reactionType: string, supportedReactions: ReactionData[]) =>
|
|
52
|
+
supportedReactions
|
|
53
|
+
? supportedReactions.some((reactionOption) => reactionOption.type === reactionType)
|
|
54
|
+
: false;
|
|
55
|
+
|
|
56
|
+
const getEmojiByReactionType = (reactionType: string, supportedReactions: ReactionData[]) =>
|
|
57
|
+
supportedReactions.find(({ type }) => type === reactionType)?.Icon ?? null;
|
|
58
|
+
|
|
59
|
+
const getLatestReactedUserNames = (reactionType: string, latestReactions?: ReactionResponse[]) =>
|
|
60
|
+
latestReactions
|
|
61
|
+
? latestReactions.flatMap((reaction) => {
|
|
62
|
+
if (reactionType && reactionType === reaction.type) {
|
|
63
|
+
const username = reaction.user?.name || reaction.user?.id;
|
|
64
|
+
return username ? [username] : [];
|
|
65
|
+
}
|
|
66
|
+
return [];
|
|
67
|
+
})
|
|
68
|
+
: [];
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Custom hook to process reactions data from message and return a list of reactions with additional info.
|
|
72
|
+
*/
|
|
73
|
+
export const useProcessReactions = <
|
|
74
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
75
|
+
>(
|
|
76
|
+
props: UseProcessReactionsParams<StreamChatGenerics>,
|
|
77
|
+
) => {
|
|
78
|
+
const { supportedReactions: contextSupportedReactions } = useMessagesContext();
|
|
79
|
+
|
|
80
|
+
const {
|
|
81
|
+
latest_reactions,
|
|
82
|
+
own_reactions,
|
|
83
|
+
reaction_groups,
|
|
84
|
+
sortReactions = defaultReactionsSort,
|
|
85
|
+
supportedReactions = contextSupportedReactions,
|
|
86
|
+
} = props;
|
|
87
|
+
|
|
88
|
+
return useMemo(() => {
|
|
89
|
+
if (!reaction_groups)
|
|
90
|
+
return { existingReactions: [], hasReactions: false, totalReactionCount: 0 };
|
|
91
|
+
const unsortedReactions = Object.entries(reaction_groups).flatMap(
|
|
92
|
+
([reactionType, { count, first_reaction_at, last_reaction_at }]) => {
|
|
93
|
+
if (count === 0 || !isSupportedReaction(reactionType, supportedReactions)) return [];
|
|
94
|
+
|
|
95
|
+
const latestReactedUserNames = getLatestReactedUserNames(reactionType, latest_reactions);
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
count,
|
|
99
|
+
firstReactionAt: first_reaction_at ? new Date(first_reaction_at) : null,
|
|
100
|
+
Icon: getEmojiByReactionType(reactionType, supportedReactions),
|
|
101
|
+
lastReactionAt: last_reaction_at ? new Date(last_reaction_at) : null,
|
|
102
|
+
latestReactedUserNames,
|
|
103
|
+
own: isOwnReaction<StreamChatGenerics>(reactionType, own_reactions),
|
|
104
|
+
type: reactionType,
|
|
105
|
+
unlistedReactedUserCount: count - latestReactedUserNames.length,
|
|
106
|
+
};
|
|
107
|
+
},
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
existingReactions: unsortedReactions.sort(sortReactions),
|
|
112
|
+
hasReactions: unsortedReactions.length > 0,
|
|
113
|
+
totalReactionCount: unsortedReactions.reduce((total, { count }) => total + count, 0),
|
|
114
|
+
};
|
|
115
|
+
}, [reaction_groups, own_reactions?.length, latest_reactions?.length, sortReactions]);
|
|
116
|
+
};
|
|
@@ -44,10 +44,7 @@ import { mergeThemes, ThemeProvider, useTheme } from '../../contexts/themeContex
|
|
|
44
44
|
import { useViewport } from '../../hooks/useViewport';
|
|
45
45
|
import type { DefaultStreamChatGenerics } from '../../types/types';
|
|
46
46
|
import { MessageTextContainer } from '../Message/MessageSimple/MessageTextContainer';
|
|
47
|
-
import {
|
|
48
|
-
OverlayReactions as DefaultOverlayReactions,
|
|
49
|
-
Reaction,
|
|
50
|
-
} from '../MessageOverlay/OverlayReactions';
|
|
47
|
+
import { OverlayReactions as DefaultOverlayReactions } from '../MessageOverlay/OverlayReactions';
|
|
51
48
|
import type { ReplyProps } from '../Reply/Reply';
|
|
52
49
|
|
|
53
50
|
const styles = StyleSheet.create({
|
|
@@ -464,26 +461,16 @@ const MessageOverlayWithContext = <
|
|
|
464
461
|
message={message}
|
|
465
462
|
/>
|
|
466
463
|
)}
|
|
467
|
-
{!!messageReactionTitle &&
|
|
468
|
-
message.latest_reactions &&
|
|
469
|
-
message.latest_reactions.length > 0 ? (
|
|
464
|
+
{!!messageReactionTitle && (
|
|
470
465
|
<OverlayReactions
|
|
471
466
|
alignment={alignment}
|
|
467
|
+
messageId={message.id}
|
|
472
468
|
OverlayReactionsAvatar={OverlayReactionsAvatar}
|
|
473
|
-
reactions={
|
|
474
|
-
message.latest_reactions.map((reaction) => ({
|
|
475
|
-
alignment: clientId && clientId === reaction.user?.id ? 'right' : 'left',
|
|
476
|
-
id: reaction?.user?.id || '',
|
|
477
|
-
image: reaction?.user?.image,
|
|
478
|
-
name: reaction?.user?.name || reaction.user_id || '',
|
|
479
|
-
type: reaction.type,
|
|
480
|
-
})) as Reaction[]
|
|
481
|
-
}
|
|
482
469
|
showScreen={showScreen}
|
|
483
470
|
supportedReactions={messagesContext?.supportedReactions}
|
|
484
471
|
title={messageReactionTitle}
|
|
485
472
|
/>
|
|
486
|
-
)
|
|
473
|
+
)}
|
|
487
474
|
</View>
|
|
488
475
|
)}
|
|
489
476
|
</Animated.View>
|