react-native-gifted-chat 2.8.2-alpha.0 → 2.8.2-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 (191) hide show
  1. package/README.md +8 -12
  2. package/package.json +20 -21
  3. package/src/Bubble/index.tsx +11 -10
  4. package/src/Bubble/types.ts +2 -2
  5. package/src/Composer.tsx +19 -26
  6. package/src/Constant.ts +0 -1
  7. package/src/GiftedAvatar.tsx +29 -36
  8. package/src/GiftedChat/index.tsx +11 -62
  9. package/src/GiftedChat/types.ts +5 -52
  10. package/src/InputToolbar.tsx +25 -8
  11. package/src/LoadEarlier.tsx +19 -17
  12. package/src/MessageAudio.tsx +19 -7
  13. package/src/MessageContainer/components/DayAnimated/index.tsx +14 -9
  14. package/src/MessageContainer/components/Item/index.tsx +7 -1
  15. package/src/MessageContainer/index.tsx +47 -28
  16. package/src/MessageContainer/types.ts +31 -6
  17. package/src/MessageImage.tsx +18 -6
  18. package/src/MessageText.tsx +18 -23
  19. package/src/MessageVideo.tsx +19 -7
  20. package/src/QuickReplies.tsx +17 -10
  21. package/src/Send.tsx +7 -1
  22. package/src/SystemMessage.tsx +9 -2
  23. package/src/Time.tsx +9 -2
  24. package/src/TypingIndicator/index.tsx +2 -1
  25. package/src/TypingIndicator/types.ts +3 -0
  26. package/src/__tests__/Actions.test.tsx +3 -4
  27. package/src/__tests__/Avatar.test.tsx +5 -6
  28. package/src/__tests__/Bubble.test.tsx +14 -19
  29. package/src/__tests__/Composer.test.tsx +3 -4
  30. package/src/__tests__/Day.test.tsx +5 -8
  31. package/src/__tests__/DayAnimated.test.tsx +11 -13
  32. package/src/__tests__/GiftedAvatar.test.tsx +3 -8
  33. package/src/__tests__/GiftedChat.test.tsx +32 -41
  34. package/src/__tests__/InputToolbar.test.tsx +3 -4
  35. package/src/__tests__/LoadEarlier.test.tsx +3 -4
  36. package/src/__tests__/Message.test.tsx +51 -58
  37. package/src/__tests__/MessageContainer.test.tsx +39 -5
  38. package/src/__tests__/MessageImage.test.tsx +12 -15
  39. package/src/__tests__/MessageText.test.tsx +7 -4
  40. package/src/__tests__/Send.test.tsx +7 -8
  41. package/src/__tests__/SystemMessage.test.tsx +12 -15
  42. package/src/__tests__/Time.test.tsx +5 -8
  43. package/src/__tests__/__snapshots__/Bubble.test.tsx.snap +48 -50
  44. package/src/__tests__/__snapshots__/Composer.test.tsx.snap +1 -2
  45. package/src/__tests__/__snapshots__/Constant.test.tsx.snap +0 -1
  46. package/src/__tests__/__snapshots__/InputToolbar.test.tsx.snap +2 -2
  47. package/src/__tests__/__snapshots__/Message.test.tsx.snap +146 -150
  48. package/src/__tests__/__snapshots__/MessageImage.test.tsx.snap +12 -10
  49. package/src/__tests__/__snapshots__/MessageText.test.tsx.snap +12 -8
  50. package/src/__tests__/__snapshots__/Send.test.tsx.snap +2 -0
  51. package/src/reanimatedCompat.ts +27 -0
  52. package/src/types.ts +4 -0
  53. package/lib/Actions.d.ts +0 -14
  54. package/lib/Actions.js +0 -57
  55. package/lib/Actions.js.map +0 -1
  56. package/lib/Avatar.d.ts +0 -18
  57. package/lib/Avatar.js +0 -93
  58. package/lib/Avatar.js.map +0 -1
  59. package/lib/Bubble/index.d.ts +0 -6
  60. package/lib/Bubble/index.js +0 -242
  61. package/lib/Bubble/index.js.map +0 -1
  62. package/lib/Bubble/styles.d.ts +0 -69
  63. package/lib/Bubble/styles.js +0 -72
  64. package/lib/Bubble/styles.js.map +0 -1
  65. package/lib/Bubble/types.d.ts +0 -47
  66. package/lib/Bubble/types.js +0 -2
  67. package/lib/Bubble/types.js.map +0 -1
  68. package/lib/Color.d.ts +0 -18
  69. package/lib/Color.js +0 -18
  70. package/lib/Color.js.map +0 -1
  71. package/lib/Composer.d.ts +0 -20
  72. package/lib/Composer.js +0 -60
  73. package/lib/Composer.js.map +0 -1
  74. package/lib/Constant.d.ts +0 -10
  75. package/lib/Constant.js +0 -17
  76. package/lib/Constant.js.map +0 -1
  77. package/lib/Day/index.d.ts +0 -4
  78. package/lib/Day/index.js +0 -39
  79. package/lib/Day/index.js.map +0 -1
  80. package/lib/Day/styles.d.ts +0 -20
  81. package/lib/Day/styles.js +0 -22
  82. package/lib/Day/styles.js.map +0 -1
  83. package/lib/Day/types.d.ts +0 -9
  84. package/lib/Day/types.js +0 -2
  85. package/lib/Day/types.js.map +0 -1
  86. package/lib/GiftedAvatar.d.ts +0 -11
  87. package/lib/GiftedAvatar.js +0 -104
  88. package/lib/GiftedAvatar.js.map +0 -1
  89. package/lib/GiftedChat/index.d.ts +0 -26
  90. package/lib/GiftedChat/index.js +0 -317
  91. package/lib/GiftedChat/index.js.map +0 -1
  92. package/lib/GiftedChat/styles.d.ts +0 -6
  93. package/lib/GiftedChat/styles.js +0 -7
  94. package/lib/GiftedChat/styles.js.map +0 -1
  95. package/lib/GiftedChat/types.d.ts +0 -112
  96. package/lib/GiftedChat/types.js +0 -2
  97. package/lib/GiftedChat/types.js.map +0 -1
  98. package/lib/GiftedChatContext.d.ts +0 -9
  99. package/lib/GiftedChatContext.js +0 -9
  100. package/lib/GiftedChatContext.js.map +0 -1
  101. package/lib/InputToolbar.d.ts +0 -23
  102. package/lib/InputToolbar.js +0 -56
  103. package/lib/InputToolbar.js.map +0 -1
  104. package/lib/LoadEarlier.d.ts +0 -14
  105. package/lib/LoadEarlier.js +0 -45
  106. package/lib/LoadEarlier.js.map +0 -1
  107. package/lib/Message/index.d.ts +0 -6
  108. package/lib/Message/index.js +0 -80
  109. package/lib/Message/index.js.map +0 -1
  110. package/lib/Message/styles.d.ts +0 -21
  111. package/lib/Message/styles.js +0 -22
  112. package/lib/Message/styles.js.map +0 -1
  113. package/lib/Message/types.d.ts +0 -22
  114. package/lib/Message/types.js +0 -2
  115. package/lib/Message/types.js.map +0 -1
  116. package/lib/MessageAudio.d.ts +0 -2
  117. package/lib/MessageAudio.js +0 -14
  118. package/lib/MessageAudio.js.map +0 -1
  119. package/lib/MessageContainer/components/DayAnimated/index.d.ts +0 -5
  120. package/lib/MessageContainer/components/DayAnimated/index.js +0 -85
  121. package/lib/MessageContainer/components/DayAnimated/index.js.map +0 -1
  122. package/lib/MessageContainer/components/DayAnimated/styles.d.ts +0 -11
  123. package/lib/MessageContainer/components/DayAnimated/styles.js +0 -12
  124. package/lib/MessageContainer/components/DayAnimated/styles.js.map +0 -1
  125. package/lib/MessageContainer/components/DayAnimated/types.d.ts +0 -17
  126. package/lib/MessageContainer/components/DayAnimated/types.js +0 -2
  127. package/lib/MessageContainer/components/DayAnimated/types.js.map +0 -1
  128. package/lib/MessageContainer/components/Item/index.d.ts +0 -23
  129. package/lib/MessageContainer/components/Item/index.js +0 -88
  130. package/lib/MessageContainer/components/Item/index.js.map +0 -1
  131. package/lib/MessageContainer/components/Item/types.d.ts +0 -17
  132. package/lib/MessageContainer/components/Item/types.js +0 -2
  133. package/lib/MessageContainer/components/Item/types.js.map +0 -1
  134. package/lib/MessageContainer/index.d.ts +0 -6
  135. package/lib/MessageContainer/index.js +0 -235
  136. package/lib/MessageContainer/index.js.map +0 -1
  137. package/lib/MessageContainer/styles.d.ts +0 -35
  138. package/lib/MessageContainer/styles.js +0 -32
  139. package/lib/MessageContainer/styles.js.map +0 -1
  140. package/lib/MessageContainer/types.d.ts +0 -51
  141. package/lib/MessageContainer/types.js +0 -2
  142. package/lib/MessageContainer/types.js.map +0 -1
  143. package/lib/MessageImage.d.ts +0 -13
  144. package/lib/MessageImage.js +0 -30
  145. package/lib/MessageImage.js.map +0 -1
  146. package/lib/MessageText.d.ts +0 -19
  147. package/lib/MessageText.js +0 -69
  148. package/lib/MessageText.js.map +0 -1
  149. package/lib/MessageVideo.d.ts +0 -2
  150. package/lib/MessageVideo.js +0 -14
  151. package/lib/MessageVideo.js.map +0 -1
  152. package/lib/QuickReplies.d.ts +0 -15
  153. package/lib/QuickReplies.js +0 -101
  154. package/lib/QuickReplies.js.map +0 -1
  155. package/lib/Send.d.ts +0 -15
  156. package/lib/Send.js +0 -34
  157. package/lib/Send.js.map +0 -1
  158. package/lib/SystemMessage.d.ts +0 -11
  159. package/lib/SystemMessage.js +0 -27
  160. package/lib/SystemMessage.js.map +0 -1
  161. package/lib/Time.d.ts +0 -11
  162. package/lib/Time.js +0 -56
  163. package/lib/Time.js.map +0 -1
  164. package/lib/TypingIndicator/index.d.ts +0 -5
  165. package/lib/TypingIndicator/index.js +0 -94
  166. package/lib/TypingIndicator/index.js.map +0 -1
  167. package/lib/TypingIndicator/styles.d.ts +0 -20
  168. package/lib/TypingIndicator/styles.js +0 -22
  169. package/lib/TypingIndicator/styles.js.map +0 -1
  170. package/lib/TypingIndicator/types.d.ts +0 -3
  171. package/lib/TypingIndicator/types.js +0 -2
  172. package/lib/TypingIndicator/types.js.map +0 -1
  173. package/lib/hooks/useUpdateLayoutEffect.d.ts +0 -8
  174. package/lib/hooks/useUpdateLayoutEffect.js +0 -17
  175. package/lib/hooks/useUpdateLayoutEffect.js.map +0 -1
  176. package/lib/index.d.ts +0 -4
  177. package/lib/index.js +0 -5
  178. package/lib/index.js.map +0 -1
  179. package/lib/logging.d.ts +0 -2
  180. package/lib/logging.js +0 -5
  181. package/lib/logging.js.map +0 -1
  182. package/lib/styles.d.ts +0 -10
  183. package/lib/styles.js +0 -11
  184. package/lib/styles.js.map +0 -1
  185. package/lib/types.d.ts +0 -67
  186. package/lib/types.js +0 -2
  187. package/lib/types.js.map +0 -1
  188. package/lib/utils.d.ts +0 -5
  189. package/lib/utils.js +0 -83
  190. package/lib/utils.js.map +0 -1
  191. package/src/__tests__/__snapshots__/MessageContainer.test.tsx.snap +0 -108
