react-native-gifted-chat 2.8.2-alpha.1 → 2.8.2-alpha.2
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.
- package/README.md +43 -19
- package/package.json +10 -11
- package/src/Actions.tsx +1 -1
- package/src/Avatar.tsx +1 -1
- package/src/Bubble/index.tsx +13 -10
- package/src/Bubble/types.ts +5 -4
- package/src/Composer.tsx +1 -1
- package/src/Day/index.tsx +3 -3
- package/src/GiftedAvatar.tsx +2 -2
- package/src/GiftedChat/index.tsx +48 -44
- package/src/GiftedChat/styles.ts +3 -0
- package/src/GiftedChat/types.ts +13 -16
- package/src/InputToolbar.tsx +2 -2
- package/src/LoadEarlier.tsx +3 -3
- package/src/Message/index.tsx +4 -18
- package/src/Message/types.ts +2 -2
- package/src/MessageAudio.tsx +1 -1
- package/src/MessageContainer/components/DayAnimated/index.tsx +2 -2
- package/src/MessageContainer/components/Item/index.tsx +3 -3
- package/src/MessageContainer/components/Item/types.ts +1 -1
- package/src/MessageContainer/index.tsx +10 -10
- package/src/MessageContainer/types.ts +2 -2
- package/src/MessageImage.tsx +119 -17
- package/src/MessageText.tsx +10 -45
- package/src/MessageVideo.tsx +1 -1
- package/src/QuickReplies.tsx +2 -2
- package/src/Send.tsx +3 -4
- package/src/SystemMessage.tsx +1 -1
- package/src/Time.tsx +1 -1
- package/src/TypingIndicator/index.tsx +2 -2
- package/src/__tests__/DayAnimated.test.tsx +2 -2
- package/src/__tests__/GiftedChat.test.tsx +3 -3
- package/src/__tests__/__snapshots__/Actions.test.tsx.snap +39 -7
- package/src/__tests__/__snapshots__/GiftedChat.test.tsx.snap +20 -22
- package/src/__tests__/__snapshots__/LoadEarlier.test.tsx.snap +37 -6
- package/src/__tests__/__snapshots__/MessageImage.test.tsx.snap +34 -15
- package/src/__tests__/__snapshots__/Send.test.tsx.snap +70 -10
- package/src/components/TouchableOpacity.tsx +45 -0
- package/src/types.ts +0 -2
- package/src/utils.ts +2 -2
package/README.md
CHANGED
|
@@ -85,21 +85,19 @@
|
|
|
85
85
|
|
|
86
86
|
## Features
|
|
87
87
|
|
|
88
|
-
- 🎉 **_`react-native-web`able_ (since 0.10.0)** [web configuration](#react-native-web)
|
|
89
|
-
- Write with **TypeScript** (since 0.8.0)
|
|
90
88
|
- Fully customizable components
|
|
91
89
|
- Composer actions (to attach photos, etc.)
|
|
92
90
|
- Load earlier messages
|
|
93
91
|
- Copy messages to clipboard
|
|
94
|
-
- Touchable links using [react-native-
|
|
92
|
+
- Touchable links using [react-native-autolink](https://github.com/joshswan/react-native-autolink)
|
|
95
93
|
- Avatar as user's initials
|
|
96
94
|
- Localized dates
|
|
97
95
|
- Multi-line TextInput
|
|
98
96
|
- InputToolbar avoiding keyboard
|
|
99
|
-
- Redux support
|
|
100
97
|
- System message
|
|
101
98
|
- Quick Reply messages (bot)
|
|
102
99
|
- Typing indicator
|
|
100
|
+
- react-native-web [web configuration](#react-native-web)
|
|
103
101
|
|
|
104
102
|
# Getting started
|
|
105
103
|
|
|
@@ -117,18 +115,18 @@ Readme for this version: [2.6.5 readme](https://github.com/FaridSafi/react-nativ
|
|
|
117
115
|
|
|
118
116
|
Yarn:
|
|
119
117
|
```bash
|
|
120
|
-
yarn add react-native-gifted-chat react-native-reanimated react-native-keyboard-controller
|
|
118
|
+
yarn add react-native-gifted-chat react-native-reanimated react-native-keyboard-controller react-native-gesture-handler react-native-safe-area-context
|
|
121
119
|
```
|
|
122
120
|
|
|
123
121
|
Npm:
|
|
124
122
|
|
|
125
123
|
```bash
|
|
126
|
-
npm install --save react-native-gifted-chat react-native-reanimated react-native-keyboard-controller
|
|
124
|
+
npm install --save react-native-gifted-chat react-native-reanimated react-native-keyboard-controller react-native-gesture-handler react-native-safe-area-context
|
|
127
125
|
```
|
|
128
126
|
|
|
129
127
|
Expo
|
|
130
128
|
```bash
|
|
131
|
-
npx expo install react-native-gifted-chat react-native-reanimated react-native-keyboard-controller
|
|
129
|
+
npx expo install react-native-gifted-chat react-native-reanimated react-native-keyboard-controller react-native-gesture-handler react-native-safe-area-context
|
|
132
130
|
```
|
|
133
131
|
|
|
134
132
|
### Non-expo users
|
|
@@ -173,9 +171,15 @@ fireEvent(loadingWrapper, 'layout', {
|
|
|
173
171
|
```jsx
|
|
174
172
|
import React, { useState, useCallback, useEffect } from 'react'
|
|
175
173
|
import { GiftedChat } from 'react-native-gifted-chat'
|
|
174
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
176
175
|
|
|
177
176
|
export function Example() {
|
|
178
177
|
const [messages, setMessages] = useState([])
|
|
178
|
+
const insets = useSafeAreaInsets()
|
|
179
|
+
|
|
180
|
+
// If you have a tab bar, include its height
|
|
181
|
+
const tabbarHeight = 50
|
|
182
|
+
const keyboardBottomOffset = insets.bottom + tabbarHeight
|
|
179
183
|
|
|
180
184
|
useEffect(() => {
|
|
181
185
|
setMessages([
|
|
@@ -205,6 +209,7 @@ export function Example() {
|
|
|
205
209
|
user={{
|
|
206
210
|
_id: 1,
|
|
207
211
|
}}
|
|
212
|
+
keyboardBottomOffset={keyboardBottomOffset}
|
|
208
213
|
/>
|
|
209
214
|
)
|
|
210
215
|
}
|
|
@@ -212,7 +217,7 @@ export function Example() {
|
|
|
212
217
|
|
|
213
218
|
## Advanced example
|
|
214
219
|
|
|
215
|
-
See [`
|
|
220
|
+
See [`examples`](example) for a working demo!
|
|
216
221
|
|
|
217
222
|
## "Slack" example
|
|
218
223
|
|
|
@@ -354,8 +359,8 @@ interface QuickReplies {
|
|
|
354
359
|
- **`textInputRef`** _(TextInput ref)_ - Ref to the text input
|
|
355
360
|
- **`messages`** _(Array)_ - Messages to display
|
|
356
361
|
- **`isTyping`** _(Bool)_ - Typing Indicator state; default `false`. If you use`renderFooter` it will override this.
|
|
362
|
+
- **`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.
|
|
357
363
|
- **`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
|
-
- **`disableKeyboardController`** _(Bool)_ - Completely disable react-native-keyboard-controller. Useful when using react-native-navigation or other conflicting keyboard libraries; default is `false`
|
|
359
364
|
- **`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
365
|
- **`onInputTextChanged`** _(Function)_ - Callback when the input text changes
|
|
361
366
|
- **`messageIdGenerator`** _(Function)_ - Generate an id for new messages. Defaults to UUID v4, generated by [uuid](https://github.com/kelektiv/node-uuid)
|
|
@@ -391,7 +396,6 @@ interface QuickReplies {
|
|
|
391
396
|
- **`renderMessageVideo`** _(Function)_ - Custom message video
|
|
392
397
|
- **`imageProps`** _(Object)_ - Extra props to be passed to the [`<Image>`](https://reactnative.dev/docs/image.html) component created by the default `renderMessageImage`
|
|
393
398
|
- **`videoProps`** _(Object)_ - Extra props to be passed to the video component created by the required `renderMessageVideo`
|
|
394
|
-
- **`lightboxProps`** _(Object)_ - Extra props to be passed to the `MessageImage`'s [Lightbox](https://github.com/oblador/react-native-lightbox)
|
|
395
399
|
- **`isCustomViewBottom`** _(Bool)_ - Determine whether renderCustomView is displayed before or after the text, image and video views; default is `false`
|
|
396
400
|
- **`renderCustomView`** _(Function)_ - Custom view inside the bubble
|
|
397
401
|
- **`renderDay`** _(Function)_ - Custom day above a message
|
|
@@ -405,22 +409,42 @@ interface QuickReplies {
|
|
|
405
409
|
- **`renderSend`** _(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))
|
|
406
410
|
- **`renderAccessory`** _(Function)_ - Custom second line of actions below the message composer
|
|
407
411
|
- **`onPressActionButton`** _(Function)_ - Callback when the Action button is pressed (if set, the default `actionSheet` will not be used)
|
|
408
|
-
- **`bottomOffset`** _(Integer)_ - Distance of the chat from the bottom of the screen (e.g. useful if you display a tab bar)
|
|
409
412
|
- **`focusOnInputWhenOpeningKeyboard`** _(Bool)_ - Focus on <TextInput> automatically when opening the keyboard; default `true`
|
|
410
413
|
- **`minInputToolbarHeight`** _(Integer)_ - Minimum height of the input toolbar; default is `44`
|
|
411
414
|
- **`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
415
|
- **`textInputProps`** _(Object)_ - props to be passed to the [`<TextInput>`](https://reactnative.dev/docs/textinput.html).
|
|
413
|
-
- **`
|
|
416
|
+
- **`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:
|
|
417
|
+
- `matchers` - Custom matchers for linking message content (like URLs, phone numbers, hashtags, mentions)
|
|
418
|
+
- `linkStyle` - Custom style for links
|
|
419
|
+
- `email` - Enable/disable email parsing (default: true)
|
|
420
|
+
- `phone` - Enable/disable phone number parsing (default: true)
|
|
421
|
+
- `url` - Enable/disable URL parsing (default: true)
|
|
422
|
+
|
|
423
|
+
Example:
|
|
414
424
|
|
|
415
425
|
```js
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
426
|
+
<GiftedChat
|
|
427
|
+
messageTextProps={{
|
|
428
|
+
matchers: [
|
|
429
|
+
{
|
|
430
|
+
pattern: /#(\w+)/g,
|
|
431
|
+
style: { color: '#0084ff', fontWeight: 'bold' },
|
|
432
|
+
onPress: (match) => console.log('Hashtag:', match.getAnchorText()),
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
pattern: /(?<![\.\w])@(?!__ELEMENT-)([\w-]+)/g,
|
|
436
|
+
style: { color: '#0084ff', fontWeight: 'bold' },
|
|
437
|
+
onPress: (match) => console.log('Mention:', match.getAnchorText()),
|
|
438
|
+
},
|
|
439
|
+
],
|
|
440
|
+
linkStyle: { left: { color: 'blue' }, right: { color: 'lightblue' } },
|
|
441
|
+
phone: false,
|
|
442
|
+
}}
|
|
443
|
+
/>
|
|
422
444
|
```
|
|
423
445
|
|
|
446
|
+
- **`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).
|
|
447
|
+
|
|
424
448
|
- **`extraData`** _(Object)_ - Extra props for re-rendering FlatList on demand. This will be useful for rendering footer etc.
|
|
425
449
|
- **`minComposerHeight`** _(Object)_ - Custom min-height of the composer.
|
|
426
450
|
- **`maxComposerHeight`** _(Object)_ - Custom max height of the composer.
|
|
@@ -514,7 +538,7 @@ If you use React Navigation, additional handling may be required to account for
|
|
|
514
538
|
module.exports = function override(config, env) {
|
|
515
539
|
config.module.rules.push({
|
|
516
540
|
test: /\.js$/,
|
|
517
|
-
exclude: /node_modules[/\\](?!react-native-gifted-chat
|
|
541
|
+
exclude: /node_modules[/\\](?!react-native-gifted-chat)/,
|
|
518
542
|
use: {
|
|
519
543
|
loader: 'babel-loader',
|
|
520
544
|
options: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-gifted-chat",
|
|
3
|
-
"version": "2.8.2-alpha.
|
|
3
|
+
"version": "2.8.2-alpha.2",
|
|
4
4
|
"description": "The most complete chat UI for React Native",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"android",
|
|
@@ -53,8 +53,7 @@
|
|
|
53
53
|
"dayjs": "^1.11.19",
|
|
54
54
|
"lodash.isequal": "^4.5.0",
|
|
55
55
|
"react-native-autolink": "^4.2.0",
|
|
56
|
-
"react-native-
|
|
57
|
-
"react-native-lightbox-v2": "^0.9.2"
|
|
56
|
+
"react-native-zoom-reanimated": "^1.4.10"
|
|
58
57
|
},
|
|
59
58
|
"devDependencies": {
|
|
60
59
|
"@babel/core": "^7.28.5",
|
|
@@ -80,16 +79,12 @@
|
|
|
80
79
|
"@typescript-eslint/eslint-plugin": "^8.46.4",
|
|
81
80
|
"@typescript-eslint/parser": "^8.46.4",
|
|
82
81
|
"babel-jest": "^29.7.0",
|
|
83
|
-
"eslint": "^
|
|
84
|
-
"eslint-config-standard": "^17.1.0",
|
|
85
|
-
"eslint-config-standard-jsx": "^11.0.0",
|
|
82
|
+
"eslint": "^9.18.0",
|
|
86
83
|
"eslint-plugin-import": "^2.32.0",
|
|
87
84
|
"eslint-plugin-jest": "^28.11.0",
|
|
88
|
-
"eslint-plugin-
|
|
89
|
-
"eslint-plugin-n": "^17.23.1",
|
|
90
|
-
"eslint-plugin-node": "^11.1.0",
|
|
91
|
-
"eslint-plugin-promise": "^7.2.1",
|
|
85
|
+
"eslint-plugin-perfectionist": "^4.15.1",
|
|
92
86
|
"eslint-plugin-react": "^7.37.5",
|
|
87
|
+
"eslint-plugin-react-hooks": "^5.1.0",
|
|
93
88
|
"husky": "^9.1.7",
|
|
94
89
|
"jest": "^29.7.0",
|
|
95
90
|
"json": "^11.0.0",
|
|
@@ -97,16 +92,20 @@
|
|
|
97
92
|
"react": "19.1.0",
|
|
98
93
|
"react-dom": "19.1.0",
|
|
99
94
|
"react-native": "0.81.5",
|
|
95
|
+
"react-native-gesture-handler": "^2.29.1",
|
|
100
96
|
"react-native-keyboard-controller": "^1.19.5",
|
|
101
97
|
"react-native-reanimated": "^3.19.4",
|
|
98
|
+
"react-native-safe-area-context": "^5.6.2",
|
|
102
99
|
"react-test-renderer": "19.1.0",
|
|
103
100
|
"typescript": "^5.9.3"
|
|
104
101
|
},
|
|
105
102
|
"peerDependencies": {
|
|
106
103
|
"react": ">=18.0.0",
|
|
107
104
|
"react-native": "*",
|
|
105
|
+
"react-native-gesture-handler": ">=2.0.0",
|
|
108
106
|
"react-native-keyboard-controller": ">=1.0.0",
|
|
109
|
-
"react-native-reanimated": ">=3.0.0 || ^4.0.0"
|
|
107
|
+
"react-native-reanimated": ">=3.0.0 || ^4.0.0",
|
|
108
|
+
"react-native-safe-area-context": ">=5.0.0"
|
|
110
109
|
},
|
|
111
110
|
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
|
|
112
111
|
"engines": {
|
package/src/Actions.tsx
CHANGED
|
@@ -2,13 +2,13 @@ import React, { ReactNode, useCallback } from 'react'
|
|
|
2
2
|
import {
|
|
3
3
|
StyleSheet,
|
|
4
4
|
Text,
|
|
5
|
-
TouchableOpacity,
|
|
6
5
|
View,
|
|
7
6
|
StyleProp,
|
|
8
7
|
ViewStyle,
|
|
9
8
|
TextStyle,
|
|
10
9
|
} from 'react-native'
|
|
11
10
|
import Color from './Color'
|
|
11
|
+
import { TouchableOpacity } from './components/TouchableOpacity'
|
|
12
12
|
import { useChatContext } from './GiftedChatContext'
|
|
13
13
|
|
|
14
14
|
import stylesCommon from './styles'
|
package/src/Avatar.tsx
CHANGED
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
ViewStyle,
|
|
8
8
|
} from 'react-native'
|
|
9
9
|
import { GiftedAvatar } from './GiftedAvatar'
|
|
10
|
-
import { isSameUser, isSameDay } from './utils'
|
|
11
10
|
import { IMessage, LeftRightStyle, User } from './types'
|
|
11
|
+
import { isSameUser, isSameDay } from './utils'
|
|
12
12
|
|
|
13
13
|
interface Styles {
|
|
14
14
|
left: {
|
package/src/Bubble/index.tsx
CHANGED
|
@@ -6,19 +6,19 @@ import {
|
|
|
6
6
|
} from 'react-native'
|
|
7
7
|
|
|
8
8
|
import { useChatContext } from '../GiftedChatContext'
|
|
9
|
-
import {
|
|
10
|
-
import { MessageText } from '../MessageText'
|
|
9
|
+
import { MessageAudio } from '../MessageAudio'
|
|
11
10
|
import { MessageImage } from '../MessageImage'
|
|
11
|
+
import { MessageText } from '../MessageText'
|
|
12
12
|
import { MessageVideo } from '../MessageVideo'
|
|
13
|
-
import {
|
|
14
|
-
import
|
|
13
|
+
import { QuickReplies } from '../QuickReplies'
|
|
14
|
+
import stylesCommon from '../styles'
|
|
15
15
|
|
|
16
|
-
import {
|
|
16
|
+
import { Time } from '../Time'
|
|
17
17
|
import { IMessage } from '../types'
|
|
18
|
-
import {
|
|
18
|
+
import { isSameUser, isSameDay } from '../utils'
|
|
19
19
|
|
|
20
|
-
import stylesCommon from '../styles'
|
|
21
20
|
import styles from './styles'
|
|
21
|
+
import { BubbleProps, RenderMessageTextProps } from './types'
|
|
22
22
|
|
|
23
23
|
export * from './types'
|
|
24
24
|
|
|
@@ -142,14 +142,17 @@ const Bubble = <TMessage extends IMessage = IMessage>(props: BubbleProps<TMessag
|
|
|
142
142
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
143
143
|
containerStyle,
|
|
144
144
|
wrapperStyle,
|
|
145
|
+
messageTextProps,
|
|
145
146
|
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
146
|
-
...
|
|
147
|
+
...messageTextPropsRest
|
|
147
148
|
} = props
|
|
148
149
|
|
|
150
|
+
const combinedProps = { ...messageTextPropsRest, ...messageTextProps } as RenderMessageTextProps<TMessage>
|
|
151
|
+
|
|
149
152
|
if (props.renderMessageText)
|
|
150
|
-
return props.renderMessageText(
|
|
153
|
+
return props.renderMessageText(combinedProps)
|
|
151
154
|
|
|
152
|
-
return <MessageText {...
|
|
155
|
+
return <MessageText {...combinedProps} />
|
|
153
156
|
}
|
|
154
157
|
|
|
155
158
|
return null
|
package/src/Bubble/types.ts
CHANGED
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
ViewStyle,
|
|
5
5
|
TextStyle,
|
|
6
6
|
} from 'react-native'
|
|
7
|
-
import { QuickRepliesProps } from '../QuickReplies'
|
|
8
|
-
import { MessageTextProps, MessageOption } from '../MessageText'
|
|
9
7
|
import { MessageImageProps } from '../MessageImage'
|
|
8
|
+
import { MessageTextProps, MessageOption } from '../MessageText'
|
|
9
|
+
import { QuickRepliesProps } from '../QuickReplies'
|
|
10
10
|
import { TimeProps } from '../Time'
|
|
11
11
|
import {
|
|
12
12
|
User,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
MessageAudioProps,
|
|
19
19
|
} from '../types'
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
export type RenderMessageImageProps<TMessage extends IMessage> = Omit<
|
|
23
23
|
BubbleProps<TMessage>,
|
|
24
24
|
'containerStyle' | 'wrapperStyle'
|
|
@@ -42,7 +42,7 @@ export type RenderMessageTextProps<TMessage extends IMessage> = Omit<
|
|
|
42
42
|
'containerStyle' | 'wrapperStyle' | 'options'
|
|
43
43
|
> &
|
|
44
44
|
MessageTextProps<TMessage>
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
|
|
47
47
|
export interface BubbleProps<TMessage extends IMessage> {
|
|
48
48
|
user?: User
|
|
@@ -66,6 +66,7 @@ export interface BubbleProps<TMessage extends IMessage> {
|
|
|
66
66
|
quickReplyStyle?: StyleProp<ViewStyle>
|
|
67
67
|
quickReplyTextStyle?: StyleProp<TextStyle>
|
|
68
68
|
quickReplyContainerStyle?: StyleProp<ViewStyle>
|
|
69
|
+
messageTextProps?: Partial<MessageTextProps<TMessage>>
|
|
69
70
|
onPressMessage?(context?: unknown, message?: unknown): void
|
|
70
71
|
onLongPressMessage?(context?: unknown, message?: unknown): void
|
|
71
72
|
onQuickReply?(replies: Reply[]): void
|
package/src/Composer.tsx
CHANGED
|
@@ -8,8 +8,8 @@ import {
|
|
|
8
8
|
TextInputContentSizeChangeEventData,
|
|
9
9
|
useColorScheme,
|
|
10
10
|
} from 'react-native'
|
|
11
|
-
import { MIN_COMPOSER_HEIGHT } from './Constant'
|
|
12
11
|
import Color from './Color'
|
|
12
|
+
import { MIN_COMPOSER_HEIGHT } from './Constant'
|
|
13
13
|
import stylesCommon from './styles'
|
|
14
14
|
|
|
15
15
|
export interface ComposerProps {
|
package/src/Day/index.tsx
CHANGED
|
@@ -4,15 +4,15 @@ import {
|
|
|
4
4
|
View,
|
|
5
5
|
} from 'react-native'
|
|
6
6
|
import dayjs from 'dayjs'
|
|
7
|
-
import relativeTime from 'dayjs/plugin/relativeTime'
|
|
8
7
|
import calendar from 'dayjs/plugin/calendar'
|
|
8
|
+
import relativeTime from 'dayjs/plugin/relativeTime'
|
|
9
9
|
|
|
10
10
|
import { DATE_FORMAT } from '../Constant'
|
|
11
|
-
import { DayProps } from './types'
|
|
12
|
-
|
|
13
11
|
import { useChatContext } from '../GiftedChatContext'
|
|
12
|
+
|
|
14
13
|
import stylesCommon from '../styles'
|
|
15
14
|
import styles from './styles'
|
|
15
|
+
import { DayProps } from './types'
|
|
16
16
|
|
|
17
17
|
export * from './types'
|
|
18
18
|
|
package/src/GiftedAvatar.tsx
CHANGED
|
@@ -2,7 +2,6 @@ import React, { useCallback, useMemo } from 'react'
|
|
|
2
2
|
import {
|
|
3
3
|
Image,
|
|
4
4
|
Text,
|
|
5
|
-
TouchableOpacity,
|
|
6
5
|
View,
|
|
7
6
|
StyleSheet,
|
|
8
7
|
StyleProp,
|
|
@@ -10,8 +9,9 @@ import {
|
|
|
10
9
|
TextStyle,
|
|
11
10
|
} from 'react-native'
|
|
12
11
|
import Color from './Color'
|
|
13
|
-
import {
|
|
12
|
+
import { TouchableOpacity } from './components/TouchableOpacity'
|
|
14
13
|
import stylesCommon from './styles'
|
|
14
|
+
import { User } from './types'
|
|
15
15
|
|
|
16
16
|
const {
|
|
17
17
|
carrot,
|
package/src/GiftedChat/index.tsx
CHANGED
|
@@ -7,17 +7,26 @@ import React, {
|
|
|
7
7
|
useCallback,
|
|
8
8
|
RefObject,
|
|
9
9
|
} from 'react'
|
|
10
|
+
import {
|
|
11
|
+
TextInput,
|
|
12
|
+
View,
|
|
13
|
+
LayoutChangeEvent,
|
|
14
|
+
} from 'react-native'
|
|
10
15
|
import {
|
|
11
16
|
ActionSheetProvider,
|
|
12
17
|
ActionSheetProviderRef,
|
|
13
18
|
} from '@expo/react-native-action-sheet'
|
|
14
19
|
import dayjs from 'dayjs'
|
|
15
20
|
import localizedFormat from 'dayjs/plugin/localizedFormat'
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
import { GestureHandlerRootView } from 'react-native-gesture-handler'
|
|
22
|
+
import { KeyboardProvider, useReanimatedKeyboardAnimation } from 'react-native-keyboard-controller'
|
|
23
|
+
import Animated, {
|
|
24
|
+
useAnimatedStyle,
|
|
25
|
+
useAnimatedReaction,
|
|
26
|
+
useSharedValue,
|
|
27
|
+
withTiming,
|
|
28
|
+
runOnJS,
|
|
29
|
+
} from 'react-native-reanimated'
|
|
21
30
|
import { Actions } from '../Actions'
|
|
22
31
|
import { Avatar } from '../Avatar'
|
|
23
32
|
import Bubble from '../Bubble'
|
|
@@ -32,25 +41,17 @@ import Message from '../Message'
|
|
|
32
41
|
import MessageContainer, { AnimatedList } from '../MessageContainer'
|
|
33
42
|
import { MessageImage } from '../MessageImage'
|
|
34
43
|
import { MessageText } from '../MessageText'
|
|
35
|
-
import {
|
|
36
|
-
IMessage,
|
|
37
|
-
} from '../types'
|
|
38
44
|
import { Send } from '../Send'
|
|
45
|
+
import stylesCommon from '../styles'
|
|
39
46
|
import { SystemMessage } from '../SystemMessage'
|
|
40
47
|
import { Time } from '../Time'
|
|
41
|
-
import
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
useAnimatedReaction,
|
|
45
|
-
useSharedValue,
|
|
46
|
-
withTiming,
|
|
47
|
-
runOnJS,
|
|
48
|
-
} from 'react-native-reanimated'
|
|
49
|
-
import { KeyboardProvider, useReanimatedKeyboardAnimation } from 'react-native-keyboard-controller'
|
|
50
|
-
import { GiftedChatProps } from './types'
|
|
48
|
+
import {
|
|
49
|
+
IMessage,
|
|
50
|
+
} from '../types'
|
|
51
51
|
|
|
52
|
-
import
|
|
52
|
+
import * as utils from '../utils'
|
|
53
53
|
import styles from './styles'
|
|
54
|
+
import { GiftedChatProps } from './types'
|
|
54
55
|
|
|
55
56
|
dayjs.extend(localizedFormat)
|
|
56
57
|
|
|
@@ -75,14 +76,13 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
75
76
|
textInputProps,
|
|
76
77
|
renderChatFooter,
|
|
77
78
|
renderInputToolbar,
|
|
78
|
-
|
|
79
|
+
keyboardBottomOffset = 0,
|
|
79
80
|
focusOnInputWhenOpeningKeyboard = true,
|
|
80
81
|
onInputTextChanged,
|
|
81
82
|
inverted = true,
|
|
82
83
|
minComposerHeight = MIN_COMPOSER_HEIGHT,
|
|
83
84
|
maxComposerHeight = MAX_COMPOSER_HEIGHT,
|
|
84
85
|
isKeyboardInternallyHandled = true,
|
|
85
|
-
disableKeyboardController = false,
|
|
86
86
|
} = props
|
|
87
87
|
|
|
88
88
|
const actionSheetRef = useRef<ActionSheetProviderRef>(null)
|
|
@@ -108,23 +108,24 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
108
108
|
// Always call the hook, but conditionally use its data
|
|
109
109
|
const keyboardControllerData = useReanimatedKeyboardAnimation()
|
|
110
110
|
|
|
111
|
-
// Create a mock keyboard object when
|
|
111
|
+
// Create a mock keyboard object when keyboard is not internally handled
|
|
112
112
|
const keyboard = useMemo(() => {
|
|
113
|
-
if (
|
|
113
|
+
if (!isKeyboardInternallyHandled)
|
|
114
114
|
return { height: { value: 0 } }
|
|
115
|
+
|
|
115
116
|
return keyboardControllerData
|
|
116
|
-
}, [
|
|
117
|
+
}, [isKeyboardInternallyHandled, keyboardControllerData])
|
|
117
118
|
|
|
118
119
|
const trackingKeyboardMovement = useSharedValue(false)
|
|
119
|
-
const
|
|
120
|
+
const keyboardBottomOffsetAnim = useSharedValue(0)
|
|
120
121
|
|
|
121
122
|
const contentStyleAnim = useAnimatedStyle(
|
|
122
123
|
() => ({
|
|
123
124
|
transform: [
|
|
124
|
-
{ translateY: keyboard.height.value
|
|
125
|
+
{ translateY: keyboard.height.value + keyboardBottomOffsetAnim.value },
|
|
125
126
|
],
|
|
126
127
|
}),
|
|
127
|
-
[keyboard,
|
|
128
|
+
[keyboard, keyboardBottomOffsetAnim]
|
|
128
129
|
)
|
|
129
130
|
|
|
130
131
|
const getTextFromProp = useCallback(
|
|
@@ -278,6 +279,7 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
278
279
|
|
|
279
280
|
const onInitialLayoutViewLayout = useCallback(
|
|
280
281
|
(e: LayoutChangeEvent) => {
|
|
282
|
+
console.log('onInitialLayoutViewLayout', e.nativeEvent.layout.height)
|
|
281
283
|
if (isInitialized)
|
|
282
284
|
return
|
|
283
285
|
|
|
@@ -349,23 +351,23 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
349
351
|
setText(props.text)
|
|
350
352
|
}, [props.text])
|
|
351
353
|
|
|
352
|
-
// Only set up keyboard animation when keyboard
|
|
354
|
+
// Only set up keyboard animation when keyboard is internally handled
|
|
353
355
|
useAnimatedReaction(
|
|
354
|
-
() =>
|
|
356
|
+
() => isKeyboardInternallyHandled ? keyboard.height.value : 0,
|
|
355
357
|
(value, prevValue) => {
|
|
356
|
-
// Skip keyboard handling when
|
|
357
|
-
if (
|
|
358
|
+
// Skip keyboard handling when not internally handled
|
|
359
|
+
if (!isKeyboardInternallyHandled)
|
|
358
360
|
return
|
|
359
361
|
|
|
360
362
|
if (prevValue !== null && value !== prevValue) {
|
|
361
|
-
const isKeyboardMovingUp = value
|
|
363
|
+
const isKeyboardMovingUp = value < prevValue
|
|
362
364
|
if (isKeyboardMovingUp !== trackingKeyboardMovement.value) {
|
|
363
365
|
trackingKeyboardMovement.value = isKeyboardMovingUp
|
|
364
|
-
|
|
365
|
-
isKeyboardMovingUp ?
|
|
366
|
+
keyboardBottomOffsetAnim.value = withTiming(
|
|
367
|
+
isKeyboardMovingUp ? keyboardBottomOffset : 0,
|
|
366
368
|
{
|
|
367
|
-
// If `
|
|
368
|
-
duration:
|
|
369
|
+
// If `keyboardBottomOffset` exists, we change the duration to a smaller value to fix the delay in the keyboard animation speed
|
|
370
|
+
duration: keyboardBottomOffset ? 150 : 400,
|
|
369
371
|
}
|
|
370
372
|
)
|
|
371
373
|
|
|
@@ -383,8 +385,8 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
383
385
|
focusOnInputWhenOpeningKeyboard,
|
|
384
386
|
handleTextInputFocusWhenKeyboardHide,
|
|
385
387
|
handleTextInputFocusWhenKeyboardShow,
|
|
386
|
-
|
|
387
|
-
|
|
388
|
+
keyboardBottomOffset,
|
|
389
|
+
isKeyboardInternallyHandled,
|
|
388
390
|
]
|
|
389
391
|
)
|
|
390
392
|
|
|
@@ -398,7 +400,7 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
398
400
|
>
|
|
399
401
|
{isInitialized
|
|
400
402
|
? (
|
|
401
|
-
<Animated.View style={[stylesCommon.fill,
|
|
403
|
+
<Animated.View style={[stylesCommon.fill, isKeyboardInternallyHandled && contentStyleAnim]}>
|
|
402
404
|
{renderMessages}
|
|
403
405
|
{inputToolbarFragment}
|
|
404
406
|
</Animated.View>
|
|
@@ -413,14 +415,16 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
413
415
|
}
|
|
414
416
|
|
|
415
417
|
function GiftedChatWrapper<TMessage extends IMessage = IMessage> (props: GiftedChatProps<TMessage>) {
|
|
416
|
-
// Don't use KeyboardProvider when keyboard
|
|
417
|
-
if (props.
|
|
418
|
+
// Don't use KeyboardProvider when keyboard is not internally handled
|
|
419
|
+
if (!props.isKeyboardInternallyHandled)
|
|
418
420
|
return <GiftedChat<TMessage> {...props} />
|
|
419
421
|
|
|
420
422
|
return (
|
|
421
|
-
<
|
|
422
|
-
<
|
|
423
|
-
|
|
423
|
+
<GestureHandlerRootView style={styles.fill}>
|
|
424
|
+
<KeyboardProvider>
|
|
425
|
+
<GiftedChat<TMessage> {...props} />
|
|
426
|
+
</KeyboardProvider>
|
|
427
|
+
</GestureHandlerRootView>
|
|
424
428
|
)
|
|
425
429
|
}
|
|
426
430
|
|
package/src/GiftedChat/styles.ts
CHANGED
package/src/GiftedChat/types.ts
CHANGED
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
import React, { RefObject } from 'react'
|
|
2
|
-
import {
|
|
3
|
-
ActionSheetOptions,
|
|
4
|
-
} from '@expo/react-native-action-sheet'
|
|
5
2
|
import {
|
|
6
3
|
TextInput,
|
|
7
4
|
StyleProp,
|
|
8
5
|
TextStyle,
|
|
9
6
|
ViewStyle,
|
|
10
7
|
} from 'react-native'
|
|
11
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
ActionSheetOptions,
|
|
10
|
+
} from '@expo/react-native-action-sheet'
|
|
12
11
|
import { ActionsProps } from '../Actions'
|
|
13
12
|
import { AvatarProps } from '../Avatar'
|
|
13
|
+
import { BubbleProps } from '../Bubble'
|
|
14
14
|
import { ComposerProps } from '../Composer'
|
|
15
15
|
import { InputToolbarProps } from '../InputToolbar'
|
|
16
16
|
import { MessageProps } from '../Message'
|
|
17
|
+
import { AnimatedList, MessageContainerProps } from '../MessageContainer'
|
|
17
18
|
import { MessageImageProps } from '../MessageImage'
|
|
18
19
|
import { MessageTextProps } from '../MessageText'
|
|
20
|
+
import { QuickRepliesProps } from '../QuickReplies'
|
|
21
|
+
import { SendProps } from '../Send'
|
|
22
|
+
import { SystemMessageProps } from '../SystemMessage'
|
|
23
|
+
import { TimeProps } from '../Time'
|
|
19
24
|
import {
|
|
20
25
|
IMessage,
|
|
21
26
|
LeftRightStyle,
|
|
@@ -23,12 +28,6 @@ import {
|
|
|
23
28
|
MessageVideoProps,
|
|
24
29
|
User,
|
|
25
30
|
} from '../types'
|
|
26
|
-
import { QuickRepliesProps } from '../QuickReplies'
|
|
27
|
-
import { SendProps } from '../Send'
|
|
28
|
-
import { SystemMessageProps } from '../SystemMessage'
|
|
29
|
-
import { TimeProps } from '../Time'
|
|
30
|
-
import { AnimatedList, MessageContainerProps } from '../MessageContainer'
|
|
31
|
-
import { BubbleProps } from '../Bubble'
|
|
32
31
|
|
|
33
32
|
export interface GiftedChatProps<TMessage extends IMessage> extends Partial<MessageContainerProps<TMessage>> {
|
|
34
33
|
/* Message container ref */
|
|
@@ -54,8 +53,6 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
|
|
|
54
53
|
dateFormatCalendar?: object
|
|
55
54
|
/* 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` */
|
|
56
55
|
isKeyboardInternallyHandled?: boolean
|
|
57
|
-
/* Completely disable react-native-keyboard-controller. Useful when using react-native-navigation or other conflicting keyboard libraries; default is `false` */
|
|
58
|
-
disableKeyboardController?: boolean
|
|
59
56
|
/* Whether to render an avatar for the current user; default is false, only show avatars for other users */
|
|
60
57
|
showUserAvatar?: boolean
|
|
61
58
|
/* When false, avatars will only be displayed when a consecutive message is from the same user on the same day; default is false */
|
|
@@ -64,10 +61,8 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
|
|
|
64
61
|
renderAvatarOnTop?: boolean
|
|
65
62
|
/* Extra props to be passed to the <Image> component created by the default renderMessageImage */
|
|
66
63
|
imageProps?: MessageImageProps<TMessage>
|
|
67
|
-
/* Extra props to be passed to the MessageImage's Lightbox */
|
|
68
|
-
lightboxProps?: LightboxProps
|
|
69
64
|
/* Distance of the chat from the bottom of the screen (e.g. useful if you display a tab bar); default is 0 */
|
|
70
|
-
|
|
65
|
+
keyboardBottomOffset?: number
|
|
71
66
|
/* Focus on <TextInput> automatically when opening the keyboard; default is true */
|
|
72
67
|
focusOnInputWhenOpeningKeyboard?: boolean
|
|
73
68
|
/* Minimum height of the input toolbar; default is 44 */
|
|
@@ -148,7 +143,9 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
|
|
|
148
143
|
onPressActionButton?(): void
|
|
149
144
|
/* Callback when the input text changes */
|
|
150
145
|
onInputTextChanged?(text: string): void
|
|
151
|
-
/*
|
|
146
|
+
/* Extra props to be passed to the MessageText component */
|
|
147
|
+
messageTextProps?: Partial<MessageTextProps<TMessage>>
|
|
148
|
+
/* Custom parse patterns for react-native-autolink used to linking message content (like URLs and phone numbers) */
|
|
152
149
|
matchers?: MessageTextProps<TMessage>['matchers']
|
|
153
150
|
renderQuickReplies?(
|
|
154
151
|
quickReplies: QuickRepliesProps<TMessage>,
|