Skip to content

Commit 7894bf9

Browse files
Merge pull request #1333 from GetStream/Enigma-I-am/mentioned-user-profile
feat: ability to add onPress handler for mentioned user names - [Documentation link](https://getstream.io/chat/docs/sdk/reactnative/core-components/channel/#onpressmessage)
2 parents 59b0dd2 + cffd237 commit 7894bf9

File tree

6 files changed

+98
-56
lines changed

6 files changed

+98
-56
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ NEXT_RELEASE_CHANGELOG.md
33
artifacts
44
e2e/.env
55
*.log
6+
.DS_STORE

docusaurus/docs/reactnative/common-content/core-components/channel/props/on_press_message.mdx

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,27 @@ You will have to handle these cases when overriding this function.
1111
| -------- |
1212
| function |
1313

14-
| Parameter | Description |
15-
| --------- | ----------------------------- |
16-
| payload | `{ actionHandlers, message }` |
14+
| Parameter | Description |
15+
| --------- | --------------------------------------------- |
16+
| payload | `{ additionalInfo, actionHandlers, message }` |
17+
18+
The `additionalInfo` prop is handy for getting information from certain click events.
19+
A good example of this is getting the user details when a textMention (for example @Enigma-I-am) is clicked.
20+
21+
For example:
22+
23+
```tsx
24+
<Channel
25+
onPressMessage={({ additionalInfo, defaultHandler, emitter }) => {
26+
if (emitter === 'textMention') {
27+
console.log(additionalInfo?.user);
28+
return;
29+
}
30+
defaultHandler?.();
31+
}}
32+
>
33+
```
34+
35+
:::info
36+
37+
The `additionalInfo` prop will change over time as we explore more usecases for different `emitter's`.

examples/SampleApp/ios/Podfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -848,4 +848,4 @@ SPEC CHECKSUMS:
848848

849849
PODFILE CHECKSUM: a640bd2ecc4e73329d8379590f3ee5bc09ecba5f
850850

851-
COCOAPODS: 1.11.2
851+
COCOAPODS: 1.11.3

package/src/components/Message/Message.tsx

Lines changed: 56 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import { GestureResponderEvent, Keyboard, StyleProp, View, ViewStyle } from 'react-native';
33

4-
import type { Attachment } from 'stream-chat';
4+
import type { Attachment, UserResponse } from 'stream-chat';
55

66
import { useCreateMessageContext } from './hooks/useCreateMessageContext';
77
import { useMessageActionHandlers } from './hooks/useMessageActionHandlers';
@@ -52,21 +52,34 @@ import {
5252
} from '../MessageList/hooks/useMessageList';
5353
import type { MessageActionListItemProps } from '../MessageOverlay/MessageActionListItem';
5454

55+
export type TouchableEmitter =
56+
| 'card'
57+
| 'fileAttachment'
58+
| 'gallery'
59+
| 'giphy'
60+
| 'message'
61+
| 'messageContent'
62+
| 'messageReplies'
63+
| 'reactionList'
64+
| 'textLink';
65+
66+
export type TextMentionTouchableHandlerPayload<
67+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
68+
> = {
69+
emitter: 'textMention';
70+
additionalInfo?: { user?: UserResponse<StreamChatGenerics> };
71+
};
72+
5573
export type TouchableHandlerPayload = {
5674
defaultHandler?: () => void;
57-
emitter?:
58-
| 'card'
59-
| 'fileAttachment'
60-
| 'gallery'
61-
| 'giphy'
62-
| 'message'
63-
| 'messageContent'
64-
| 'messageReplies'
65-
| 'reactionList'
66-
| 'textLink'
67-
| 'textMention';
6875
event?: GestureResponderEvent;
69-
};
76+
} & (
77+
| {
78+
additionalInfo?: Record<string, unknown>;
79+
emitter?: TouchableEmitter;
80+
}
81+
| TextMentionTouchableHandlerPayload
82+
);
7083