package/README.md CHANGED
@@ -357,7 +357,7 @@ interface QuickReplies {
357
357
  - **`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`
358
358
  - **`disableKeyboardController`** _(Bool)_ - Completely disable react-native-keyboard-controller. Useful when using react-native-navigation or other conflicting keyboard libraries; default is `false`
359
359
  - **`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))
360
- - **`placeholder`** _(String)_ - Placeholder when `text` is empty; default is `'Type a message...'`
360
+ - **`onInputTextChanged`** _(Function)_ - Callback when the input text changes
361
361
  - **`messageIdGenerator`** _(Function)_ - Generate an id for new messages. Defaults to UUID v4, generated by [uuid](https://github.com/kelektiv/node-uuid)
362
362
  - **`user`** _(Object)_ - User sending the messages: `{ _id, name, avatar }`
363
363
  - **`onSend`** _(Function)_ - Callback when sending a message
@@ -380,8 +380,8 @@ interface QuickReplies {
380
380
  - **`renderBubble`** _(Function)_ - Custom message bubble
381
381
  - **`renderTicks`** _(Function(`message`))_ - Custom ticks indicator to display message status
382
382
  - **`renderSystemMessage`** _(Function)_ - Custom system message
383
- - **`onPress`** _(Function(`context`, `message`))_ - Callback when a message bubble is pressed
384
- - **`onLongPress`** _(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))
383
+ - **`onPressMessage`** _(Function(`context`, `message`))_ - Callback when a message bubble is pressed
384
+ - **`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))
385
385
  - **`inverted`** _(Bool)_ - Reverses display order of `messages`; default is `true`
