Skip to content

feat: reply message functionality#2692

Closed
DimaIvashchuk wants to merge 2 commits into
FaridSafi:masterfrom
DimaIvashchuk:feat/reply-message
Closed

feat: reply message functionality#2692
DimaIvashchuk wants to merge 2 commits into
FaridSafi:masterfrom
DimaIvashchuk:feat/reply-message

Conversation

@DimaIvashchuk
Copy link
Copy Markdown

Here's the updated PR description:

# Reply Message Feature

This PR adds a complete reply message feature to react-native-gifted-chat, allowing users to swipe on messages to reply and display replied messages within message bubbles.

## Features

### 1. Swipe to Reply
- Swipe left on any message to trigger a reply action
- Configurable swipe direction (`left` or `right`, default: `right`)
- Built-in animated reply icon indicator
- Can be enabled/disabled via `isSwipeToReplyEnabled` prop

### 2. Reply Preview in Input Toolbar
- Shows a preview of the message being replied to above the input
- Displays the original sender's name and message text
- Built-in clear button to cancel the reply
- Customizable styles and render prop for full control

### 3. Reply Message Display in Bubble
- Displays the replied message at the top of the message bubble
- Shows sender name, text, and optional image thumbnail
- Pressable to navigate to the original message (navigation logic should be implemented on client side)
- Different styling for left/right positioned messages

### 4. Automatic Reply Attachment
- Reply message is automatically attached when sending
- Reply is cleared after sending
- Supports both controlled and uncontrolled state management

## New Components

### `MessageReply`
Renders the replied message inside a bubble.

```tsx
import { MessageReply } from 'react-native-gifted-chat'

ReplyPreview

Renders the reply preview in the input toolbar.

import { ReplyPreview } from 'react-native-gifted-chat'

New Props on GiftedChat

Swipe to Reply Props

Prop Type Default Description
isSwipeToReplyEnabled boolean false Enable swipe to reply on messages
swipeToReplyDirection 'left' | 'right' 'right' Swipe direction for reply
onSwipeToReply (message: TMessage) => void - Callback when swipe to reply is triggered
renderSwipeToReplyAction (progress, dragX, position) => ReactNode - Custom render for swipe action indicator
swipeToReplyActionContainerStyle StyleProp<ViewStyle> - Style for swipe action container

Reply State Props

Prop Type Default Description
replyMessage ReplyMessage | null - Reply message for controlled mode
onClearReply () => void - Callback when reply is cleared

Reply Preview Props (Input Toolbar)

Prop Type Default Description
renderReplyPreview (props: ReplyPreviewProps) => ReactNode - Custom render for reply preview
replyPreviewContainerStyle StyleProp<ViewStyle> - Style for reply preview container
replyPreviewUsernameStyle StyleProp<TextStyle> - Style for reply preview username
replyPreviewTextStyle StyleProp<TextStyle> - Style for reply preview text

Message Reply Props (Bubble)

Prop Type Default Description
renderMessageReply (props: MessageReplyProps) => ReactNode - Custom render for message reply in bubble
onPressMessageReply (replyMessage: ReplyMessage) => void - Callback when message reply is pressed (must be implemented on client side)
messageReplyContainerStyle LeftRightStyle<ViewStyle> - Style for message reply container
messageReplyContentContainerStyle LeftRightStyle<ViewStyle> - Style for message reply content container
messageReplyImageStyle StyleProp<ImageStyle> - Style for message reply image
messageReplyUsernameStyle StyleProp<TextStyle> - Style for message reply username
messageReplyTextStyle StyleProp<TextStyle> - Style for message reply text

Usage

Basic Usage (Uncontrolled)

<GiftedChat
  messages={messages}
  onSend={onSend}
  user={user}
  isSwipeToReplyEnabled
/>

Controlled Mode

const [replyMessage, setReplyMessage] = useState<ReplyMessage | null>(null)

<GiftedChat
  messages={messages}
  onSend={onSend}
  user={user}
  isSwipeToReplyEnabled
  replyMessage={replyMessage}
  onSwipeToReply={(message) => setReplyMessage({
    _id: message._id,
    text: message.text,
    user: message.user,
    image: message.image,
  })}
  onClearReply={() => setReplyMessage(null)}
/>

With onPressMessageReply (Client-Side Implementation)

Note: The onPressMessageReply callback is provided by the library, but the actual navigation/scroll to the original message must be implemented on the client side based on your app's requirements.

const messagesContainerRef = useRef<FlatList>(null)

const handlePressMessageReply = useCallback((replyMessage: ReplyMessage) => {
  // Find the index of the original message
  const index = messages.findIndex(m => m._id === replyMessage._id)
  
  if (index !== -1 && messagesContainerRef.current) {
    // Scroll to the original message
    messagesContainerRef.current.scrollToIndex({
      index,
      animated: true,
    })
    
    // Optionally highlight the message
    // Your highlighting logic here...
  }
}, [messages])

<GiftedChat
  messages={messages}
  onSend={onSend}
  user={user}
  isSwipeToReplyEnabled
  messagesContainerRef={messagesContainerRef}
  onPressMessageReply={handlePressMessageReply}
/>

Types

ReplyMessage

Already existed in Models.ts:

interface ReplyMessage extends Pick<IMessage, '_id' | 'text' | 'user' | 'audio' | 'image'> {}

MessageReplyProps

interface MessageReplyProps<TMessage extends IMessage> {
  position?: 'left' | 'right'
  currentMessage: TMessage
  containerStyle?: LeftRightStyle<ViewStyle>
  contentContainerStyle?: LeftRightStyle<ViewStyle>
  imageStyle?: StyleProp<ImageStyle>
  usernameStyle?: StyleProp<TextStyle>
  textStyle?: StyleProp<TextStyle>
  onPress?: (replyMessage: ReplyMessage) => void
}

ReplyPreviewProps

interface ReplyPreviewProps {
  replyMessage: ReplyMessage
  onClearReply: () => void
  containerStyle?: StyleProp<ViewStyle>
  usernameStyle?: StyleProp<TextStyle>
  textStyle?: StyleProp<TextStyle>
  clearButtonStyle?: StyleProp<ViewStyle>
  clearButtonTextStyle?: StyleProp<TextStyle>
}

Files Changed

New Files

  • src/MessageReply.tsx - Component for displaying reply in message bubble
  • src/ReplyPreview.tsx - Component for reply preview in input toolbar

Modified Files

  • src/Message/index.tsx - Added Swipeable wrapper for swipe-to-reply
  • src/Message/types.ts - Added swipe-to-reply props
  • src/Bubble/index.tsx - Added renderMessageReply support
  • src/Bubble/types.ts - Added renderMessageReply and style props
  • src/InputToolbar.tsx - Added reply preview support
  • src/GiftedChat/index.tsx - Added reply state management
  • src/GiftedChat/types.ts - Added reply-related props
  • src/MessagesContainer/types.ts - Added pass-through props
  • src/index.ts - Added exports for new components
  • src/types.ts - Added exports for new types

@DimaIvashchuk
Copy link
Copy Markdown
Author

PR to close #2657
@kesha-antonov the pipeline is failed and I believe Its not an issue on my side
Meanwhile can you review. I am not sure I will be able to fix issues in a few weeks so you can do it on your own
but it would be nice to have a feedback

@kesha-antonov
Copy link
Copy Markdown
Collaborator

Hi
I'm busy too in December
If somebody else can review that could be great

@kesha-antonov
Copy link
Copy Markdown
Collaborator

Thanks for the PR!

@kesha-antonov
Copy link
Copy Markdown
Collaborator

Added to master

Thanks for the PR again !!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants