react-native-gifted-chat 2.9.0-alpha.0 → 3.0.0-alpha.0
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 +183 -262
- package/package.json +1 -1
- package/src/Avatar.tsx +12 -12
- package/src/Bubble/index.tsx +2 -2
- package/src/Bubble/types.ts +22 -22
- package/src/Composer.tsx +0 -3
- package/src/GiftedAvatar.tsx +1 -1
- package/src/GiftedChat/index.tsx +20 -23
- package/src/GiftedChat/types.ts +38 -47
- package/src/InputToolbar.tsx +6 -6
- package/src/Message/index.tsx +5 -6
- package/src/Message/types.ts +8 -12
- package/src/MessageContainer/components/DayAnimated/types.ts +1 -1
- package/src/MessageContainer/components/Item/index.tsx +2 -2
- package/src/MessageContainer/components/Item/types.ts +1 -1
- package/src/MessageContainer/index.tsx +28 -30
- package/src/MessageContainer/types.ts +12 -16
- package/src/MessageImage.tsx +1 -1
- package/src/MessageText.tsx +1 -1
- package/src/Models.ts +63 -0
- package/src/QuickReplies.tsx +1 -1
- package/src/Send.tsx +30 -31
- package/src/SystemMessage.tsx +1 -1
- package/src/Time.tsx +1 -1
- package/src/__tests__/Message.test.tsx +2 -2
- package/src/__tests__/Send.test.tsx +1 -1
- package/src/__tests__/__snapshots__/Actions.test.tsx.snap +2 -86
- package/src/__tests__/__snapshots__/LoadEarlier.test.tsx.snap +3 -89
- package/src/__tests__/__snapshots__/Message.test.tsx.snap +2 -2
- package/src/__tests__/__snapshots__/Send.test.tsx.snap +10 -142
- package/src/__tests__/data.ts +1 -1
- package/src/components/TouchableOpacity.tsx +19 -8
- package/src/types.ts +1 -63
- package/src/utils.ts +1 -1
package/src/Bubble/types.ts
CHANGED
|
@@ -6,8 +6,6 @@ import {
|
|
|
6
6
|
} from 'react-native'
|
|
7
7
|
import { MessageImageProps } from '../MessageImage'
|
|
8
8
|
import { MessageTextProps } from '../MessageText'
|
|
9
|
-
import { QuickRepliesProps } from '../QuickReplies'
|
|
10
|
-
import { TimeProps } from '../Time'
|
|
11
9
|
import {
|
|
12
10
|
User,
|
|
13
11
|
IMessage,
|
|
@@ -16,7 +14,9 @@ import {
|
|
|
16
14
|
Omit,
|
|
17
15
|
MessageVideoProps,
|
|
18
16
|
MessageAudioProps,
|
|
19
|
-
} from '../
|
|
17
|
+
} from '../Models'
|
|
18
|
+
import { QuickRepliesProps } from '../QuickReplies'
|
|
19
|
+
import { TimeProps } from '../Time'
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
export type RenderMessageImageProps<TMessage extends IMessage> = Omit<
|
|
@@ -47,9 +47,9 @@ export type RenderMessageTextProps<TMessage extends IMessage> = Omit<
|
|
|
47
47
|
export interface BubbleProps<TMessage extends IMessage> {
|
|
48
48
|
user?: User
|
|
49
49
|
touchableProps?: object
|
|
50
|
-
|
|
50
|
+
isUsernameVisible?: boolean
|
|
51
51
|
isCustomViewBottom?: boolean
|
|
52
|
-
|
|
52
|
+
isInverted?: boolean
|
|
53
53
|
position: 'left' | 'right'
|
|
54
54
|
currentMessage: TMessage
|
|
55
55
|
nextMessage?: TMessage
|
|
@@ -66,25 +66,25 @@ export interface BubbleProps<TMessage extends IMessage> {
|
|
|
66
66
|
quickReplyTextStyle?: StyleProp<TextStyle>
|
|
67
67
|
quickReplyContainerStyle?: StyleProp<ViewStyle>
|
|
68
68
|
messageTextProps?: Partial<MessageTextProps<TMessage>>
|
|
69
|
-
onPressMessage
|
|
70
|
-
onLongPressMessage
|
|
71
|
-
onQuickReply
|
|
72
|
-
renderMessageImage
|
|
69
|
+
onPressMessage?: (context?: unknown, message?: unknown) => void
|
|
70
|
+
onLongPressMessage?: (context?: unknown, message?: unknown) => void
|
|
71
|
+
onQuickReply?: (replies: Reply[]) => void
|
|
72
|
+
renderMessageImage?: (
|
|
73
73
|
props: RenderMessageImageProps<TMessage>,
|
|
74
|
-
)
|
|
75
|
-
renderMessageVideo
|
|
74
|
+
) => React.ReactNode
|
|
75
|
+
renderMessageVideo?: (
|
|
76
76
|
props: RenderMessageVideoProps<TMessage>,
|
|
77
|
-
)
|
|
78
|
-
renderMessageAudio
|
|
77
|
+
) => React.ReactNode
|
|
78
|
+
renderMessageAudio?: (
|
|
79
79
|
props: RenderMessageAudioProps<TMessage>,
|
|
80
|
-
)
|
|
81
|
-
renderMessageText
|
|
82
|
-
renderCustomView
|
|
83
|
-
renderTime
|
|
84
|
-
renderTicks
|
|
85
|
-
renderUsername
|
|
86
|
-
renderQuickReplySend
|
|
87
|
-
renderQuickReplies
|
|
80
|
+
) => React.ReactNode
|
|
81
|
+
renderMessageText?: (props: RenderMessageTextProps<TMessage>) => React.ReactNode
|
|
82
|
+
renderCustomView?: (bubbleProps: BubbleProps<TMessage>) => React.ReactNode
|
|
83
|
+
renderTime?: (timeProps: TimeProps<TMessage>) => React.ReactNode
|
|
84
|
+
renderTicks?: (currentMessage: TMessage) => React.ReactNode
|
|
85
|
+
renderUsername?: (user?: TMessage['user']) => React.ReactNode
|
|
86
|
+
renderQuickReplySend?: () => React.ReactNode
|
|
87
|
+
renderQuickReplies?: (
|
|
88
88
|
quickReplies: QuickRepliesProps<TMessage>,
|
|
89
|
-
)
|
|
89
|
+
) => React.ReactNode
|
|
90
90
|
}
|
package/src/Composer.tsx
CHANGED
|
@@ -16,14 +16,12 @@ export interface ComposerProps {
|
|
|
16
16
|
composerHeight?: number
|
|
17
17
|
text?: string
|
|
18
18
|
textInputProps?: Partial<TextInputProps>
|
|
19
|
-
onTextChanged?(text: string): void
|
|
20
19
|
onInputSizeChanged?(layout: { width: number, height: number }): void
|
|
21
20
|
}
|
|
22
21
|
|
|
23
22
|
export function Composer ({
|
|
24
23
|
composerHeight = MIN_COMPOSER_HEIGHT,
|
|
25
24
|
onInputSizeChanged,
|
|
26
|
-
onTextChanged,
|
|
27
25
|
text = '',
|
|
28
26
|
textInputProps,
|
|
29
27
|
}: ComposerProps): React.ReactElement {
|
|
@@ -67,7 +65,6 @@ export function Composer ({
|
|
|
67
65
|
accessibilityLabel={placeholder}
|
|
68
66
|
placeholderTextColor={textInputProps?.placeholderTextColor ?? (isDark ? '#888' : Color.defaultColor)}
|
|
69
67
|
onContentSizeChange={handleContentSizeChange}
|
|
70
|
-
onChangeText={onTextChanged}
|
|
71
68
|
value={text}
|
|
72
69
|
enablesReturnKeyAutomatically
|
|
73
70
|
underlineColorAndroid='transparent'
|
package/src/GiftedAvatar.tsx
CHANGED
|
@@ -10,8 +10,8 @@ import {
|
|
|
10
10
|
} from 'react-native'
|
|
11
11
|
import { Color } from './Color'
|
|
12
12
|
import { TouchableOpacity } from './components/TouchableOpacity'
|
|
13
|
+
import { User } from './Models'
|
|
13
14
|
import stylesCommon from './styles'
|
|
14
|
-
import { User } from './types'
|
|
15
15
|
|
|
16
16
|
const {
|
|
17
17
|
carrot,
|
package/src/GiftedChat/index.tsx
CHANGED
|
@@ -32,10 +32,8 @@ import { MAX_COMPOSER_HEIGHT, MIN_COMPOSER_HEIGHT, TEST_ID } from '../Constant'
|
|
|
32
32
|
import { GiftedChatContext } from '../GiftedChatContext'
|
|
33
33
|
import { InputToolbar } from '../InputToolbar'
|
|
34
34
|
import { MessageContainer, AnimatedList } from '../MessageContainer'
|
|
35
|
+
import { IMessage } from '../Models'
|
|
35
36
|
import stylesCommon from '../styles'
|
|
36
|
-
import {
|
|
37
|
-
IMessage,
|
|
38
|
-
} from '../types'
|
|
39
37
|
import { renderComponentOrElement } from '../utils'
|
|
40
38
|
import styles from './styles'
|
|
41
39
|
import { GiftedChatProps } from './types'
|
|
@@ -64,9 +62,8 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
64
62
|
renderChatFooter,
|
|
65
63
|
renderInputToolbar,
|
|
66
64
|
keyboardBottomOffset = 0,
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
inverted = true,
|
|
65
|
+
shouldFocusInputOnKeyboardOpen = true,
|
|
66
|
+
isInverted = true,
|
|
70
67
|
minComposerHeight = MIN_COMPOSER_HEIGHT,
|
|
71
68
|
maxComposerHeight = MAX_COMPOSER_HEIGHT,
|
|
72
69
|
isKeyboardInternallyHandled = true,
|
|
@@ -158,7 +155,7 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
158
155
|
if (!messageContainerRef?.current)
|
|
159
156
|
return
|
|
160
157
|
|
|
161
|
-
if (
|
|
158
|
+
if (isInverted) {
|
|
162
159
|
messageContainerRef.current.scrollToOffset({
|
|
163
160
|
offset: 0,
|
|
164
161
|
animated: isAnimated,
|
|
@@ -168,7 +165,7 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
168
165
|
|
|
169
166
|
messageContainerRef.current.scrollToEnd({ animated: isAnimated })
|
|
170
167
|
},
|
|
171
|
-
[
|
|
168
|
+
[isInverted, messageContainerRef]
|
|
172
169
|
)
|
|
173
170
|
|
|
174
171
|
const renderMessages = useMemo(() => {
|
|
@@ -181,7 +178,7 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
181
178
|
<View style={[stylesCommon.fill, messagesContainerStyle]}>
|
|
182
179
|
<MessageContainer<TMessage>
|
|
183
180
|
{...messagesContainerProps}
|
|
184
|
-
|
|
181
|
+
isInverted={isInverted}
|
|
185
182
|
messages={messages}
|
|
186
183
|
forwardRef={messageContainerRef}
|
|
187
184
|
isTyping={isTyping}
|
|
@@ -194,14 +191,14 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
194
191
|
isTyping,
|
|
195
192
|
messages,
|
|
196
193
|
props,
|
|
197
|
-
|
|
194
|
+
isInverted,
|
|
198
195
|
messageContainerRef,
|
|
199
196
|
renderChatFooter,
|
|
200
197
|
])
|
|
201
198
|
|
|
202
199
|
const notifyInputTextReset = useCallback(() => {
|
|
203
|
-
|
|
204
|
-
}, [
|
|
200
|
+
props.textInputProps?.onChangeText?.('')
|
|
201
|
+
}, [props.textInputProps])
|
|
205
202
|
|
|
206
203
|
const resetInputToolbar = useCallback(() => {
|
|
207
204
|
textInputRef.current?.clear()
|
|
@@ -253,15 +250,15 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
253
250
|
[maxComposerHeight, minComposerHeight]
|
|
254
251
|
)
|
|
255
252
|
|
|
256
|
-
const
|
|
253
|
+
const _onChangeText = useCallback(
|
|
257
254
|
(text: string) => {
|
|
258
|
-
|
|
255
|
+
props.textInputProps?.onChangeText?.(text)
|
|
259
256
|
|
|
260
257
|
// Only set state if it's not being overridden by a prop.
|
|
261
258
|
if (props.text === undefined)
|
|
262
259
|
setText(text)
|
|
263
260
|
},
|
|
264
|
-
[
|
|
261
|
+
[props.text, props.textInputProps]
|
|
265
262
|
)
|
|
266
263
|
|
|
267
264
|
const onInitialLayoutViewLayout = useCallback(
|
|
@@ -293,9 +290,9 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
293
290
|
composerHeight: Math.max(minComposerHeight!, composerHeight),
|
|
294
291
|
onSend: _onSend,
|
|
295
292
|
onInputSizeChanged,
|
|
296
|
-
onTextChanged: _onInputTextChanged,
|
|
297
293
|
textInputProps: {
|
|
298
294
|
...textInputProps,
|
|
295
|
+
onChangeText: _onChangeText,
|
|
299
296
|
ref: textInputRef,
|
|
300
297
|
},
|
|
301
298
|
}
|
|
@@ -316,7 +313,7 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
316
313
|
composerHeight,
|
|
317
314
|
textInputRef,
|
|
318
315
|
textInputProps,
|
|
319
|
-
|
|
316
|
+
_onChangeText,
|
|
320
317
|
])
|
|
321
318
|
|
|
322
319
|
const contextValues = useMemo(
|
|
@@ -357,7 +354,7 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
357
354
|
}
|
|
358
355
|
)
|
|
359
356
|
|
|
360
|
-
if (
|
|
357
|
+
if (shouldFocusInputOnKeyboardOpen)
|
|
361
358
|
if (isKeyboardMovingUp)
|
|
362
359
|
runOnJS(handleTextInputFocusWhenKeyboardShow)()
|
|
363
360
|
else
|
|
@@ -368,7 +365,7 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
368
365
|
[
|
|
369
366
|
keyboard,
|
|
370
367
|
trackingKeyboardMovement,
|
|
371
|
-
|
|
368
|
+
shouldFocusInputOnKeyboardOpen,
|
|
372
369
|
handleTextInputFocusWhenKeyboardHide,
|
|
373
370
|
handleTextInputFocusWhenKeyboardShow,
|
|
374
371
|
keyboardBottomOffset,
|
|
@@ -415,12 +412,12 @@ function GiftedChatWrapper<TMessage extends IMessage = IMessage> (props: GiftedC
|
|
|
415
412
|
GiftedChatWrapper.append = <TMessage extends IMessage>(
|
|
416
413
|
currentMessages: TMessage[] = [],
|
|
417
414
|
messages: TMessage[],
|
|
418
|
-
|
|
415
|
+
isInverted = true
|
|
419
416
|
) => {
|
|
420
417
|
if (!Array.isArray(messages))
|
|
421
418
|
messages = [messages]
|
|
422
419
|
|
|
423
|
-
return
|
|
420
|
+
return isInverted
|
|
424
421
|
? messages.concat(currentMessages)
|
|
425
422
|
: currentMessages.concat(messages)
|
|
426
423
|
}
|
|
@@ -428,12 +425,12 @@ GiftedChatWrapper.append = <TMessage extends IMessage>(
|
|
|
428
425
|
GiftedChatWrapper.prepend = <TMessage extends IMessage>(
|
|
429
426
|
currentMessages: TMessage[] = [],
|
|
430
427
|
messages: TMessage[],
|
|
431
|
-
|
|
428
|
+
isInverted = true
|
|
432
429
|
) => {
|
|
433
430
|
if (!Array.isArray(messages))
|
|
434
431
|
messages = [messages]
|
|
435
432
|
|
|
436
|
-
return
|
|
433
|
+
return isInverted
|
|
437
434
|
? currentMessages.concat(messages)
|
|
438
435
|
: messages.concat(currentMessages)
|
|
439
436
|
}
|
package/src/GiftedChat/types.ts
CHANGED
|
@@ -13,21 +13,20 @@ import { AvatarProps } from '../Avatar'
|
|
|
13
13
|
import { BubbleProps } from '../Bubble'
|
|
14
14
|
import { ComposerProps } from '../Composer'
|
|
15
15
|
import { InputToolbarProps } from '../InputToolbar'
|
|
16
|
-
import { MessageProps } from '../Message'
|
|
17
16
|
import { AnimatedList, MessageContainerProps } from '../MessageContainer'
|
|
18
17
|
import { MessageImageProps } from '../MessageImage'
|
|
19
18
|
import { MessageTextProps } from '../MessageText'
|
|
20
|
-
import { QuickRepliesProps } from '../QuickReplies'
|
|
21
|
-
import { SendProps } from '../Send'
|
|
22
|
-
import { SystemMessageProps } from '../SystemMessage'
|
|
23
|
-
import { TimeProps } from '../Time'
|
|
24
19
|
import {
|
|
25
20
|
IMessage,
|
|
26
21
|
LeftRightStyle,
|
|
27
22
|
MessageAudioProps,
|
|
28
23
|
MessageVideoProps,
|
|
29
24
|
User,
|
|
30
|
-
} from '../
|
|
25
|
+
} from '../Models'
|
|
26
|
+
import { QuickRepliesProps } from '../QuickReplies'
|
|
27
|
+
import { SendProps } from '../Send'
|
|
28
|
+
import { SystemMessageProps } from '../SystemMessage'
|
|
29
|
+
import { TimeProps } from '../Time'
|
|
31
30
|
|
|
32
31
|
export interface GiftedChatProps<TMessage extends IMessage> extends Partial<MessageContainerProps<TMessage>> {
|
|
33
32
|
/* Message container ref */
|
|
@@ -35,7 +34,7 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
|
|
|
35
34
|
/* text input ref */
|
|
36
35
|
textInputRef?: RefObject<TextInput>
|
|
37
36
|
/* Controls whether or not to show user.name property in the message bubble */
|
|
38
|
-
|
|
37
|
+
isUsernameVisible?: boolean
|
|
39
38
|
/* Messages container style */
|
|
40
39
|
messagesContainerStyle?: StyleProp<ViewStyle>
|
|
41
40
|
/* Input text; default is undefined, but if specified, it will override GiftedChat's internal state */
|
|
@@ -54,23 +53,23 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
|
|
|
54
53
|
/* 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` */
|
|
55
54
|
isKeyboardInternallyHandled?: boolean
|
|
56
55
|
/* Whether to render an avatar for the current user; default is false, only show avatars for other users */
|
|
57
|
-
|
|
56
|
+
isUserAvatarVisible?: boolean
|
|
58
57
|
/* When false, avatars will only be displayed when a consecutive message is from the same user on the same day; default is false */
|
|
59
|
-
|
|
58
|
+
isAvatarVisibleForEveryMessage?: boolean
|
|
60
59
|
/* Render the message avatar at the top of consecutive messages, rather than the bottom; default is false */
|
|
61
|
-
|
|
60
|
+
isAvatarOnTop?: boolean
|
|
62
61
|
/* Extra props to be passed to the <Image> component created by the default renderMessageImage */
|
|
63
62
|
imageProps?: MessageImageProps<TMessage>
|
|
64
63
|
/* Distance of the chat from the bottom of the screen (e.g. useful if you display a tab bar); default is 0 */
|
|
65
64
|
keyboardBottomOffset?: number
|
|
66
65
|
/* Focus on <TextInput> automatically when opening the keyboard; default is true */
|
|
67
|
-
|
|
66
|
+
shouldFocusInputOnKeyboardOpen?: boolean
|
|
68
67
|
/* Minimum height of the input toolbar; default is 44 */
|
|
69
68
|
minInputToolbarHeight?: number
|
|
70
69
|
/* Extra props to be passed to the <TextInput>. See https://reactnative.dev/docs/textinput */
|
|
71
70
|
textInputProps?: Partial<React.ComponentProps<typeof TextInput>>
|
|
72
71
|
/* Force send button */
|
|
73
|
-
|
|
72
|
+
isSendButtonAlwaysVisible?: boolean
|
|
74
73
|
/* Image style */
|
|
75
74
|
imageStyle?: StyleProp<ViewStyle>
|
|
76
75
|
/* composer min Height */
|
|
@@ -86,73 +85,65 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
|
|
|
86
85
|
isCustomViewBottom?: boolean
|
|
87
86
|
timeTextStyle?: LeftRightStyle<TextStyle>
|
|
88
87
|
/* Custom action sheet */
|
|
89
|
-
actionSheet
|
|
88
|
+
actionSheet?: () => {
|
|
90
89
|
showActionSheetWithOptions: (
|
|
91
90
|
options: ActionSheetOptions,
|
|
92
91
|
callback: (buttonIndex: number) => void | Promise<void>,
|
|
93
92
|
) => void
|
|
94
93
|
}
|
|
95
94
|
/* Callback when a message avatar is tapped */
|
|
96
|
-
onPressAvatar
|
|
95
|
+
onPressAvatar?: (user: User) => void
|
|
97
96
|
/* Callback when a message avatar is tapped */
|
|
98
|
-
onLongPressAvatar
|
|
99
|
-
/* Generate an id for new messages. Defaults to
|
|
100
|
-
messageIdGenerator
|
|
97
|
+
onLongPressAvatar?: (user: User) => void
|
|
98
|
+
/* Generate an id for new messages. Defaults to a simple random string generator */
|
|
99
|
+
messageIdGenerator?: (message?: TMessage) => string
|
|
101
100
|
/* Callback when sending a message */
|
|
102
|
-
onSend
|
|
101
|
+
onSend?: (messages: TMessage[]) => void
|
|
103
102
|
/* Render a loading view when initializing */
|
|
104
|
-
renderLoading
|
|
103
|
+
renderLoading?: () => React.ReactNode
|
|
105
104
|
/* Custom message avatar; set to null to not render any avatar for the message */
|
|
106
105
|
renderAvatar?: null | ((props: AvatarProps<TMessage>) => React.ReactNode)
|
|
107
106
|
/* Custom message bubble */
|
|
108
|
-
renderBubble
|
|
107
|
+
renderBubble?: (props: BubbleProps<TMessage>) => React.ReactNode
|
|
109
108
|
/* Custom system message */
|
|
110
|
-
renderSystemMessage
|
|
109
|
+
renderSystemMessage?: (props: SystemMessageProps<TMessage>) => React.ReactNode
|
|
111
110
|
/* Callback when a message bubble is pressed; default is to do nothing */
|
|
112
|
-
onPressMessage
|
|
111
|
+
onPressMessage?: (context: unknown, message: TMessage) => void
|
|
113
112
|
/* Callback when a message bubble is long-pressed; default is to show an ActionSheet with "Copy Text" (see example using showActionSheetWithOptions()) */
|
|
114
|
-
onLongPressMessage
|
|
113
|
+
onLongPressMessage?: (context: unknown, message: TMessage) => void
|
|
115
114
|
/* Custom Username container */
|
|
116
|
-
renderUsername
|
|
115
|
+
renderUsername?: (user: User) => React.ReactNode
|
|
117
116
|
/* Reverses display order of messages; default is true */
|
|
118
117
|
/* Custom message text */
|
|
119
|
-
renderMessageText
|
|
118
|
+
renderMessageText?: (messageText: MessageTextProps<TMessage>) => React.ReactNode
|
|
120
119
|
/* Custom message image */
|
|
121
|
-
renderMessageImage
|
|
120
|
+
renderMessageImage?: (props: MessageImageProps<TMessage>) => React.ReactNode
|
|
122
121
|
/* Custom message video */
|
|
123
|
-
renderMessageVideo
|
|
122
|
+
renderMessageVideo?: (props: MessageVideoProps<TMessage>) => React.ReactNode
|
|
124
123
|
/* Custom message video */
|
|
125
|
-
renderMessageAudio
|
|
124
|
+
renderMessageAudio?: (props: MessageAudioProps<TMessage>) => React.ReactNode
|
|
126
125
|
/* Custom view inside the bubble */
|
|
127
|
-
renderCustomView
|
|
126
|
+
renderCustomView?: (props: BubbleProps<TMessage>) => React.ReactNode
|
|
128
127
|
/* Custom time inside a message */
|
|
129
|
-
renderTime
|
|
128
|
+
renderTime?: (props: TimeProps<TMessage>) => React.ReactNode
|
|
130
129
|
/* Custom component to render below the MessageContainer (separate from the ListView) */
|
|
131
|
-
renderChatFooter
|
|
130
|
+
renderChatFooter?: () => React.ReactNode
|
|
132
131
|
/* Custom message composer container. Can be a component, element, render function, or null */
|
|
133
132
|
renderInputToolbar?: React.ComponentType<InputToolbarProps<TMessage>> | React.ReactElement | ((props: InputToolbarProps<TMessage>) => React.ReactNode) | null
|
|
134
133
|
/* Custom text input message composer */
|
|
135
|
-
renderComposer
|
|
134
|
+
renderComposer?: (props: ComposerProps) => React.ReactNode
|
|
136
135
|
/* Custom action button on the left of the message composer */
|
|
137
|
-
renderActions
|
|
136
|
+
renderActions?: (props: ActionsProps) => React.ReactNode
|
|
138
137
|
/* Custom send button; you can pass children to the original Send component quite easily, for example to use a custom icon (example) */
|
|
139
|
-
renderSend
|
|
138
|
+
renderSend?: (props: SendProps<TMessage>) => React.ReactNode
|
|
140
139
|
/* Custom second line of actions below the message composer */
|
|
141
|
-
renderAccessory
|
|
140
|
+
renderAccessory?: (props: InputToolbarProps<TMessage>) => React.ReactNode
|
|
142
141
|
/* Callback when the Action button is pressed (if set, the default actionSheet will not be used) */
|
|
143
|
-
onPressActionButton
|
|
144
|
-
/* Callback when the input text changes */
|
|
145
|
-
onInputTextChanged?(text: string): void
|
|
142
|
+
onPressActionButton?: () => void
|
|
146
143
|
/* Extra props to be passed to the MessageText component */
|
|
147
144
|
messageTextProps?: Partial<MessageTextProps<TMessage>>
|
|
148
|
-
|
|
149
|
-
matchers?: MessageTextProps<TMessage>['matchers']
|
|
150
|
-
renderQuickReplies?(
|
|
145
|
+
renderQuickReplies?: (
|
|
151
146
|
quickReplies: QuickRepliesProps<TMessage>,
|
|
152
|
-
)
|
|
153
|
-
renderQuickReplySend
|
|
154
|
-
shouldUpdateMessage?(
|
|
155
|
-
props: MessageProps<TMessage>,
|
|
156
|
-
nextProps: MessageProps<TMessage>,
|
|
157
|
-
): boolean
|
|
147
|
+
) => React.ReactNode
|
|
148
|
+
renderQuickReplySend?: () => React.ReactNode
|
|
158
149
|
}
|
package/src/InputToolbar.tsx
CHANGED
|
@@ -4,8 +4,8 @@ import { StyleSheet, View, StyleProp, ViewStyle, useColorScheme } from 'react-na
|
|
|
4
4
|
import { Actions, ActionsProps } from './Actions'
|
|
5
5
|
import { Color } from './Color'
|
|
6
6
|
import { Composer, ComposerProps } from './Composer'
|
|
7
|
+
import { IMessage } from './Models'
|
|
7
8
|
import { Send, SendProps } from './Send'
|
|
8
|
-
import { IMessage } from './types'
|
|
9
9
|
import { renderComponentOrElement } from './utils'
|
|
10
10
|
|
|
11
11
|
export interface InputToolbarProps<TMessage extends IMessage> {
|
|
@@ -14,11 +14,11 @@ export interface InputToolbarProps<TMessage extends IMessage> {
|
|
|
14
14
|
containerStyle?: StyleProp<ViewStyle>
|
|
15
15
|
primaryStyle?: StyleProp<ViewStyle>
|
|
16
16
|
accessoryStyle?: StyleProp<ViewStyle>
|
|
17
|
-
renderAccessory
|
|
18
|
-
renderActions
|
|
19
|
-
renderSend
|
|
20
|
-
renderComposer
|
|
21
|
-
onPressActionButton
|
|
17
|
+
renderAccessory?: (props: InputToolbarProps<TMessage>) => React.ReactNode
|
|
18
|
+
renderActions?: (props: ActionsProps) => React.ReactNode
|
|
19
|
+
renderSend?: (props: SendProps<TMessage>) => React.ReactNode
|
|
20
|
+
renderComposer?: (props: ComposerProps) => React.ReactNode
|
|
21
|
+
onPressActionButton?: () => void
|
|
22
22
|
icon?: () => React.ReactNode
|
|
23
23
|
wrapperStyle?: StyleProp<ViewStyle>
|
|
24
24
|
}
|
package/src/Message/index.tsx
CHANGED
|
@@ -3,9 +3,8 @@ import { View } from 'react-native'
|
|
|
3
3
|
|
|
4
4
|
import { Avatar } from '../Avatar'
|
|
5
5
|
import { Bubble } from '../Bubble'
|
|
6
|
+
import { IMessage } from '../Models'
|
|
6
7
|
import { SystemMessage } from '../SystemMessage'
|
|
7
|
-
|
|
8
|
-
import { IMessage } from '../types'
|
|
9
8
|
import { isSameUser, renderComponentOrElement } from '../utils'
|
|
10
9
|
import styles from './styles'
|
|
11
10
|
import { MessageProps } from './types'
|
|
@@ -22,7 +21,7 @@ export const Message = <TMessage extends IMessage = IMessage>(props: MessageProp
|
|
|
22
21
|
position,
|
|
23
22
|
containerStyle,
|
|
24
23
|
user,
|
|
25
|
-
|
|
24
|
+
isUserAvatarVisible,
|
|
26
25
|
} = props
|
|
27
26
|
|
|
28
27
|
const renderBubble = useCallback(() => {
|
|
@@ -60,7 +59,7 @@ export const Message = <TMessage extends IMessage = IMessage>(props: MessageProp
|
|
|
60
59
|
user?._id &&
|
|
61
60
|
currentMessage?.user &&
|
|
62
61
|
user._id === currentMessage.user._id &&
|
|
63
|
-
!
|
|
62
|
+
!isUserAvatarVisible
|
|
64
63
|
)
|
|
65
64
|
return null
|
|
66
65
|
|
|
@@ -80,7 +79,7 @@ export const Message = <TMessage extends IMessage = IMessage>(props: MessageProp
|
|
|
80
79
|
props,
|
|
81
80
|
user,
|
|
82
81
|
currentMessage,
|
|
83
|
-
|
|
82
|
+
isUserAvatarVisible,
|
|
84
83
|
])
|
|
85
84
|
|
|
86
85
|
if (!currentMessage)
|
|
@@ -99,7 +98,7 @@ export const Message = <TMessage extends IMessage = IMessage>(props: MessageProp
|
|
|
99
98
|
style={[
|
|
100
99
|
styles[position].container,
|
|
101
100
|
{ marginBottom: sameUser ? 2 : 10 },
|
|
102
|
-
!props.
|
|
101
|
+
!props.isInverted && { marginBottom: 2 },
|
|
103
102
|
containerStyle?.[position],
|
|
104
103
|
]}
|
|
105
104
|
>
|
package/src/Message/types.ts
CHANGED
|
@@ -2,25 +2,21 @@ import { ViewStyle, LayoutChangeEvent } from 'react-native'
|
|
|
2
2
|
import { AvatarProps } from '../Avatar'
|
|
3
3
|
import { BubbleProps } from '../Bubble'
|
|
4
4
|
import { DayProps } from '../Day'
|
|
5
|
+
import { IMessage, User, LeftRightStyle } from '../Models'
|
|
5
6
|
import { SystemMessageProps } from '../SystemMessage'
|
|
6
|
-
import { IMessage, User, LeftRightStyle } from '../types'
|
|
7
7
|
|
|
8
8
|
export interface MessageProps<TMessage extends IMessage> {
|
|
9
|
-
|
|
9
|
+
isUserAvatarVisible?: boolean
|
|
10
10
|
position: 'left' | 'right'
|
|
11
11
|
currentMessage: TMessage
|
|
12
12
|
nextMessage?: TMessage
|
|
13
13
|
previousMessage?: TMessage
|
|
14
14
|
user: User
|
|
15
|
-
|
|
15
|
+
isInverted?: boolean
|
|
16
16
|
containerStyle?: LeftRightStyle<ViewStyle>
|
|
17
|
-
renderBubble
|
|
18
|
-
renderDay
|
|
19
|
-
renderSystemMessage
|
|
20
|
-
renderAvatar
|
|
21
|
-
|
|
22
|
-
props: MessageProps<IMessage>,
|
|
23
|
-
nextProps: MessageProps<IMessage>,
|
|
24
|
-
): boolean
|
|
25
|
-
onMessageLayout?(event: LayoutChangeEvent): void
|
|
17
|
+
renderBubble?: (props: BubbleProps<TMessage>) => React.ReactNode
|
|
18
|
+
renderDay?: (props: DayProps) => React.ReactNode
|
|
19
|
+
renderSystemMessage?: (props: SystemMessageProps<TMessage>) => React.ReactNode
|
|
20
|
+
renderAvatar?: (props: AvatarProps<TMessage>) => React.ReactNode
|
|
21
|
+
onMessageLayout?: (event: LayoutChangeEvent) => void
|
|
26
22
|
}
|
|
@@ -2,8 +2,8 @@ import React, { useCallback, useMemo } from 'react'
|
|
|
2
2
|
import { LayoutChangeEvent, View } from 'react-native'
|
|
3
3
|
import Animated, { interpolate, useAnimatedStyle, useDerivedValue, useSharedValue } from 'react-native-reanimated'
|
|
4
4
|
import { Day } from '../../../Day'
|
|
5
|
-
import { Message,MessageProps } from '../../../Message'
|
|
6
|
-
import { IMessage } from '../../../
|
|
5
|
+
import { Message, MessageProps } from '../../../Message'
|
|
6
|
+
import { IMessage } from '../../../Models'
|
|
7
7
|
import { isSameDay } from '../../../utils'
|
|
8
8
|
import { DaysPositions } from '../../types'
|
|
9
9
|
import { ItemProps } from './types'
|