386
386
  - **`renderUsernameOnMessage`** _(Bool)_ - Indicate whether to show the user's username inside the message bubble; default is `false`
387
387
  - **`renderUsername`** _(Function)_ - Custom Username container
@@ -389,7 +389,7 @@ interface QuickReplies {
389
389
  - **`renderMessageText`** _(Function)_ - Custom message text
390
390
  - **`renderMessageImage`** _(Function)_ - Custom message image
391
391
  - **`renderMessageVideo`** _(Function)_ - Custom message video
392
- - **`imageProps`** _(Object)_ - Extra props to be passed to the [`<Image>`](https://facebook.github.io/react-native/docs/image.html) component created by the default `renderMessageImage`
392
+ - **`imageProps`** _(Object)_ - Extra props to be passed to the [`<Image>`](https://reactnative.dev/docs/image.html) component created by the default `renderMessageImage`
393
393
  - **`videoProps`** _(Object)_ - Extra props to be passed to the video component created by the required `renderMessageVideo`
394
394
  - **`lightboxProps`** _(Object)_ - Extra props to be passed to the `MessageImage`'s [Lightbox](https://github.com/oblador/react-native-lightbox)
395
395
  - **`isCustomViewBottom`** _(Bool)_ - Determine whether renderCustomView is displayed before or after the text, image and video views; default is `false`
@@ -408,13 +408,8 @@ interface QuickReplies {
408
408
  - **`bottomOffset`** _(Integer)_ - Distance of the chat from the bottom of the screen (e.g. useful if you display a tab bar)
409
409
  - **`focusOnInputWhenOpeningKeyboard`** _(Bool)_ - Focus on <TextInput> automatically when opening the keyboard; default `true`
410
410
  - **`minInputToolbarHeight`** _(Integer)_ - Minimum height of the input toolbar; default is `44`
411
- - **`listViewProps`** _(Object)_ - Extra props to be passed to the messages [`<ListView>`](https://facebook.github.io/react-native/docs/listview.html); some props can't be overridden, see the code in `MessageContainer.render()` for details
412
- - **`textInputProps`** _(Object)_ - Extra props to be passed to the [`<TextInput>`](https://facebook.github.io/react-native/docs/textinput.html)
413
- - **`textInputStyle`** _(Object)_ - Custom style to be passed to the [`<TextInput>`](https://facebook.github.io/react-native/docs/textinput.html)
414
- - **`multiline`** _(Bool)_ - Indicates whether to allow the [`<TextInput>`](https://facebook.github.io/react-native/docs/textinput.html) to be multiple lines or not; default `true`.
415
- - **`keyboardShouldPersistTaps`** _(Enum)_ - Determines whether the keyboard should stay visible after a tap; see [`<ScrollView>`](https://facebook.github.io/react-native/docs/scrollview.html) docs
416
- - **`onInputTextChanged`** _(Function)_ - Callback when the input text changes
417
- - **`maxInputLength`** _(Integer)_ - Max message composer TextInput length
411
+ - **`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
412
+ - **`textInputProps`** _(Object)_ - props to be passed to the [`<TextInput>`](https://reactnative.dev/docs/textinput.html).
418
413
  - **`matchers`** _(Array)_ - Custom matchers for [react-native-autolink](https://github.com/joshswan/react-native-autolink) used to linking message content (like URLs and phone numbers), e.g.:
419
414
 
420
415
  ```js
@@ -441,6 +436,7 @@ interface QuickReplies {
441
436
  * **`renderQuickReplySend`** _(Function)_ - Custom quick reply **send** view
442
437
  * **`shouldUpdateMessage`** _(Function)_ - Lets the message component know when to update outside of normal cases.
443
438
  * **`infiniteScroll`** _(Bool)_ - infinite scroll up when reach the top of messages container, automatically call onLoadEarlier function if exist (not yet supported for the web). You need to add `loadEarlier` prop too.
439
+ * **`typingIndicatorStyle`** _(StyleProp<ViewStyle>)_ - Custom style for the TypingIndicator component.
444
440
 
445
441
  ## Notes for [Redux](https://github.com/reactjs/redux)
446
442
 
@@ -474,7 +470,7 @@ If you are using Create React Native App / Expo, no Android specific installatio
474
470
 
475
471
  - For **Expo**, there are at least 2 solutions to fix it:
476
472
 
477
- - Append [`KeyboardAvoidingView`](https://facebook.github.io/react-native/docs/keyboardavoidingview) after GiftedChat. This should only be done for Android, as `KeyboardAvoidingView` may conflict with the iOS keyboard avoidance already built into GiftedChat, e.g.:
473
+ - Append [`KeyboardAvoidingView`](https://reactnative.dev/docs/keyboardavoidingview) after GiftedChat. This should only be done for Android, as `KeyboardAvoidingView` may conflict with the iOS keyboard avoidance already built into GiftedChat, e.g.:
478
474
 
479
475
  ```
480
476
  <View style={{ flex: 1 }}>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-gifted-chat",
3
- "version": "2.8.2-alpha.0",
3
+ "version": "2.8.2-alpha.1",
4
4
  "description": "The most complete chat UI for React Native",
5
5
  "keywords": [
6
6
  "android",
@@ -23,17 +23,15 @@
23
23
  "license": "MIT",
24
24
  "author": "Farid Safi",
25
25
  "type": "module",
26
- "main": "lib/index.js",
27
- "types": "lib/index.d.ts",
26
+ "main": "src/index.ts",
27
+ "types": "src/index.ts",
28
28
  "files": [
29
- "src",
30
- "lib"
29
+ "src"
31
30
  ],
32
31
  "scripts": {
33
- "build": "rm -rf lib/ && yarn tsc",
34
32
  "lint": "yarn eslint src",
35
33
  "lint:fix": "yarn eslint --cache --fix",
36
- "prepublishOnly": "yarn lint && yarn build",
34
+ "prepublishOnly": "yarn lint && yarn test",
37
35
  "start": "cd example && expo start",
38
36
  "start:web": "cd example && expo start -w --dev",
39
37
  "test": "TZ=Europe/Paris jest --no-watchman",
@@ -46,26 +44,23 @@
46
44
  },
47
45
  "lint-staged": {
48
46
  "src/*.{json,js,jsx,ts,tsx}": [
49
- "yarn lint:fix",
50
- "bash -c 'yarn tsc:write'"
47
+ "yarn lint:fix"
51
48
  ]
52
49
  },
53
50
  "dependencies": {
54
51
  "@expo/react-native-action-sheet": "^4.1.1",
55
52
  "@types/lodash.isequal": "^4.5.8",
56
- "dayjs": "^1.11.18",
53
+ "dayjs": "^1.11.19",
57
54
  "lodash.isequal": "^4.5.0",
58
55
  "react-native-autolink": "^4.2.0",
59
56
  "react-native-communications": "^2.2.1",
60
- "react-native-iphone-x-helper": "^1.3.1",
61
57
  "react-native-lightbox-v2": "^0.9.2"
62
58
  },
63
59
  "devDependencies": {
64
- "@babel/core": "^7.28.4",
60
+ "@babel/core": "^7.28.5",
65
61
  "@babel/plugin-transform-react-jsx": "^7.27.1",
66
62
  "@babel/plugin-transform-unicode-property-regex": "^7.27.1",
67
- "@babel/preset-env": "^7.28.3",
68
- "@stylistic/eslint-plugin": "^3.1.0",
63
+ "@babel/preset-env": "^7.28.5",
69
64
  "@react-native-community/cli": "20.0.0",
70
65
  "@react-native-community/cli-platform-android": "20.0.0",
71
66
  "@react-native-community/cli-platform-ios": "20.0.0",
@@ -73,13 +68,17 @@
73
68
  "@react-native/eslint-config": "0.81.5",
74
69
  "@react-native/metro-config": "0.81.5",
75
70
  "@react-native/typescript-config": "0.81.5",
71
+ "@stylistic/eslint-plugin": "^3.1.0",
72
+ "@testing-library/dom": "^10.4.1",
73
+ "@testing-library/react": "^16.3.0",
74
+ "@testing-library/react-native": "^13.3.3",
76
75
  "@types/jest": "^29.5.13",
77
- "@types/react": "^19.1.0",
78
- "@types/react-test-renderer": "^19.1.0",
79
- "@types/react-dom": "^19.1.9",
76
+ "@types/react": "^19.2.5",
77
+ "@types/react-dom": "^19.2.3",
80
78
  "@types/react-native": "^0.72.8",
81
- "@typescript-eslint/eslint-plugin": "^8.44.1",
82
- "@typescript-eslint/parser": "^8.44.1",
79
+ "@types/react-test-renderer": "^19.1.0",
80
+ "@typescript-eslint/eslint-plugin": "^8.46.4",
81
+ "@typescript-eslint/parser": "^8.46.4",
83
82
  "babel-jest": "^29.7.0",
84
83
  "eslint": "^8.57.0",
85
84
  "eslint-config-standard": "^17.1.0",
@@ -101,13 +100,13 @@
101
100
  "react-native-keyboard-controller": "^1.19.5",
102
101
  "react-native-reanimated": "^3.19.4",
103
102
  "react-test-renderer": "19.1.0",
104
- "typescript": "^5.9.2"
103
+ "typescript": "^5.9.3"
105
104
  },
106
105
  "peerDependencies": {
107
106
  "react": ">=18.0.0",
108
107
  "react-native": "*",
109
108
  "react-native-keyboard-controller": ">=1.0.0",
110
- "react-native-reanimated": ">=3.0.0"
109
+ "react-native-reanimated": ">=3.0.0 || ^4.0.0"
111
110
  },
112
111
  "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
113
112
  "engines": {
@@ -1,7 +1,7 @@
1
1
  import React, { JSX, useCallback } from 'react'
2
2
  import {
3
3
  Text,
4
- TouchableWithoutFeedback,
4
+ Pressable,
5
5
  View,
6
6
  } from 'react-native'
7
7
 
@@ -38,22 +38,22 @@ const Bubble = <TMessage extends IMessage = IMessage>(props: BubbleProps<TMessag
38
38
  containerStyle,
39
39
  wrapperStyle,
40
40
  bottomContainerStyle,
41
- onPress: onPressProp,
42
- onLongPress: onLongPressProp,
41
+ onPressMessage: onPressMessageProp,
42
+ onLongPressMessage: onLongPressMessageProp,
43
43
  } = props
44
44
 
45
45
  const context = useChatContext()
46
46
 
47
47
  const onPress = useCallback(() => {
48
- onPressProp?.(context, currentMessage)
49
- }, [onPressProp, context, currentMessage])
48
+ onPressMessageProp?.(context, currentMessage)
49
+ }, [onPressMessageProp, context, currentMessage])
50
50
 
51
51
  const onLongPress = useCallback(() => {
52
- onLongPressProp?.(context, currentMessage)
52
+ onLongPressMessageProp?.(context, currentMessage)
53
53
  }, [
54
54
  currentMessage,
55
55
  context,
56
- onLongPressProp,
56
+ onLongPressMessageProp,
57
57
  ])
58
58
 
59
59
  const styledBubbleToNext = useCallback(() => {
@@ -151,6 +151,7 @@ const Bubble = <TMessage extends IMessage = IMessage>(props: BubbleProps<TMessag
151
151
 
152
152
  return <MessageText {...messageTextProps} />
153
153
  }
154
+
154
155
  return null
155
156
  }, [props, currentMessage])
156
157
 
@@ -169,6 +170,7 @@ const Bubble = <TMessage extends IMessage = IMessage>(props: BubbleProps<TMessag
169
170
 
170
171
  return <MessageImage {...messageImageProps} />
171
172
  }
173
+
172
174
  return null
173
175
  }, [props, currentMessage])
174
176
 
@@ -349,10 +351,9 @@ const Bubble = <TMessage extends IMessage = IMessage>(props: BubbleProps<TMessag
349
351
  wrapperStyle && wrapperStyle[position],
350
352
  ]}
351
353
  >
352
- <TouchableWithoutFeedback
354
+ <Pressable
353
355
  onPress={onPress}
354
356
  onLongPress={onLongPress}
355
- accessibilityRole='text'
356
357
  {...props.touchableProps}
357
358
  >
358
359
  <View>
@@ -368,7 +369,7 @@ const Bubble = <TMessage extends IMessage = IMessage>(props: BubbleProps<TMessag
368
369
  {renderTicks()}
369
370
  </View>
370
371
  </View>
371
- </TouchableWithoutFeedback>
372
+ </Pressable>
372
373
  </View>
373
374
  {renderQuickReplies()}
374
375
  </View>
@@ -66,8 +66,8 @@ export interface BubbleProps<TMessage extends IMessage> {
66
66
  quickReplyStyle?: StyleProp<ViewStyle>
67
67
  quickReplyTextStyle?: StyleProp<TextStyle>
68
68
  quickReplyContainerStyle?: StyleProp<ViewStyle>
69
- onPress?(context?: unknown, message?: unknown): void
70
- onLongPress?(context?: unknown, message?: unknown): void
69
+ onPressMessage?(context?: unknown, message?: unknown): void
70
+ onLongPressMessage?(context?: unknown, message?: unknown): void
71
71
  onQuickReply?(replies: Reply[]): void
72
72
  renderMessageImage?(
73
73
  props: RenderMessageImageProps<TMessage>,
package/src/Composer.tsx CHANGED
@@ -6,41 +6,30 @@ import {
6
6
  TextInputProps,
7
7
  NativeSyntheticEvent,
8
8
  TextInputContentSizeChangeEventData,
9
+ useColorScheme,
9
10
  } from 'react-native'
10
- import { MIN_COMPOSER_HEIGHT, DEFAULT_PLACEHOLDER } from './Constant'
11
+ import { MIN_COMPOSER_HEIGHT } from './Constant'
11
12
  import Color from './Color'
12
13
  import stylesCommon from './styles'
13
14
 
14
15
  export interface ComposerProps {
15
16
  composerHeight?: number
16
17
  text?: string
17
- placeholder?: string
18
- placeholderTextColor?: string
19
18
  textInputProps?: Partial<TextInputProps>
20
- textInputStyle?: TextInputProps['style']
21
- textInputAutoFocus?: boolean
22
- keyboardAppearance?: TextInputProps['keyboardAppearance']
23
- multiline?: boolean
24
- disableComposer?: boolean
25
19
  onTextChanged?(text: string): void
26
20
  onInputSizeChanged?(layout: { width: number, height: number }): void
27
21
  }
28
22
 
29
23
  export function Composer ({
30
24
  composerHeight = MIN_COMPOSER_HEIGHT,
31
- disableComposer = false,
32
- keyboardAppearance = 'default',
33
- multiline = true,
34
25
  onInputSizeChanged,
35
26
  onTextChanged,
36
- placeholder = DEFAULT_PLACEHOLDER,
37
- placeholderTextColor = Color.defaultColor,
38
27
  text = '',
39
- textInputAutoFocus = false,
40
28
  textInputProps,
41
- textInputStyle,
42
29
  }: ComposerProps): React.ReactElement {
43
30
  const dimensionsRef = useRef<{ width: number, height: number }>(null)
31
+ const colorScheme = useColorScheme()
32
+ const isDark = colorScheme === 'dark'
44
33
 
45
34
  const determineInputSizeChange = useCallback(
46
35
  (dimensions: { width: number, height: number }) => {
@@ -69,21 +58,28 @@ export function Composer ({
69
58
  [determineInputSizeChange]
70
59
  )
71
60
 
61
+ const placeholder = textInputProps?.placeholder ?? 'Type a message...'
62
+
72
63
  return (
73
64
  <TextInput
74
65
  testID={placeholder}
75
66
  accessible
76
67
  accessibilityLabel={placeholder}
77
- placeholder={placeholder}
78
- placeholderTextColor={placeholderTextColor}
79
- multiline={multiline}
80
- editable={!disableComposer}
68
+ placeholderTextColor={textInputProps?.placeholderTextColor ?? (isDark ? '#888' : Color.defaultColor)}
81
69
  onContentSizeChange={handleContentSizeChange}
82
70
  onChangeText={onTextChanged}
71
+ value={text}
72
+ enablesReturnKeyAutomatically
73
+ underlineColorAndroid='transparent'
74
+ keyboardAppearance={isDark ? 'dark' : 'default'}
75
+ multiline
76
+ placeholder={placeholder}
77
+ {...textInputProps}
83
78
  style={[
84
79
  stylesCommon.fill,
85
80
  styles.textInput,
86
- textInputStyle,
81
+ styles[`textInput_${colorScheme}`],
82
+ textInputProps?.style,
87
83
  {
88
84
  height: composerHeight,
89
85
  ...Platform.select({
@@ -95,12 +91,6 @@ export function Composer ({
95
91
  }),
96
92
  },
97
93
  ]}
98
- autoFocus={textInputAutoFocus}
99
- value={text}
100
- enablesReturnKeyAutomatically
101
- underlineColorAndroid='transparent'
102
- keyboardAppearance={keyboardAppearance}
103
- {...textInputProps}
104
94
  />
105
95
  )
106
96
  }
@@ -127,4 +117,7 @@ const styles = StyleSheet.create({
127
117
  web: 4,
128
118
  }),
129
119
  },
120
+ textInput_dark: {
121
+ color: '#fff',
122
+ },
130
123
  })
package/src/Constant.ts CHANGED
@@ -7,7 +7,6 @@ export const MIN_COMPOSER_HEIGHT = Platform.select({
7
7
  windows: 34,
8
8
  })
9
9
  export const MAX_COMPOSER_HEIGHT = 200
10
- export const DEFAULT_PLACEHOLDER = 'Type a message...'
11
10
  export const DATE_FORMAT = 'D MMMM'
12
11
  export const TIME_FORMAT = 'LT'
13
12
 
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useEffect, useState } from 'react'
1
+ import React, { useCallback, useMemo } from 'react'
2
2
  import {
3
3
  Image,
4
4
  Text,
@@ -51,9 +51,6 @@ export interface GiftedAvatarProps {
51
51
  export function GiftedAvatar (
52
52
  props: GiftedAvatarProps
53
53
  ) {
54
- const [avatarName, setAvatarName] = useState<string | undefined>(undefined)
55
- const [backgroundColor, setBackgroundColor] = useState<string | undefined>(undefined)
56
-
57
54
  const {
58
55
  user,
59
56
  avatarStyle,
@@ -61,23 +58,23 @@ export function GiftedAvatar (
61
58
  onPress,
62
59
  } = props
63
60
 
64
- const setAvatarColor = useCallback(() => {
65
- if (backgroundColor)
66
- return
67
-
61
+ const avatarName = useMemo(() => {
68
62
  const userName = user?.name || ''
69
63
  const name = userName.toUpperCase().split(' ')
70
64
 
71
65
  if (name.length === 1)
72
- setAvatarName(`${name[0].charAt(0)}`)
66
+ return `${name[0].charAt(0)}`
73
67
  else if (name.length > 1)
74
- setAvatarName(`${name[0].charAt(0)}${name[1].charAt(0)}`)
68
+ return `${name[0].charAt(0)}${name[1].charAt(0)}`
75
69
  else
76
- setAvatarName('')
70
+ return ''
71
+ }, [user?.name])
77
72
 
73
+ const backgroundColor = useMemo(() => {
78
74
  let sumChars = 0
79
- for (let i = 0; i < userName.length; i += 1)
80
- sumChars += userName.charCodeAt(i)
75
+ if (user?.name)
76
+ for (let i = 0; i < user.name.length; i += 1)
77
+ sumChars += user.name.charCodeAt(i)
81
78
 
82
79
  // inspired by https://github.com/wbinnssmith/react-user-avatar
83
80
  // colors from https://flatuicolors.com/
@@ -91,8 +88,8 @@ export function GiftedAvatar (
91
88
  midnightBlue,
92
89
  ]
93
90
 
94
- setBackgroundColor(colors[sumChars % colors.length])
95
- }, [user?.name, backgroundColor])
91
+ return colors[sumChars % colors.length]
92
+ }, [user?.name])
96
93
 
97
94
  const renderAvatar = useCallback(() => {
98
95
  switch (typeof user?.avatar) {
@@ -125,17 +122,16 @@ export function GiftedAvatar (
125
122
  )
126
123
  }, [textStyle, avatarName])
127
124
 
128
- const handleOnPress = () => {
125
+ const handleOnPress = useCallback(() => {
129
126
  const {
130
127
  onPress,
131
128
  ...rest
132
129
  } = props
133
130
 
134
- if (onPress)
135
- onPress(rest)
136
- }
131
+ onPress?.(rest)
132
+ }, [props])
137
133
 
138
- const handleOnLongPress = () => {
134
+ const handleOnLongPress = useCallback(() => {
139
135
  const {
140
136
  onLongPress,
141
137
  ...rest
@@ -143,25 +139,22 @@ export function GiftedAvatar (
143
139
 
144
140
  if (onLongPress)
145
141
  onLongPress(rest)
146
- }
142
+ }, [props])
147
143
 
148
- useEffect(() => {
149
- setAvatarColor()
150
- }, [setAvatarColor])
144
+ const placeholderView = useMemo(() => (
145
+ <View
146
+ style={[
147
+ stylesCommon.centerItems,
148
+ styles.avatarStyle,
149
+ styles.avatarTransparent,
150
+ avatarStyle,
151
+ ]}
152
+ accessibilityRole='image'
153
+ />
154
+ ), [avatarStyle])
151
155
 
152
156
  if (!user || (!user.name && !user.avatar))
153
- // render placeholder
154
- return (
155
- <View
156
- style={[
157
- stylesCommon.centerItems,
158
- styles.avatarStyle,
159
- styles.avatarTransparent,
160
- avatarStyle,
161
- ]}
162
- accessibilityRole='image'
163
- />
164
- )
157
+ return placeholderView
165
158
 
166
159
  if (user.avatar)
167
160
  return (
@@ -14,7 +14,6 @@ import {
14
14
  import dayjs from 'dayjs'
15
15
  import localizedFormat from 'dayjs/plugin/localizedFormat'
16
16
  import {
17
- Platform,
18
17
  TextInput,
19
18
  View,
20
19
  LayoutChangeEvent,
@@ -72,19 +71,13 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
72
71
  onSend,
73
72
  locale = 'en',
74
73
  renderLoading,
75
- actionSheet = null,
74
+ actionSheet,
76
75
  textInputProps,
77
- renderChatFooter = null,
78
- renderInputToolbar = null,
76
+ renderChatFooter,
77
+ renderInputToolbar,
79
78
  bottomOffset = 0,
80
79
  focusOnInputWhenOpeningKeyboard = true,
81
- keyboardShouldPersistTaps = Platform.select({
82
- ios: 'never',
83
- android: 'always',
84
- default: 'never',
85
- }),
86
- onInputTextChanged = null,
87
- maxInputLength = null,
80
+ onInputTextChanged,
88
81
  inverted = true,
89
82
  minComposerHeight = MIN_COMPOSER_HEIGHT,
90
83
  maxComposerHeight = MAX_COMPOSER_HEIGHT,
@@ -111,7 +104,6 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
111
104
  minComposerHeight!
112
105
  )
113
106
  const [text, setText] = useState<string | undefined>(() => props.text || '')
114
- const [isTypingDisabled, setIsTypingDisabled] = useState<boolean>(false)
115
107
 
116
108
  // Always call the hook, but conditionally use its data
117
109
  const keyboardControllerData = useReanimatedKeyboardAnimation()
@@ -124,7 +116,6 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
124
116
  }, [disableKeyboardController, keyboardControllerData])
125
117
 
126
118
  const trackingKeyboardMovement = useSharedValue(false)
127
- const debounceEnableTypingTimeoutId = useRef<ReturnType<typeof setTimeout>>(undefined)
128
119
  const keyboardOffsetBottom = useSharedValue(0)
129
120
 
130
121
  const contentStyleAnim = useAnimatedStyle(
@@ -174,23 +165,6 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
174
165
  isTextInputWasFocused.current = false
175
166
  }, [textInputRef])
176
167
 
177
- const disableTyping = useCallback(() => {
178
- clearTimeout(debounceEnableTypingTimeoutId.current)
179
- setIsTypingDisabled(true)
180
- }, [])
181
-
182
- const enableTyping = useCallback(() => {
183
- clearTimeout(debounceEnableTypingTimeoutId.current)
184
- setIsTypingDisabled(false)
185
- }, [])
186
-
187
- const debounceEnableTyping = useCallback(() => {
188
- clearTimeout(debounceEnableTypingTimeoutId.current)
189
- debounceEnableTypingTimeoutId.current = setTimeout(() => {
190
- enableTyping()
191
- }, 50)
192
- }, [enableTyping])
193
-
194
168
  const scrollToBottom = useCallback(
195
169
  (isAnimated = true) => {
196
170
  if (!messageContainerRef?.current)
@@ -219,10 +193,7 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
219
193
  <View style={[stylesCommon.fill, messagesContainerStyle]}>
220
194
  <MessageContainer<TMessage>
221
195
  {...messagesContainerProps}
222
- invertibleScrollViewProps={{
223
- inverted,
224
- keyboardShouldPersistTaps,
225
- }}
196
+ inverted={inverted}
226
197
  messages={messages}
227
198
  forwardRef={messageContainerRef}
228
199
  isTyping={isTyping}
@@ -236,7 +207,6 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
236
207
  messages,
237
208
  props,
238
209
  inverted,
239
- keyboardShouldPersistTaps,
240
210
  messageContainerRef,
241
211
  renderChatFooter,
242
212
  ])
@@ -252,13 +222,11 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
252
222
 
253
223
  setComposerHeight(minComposerHeight!)
254
224
  setText(getTextFromProp(''))
255
- enableTyping()
256
225
  }, [
257
226
  minComposerHeight,
258
227
  getTextFromProp,
259
228
  textInputRef,
260
229
  notifyInputTextReset,
261
- enableTyping,
262
230
  ])
263
231
 
264
232
  const _onSend = useCallback(
@@ -275,17 +243,14 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
275
243
  }
276
244
  })
277
245
 
278
- if (shouldResetInputToolbar === true) {
279
- disableTyping()
280
-
246
+ if (shouldResetInputToolbar === true)
281
247
  resetInputToolbar()
282
- }
283
248
 
284
249
  onSend?.(newMessages)
285
250
 
286
251
  setTimeout(() => scrollToBottom(), 10)
287
252
  },
288
- [messageIdGenerator, onSend, user, resetInputToolbar, disableTyping, scrollToBottom]
253
+ [messageIdGenerator, onSend, user, resetInputToolbar, scrollToBottom]
289
254
  )
290
255
 
291
256
  const onInputSizeChanged = useCallback(
@@ -301,17 +266,14 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
301
266
  )
302
267
 
303
268
  const _onInputTextChanged = useCallback(
304
- (_text: string) => {
305
- if (isTypingDisabled)
306
- return
307
-
308
- onInputTextChanged?.(_text)
269
+ (text: string) => {
270
+ onInputTextChanged?.(text)
309
271
 
310
272
  // Only set state if it's not being overridden by a prop.
311
273
  if (props.text === undefined)
312
- setText(_text)
274
+ setText(text)
313
275
  },
314
- [onInputTextChanged, isTypingDisabled, props.text]
276
+ [onInputTextChanged, props.text]
315
277
  )
316
278
 
317
279
  const onInitialLayoutViewLayout = useCallback(
@@ -347,7 +309,6 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
347
309
  textInputProps: {
348
310
  ...textInputProps,
349
311
  ref: textInputRef,
350
- maxLength: isTypingDisabled ? 0 : maxInputLength,
351
312
  },
352
313
  }
353
314
 
@@ -359,14 +320,12 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
359
320
  isInitialized,
360
321
  _onSend,
361
322
  getTextFromProp,
362
- maxInputLength,
363
323
  minComposerHeight,
364
324
  onInputSizeChanged,
365
325
  props,
366
326
  text,
367
327
  renderInputToolbar,
368
328
  composerHeight,
369
- isTypingDisabled,
370
329
  textInputRef,
371
330
  textInputProps,
372
331
  _onInputTextChanged,
@@ -415,13 +374,6 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
415
374
  runOnJS(handleTextInputFocusWhenKeyboardShow)()
416
375
  else
417
376
  runOnJS(handleTextInputFocusWhenKeyboardHide)()
418
-
419
- if (value === 0) {
420
- runOnJS(enableTyping)()
421
- } else {
422
- runOnJS(disableTyping)()
423
- runOnJS(debounceEnableTyping)()
424
- }
425
377
  }
426
378
  }
427
379
  },
@@ -431,9 +383,6 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
431
383
  focusOnInputWhenOpeningKeyboard,
432
384
  handleTextInputFocusWhenKeyboardHide,
433
385
  handleTextInputFocusWhenKeyboardShow,
434
- enableTyping,
435
- disableTyping,
436
- debounceEnableTyping,
437
386
  bottomOffset,
438
387
  disableKeyboardController,
439
388
  ]