7184
export type MessageTouchableHandlerPayload<
7285
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
@@ -595,45 +608,40 @@ const MessageWithContext = <
595608
onlyEmojis,
596609
onOpenThread,
597610
onPress: (payload) => {
598-
onPressProp
599-
? onPressProp({
600-
actionHandlers,
601-
defaultHandler: payload.defaultHandler || onPress,
602-
emitter: payload.emitter || 'message',
603-
event: payload.event,
604-
message,
605-
})
606-
: onPressMessageProp
607-
? onPressMessageProp({
608-
actionHandlers,
609-
defaultHandler: payload.defaultHandler || onPress,
610-
emitter: payload.emitter || 'message',
611-
event: payload.event,
612-
message,
613-
})
614-
: payload.defaultHandler
615-
? payload.defaultHandler()
616-
: onPress();
611+
const onPressArgs = {
612+
actionHandlers,
613+
additionalInfo: payload.additionalInfo,
614+
defaultHandler: payload.defaultHandler || onPress,
615+
emitter: payload.emitter || 'message',
616+
event: payload.event,
617+
message,
618+
};
619+
620+
const handleOnPress = () => {
621+
if (onPressProp) return onPressProp(onPressArgs);
622+
if (onPressMessageProp) return onPressMessageProp(onPressArgs);
623+
if (payload.defaultHandler) return payload.defaultHandler();
624+
625+
return onPress();
626+
};
627+
628+
handleOnPress();
617629
},
618630
onPressIn:
619631
onPressInProp || onPressInMessageProp
620632
? (payload) => {
621-
onPressInProp
622-
? onPressInProp({
623-
actionHandlers,
624-
defaultHandler: payload.defaultHandler,
625-
emitter: payload.emitter || 'message',
626-
event: payload.event,
627-
message,
628-
})
629-
: onPressInMessageProp &&
630-
onPressInMessageProp({
631-
actionHandlers,
632-
defaultHandler: payload.defaultHandler,
633-
emitter: payload.emitter || 'message',
634-
event: payload.event,
635-
message,
636-
});
633+
const onPressInArgs = {
634+
actionHandlers,
635+
defaultHandler: payload.defaultHandler,
636+
emitter: payload.emitter || 'message',
637+
event: payload.event,
638+
message,
639+
};
640+
const handleOnpressIn = () => {
641+
if (onPressInProp) return onPressInProp(onPressInArgs);
642+
if (onPressInMessageProp) return onPressInMessageProp(onPressInArgs);
643+
};
644+
handleOnpressIn();
637645
}
638646
: null,
639647
otherAttachments: attachments.other,

package/src/components/Message/MessageSimple/utils/renderText.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import {
1717
State,
1818
} from 'simple-markdown';
1919

20+
import type { UserResponse } from 'stream-chat';
21+
2022
import { parseLinksFromText } from './parseLinks';
2123

2224
import type { MessageContextValue } from '../../../../contexts/messageContext/MessageContext';
@@ -211,9 +213,16 @@ export const renderText = <
211213
const match: MatchFunction = (source) => regEx.exec(source);
212214

213215
const mentionsReact: ReactNodeOutput = (node, output, { ...state }) => {
216+
/**removes the @ prefix of username */
217+
const userName = node.content[0]?.content?.substring(1);
214218
const onPress = (event: GestureResponderEvent) => {
215219
if (!preventPress && onPressParam) {
216220
onPressParam({
221+
additionalInfo: {
222+
user: mentioned_users?.find(
223+
(user: UserResponse<StreamChatGenerics>) => userName === user.name,
224+
),
225+
},
217226
emitter: 'textMention',
218227
event,
219228
});

package/src/contexts/messageContext/MessageContext.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import React, { PropsWithChildren, useContext } from 'react';
33
import type { Attachment } from 'stream-chat';
44

55
import type { ActionHandler } from '../../components/Attachment/Attachment';
6-
import type { TouchableHandlerPayload } from '../../components/Message/Message';
6+
import type {
7+
MessageTouchableHandlerPayload,
8+
TouchableHandlerPayload,
9+
} from '../../components/Message/Message';
710
import type { GroupType, MessageType } from '../../components/MessageList/hooks/useMessageList';
811
import type { ChannelContextValue } from '../../contexts/channelContext/ChannelContext';
912
import type { MessageContentType } from '../../contexts/messagesContext/MessagesContext';
@@ -62,7 +65,7 @@ export type MessageContextValue<
6265
*
6366
* By default, we show the overlay with all the message actions on long press.
6467
*
65-
* @param event Event object for onLongPress event
68+
* @param payload Payload object for onLongPress event
6669
*/
6770
onLongPress: (payload: TouchableHandlerPayload) => void;
6871
/** Whether the message is only text and the text is only emojis */
@@ -77,9 +80,9 @@ export type MessageContextValue<
7780
*
7881
* By default, we will dismiss the keyboard on press.
7982
*
80-
* @param event Event object for onPress event
83+
* @param payload Payload object for onPress event
8184
*/
82-
onPress: (payload: TouchableHandlerPayload) => void;
85+
onPress: (payload: MessageTouchableHandlerPayload) => void;
8386
onPressIn: ((payload: TouchableHandlerPayload) => void) | null;
8487
/** The images attached to a message */
8588
otherAttachments: Attachment<StreamChatGenerics>[];

0 commit comments

Comments
 (0)