react-native-gifted-chat 2.9.0-alpha.0 → 3.0.0-alpha.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 (38) hide show
  1. package/README.md +234 -319
  2. package/package.json +2 -2
  3. package/src/Avatar.tsx +12 -12
  4. package/src/Bubble/index.tsx +2 -2
  5. package/src/Bubble/types.ts +22 -22
  6. package/src/Composer.tsx +0 -3
  7. package/src/GiftedAvatar.tsx +1 -1
  8. package/src/GiftedChat/index.tsx +56 -145
  9. package/src/GiftedChat/types.ts +40 -52
  10. package/src/InputToolbar.tsx +6 -6
  11. package/src/Message/index.tsx +5 -6
  12. package/src/Message/types.ts +8 -12
  13. package/src/MessageContainer/components/DayAnimated/types.ts +1 -1
  14. package/src/MessageContainer/components/Item/index.tsx +2 -2
  15. package/src/MessageContainer/components/Item/types.ts +1 -1
  16. package/src/MessageContainer/index.tsx +30 -30
  17. package/src/MessageContainer/styles.ts +12 -5
  18. package/src/MessageContainer/types.ts +12 -16
  19. package/src/MessageImage.tsx +100 -67
  20. package/src/MessageText.tsx +1 -1
  21. package/src/Models.ts +63 -0
  22. package/src/QuickReplies.tsx +1 -1
  23. package/src/Send.tsx +30 -31
  24. package/src/SystemMessage.tsx +1 -1
  25. package/src/Time.tsx +1 -1
  26. package/src/__tests__/GiftedChat.test.tsx +0 -28
  27. package/src/__tests__/Message.test.tsx +2 -2
  28. package/src/__tests__/Send.test.tsx +1 -1
  29. package/src/__tests__/__snapshots__/Actions.test.tsx.snap +2 -86
  30. package/src/__tests__/__snapshots__/GiftedChat.test.tsx.snap +31 -54
  31. package/src/__tests__/__snapshots__/LoadEarlier.test.tsx.snap +3 -89
  32. package/src/__tests__/__snapshots__/Message.test.tsx.snap +2 -2
  33. package/src/__tests__/__snapshots__/MessageImage.test.tsx.snap +1 -1
  34. package/src/__tests__/__snapshots__/Send.test.tsx.snap +10 -142
  35. package/src/__tests__/data.ts +1 -1
  36. package/src/components/TouchableOpacity.tsx +19 -8
  37. package/src/types.ts +1 -63
  38. package/src/utils.ts +1 -1
package/README.md CHANGED
@@ -1,11 +1,3 @@
1
- <p align="center">
2
- <p align="center">
3
- <a href="https://reactnative.gallery/FaridSafi/gifted-chat">
4
-    <img alt="react-native-gifted-chat" src="https://thumbs.gfycat.com/AbsoluteSadDobermanpinscher-size_restricted.gif" width="260" height="510" />
5
- </a>
6
-
7
- </p>
8
-
9
1
  <h3 align="center">
10
2
  💬 Gifted Chat
11
3
  </h3>
@@ -16,26 +8,59 @@
16
8
  <a href="https://www.npmjs.com/package/react-native-gifted-chat">
17
9
  <img alt="npm downloads" src="https://img.shields.io/npm/dm/react-native-gifted-chat.svg"/></a>
18
10
  <a href="https://www.npmjs.com/package/react-native-gifted-chat"><img alt="npm version" src="https://badge.fury.io/js/react-native-gifted-chat.svg"/></a>
11
+  <a href="https://circleci.com/gh/FaridSafi/react-native-gifted-chat"><img src="https://circleci.com/gh/FaridSafi/react-native-gifted-chat.svg?style=shield" alt="build"></a>
19
12
  </p>
13
+
14
+ ---
15
+
16
+ <h3 align="center">
17
+ 🚀 Try it now in your browser!
18
+ </h3>
20
19
  <p align="center">
21
-  <a href="https://circleci.com/gh/FaridSafi/react-native-gifted-chat"><img src="https://circleci.com/gh/FaridSafi/react-native-gifted-chat.svg?style=shield" alt="build"></a>
22
- <a title='License' href="https://github.com/FaridSafi/react-native-gifted-chat/blob/master/LICENSE" height="18">
23
- <img src='https://img.shields.io/badge/license-MIT-blue.svg' />
20
+ <a href="https://snack.expo.dev/@kesha-antonov/gifted-chat-playground" target="_blank">
21
+ <img src="https://img.shields.io/badge/▶️_Try_GiftedChat_Playground-4630EB?style=for-the-badge&logo=expo&logoColor=white" alt="Try GiftedChat on Expo Snack"/>
24
22
  </a>
25
- <a href="#hire-an-expert"><img src="https://img.shields.io/badge/%F0%9F%92%AA-hire%20an%20expert-brightgreen"/></a>
23
+ </p>
24
+ <p align="center">
25
+ <strong>No installation required • Interactive examples • Edit and run in real-time</strong>
26
26
  </p>
27
27
 
28
+ <br />
29
+
30
+ <!-- previews -->
31
+
28
32
  <p align="center">
29
- <a href="https://snack.expo.dev/@kesha-antonov/gifted-chat-playground" target="_blank">Snack GiftedChat playground</a>
30
- <img height="18" src="https://snack.expo.io/favicon.ico" />
33
+ <img width="200" src="https://github.com/user-attachments/assets/c9da88f5-0b20-471c-8cd7-373bdb767517" />
34
+ &nbsp;&nbsp;&nbsp;&nbsp;
35
+ <img width="200" src="https://github.com/user-attachments/assets/f72b17f1-6c2e-43b5-87e7-477011aa3b07" />
36
+ &nbsp;&nbsp;&nbsp;&nbsp;
37
+ <img width="200" src="https://github.com/user-attachments/assets/86711e73-ee3c-4527-b38d-e4dab47a44fe" />
31
38
  </p>
