Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Conversation

@DimaIvashchuk
Copy link
Contributor

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
Contributor 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
Collaborator

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

@kesha-antonov
Copy link
Collaborator

Thanks for the PR!

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

Morty Proxy This is a proxified and sanitized view of the page, visit original site.