32
39
 
40
+ ---
41
+
42
+ ## Features
43
+
44
+ - Fully customizable components
45
+ - Composer actions (to attach photos, etc.)
46
+ - Load earlier messages
47
+ - Copy messages to clipboard
48
+ - Touchable links using [react-native-autolink](https://github.com/joshswan/react-native-autolink)
49
+ - Avatar as user's initials
50
+ - Localized dates
51
+ - Multi-line TextInput
52
+ - InputToolbar avoiding keyboard
53
+ - System message
54
+ - Quick Reply messages (bot)
55
+ - Typing indicator
56
+ - react-native-web [web configuration](#react-native-web)
57
+
33
58
  ## Sponsor
34
59
 
35
60
  <p align="center">
36
61
  <br/>
37
62
  <a href="https://www.lereacteur.io" target="_blank">
38
- <img src="https://raw.githubusercontent.com/FaridSafi/react-native-gifted-chat/master/media/logo_sponsor.png">
63
+ <img src="https://raw.githubusercontent.com/FaridSafi/react-native-gifted-chat/master/media/logo_sponsor.png" height="60">
39
64
  </a>
40
65
  <br>
41
66
  <p align="center">
@@ -51,7 +76,7 @@
51
76
  <p align="center">
52
77
  <br/>
53
78
  <a href="https://getstream.io/chat/?utm_source=Github&utm_medium=Github_Repo_Content_Ad&utm_content=Developer&utm_campaign=Github_Jan2022_Chat&utm_term=react-native-gifted-chat" target="_blank">
54
- <img src="https://raw.githubusercontent.com/FaridSafi/react-native-gifted-chat/master/media/stream-logo.png" height="50">
79
+ <img src="https://raw.githubusercontent.com/FaridSafi/react-native-gifted-chat/master/media/stream-logo.png" height="40">
55
80
  </a>
56
81
  <br>
57
82
  <p align="center">
@@ -65,7 +90,7 @@
65
90
  <p align="center">
66
91
  <br/>
67
92
  <a href="https://www.ethora.com" target="_blank">
68
- <img src="https://www.dappros.com/wp-content/uploads/2023/12/Ethora-Logo.png" width="300px">
93
+ <img src="https://www.dappros.com/wp-content/uploads/2023/12/Ethora-Logo.png" height="60">
69
94
  </a>
70
95
  <br>
71
96
  <p align="center">
@@ -80,50 +105,26 @@
80
105
  <a href="https://amzn.to/3ZmTyb2" target="_blank">React Key Concepts: Consolidate your knowledge of React’s core features (2nd ed. Edition)</a>
81
106
  </p>
82
107
 
83
- ## Features
84
-
85
- - Fully customizable components
86
- - Composer actions (to attach photos, etc.)
87
- - Load earlier messages
88
- - Copy messages to clipboard
89
- - Touchable links using [react-native-autolink](https://github.com/joshswan/react-native-autolink)
90
- - Avatar as user's initials
91
- - Localized dates
92
- - Multi-line TextInput
93
- - InputToolbar avoiding keyboard
94
- - System message
95
- - Quick Reply messages (bot)
96
- - Typing indicator
97
- - react-native-web [web configuration](#react-native-web)
98
-
99
108
  # Getting started
100
109
 
101
- ## 🚧👷 Important notice
102
-
103
- There's currently WIP going on to make the library more performant, modern in terms of chat UI and easier to maintain. If you have any issues, please report them. If you want to contribute, please do so.
104
-
105
- The most stable version is `2.6.5`. If you want to use the latest version, please be aware that it's a work in progress.
106
-
107
- Readme for this version: [2.6.5 readme](https://github.com/FaridSafi/react-native-gifted-chat/blob/eebab3751fcbe07715135e6e7b2aa3f76a10d8ac/README.md)
108
-
109
110
  ## Installation
110
111
 
111
112
  ### Install dependencies
112
113
 
113
114
  Yarn:
114
115
  ```bash
115
- yarn add react-native-gifted-chat react-native-reanimated react-native-keyboard-controller react-native-gesture-handler react-native-safe-area-context
116
+ yarn add react-native-gifted-chat react-native-reanimated react-native-gesture-handler react-native-safe-area-context react-native-keyboard-controller
116
117
  ```
117
118
 
118
119
  Npm:
119
120
 
120
121
  ```bash
121
- npm install --save react-native-gifted-chat react-native-reanimated react-native-keyboard-controller react-native-gesture-handler react-native-safe-area-context
122
+ npm install --save react-native-gifted-chat react-native-reanimated react-native-gesture-handler react-native-safe-area-context react-native-keyboard-controller
122
123
  ```
123
124
 
124
125
  Expo
125
126
  ```bash
126
- npx expo install react-native-gifted-chat react-native-reanimated react-native-keyboard-controller react-native-gesture-handler react-native-safe-area-context
127
+ npx expo install react-native-gifted-chat react-native-reanimated react-native-gesture-handler react-native-safe-area-context react-native-keyboard-controller
127
128
  ```
128
129
 
129
130
  ### Non-expo users
@@ -136,34 +137,9 @@ npx pod-install
136
137
 
137
138
  Follow guide: [react-native-reanimated](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started/#step-2-add-reanimateds-babel-plugin)
138
139
 
139
- ## Testing
140
- `TEST_ID` is exported as constants that can be used in your testing library of choice
141
-
142
- Gifted Chat uses `onLayout` to determine the height of the chat container. To trigger `onLayout` during your tests, you can run the following bits of code.
143
-
144
- ```typescript
145
- const WIDTH = 200; // or any number
146
- const HEIGHT = 2000; // or any number
147
-
148
- const loadingWrapper = getByTestId(TEST_ID.LOADING_WRAPPER)
149
- fireEvent(loadingWrapper, 'layout', {
150
- nativeEvent: {
151
- layout: {
152
- width: WIDTH,
153
- height: HEIGHT,
154
- },
155
- },
156
- })
157
- ```
158
-
159
- ## You have a question?
140
+ ## Examples
160
141
 
161
- 1. Please check this readme and may find a response
162
- 1. Please ask on StackOverflow first: https://stackoverflow.com/questions/tagged/react-native-gifted-chat
163
- 1. Find response on existing issues
164
- 1. Try to keep issues for issues
165
-
166
- ## Example
142
+ ### Basic usage
167
143
 
168
144
  ```jsx
169
145
  import React, { useState, useCallback, useEffect } from 'react'
@@ -176,7 +152,7 @@ export function Example() {
176
152
 
177
153
  // If you have a tab bar, include its height
178
154
  const tabbarHeight = 50
179
- const keyboardBottomOffset = insets.bottom + tabbarHeight
155
+ const keyboardVerticalOffset = insets.bottom + tabbarHeight
180
156
 
181
157
  useEffect(() => {
182
158
  setMessages([
@@ -206,228 +182,89 @@ export function Example() {
206
182
  user={{
207
183
  _id: 1,
208
184
  }}
209
- keyboardBottomOffset={keyboardBottomOffset}
185
+
186
+ keyboardAvoidingViewProps={{ keyboardVerticalOffset }}
210
187
  />
211
188
  )
212
189
  }
213
190
  ```
214
191
 
215
- ## Advanced example
192
+ ### Other examples
216
193
 
217
- See [`examples`](example) for a working demo!
194
+ Check out code of [`examples`](example)
218
195
 
219
- ## "Slack" example
196
+ ## Data structure
220
197
 
221
- See the files in [`example/example-slack-message`](example/example-slack-message) for an example of how to override the default UI to make something that looks more like Slack -- with usernames displayed and all messages on the left.
198
+ Messages, system messages, quick replies etc.: [data structure](src/Models.ts)
222
199
 
223
- ## Message object
200
+ ## Props
224
201
 
225
- > e.g. Chat Message
202
+ ### Core Configuration
226
203
 
227
- ```ts
228
- export interface IMessage {
229
- _id: string | number
230
- text: string
231
- createdAt: Date | number
232
- user: User
233
- image?: string
234
- video?: string
235
- audio?: string
236
- system?: boolean
237
- sent?: boolean
238
- received?: boolean
239
- pending?: boolean
240
- quickReplies?: QuickReplies
241
- }
242
- ```
204
+ - **`messages`** _(Array)_ - Messages to display
205
+ - **`user`** _(Object)_ - User sending the messages: `{ _id, name, avatar }`
206
+ - **`onSend`** _(Function)_ - Callback when sending a message
207
+ - **`messageIdGenerator`** _(Function)_ - Generate an id for new messages. Defaults to a simple random string generator.
208
+ - **`locale`** _(String)_ - Locale to localize the dates. You need first to import the locale you need (ie. `require('dayjs/locale/de')` or `import 'dayjs/locale/fr'`)
243
209
 
244
- ```js
245
- {
246
- _id: 1,
247
- text: 'My message',
248
- createdAt: new Date(Date.UTC(2016, 5, 11, 17, 20, 0)),
249
- user: {
250
- _id: 2,
251
- name: 'React Native',
252
- avatar: 'https://facebook.github.io/react/img/logo_og.png',
253
- },
254
- image: 'https://facebook.github.io/react/img/logo_og.png',
255
- // You can also add a video prop:
256
- video: 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4',
257
- // Mark the message as sent, using one tick
258
- sent: true,
259
- // Mark the message as received, using two tick
260
- received: true,
261
- // Mark the message as pending with a clock loader
262
- pending: true,
263
- // Any additional custom parameters are passed through
264
- }
265
- ```
210
+ ### Refs
266
211
 
267
- > e.g. System Message
212
+ - **`messageContainerRef`** _(FlatList ref)_ - Ref to the flatlist
213
+ - **`textInputRef`** _(TextInput ref)_ - Ref to the text input
268
214
 
269
- ```js
270
- {
271
- _id: 1,
272
- text: 'This is a system message',
273
- createdAt: new Date(Date.UTC(2016, 5, 11, 17, 20, 0)),
274
- system: true,
275
- // Any additional custom parameters are passed through
276
- }
277
- ```
215
+ ### Keyboard & Layout
278
216
 
279
- > e.g. Chat Message with Quick Reply options
217
+ - **`keyboardProviderProps`** _(Object)_ - Props to be passed to the [`KeyboardProvider`](https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/keyboard-provider) for keyboard handling.
218
+ - **`keyboardAvoidingViewProps`** _(Object)_ - Props to be passed to the [`KeyboardAvoidingView`](https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/keyboard-avoiding-view). The `behavior` prop defaults to `'padding'`.
219
+ - **`isAlignedTop`** _(Boolean)_ Controls whether or not the message bubbles appear at the top of the chat (Default is false - bubbles align to bottom)
220
+ - **`isInverted`** _(Bool)_ - Reverses display order of `messages`; default is `true`
280
221
 
281
- See PR [#1211](https://github.com/FaridSafi/react-native-gifted-chat/pull/1211)
222
+ ### Text Input & Composer
282
223
 
283
- ```ts
284
- interface Reply {
285
- title: string
286
- value: string
287
- messageId?: number | string
288
- }
224
+ - **`text`** _(String)_ - Input text; default is `undefined`, but if specified, it will override GiftedChat's internal state. Useful for managing text state outside of GiftedChat (e.g. with Redux). Don't forget to implement `textInputProps.onChangeText` to update the text state.
225
+ - **`initialText`** _(String)_ - Initial text to display in the input field
226
+ - **`isSendButtonAlwaysVisible`** _(Bool)_ - Always show send button in input text composer; default `false`, show only when text input is not empty
227
+ - **`minComposerHeight`** _(Object)_ - Custom min-height of the composer.
228
+ - **`maxComposerHeight`** _(Object)_ - Custom max height of the composer.
229
+ - **`minInputToolbarHeight`** _(Integer)_ - Minimum height of the input toolbar; default is `44`
230
+ - **`renderInputToolbar`** _(Component | Function)_ - Custom message composer container
231
+ - **`renderComposer`** _(Component | Function)_ - Custom text input message composer
232
+ - **`renderSend`** _(Component | Function)_ - Custom send button; you can pass children to the original `Send` component quite easily, for example, to use a custom icon ([example](https://github.com/FaridSafi/react-native-gifted-chat/pull/487))
233
+ - **`renderActions`** _(Component | Function)_ - Custom action button on the left of the message composer
234
+ - **`renderAccessory`** _(Component | Function)_ - Custom second line of actions below the message composer
235
+ - **`textInputProps`** _(Object)_ - props to be passed to the [`<TextInput>`](https://reactnative.dev/docs/textinput.html).
289
236
 
290
- interface QuickReplies {
291
- type: 'radio' | 'checkbox'
292
- values: Reply[]
293
- keepIt?: boolean
294
- }
295
- ```
237
+ ### Actions & Action Sheet
296
238
 
297
- ```js
298
- {
299
- _id: 1,
300
- text: 'This is a quick reply. Do you love Gifted Chat? (radio) KEEP IT',
301
- createdAt: new Date(),
302
- quickReplies: {
303
- type: 'radio', // or 'checkbox',
304
- keepIt: true,
305
- values: [
306
- {
307
- title: '😋 Yes',
308
- value: 'yes',
309
- },
310
- {
311
- title: '📷 Yes, let me show you with a picture!',
312
- value: 'yes_picture',
313
- },
314
- {
315
- title: '😞 Nope. What?',
316
- value: 'no',
317
- },
318
- ],
319
- },
320
- user: {
321
- _id: 2,
322
- name: 'React Native',
323
- },
324
- },
325
- {
326
- _id: 2,
327
- text: 'This is a quick reply. Do you love Gifted Chat? (checkbox)',
328
- createdAt: new Date(),
329
- quickReplies: {
330
- type: 'checkbox', // or 'radio',
331
- values: [
332
- {
333
- title: 'Yes',
334
- value: 'yes',
335
- },
336
- {
337
- title: 'Yes, let me show you with a picture!',
338
- value: 'yes_picture',
339
- },
340
- {
341
- title: 'Nope. What?',
342
- value: 'no',
343
- },
344
- ],
345
- },
346
- user: {
347
- _id: 2,
348
- name: 'React Native',
349
- },
350
- }
351
- ```
239
+ - **`onPressActionButton`** _(Function)_ - Callback when the Action button is pressed (if set, the default `actionSheet` will not be used)
240
+ - **`actionSheet`** _(Function)_ - Custom action sheet interface for showing action options
241
+ - **`actions`** _(Array)_ - Custom action options for the input toolbar action button; array of objects with `title` (string) and `action` (function) properties
242
+ - **`actionSheetOptionTintColor`** _(String)_ - Tint color for action sheet options
352
243
 
353
- ## Props
244
+ ### Messages & Message Container
354
245
 
355
- - **`messageContainerRef`** _(FlatList ref)_ - Ref to the flatlist
356
- - **`textInputRef`** _(TextInput ref)_ - Ref to the text input
357
- - **`messages`** _(Array)_ - Messages to display
358
246
  - **`messagesContainerStyle`** _(Object)_ - Custom style for the messages container
359
- - **`isTyping`** _(Bool)_ - Typing Indicator state; default `false`. If you use`renderFooter` it will override this.
360
- - **`keyboardBottomOffset`** _(Integer)_ - Distance between the bottom of the screen and bottom of the `GiftedChat` component. Useful when you have a tab bar or navigation bar; default is `0`. Needed for correct keyboard avoiding behavior. Without it you might see gap between the keyboard and the input toolbar if you have a tab bar, navigation bar, or safe area.
361
- - **`isKeyboardInternallyHandled`** _(Bool)_ - Determine whether to handle keyboard awareness inside the plugin. If you have your own keyboard handling outside the plugin set this to false; default is `true`
362
- - **`text`** _(String)_ - Input text; default is `undefined`, but if specified, it will override GiftedChat's internal state (e.g. for redux; [see notes below](#notes-for-redux))
363
- - **`initialText`** _(String)_ - Initial text to display in the input field
364
- - **`onInputTextChanged`** _(Function)_ - Callback when the input text changes
365
- - **`messageIdGenerator`** _(Function)_ - Generate an id for new messages. Defaults to UUID v4, generated by [uuid](https://github.com/kelektiv/node-uuid)
366
- - **`user`** _(Object)_ - User sending the messages: `{ _id, name, avatar }`
367
- - **`onSend`** _(Function)_ - Callback when sending a message
368
- - **`alwaysShowSend`** _(Bool)_ - Always show send button in input text composer; default `false`, show only when text input is not empty
369
- - **`locale`** _(String)_ - Locale to localize the dates. You need first to import the locale you need (ie. `require('dayjs/locale/de')` or `import 'dayjs/locale/fr'`)
370
- - **`timeFormat`** _(String)_ - Format to use for rendering times; default is `'LT'` (see [Day.js Format](https://day.js.org/docs/en/display/format))
371
- - **`dateFormat`** _(String)_ - Format to use for rendering dates; default is `'D MMMM'` (see [Day.js Format](https://day.js.org/docs/en/display/format))
372
- - **`dateFormatCalendar`** _(Object)_ - Format to use for rendering relative times; default is `{ sameDay: '[Today]' }` (see [Day.js Calendar](https://day.js.org/docs/en/plugin/calendar))
373
- - **`loadEarlierMessagesProps`** _(Object)_ - Props to pass to the LoadEarlierMessages component. The button is only visible when `isAvailable` is `true`. Supports the following props:
374
- - `isAvailable` - Controls button visibility (default: false)
375
- - `onPress` - Callback when button is pressed
376
- - `isLoading` - Display loading indicator (default: false)
377
- - `isInfiniteScrollEnabled` - Enable infinite scroll up when reaching the top of messages container, automatically calls `onPress` (not yet supported for web)
378
- - `label` - Override the default "Load earlier messages" text
379
- - `containerStyle` - Custom style for the button container
380
- - `wrapperStyle` - Custom style for the button wrapper
381
- - `textStyle` - Custom style for the button text
382
- - `activityIndicatorStyle` - Custom style for the loading indicator
383
- - `activityIndicatorColor` - Color of the loading indicator (default: 'white')
384
- - `activityIndicatorSize` - Size of the loading indicator (default: 'small')
247
+ - **`renderMessage`** _(Component | Function)_ - Custom message container
385
248
  - **`renderLoading`** _(Component | Function)_ - Render a loading view when initializing
386
- - **`renderLoadEarlier`** _(Component | Function)_ - Custom "Load earlier messages" button
387
- - **`renderAvatar`** _(Component | Function)_ - Custom message avatar; set to `null` to not render any avatar for the message
388
- - **`showUserAvatar`** _(Bool)_ - Whether to render an avatar for the current user; default is `false`, only show avatars for other users
389
- - **`showAvatarForEveryMessage`** _(Bool)_ - When false, avatars will only be displayed when a consecutive message is from the same user on the same day; default is `false`
390
- - **`onPressAvatar`** _(Function(`user`))_ - Callback when a message avatar is tapped
391
- - **`onLongPressAvatar`** _(Function(`user`))_ - Callback when a message avatar is long-pressed
392
- - **`renderAvatarOnTop`** _(Bool)_ - Render the message avatar at the top of consecutive messages, rather than the bottom; default is `false`
249
+ - **`renderChatEmpty`** _(Component | Function)_ - Custom component to render in the ListView when messages are empty
250
+ - **`renderChatFooter`** _(Component | Function)_ - Custom component to render below the MessageContainer (separate from the ListView)
251
+ - **`listProps`** _(Object)_ - Extra props to be passed to the messages [`<FlatList>`](https://reactnative.dev/docs/flatlist.html); some props can't be overridden, see the code in `MessageContainer.render()` for details
252
+
253
+ ### Message Bubbles & Content
254
+
393
255
  - **`renderBubble`** _(Component | Function)_ - Custom message bubble
394
- - **`renderTicks`** _(Component | Function(`message`))_ - Custom ticks indicator to display message status
395
- - **`renderSystemMessage`** _(Component | Function)_ - Custom system message
396
- - **`onPressMessage`** _(Function(`context`, `message`))_ - Callback when a message bubble is pressed
397
- - **`onLongPressMessage`** _(Function(`context`, `message`))_ - Callback when a message bubble is long-pressed (see [example using `showActionSheetWithOptions()`](https://github.com/FaridSafi/react-native-gifted-chat/blob/master@%7B2017-09-25%7D/src/Bubble.js#L96-L119))
398
- - **`inverted`** _(Bool)_ - Reverses display order of `messages`; default is `true`
399
- - **`renderUsernameOnMessage`** _(Bool)_ - Indicate whether to show the user's username inside the message bubble; default is `false`
400
- - **`renderUsername`** _(Component | Function)_ - Custom Username container
401
- - **`renderMessage`** _(Component | Function)_ - Custom message container
402
256
  - **`renderMessageText`** _(Component | Function)_ - Custom message text
403
257
  - **`renderMessageImage`** _(Component | Function)_ - Custom message image
404
258
  - **`renderMessageVideo`** _(Component | Function)_ - Custom message video
405
259
  - **`renderMessageAudio`** _(Component | Function)_ - Custom message audio
260
+ - **`renderCustomView`** _(Component | Function)_ - Custom view inside the bubble
261
+ - **`isCustomViewBottom`** _(Bool)_ - Determine whether renderCustomView is displayed before or after the text, image and video views; default is `false`
262
+ - **`renderTicks`** _(Component | Function(`message`))_ - Custom ticks indicator to display message status
263
+ - **`onPressMessage`** _(Function(`context`, `message`))_ - Callback when a message bubble is pressed
264
+ - **`onLongPressMessage`** _(Function(`context`, `message`))_ - Callback when a message bubble is long-pressed; you can use this to show action sheets (e.g., copy, delete, reply)
406
265
  - **`imageProps`** _(Object)_ - Extra props to be passed to the [`<Image>`](https://reactnative.dev/docs/image.html) component created by the default `renderMessageImage`
407
266
  - **`imageStyle`** _(Object)_ - Custom style for message images
408
267
  - **`videoProps`** _(Object)_ - Extra props to be passed to the video component created by the required `renderMessageVideo`
409
- - **`isCustomViewBottom`** _(Bool)_ - Determine whether renderCustomView is displayed before or after the text, image and video views; default is `false`
410
- - **`renderCustomView`** _(Component | Function)_ - Custom view inside the bubble
411
- - **`renderDay`** _(Component | Function)_ - Custom day above a message
412
- - **`renderTime`** _(Component | Function)_ - Custom time inside a message
413
- - **`timeTextStyle`** _(Object)_ - Custom text style for time inside messages (supports left/right styles)
414
- - **`renderFooter`** _(Component | Function)_ - Custom footer component on the ListView, e.g. `'User is typing...'`; see [App.tsx](/example/App.tsx) for an example. Overrides default typing indicator that triggers when `isTyping` is true.
415
- - **`renderTypingIndicator`** _(Component | Function)_ - Custom typing indicator component
416
- - **`renderChatEmpty`** _(Component | Function)_ - Custom component to render in the ListView when messages are empty
417
- - **`renderChatFooter`** _(Component | Function)_ - Custom component to render below the MessageContainer (separate from the ListView)
418
- - **`renderInputToolbar`** _(Component | Function)_ - Custom message composer container
419
- - **`renderComposer`** _(Component | Function)_ - Custom text input message composer
420
- - **`renderActions`** _(Component | Function)_ - Custom action button on the left of the message composer
421
- - **`renderSend`** _(Component | Function)_ - Custom send button; you can pass children to the original `Send` component quite easily, for example, to use a custom icon ([example](https://github.com/FaridSafi/react-native-gifted-chat/pull/487))
422
- - **`renderAccessory`** _(Component | Function)_ - Custom second line of actions below the message composer
423
- - **`onPressActionButton`** _(Function)_ - Callback when the Action button is pressed (if set, the default `actionSheet` will not be used)
424
- - **`actionSheet`** _(Function)_ - Custom action sheet interface for showing action options
425
- - **`actions`** _(Array)_ - Custom action options for the input toolbar action button; array of objects with `title` (string) and `action` (function) properties
426
- - **`actionSheetOptionTintColor`** _(String)_ - Tint color for action sheet options
427
- - **`focusOnInputWhenOpeningKeyboard`** _(Bool)_ - Focus on <TextInput> automatically when opening the keyboard; default `true`
428
- - **`minInputToolbarHeight`** _(Integer)_ - Minimum height of the input toolbar; default is `44`
429
- - **`listProps`** _(Object)_ - Extra props to be passed to the messages [`<FlatList>`](https://reactnative.dev/docs/flatlist.html); some props can't be overridden, see the code in `MessageContainer.render()` for details
430
- - **`textInputProps`** _(Object)_ - props to be passed to the [`<TextInput>`](https://reactnative.dev/docs/textinput.html).
431
268
  - **`messageTextProps`** _(Object)_ - Extra props to be passed to the MessageText component. Useful for customizing link parsing behavior, text styles, and matchers. Supports all [react-native-autolink](https://github.com/joshswan/react-native-autolink) props including:
432
269
  - `matchers` - Custom matchers for linking message content (like URLs, phone numbers, hashtags, mentions)
433
270
  - `linkStyle` - Custom style for links
@@ -437,63 +274,121 @@ interface QuickReplies {
437
274
 
438
275
  Example:
439
276
 
440
- ```js
277
+ ```tsx
441
278
  <GiftedChat
442
279
  messageTextProps={{
280
+ phone: false, // Disable default phone number linking
443
281
  matchers: [
444
282
  {
445
- pattern: /#(\w+)/g,
446
- style: { color: '#0084ff', fontWeight: 'bold' },
447
- onPress: (match) => console.log('Hashtag:', match.getAnchorText()),
448
- },
449
- {
450
- pattern: /(?<![\.\w])@(?!__ELEMENT-)([\w-]+)/g,
451
- style: { color: '#0084ff', fontWeight: 'bold' },
452
- onPress: (match) => console.log('Mention:', match.getAnchorText()),
283
+ type: 'phone',
284
+ pattern: /\+?[1-9][0-9\-\(\) ]{7,}[0-9]/g,
285
+ getLinkUrl: (replacerArgs: ReplacerArgs): string => {
286
+ return replacerArgs[0].replace(/[\-\(\) ]/g, '')
287
+ },
288
+ getLinkText: (replacerArgs: ReplacerArgs): string => {
289
+ return replacerArgs[0]
290
+ },
291
+ style: styles.linkStyle,
292
+ onPress: (match: CustomMatch) => {
293
+ const url = match.getAnchorHref()
294
+
295
+ const options: {
296
+ title: string
297
+ action?: () => void
298
+ }[] = [
299
+ { title: 'Copy', action: () => setStringAsync(url) },
300
+ { title: 'Call', action: () => Linking.openURL(`tel:${url}`) },
301
+ { title: 'Send SMS', action: () => Linking.openURL(`sms:${url}`) },
302
+ { title: 'Cancel' },
303
+ ]
304
+
305
+ showActionSheetWithOptions({
306
+ options: options.map(o => o.title),
307
+ cancelButtonIndex: options.length - 1,
308
+ }, (buttonIndex?: number) => {
309
+ if (buttonIndex === undefined)
310
+ return
311
+
312
+ const option = options[buttonIndex]
313
+ option.action?.()
314
+ })
315
+ },
453
316
  },
454
317
  ],
455
318
  linkStyle: { left: { color: 'blue' }, right: { color: 'lightblue' } },
456
- phone: false,
457
319
  }}
458
320
  />
459
321
  ```
460
322
 
461
- - **`matchers`** _(Array)_ - **Deprecated:** Use `messageTextProps.matchers` instead. Custom matchers for [react-native-autolink](https://github.com/joshswan/react-native-autolink) used to linking message content (like URLs and phone numbers).
323
+ See full example in [LinksExample](example/components/chat-examples/LinksExample.tsx)
462
324
 
463
- - **`extraData`** _(Object)_ - Extra props for re-rendering FlatList on demand. This will be useful for rendering footer etc.
464
- - **`minComposerHeight`** _(Object)_ - Custom min-height of the composer.
465
- - **`maxComposerHeight`** _(Object)_ - Custom max height of the composer.
325
+ ### Avatars
466
326
 
467
- * **`isScrollToBottomEnabled`** _(Bool)_ - Enables the scroll to bottom Component (Default is false)
468
- * **`scrollToBottomComponent`** _(Function)_ - Custom Scroll To Bottom Component container
469
- * **`scrollToBottomOffset`** _(Integer)_ - Custom Height Offset upon which to begin showing Scroll To Bottom Component (Default is 200)
470
- * **`scrollToBottomStyle`** _(Object)_ - Custom style for Bottom Component container
471
- * **`alignTop`** _(Boolean)_ Controls whether or not the message bubbles appear at the top of the chat (Default is false - bubbles align to bottom)
472
- * **`onQuickReply`** _(Function)_ - Callback when sending a quick reply (to backend server)
473
- * **`renderQuickReplies`** _(Function)_ - Custom all quick reply view
474
- * **`quickReplyStyle`** _(StyleProp<ViewStyle>)_ - Custom quick reply view style
475
- * **`quickReplyTextStyle`** _(StyleProp<TextStyle>)_ - Custom text style for quick reply buttons
476
- * **`quickReplyContainerStyle`** _(StyleProp<ViewStyle>)_ - Custom container style for quick replies
477
- * **`renderQuickReplySend`** _(Function)_ - Custom quick reply **send** view
478
- * **`shouldUpdateMessage`** _(Function)_ - Lets the message component know when to update outside of normal cases.
479
- * **`typingIndicatorStyle`** _(StyleProp<ViewStyle>)_ - Custom style for the TypingIndicator component.
480
- * **`handleOnScroll`** _(Function)_ - Custom scroll event handler for the message list
481
-
482
- ## Notes for [Redux](https://github.com/reactjs/redux)
483
-
484
- The `messages` prop should work out-of-the-box with Redux. In most cases, this is all you need.
485
-
486
- If you decide to specify a `text` prop, GiftedChat will no longer manage its own internal `text` state and will defer entirely to your prop.
487
- This is great for using a tool like Redux, but there's one extra step you'll need to take:
488
- simply implement `onInputTextChanged` to receive typing events and reset events (e.g. to clear the text `onSend`):
327
+ - **`renderAvatar`** _(Component | Function)_ - Custom message avatar; set to `null` to not render any avatar for the message
328
+ - **`isUserAvatarVisible`** _(Bool)_ - Whether to render an avatar for the current user; default is `false`, only show avatars for other users
329
+ - **`isAvatarVisibleForEveryMessage`** _(Bool)_ - When false, avatars will only be displayed when a consecutive message is from the same user on the same day; default is `false`
330
+ - **`onPressAvatar`** _(Function(`user`))_ - Callback when a message avatar is tapped
331
+ - **`onLongPressAvatar`** _(Function(`user`))_ - Callback when a message avatar is long-pressed
332
+ - **`isAvatarOnTop`** _(Bool)_ - Render the message avatar at the top of consecutive messages, rather than the bottom; default is `false`
489
333
 
490
- ```js
491
- <GiftedChat
492
- text={customText}
493
- onInputTextChanged={text => this.setCustomText(text)}
494
- /* ... */
495
- />
496
- ```
334
+ ### Username
335
+
336
+ - **`isUsernameVisible`** _(Bool)_ - Indicate whether to show the user's username inside the message bubble; default is `false`
337
+ - **`renderUsername`** _(Component | Function)_ - Custom Username container
338
+
339
+ ### Date & Time
340
+
341
+ - **`timeFormat`** _(String)_ - Format to use for rendering times; default is `'LT'` (see [Day.js Format](https://day.js.org/docs/en/display/format))
342
+ - **`dateFormat`** _(String)_ - Format to use for rendering dates; default is `'D MMMM'` (see [Day.js Format](https://day.js.org/docs/en/display/format))
343
+ - **`dateFormatCalendar`** _(Object)_ - Format to use for rendering relative times; default is `{ sameDay: '[Today]' }` (see [Day.js Calendar](https://day.js.org/docs/en/plugin/calendar))
344
+ - **`renderDay`** _(Component | Function)_ - Custom day above a message
345
+ - **`renderTime`** _(Component | Function)_ - Custom time inside a message
346
+ - **`timeTextStyle`** _(Object)_ - Custom text style for time inside messages (supports left/right styles)
347
+
348
+ ### System Messages
349
+
350
+ - **`renderSystemMessage`** _(Component | Function)_ - Custom system message
351
+
352
+ ### Load Earlier Messages
353
+
354
+ - **`loadEarlierMessagesProps`** _(Object)_ - Props to pass to the LoadEarlierMessages component. The button is only visible when `isAvailable` is `true`. Supports the following props:
355
+ - `isAvailable` - Controls button visibility (default: false)
356
+ - `onPress` - Callback when button is pressed
357
+ - `isLoading` - Display loading indicator (default: false)
358
+ - `isInfiniteScrollEnabled` - Enable infinite scroll up when reaching the top of messages container, automatically calls `onPress` (not yet supported for web)
359
+ - `label` - Override the default "Load earlier messages" text
360
+ - `containerStyle` - Custom style for the button container
361
+ - `wrapperStyle` - Custom style for the button wrapper
362
+ - `textStyle` - Custom style for the button text
363
+ - `activityIndicatorStyle` - Custom style for the loading indicator
364
+ - `activityIndicatorColor` - Color of the loading indicator (default: 'white')
365
+ - `activityIndicatorSize` - Size of the loading indicator (default: 'small')
366
+ - **`renderLoadEarlier`** _(Component | Function)_ - Custom "Load earlier messages" button
367
+
368
+ ### Typing Indicator
369
+
370
+ - **`isTyping`** _(Bool)_ - Typing Indicator state; default `false`. If you use`renderFooter` it will override this.
371
+ - **`renderTypingIndicator`** _(Component | Function)_ - Custom typing indicator component
372
+ - **`typingIndicatorStyle`** _(StyleProp<ViewStyle>)_ - Custom style for the TypingIndicator component.
373
+ - **`renderFooter`** _(Component | Function)_ - Custom footer component on the ListView, e.g. `'User is typing...'`; see [CustomizedFeaturesExample.tsx](example/components/chat-examples/CustomizedFeaturesExample.tsx) for an example. Overrides default typing indicator that triggers when `isTyping` is true.
374
+
375
+ ### Quick Replies
376
+
377
+ See [Quick Replies example in messages.ts](example/example-expo/data/messages.ts)
378
+
379
+ - **`onQuickReply`** _(Function)_ - Callback when sending a quick reply (to backend server)
380
+ - **`renderQuickReplies`** _(Function)_ - Custom all quick reply view
381
+ - **`quickReplyStyle`** _(StyleProp<ViewStyle>)_ - Custom quick reply view style
382
+ - **`quickReplyTextStyle`** _(StyleProp<TextStyle>)_ - Custom text style for quick reply buttons
383
+ - **`quickReplyContainerStyle`** _(StyleProp<ViewStyle>)_ - Custom container style for quick replies
384
+ - **`renderQuickReplySend`** _(Function)_ - Custom quick reply **send** view
385
+
386
+ ### Scroll to Bottom
387
+
388
+ - **`isScrollToBottomEnabled`** _(Bool)_ - Enables the scroll to bottom Component (Default is false)
389
+ - **`scrollToBottomComponent`** _(Function)_ - Custom Scroll To Bottom Component container
390
+ - **`scrollToBottomOffset`** _(Integer)_ - Custom Height Offset upon which to begin showing Scroll To Bottom Component (Default is 200)
391
+ - **`scrollToBottomStyle`** _(Object)_ - Custom style for Bottom Component container
497
392
 
498
393
  ## Notes for Android
499
394
 
@@ -578,6 +473,26 @@ module.exports = function override(config, env) {
578
473
 
579
474
  > Another example with **Gatsby** : [xcarpentier/clean-archi-boilerplate](https://github.com/xcarpentier/clean-archi-boilerplate/tree/develop/apps/web)
580
475
 
476
+ ## Testing
477
+ `TEST_ID` is exported as constants that can be used in your testing library of choice
478
+
479
+ Gifted Chat uses `onLayout` to determine the height of the chat container. To trigger `onLayout` during your tests, you can run the following bits of code.
480
+
481
+ ```typescript
482
+ const WIDTH = 200; // or any number
483
+ const HEIGHT = 2000; // or any number
484
+
485
+ const loadingWrapper = getByTestId(TEST_ID.LOADING_WRAPPER)
486
+ fireEvent(loadingWrapper, 'layout', {
487
+ nativeEvent: {
488
+ layout: {
489
+ width: WIDTH,
490
+ height: HEIGHT,
491
+ },
492
+ },
493
+ })
494
+ ```
495
+
581
496
  ## Questions
582
497
 
583
498
  - [How can I set Bubble color for each user?](https://github.com/FaridSafi/react-native-gifted-chat/issues/672)
@@ -590,23 +505,23 @@ module.exports = function override(config, env) {
590
505
  - [How to use renderLoading?](https://github.com/FaridSafi/react-native-gifted-chat/issues/298)
591
506
  - [Can I use MySql to save the message?](https://github.com/FaridSafi/react-native-gifted-chat/issues/738)
592
507
 
593
- ## License
508
+ ## You have a question?
509
+
510
+ 1. Please check this readme and you might find a response
511
+ 1. Please ask on StackOverflow first: https://stackoverflow.com/questions/tagged/react-native-gifted-chat
512
+ 1. Find responses in existing issues
513
+ 1. Try to keep issues for issues
594
514
 
595
- - [MIT](LICENSE)
515
+ ## Hire an expert
596
516
 
597
- ## Author
517
+ Looking for a React Native freelance expert with more than 14 years of experience? Contact Xavier from his [website](https://xaviercarpentier.com)
598
518
 
599
- Feel free to ask me questions on Twitter [@FaridSafi](https://www.twitter.com/FaridSafi)! or [@xcapetir](https://www.twitter.com/xcapetir)!
519
+ ## Author
600
520
 
601
- ## Contributors
521
+ Feel free to ask me questions on Twitter [@FaridSafi](https://www.twitter.com/FaridSafi) or [@xcapetir](https://www.twitter.com/xcapetir)
602
522
 
603
- - Kevin Cooper [cooperka](https://github.com/cooperka)
604
- - Kfir Golan [kfiroo](https://github.com/kfiroo)
605
- - Bruno Cascio [brunocascio](https://github.com/brunocascio)
606
- - Xavier Carpentier [xcarpentier](https://github.com/xcarpentier)
607
- - Kesha Antonov [kesha-antonov](https://github.com/kesha-antonov)
608
- - [more](https://github.com/FaridSafi/react-native-gifted-chat/graphs/contributors)
523
+ ## Maintainer
609
524
 
610
- ## Hire an expert!
525
+ Have any questions? Reach out to [Kesha Antonov](https://github.com/kesha-antonov)
611
526
 
612
- Looking for a ReactNative freelance expert with more than 14 years of experience? Contact Xavier from his [website](https://xaviercarpentier.com)!
527
+ Please note that I'm maintaining this project in my free time for free. If you find any issues, feel free to open them, and I'll do my best to address them as time permits.