react-native-gifted-chat 2.8.2-alpha.6 → 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.
Files changed (66) hide show
  1. package/README.md +190 -269
  2. package/package.json +2 -1
  3. package/src/Actions.tsx +1 -1
  4. package/src/Avatar.tsx +12 -12
  5. package/src/Bubble/index.tsx +14 -16
  6. package/src/Bubble/styles.ts +1 -1
  7. package/src/Bubble/types.ts +26 -27
  8. package/src/Color.ts +1 -1
  9. package/src/Composer.tsx +1 -4
  10. package/src/Day/styles.ts +1 -1
  11. package/src/GiftedAvatar.tsx +2 -2
  12. package/src/GiftedChat/index.tsx +26 -61
  13. package/src/GiftedChat/types.ts +40 -49
  14. package/src/InputToolbar.tsx +28 -19
  15. package/src/LoadEarlierMessages.tsx +1 -1
  16. package/src/Message/index.tsx +11 -14
  17. package/src/Message/types.ts +8 -12
  18. package/src/MessageAudio.tsx +1 -1
  19. package/src/MessageContainer/components/DayAnimated/index.tsx +1 -3
  20. package/src/MessageContainer/components/DayAnimated/types.ts +1 -1
  21. package/src/MessageContainer/components/Item/index.tsx +9 -11
  22. package/src/MessageContainer/components/Item/types.ts +1 -1
  23. package/src/MessageContainer/index.tsx +32 -36
  24. package/src/MessageContainer/styles.ts +1 -1
  25. package/src/MessageContainer/types.ts +12 -16
  26. package/src/MessageImage.tsx +1 -1
  27. package/src/MessageText.tsx +1 -1
  28. package/src/MessageVideo.tsx +1 -1
  29. package/src/Models.ts +63 -0
  30. package/src/QuickReplies.tsx +2 -2
  31. package/src/Send.tsx +31 -32
  32. package/src/SystemMessage.tsx +2 -2
  33. package/src/Time.tsx +6 -6
  34. package/src/TypingIndicator/index.tsx +1 -3
  35. package/src/TypingIndicator/styles.ts +1 -1
  36. package/src/__tests__/Actions.test.tsx +1 -1
  37. package/src/__tests__/Avatar.test.tsx +7 -2
  38. package/src/__tests__/Bubble.test.tsx +3 -7
  39. package/src/__tests__/Color.test.tsx +1 -1
  40. package/src/__tests__/Composer.test.tsx +1 -1
  41. package/src/__tests__/Day.test.tsx +3 -3
  42. package/src/__tests__/DayAnimated.test.tsx +5 -11
  43. package/src/__tests__/GiftedAvatar.test.tsx +1 -1
  44. package/src/__tests__/GiftedChat.test.tsx +1 -1
  45. package/src/__tests__/InputToolbar.test.tsx +1 -1
  46. package/src/__tests__/LoadEarlier.test.tsx +2 -2
  47. package/src/__tests__/Message.test.tsx +7 -13
  48. package/src/__tests__/MessageContainer.test.tsx +4 -4
  49. package/src/__tests__/MessageImage.test.tsx +2 -2
  50. package/src/__tests__/MessageText.test.tsx +3 -2
  51. package/src/__tests__/Send.test.tsx +2 -2
  52. package/src/__tests__/SystemMessage.test.tsx +1 -1
  53. package/src/__tests__/Time.test.tsx +1 -1
  54. package/src/__tests__/__snapshots__/Actions.test.tsx.snap +2 -86
  55. package/src/__tests__/__snapshots__/Bubble.test.tsx.snap +1 -1
  56. package/src/__tests__/__snapshots__/Day.test.tsx.snap +96 -2
  57. package/src/__tests__/__snapshots__/InputToolbar.test.tsx.snap +1 -1
  58. package/src/__tests__/__snapshots__/LoadEarlier.test.tsx.snap +3 -89
  59. package/src/__tests__/__snapshots__/Message.test.tsx.snap +43 -4
  60. package/src/__tests__/__snapshots__/MessageText.test.tsx.snap +1 -1
  61. package/src/__tests__/__snapshots__/Send.test.tsx.snap +10 -142
  62. package/src/__tests__/data.ts +2 -2
  63. package/src/components/TouchableOpacity.tsx +19 -8
  64. package/src/index.ts +19 -1
  65. package/src/types.ts +1 -63
  66. package/src/utils.ts +23 -2
@@ -2,10 +2,11 @@ import React, { useMemo } from 'react'
2
2
  import { StyleSheet, View, StyleProp, ViewStyle, useColorScheme } from 'react-native'
3
3
 
4
4
  import { Actions, ActionsProps } from './Actions'
5
- import Color from './Color'
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
+ import { renderComponentOrElement } from './utils'
9
10
 
10
11
  export interface InputToolbarProps<TMessage extends IMessage> {
11
12
  actions?: Array<{ title: string, action: () => void }>
@@ -13,11 +14,11 @@ export interface InputToolbarProps<TMessage extends IMessage> {
13
14
  containerStyle?: StyleProp<ViewStyle>
14
15
  primaryStyle?: StyleProp<ViewStyle>
15
16
  accessoryStyle?: StyleProp<ViewStyle>
16
- renderAccessory?(props: InputToolbarProps<TMessage>): React.ReactNode
17
- renderActions?(props: ActionsProps): React.ReactNode
18
- renderSend?(props: SendProps<TMessage>): React.ReactNode
19
- renderComposer?(props: ComposerProps): React.ReactNode
20
- onPressActionButton?(): void
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
21
22
  icon?: () => React.ReactNode
22
23
  wrapperStyle?: StyleProp<ViewStyle>
23
24
  }
@@ -41,7 +42,7 @@ export function InputToolbar<TMessage extends IMessage = IMessage> (
41
42
  const colorScheme = useColorScheme()
42
43
 
43
44
  const actionsFragment = useMemo(() => {
44
- const props = {
45
+ const actionsProps = {
45
46
  onPressActionButton,
46
47
  actions,
47
48
  actionSheetOptionTintColor,
@@ -50,9 +51,13 @@ export function InputToolbar<TMessage extends IMessage = IMessage> (
50
51
  containerStyle,
51
52
  }
52
53
 
53
- return (
54
- renderActions?.(props) || (onPressActionButton && <Actions {...props} />)
55
- )
54
+ if (renderActions)
55
+ return renderComponentOrElement(renderActions, actionsProps)
56
+
57
+ if (onPressActionButton)
58
+ return <Actions {...actionsProps} />
59
+
60
+ return null
56
61
  }, [
57
62
  renderActions,
58
63
  onPressActionButton,
@@ -64,15 +69,19 @@ export function InputToolbar<TMessage extends IMessage = IMessage> (
64
69
  ])
65
70
 
66
71
  const composerFragment = useMemo(() => {
67
- return (
68
- renderComposer?.(props as ComposerProps) || (
69
- <Composer {...(props as ComposerProps)} />
70
- )
71
- )
72
+ const composerProps = props as ComposerProps
73
+
74
+ if (renderComposer)
75
+ return renderComponentOrElement(renderComposer, composerProps)
76
+
77
+ return <Composer {...composerProps} />
72
78
  }, [renderComposer, props])
73
79
 
74
80
  const sendFragment = useMemo(() => {
75
- return renderSend?.(props) || <Send {...props} />
81
+ if (renderSend)
82
+ return renderComponentOrElement(renderSend, props)
83
+
84
+ return <Send {...props} />
76
85
  }, [renderSend, props])
77
86
 
78
87
  const accessoryFragment = useMemo(() => {
@@ -81,13 +90,13 @@ export function InputToolbar<TMessage extends IMessage = IMessage> (
81
90
 
82
91
  return (
83
92
  <View style={[styles.accessory, props.accessoryStyle]}>
84
- {renderAccessory(props)}
93
+ {renderComponentOrElement(renderAccessory, props)}
85
94
  </View>
86
95
  )
87
96
  }, [renderAccessory, props])
88
97
 
89
98
  return (
90
- <View style={[styles.container, styles[`container_${colorScheme}`], containerStyle]}>
99
+ <View style={[styles.container, colorScheme === 'dark' && styles.container_dark, containerStyle]}>
91
100
  <View style={[styles.primary, props.primaryStyle]}>
92
101
  {actionsFragment}
93
102
  {composerFragment}
@@ -8,7 +8,7 @@ import {
8
8
  ViewStyle,
9
9
  TextStyle,
10
10
  } from 'react-native'
11
- import Color from './Color'
11
+ import { Color } from './Color'
12
12
  import { TouchableOpacity } from './components/TouchableOpacity'
13
13
  import stylesCommon from './styles'
14
14
 
@@ -1,18 +1,17 @@
1
- import React, { memo, useCallback } from 'react'
1
+ import React, { useCallback } from 'react'
2
2
  import { View } from 'react-native'
3
3
 
4
4
  import { Avatar } from '../Avatar'
5
- import Bubble from '../Bubble'
5
+ import { Bubble } from '../Bubble'
6
+ import { IMessage } from '../Models'
6
7
  import { SystemMessage } from '../SystemMessage'
7
-
8
- import { IMessage } from '../types'
9
- import { isSameUser } from '../utils'
8
+ import { isSameUser, renderComponentOrElement } from '../utils'
10
9
  import styles from './styles'
11
10
  import { MessageProps } from './types'
12
11
 
13
12
  export * from './types'
14
13
 
15
- const Message: React.FC<MessageProps<IMessage>> = (props: MessageProps<IMessage>) => {
14
+ export const Message = <TMessage extends IMessage = IMessage>(props: MessageProps<TMessage>) => {
16
15
  const {
17
16
  currentMessage,
18
17
  renderBubble: renderBubbleProp,
@@ -22,7 +21,7 @@ const Message: React.FC<MessageProps<IMessage>> = (props: MessageProps<IMessage>
22
21
  position,
23
22
  containerStyle,
24
23
  user,
25
- showUserAvatar,
24
+ isUserAvatarVisible,
26
25
  } = props
27
26
 
28
27
  const renderBubble = useCallback(() => {
@@ -35,7 +34,7 @@ const Message: React.FC<MessageProps<IMessage>> = (props: MessageProps<IMessage>
35
34
  } = props
36
35
 
37
36
  if (renderBubbleProp)
38
- return renderBubbleProp(rest)
37
+ return renderComponentOrElement(renderBubbleProp, rest)
39
38
 
40
39
  return <Bubble {...rest} />
41
40
  }, [props, renderBubbleProp])
@@ -50,7 +49,7 @@ const Message: React.FC<MessageProps<IMessage>> = (props: MessageProps<IMessage>
50
49
  } = props
51
50
 
52
51
  if (renderSystemMessageProp)
53
- return renderSystemMessageProp(rest)
52
+ return renderComponentOrElement(renderSystemMessageProp, rest)
54
53
 
55
54
  return <SystemMessage {...rest} />
56
55
  }, [props, renderSystemMessageProp])
@@ -60,7 +59,7 @@ const Message: React.FC<MessageProps<IMessage>> = (props: MessageProps<IMessage>
60
59
  user?._id &&
61
60
  currentMessage?.user &&
62
61
  user._id === currentMessage.user._id &&
63
- !showUserAvatar
62
+ !isUserAvatarVisible
64
63
  )
65
64
  return null
66
65
 
@@ -80,7 +79,7 @@ const Message: React.FC<MessageProps<IMessage>> = (props: MessageProps<IMessage>
80
79
  props,
81
80
  user,
82
81
  currentMessage,
83
- showUserAvatar,
82
+ isUserAvatarVisible,
84
83
  ])
85
84
 
86
85
  if (!currentMessage)
@@ -99,7 +98,7 @@ const Message: React.FC<MessageProps<IMessage>> = (props: MessageProps<IMessage>
99
98
  style={[
100
99
  styles[position].container,
101
100
  { marginBottom: sameUser ? 2 : 10 },
102
- !props.inverted && { marginBottom: 2 },
101
+ !props.isInverted && { marginBottom: 2 },
103
102
  containerStyle?.[position],
104
103
  ]}
105
104
  >
@@ -111,5 +110,3 @@ const Message: React.FC<MessageProps<IMessage>> = (props: MessageProps<IMessage>
111
110
  </View>
112
111
  )
113
112
  }
114
-
115
- export default memo(Message)
@@ -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
- showUserAvatar?: boolean
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
- inverted?: boolean
15
+ isInverted?: boolean
16
16
  containerStyle?: LeftRightStyle<ViewStyle>
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
- shouldUpdateMessage?(
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
  }
@@ -1,6 +1,6 @@
1
1
  import React, { useMemo } from 'react'
2
2
  import { View, Text, StyleSheet } from 'react-native'
3
- import Color from './Color'
3
+ import { Color } from './Color'
4
4
 
5
5
  const styles = StyleSheet.create({
6
6
  container: {
@@ -11,7 +11,7 @@ import { DayAnimatedProps } from './types'
11
11
 
12
12
  export * from './types'
13
13
 
14
- const DayAnimated = ({ scrolledY, daysPositions, listHeight, renderDay, messages, isLoading, ...rest }: DayAnimatedProps) => {
14
+ export const DayAnimated = ({ scrolledY, daysPositions, listHeight, renderDay, messages, isLoading, ...rest }: DayAnimatedProps) => {
15
15
  const opacity = useSharedValue(0)
16
16
  const fadeOutOpacityTimeoutId = useSharedValue<ReturnType<typeof setTimeout> | undefined>(undefined)
17
17
  const containerHeight = useSharedValue(0)
@@ -145,5 +145,3 @@ const DayAnimated = ({ scrolledY, daysPositions, listHeight, renderDay, messages
145
145
  </Animated.View>
146
146
  )
147
147
  }
148
-
149
- export default DayAnimated
@@ -1,5 +1,5 @@
1
1
  import { DayProps } from '../../../Day'
2
- import { IMessage } from '../../../types'
2
+ import { IMessage } from '../../../Models'
3
3
  import { DaysPositions } from '../../types'
4
4
 
5
5
  export interface DayAnimatedProps extends Omit<DayProps, 'createdAt'> {
@@ -1,9 +1,9 @@
1
- import React, { forwardRef, useCallback, useMemo } from 'react'
1
+ 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 '../../../types'
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'
@@ -68,7 +68,7 @@ export const useRelativeScrolledPositionToBottomOfDay = (
68
68
  return relativeScrolledPositionToBottomOfDay
69
69
  }
70
70
 
71
- const DayWrapper = forwardRef<View, MessageProps<IMessage>>((props, ref) => {
71
+ const DayWrapper = <TMessage extends IMessage>(props: MessageProps<TMessage>) => {
72
72
  const {
73
73
  renderDay: renderDayProp,
74
74
  currentMessage,
@@ -87,7 +87,7 @@ const DayWrapper = forwardRef<View, MessageProps<IMessage>>((props, ref) => {
87
87
  } = props
88
88
 
89
89
  return (
90
- <View ref={ref}>
90
+ <View>
91
91
  {
92
92
  renderDayProp
93
93
  ? renderDayProp({ ...rest, createdAt: currentMessage.createdAt })
@@ -95,9 +95,9 @@ const DayWrapper = forwardRef<View, MessageProps<IMessage>>((props, ref) => {
95
95
  }
96
96
  </View>
97
97
  )
98
- })
98
+ }
99
99
 
100
- const Item = <TMessage extends IMessage>(props: ItemProps<TMessage>) => {
100
+ export const Item = <TMessage extends IMessage>(props: ItemProps<TMessage>) => {
101
101
  const {
102
102
  renderMessage: renderMessageProp,
103
103
  scrolledY,
@@ -146,15 +146,13 @@ const Item = <TMessage extends IMessage>(props: ItemProps<TMessage>) => {
146
146
  style={style}
147
147
  onLayout={handleLayoutDayContainer}
148
148
  >
149
- <DayWrapper {...rest as MessageProps<TMessage>} />
149
+ <DayWrapper<TMessage> {...rest as MessageProps<TMessage>} />
150
150
  </Animated.View>
151
151
  {
152
152
  renderMessageProp
153
153
  ? renderMessageProp(rest as MessageProps<TMessage>)
154
- : <Message {...rest as MessageProps<TMessage>} />
154
+ : <Message<TMessage> {...rest as MessageProps<TMessage>} />
155
155
  }
156
156
  </View>
157
157
  )
158
158
  }
159
-
160
- export default Item
@@ -1,4 +1,4 @@
1
- import { IMessage } from '../../../types'
1
+ import { IMessage } from '../../../Models'
2
2
  import { MessageContainerProps, DaysPositions } from '../../types'
3
3
 
4
4
  export interface ItemProps<TMessage extends IMessage> extends MessageContainerProps<TMessage> {
@@ -11,15 +11,14 @@ import { FlatList } from 'react-native-gesture-handler'
11
11
  import Animated, { runOnJS, useAnimatedScrollHandler, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated'
12
12
  import { LoadEarlierMessages } from '../LoadEarlierMessages'
13
13
  import { warning } from '../logging'
14
+ import { IMessage } from '../Models'
14
15
  import { ReanimatedScrollEvent } from '../reanimatedCompat'
15
-
16
16
  import stylesCommon from '../styles'
17
- import { IMessage } from '../types'
18
- import TypingIndicator from '../TypingIndicator'
17
+ import { TypingIndicator } from '../TypingIndicator'
19
18
  import { isSameDay, useCallbackThrottled } from '../utils'
20
- import DayAnimated from './components/DayAnimated'
19
+ import { DayAnimated } from './components/DayAnimated'
21
20
 
22
- import Item from './components/Item'
21
+ import { Item } from './components/Item'
23
22
  import { ItemProps } from './components/Item/types'
24
23
  import styles from './styles'
25
24
  import { MessageContainerProps, DaysPositions } from './types'
@@ -29,29 +28,29 @@ export * from './types'
29
28
 
30
29
  const AnimatedFlatList = Animated.createAnimatedComponent(FlatList) as React.ComponentType<any>
31
30
 
32
- function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageContainerProps<TMessage>) {
31
+ export const MessageContainer = <TMessage extends IMessage>(props: MessageContainerProps<TMessage>) => {
33
32
  const {
34
33
  messages = [],
35
34
  user,
36
35
  isTyping = false,
37
36
  renderChatEmpty: renderChatEmptyProp,
38
- inverted = true,
37
+ isInverted = true,
39
38
  listProps,
40
- extraData,
41
39
  isScrollToBottomEnabled = false,
42
40
  scrollToBottomOffset = 200,
43
- alignTop = false,
41
+ isAlignedTop = false,
44
42
  scrollToBottomStyle,
45
43
  loadEarlierMessagesProps,
46
44
  renderTypingIndicator: renderTypingIndicatorProp,
47
45
  renderFooter: renderFooterProp,
48
46
  renderLoadEarlier: renderLoadEarlierProp,
49
47
  forwardRef,
50
- handleOnScroll: handleOnScrollProp,
51
48
  scrollToBottomComponent: scrollToBottomComponentProp,
52
49
  renderDay: renderDayProp,
53
50
  } = props
54
51
 
52
+ const listPropsOnScrollProp = listProps?.onScroll
53
+
55
54
  const scrollToBottomOpacity = useSharedValue(0)
56
55
  const isScrollingDown = useSharedValue(false)
57
56
  const lastScrolledY = useSharedValue(0)
@@ -111,14 +110,14 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
111
110
  isScrollingDown.value = true
112
111
  changeScrollToBottomVisibility(false)
113
112
 
114
- if (inverted)
113
+ if (isInverted)
115
114
  scrollTo({ offset: 0, animated })
116
115
  else if (forwardRef?.current)
117
116
  forwardRef.current.scrollToEnd({ animated })
118
- }, [forwardRef, inverted, scrollTo, isScrollingDown, changeScrollToBottomVisibility])
117
+ }, [forwardRef, isInverted, scrollTo, isScrollingDown, changeScrollToBottomVisibility])
119
118
 
120
119
  const handleOnScroll = useCallback((event: ReanimatedScrollEvent) => {
121
- handleOnScrollProp?.(event)
120
+ listPropsOnScrollProp?.(event as any)
122
121
 
123
122
  const {
124
123
  contentOffset: { y: contentOffsetY },
@@ -127,12 +126,12 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
127
126
  } = event
128
127
 
129
128
  isScrollingDown.value =
130
- (inverted && lastScrolledY.value > contentOffsetY) ||
131
- (!inverted && lastScrolledY.value < contentOffsetY)
129
+ (isInverted && lastScrolledY.value > contentOffsetY) ||
130
+ (!isInverted && lastScrolledY.value < contentOffsetY)
132
131
 
133
132
  lastScrolledY.value = contentOffsetY
134
133
 
135
- if (inverted)
134
+ if (isInverted)
136
135
  if (contentOffsetY > scrollToBottomOffset!)
137
136
  changeScrollToBottomVisibility(true)
138
137
  else
@@ -144,7 +143,7 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
144
143
  changeScrollToBottomVisibility(false)
145
144
  else
146
145
  changeScrollToBottomVisibility(false)
147
- }, [handleOnScrollProp, inverted, scrollToBottomOffset, changeScrollToBottomVisibility, isScrollingDown, lastScrolledY])
146
+ }, [isInverted, scrollToBottomOffset, changeScrollToBottomVisibility, isScrollingDown, lastScrolledY, listPropsOnScrollProp])
148
147
 
149
148
  const restProps = useMemo(() => {
150
149
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -170,9 +169,9 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
170
169
 
171
170
  if (messages && user) {
172
171
  const previousMessage =
173
- (inverted ? messages[index + 1] : messages[index - 1]) || {}
172
+ (isInverted ? messages[index + 1] : messages[index - 1]) || {}
174
173
  const nextMessage =
175
- (inverted ? messages[index - 1] : messages[index + 1]) || {}
174
+ (isInverted ? messages[index - 1] : messages[index + 1]) || {}
176
175
 
177
176
  const messageProps: ItemProps<TMessage> = {
178
177
  ...restProps,
@@ -191,7 +190,7 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
191
190
  }
192
191
 
193
192
  return null
194
- }, [messages, restProps, inverted, scrolledY, daysPositions, listHeight, user])
193
+ }, [messages, restProps, isInverted, scrolledY, daysPositions, listHeight, user])
195
194
 
196
195
  const emptyContent = useMemo(() => {
197
196
  if (!renderChatEmptyProp)
@@ -202,7 +201,7 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
202
201
 
203
202
  const renderChatEmpty = useCallback(() => {
204
203
  if (renderChatEmptyProp)
205
- return inverted
204
+ return isInverted
206
205
  ? (
207
206
  emptyContent
208
207
  )
@@ -213,7 +212,7 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
213
212
  )
214
213
 
215
214
  return <View style={stylesCommon.fill} />
216
- }, [inverted, renderChatEmptyProp, emptyContent])
215
+ }, [isInverted, renderChatEmptyProp, emptyContent])
217
216
 
218
217
  const ListHeaderComponent = useMemo(() => {
219
218
  const content = renderLoadEarlier()
@@ -273,7 +272,7 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
273
272
  listHeight.value = event.nativeEvent.layout.height
274
273
 
275
274
  if (
276
- !inverted &&
275
+ !isInverted &&
277
276
  messages?.length &&
278
277
  isScrollToBottomEnabled
279
278
  )
@@ -282,7 +281,7 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
282
281
  }, 500)
283
282
 
284
283
  listProps?.onLayout?.(event)
285
- }, [inverted, messages, doScrollToBottom, listHeight, listProps, isScrollToBottomEnabled])
284
+ }, [isInverted, messages, doScrollToBottom, listHeight, listProps, isScrollToBottomEnabled])
286
285
 
287
286
  const onEndReached = useCallback(() => {
288
287
  if (
@@ -326,7 +325,7 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
326
325
  }
327
326
 
328
327
  for (const [key, item] of Object.entries(value))
329
- if (isSameDay(newValue.createdAt, item.createdAt) && (inverted ? item.y <= newValue.y : item.y >= newValue.y)) {
328
+ if (isSameDay(newValue.createdAt, item.createdAt) && (isInverted ? item.y <= newValue.y : item.y >= newValue.y)) {
330
329
  delete value[key]
331
330
  break
332
331
  }
@@ -345,7 +344,7 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
345
344
  {children}
346
345
  </View>
347
346
  )
348
- }, [daysPositions, inverted])
347
+ }, [daysPositions, isInverted])
349
348
 
350
349
  const scrollHandler = useAnimatedScrollHandler({
351
350
  onScroll: event => {
@@ -362,7 +361,7 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
362
361
  let shouldRemove = messageIndex === -1
363
362
 
364
363
  if (!shouldRemove) {
365
- const prevMessage = messages[messageIndex + (inverted ? 1 : -1)]
364
+ const prevMessage = messages[messageIndex + (isInverted ? 1 : -1)]
366
365
  const message = messages[messageIndex]
367
366
  shouldRemove = !!prevMessage && isSameDay(message, prevMessage)
368
367
  }
@@ -375,36 +374,35 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
375
374
  return value
376
375
  })
377
376
  })
378
- }, [messages, daysPositions, inverted])
377
+ }, [messages, daysPositions, isInverted])
379
378
 
380
379
  return (
381
380
  <View
382
381
  style={[
383
382
  styles.contentContainerStyle,
384
- alignTop ? styles.containerAlignTop : stylesCommon.fill,
383
+ isAlignedTop ? styles.containerAlignTop : stylesCommon.fill,
385
384
  ]}
386
385
  >
387
386
  <AnimatedFlatList
388
- extraData={extraData}
389
387
  ref={forwardRef}
390
388
  keyExtractor={keyExtractor}
391
389
  data={messages}
392
390
  renderItem={renderItem}
393
- inverted={inverted}
391
+ inverted={isInverted}
394
392
  automaticallyAdjustContentInsets={false}
395
393
  style={stylesCommon.fill}
396
394
  ListEmptyComponent={renderChatEmpty}
397
395
  ListFooterComponent={
398
- inverted ? ListHeaderComponent : ListFooterComponent
396
+ isInverted ? ListHeaderComponent : ListFooterComponent
399
397
  }
400
398
  ListHeaderComponent={
401
- inverted ? ListFooterComponent : ListHeaderComponent
399
+ isInverted ? ListFooterComponent : ListHeaderComponent
402
400
  }
403
- onScroll={scrollHandler}
404
401
  scrollEventThrottle={1}
405
402
  onEndReached={onEndReached}
406
403
  onEndReachedThreshold={0.1}
407
404
  {...listProps}
405
+ onScroll={scrollHandler}
408
406
  onLayout={onLayoutList}
409
407
  CellRendererComponent={renderCell}
410
408
  />
@@ -420,5 +418,3 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
420
418
  </View>
421
419
  )
422
420
  }
423
-
424
- export default MessageContainer
@@ -1,5 +1,5 @@
1
1
  import { StyleSheet } from 'react-native'
2
- import Color from '../Color'
2
+ import { Color } from '../Color'
3
3
 
4
4
  export default StyleSheet.create({
5
5
  containerAlignTop: {
@@ -6,10 +6,10 @@ import {
6
6
  } from 'react-native'
7
7
  import { FlatList } from 'react-native-gesture-handler'
8
8
 
9
+ import { DayProps } from '../Day'
9
10
  import { LoadEarlierMessagesProps } from '../LoadEarlierMessages'
10
11
  import { MessageProps } from '../Message'
11
- import { ReanimatedScrollEvent } from '../reanimatedCompat'
12
- import { User, IMessage, Reply, DayProps } from '../types'
12
+ import { User, IMessage, Reply } from '../Models'
13
13
  import { TypingIndicatorProps } from '../TypingIndicator/types'
14
14
 
15
15
  export type ListProps<TMessage extends IMessage = IMessage> = Partial<FlatListProps<TMessage>>
@@ -27,37 +27,33 @@ export interface MessageContainerProps<TMessage extends IMessage = IMessage>
27
27
  /** Additional props for FlatList */
28
28
  listProps?: ListProps<TMessage>
29
29
  /** Reverses display order of messages; default is true */
30
- inverted?: boolean
30
+ isInverted?: boolean
31
31
  /** Controls whether or not the message bubbles appear at the top of the chat */
32
- alignTop?: boolean
32
+ isAlignedTop?: boolean
33
33
  /** Enables the isScrollToBottomEnabled Component */
34
34
  isScrollToBottomEnabled?: boolean
35
35
  /** Scroll to bottom wrapper style */
36
36
  scrollToBottomStyle?: StyleProp<ViewStyle>
37
- /** This can be used to pass unknown data which needs to be re-rendered */
38
- extraData?: object
39
37
  /** Distance from bottom before showing scroll to bottom button */
40
38
  scrollToBottomOffset?: number
41
39
  /** Custom component to render when messages are empty */
42
- renderChatEmpty?(): React.ReactNode
40
+ renderChatEmpty?: () => React.ReactNode
43
41
  /** Custom footer component on the ListView, e.g. 'User is typing...' */
44
- renderFooter?(props: MessageContainerProps<TMessage>): React.ReactNode
42
+ renderFooter?: (props: MessageContainerProps<TMessage>) => React.ReactNode
45
43
  /** Custom message container */
46
- renderMessage?(props: MessageProps<TMessage>): React.ReactElement
44
+ renderMessage?: (props: MessageProps<TMessage>) => React.ReactElement
47
45
  /** Custom day above a message */
48
- renderDay?(props: DayProps): React.ReactNode
46
+ renderDay?: (props: DayProps) => React.ReactNode
49
47
  /** Custom "Load earlier messages" button */
50
- renderLoadEarlier?(props: LoadEarlierMessagesProps): React.ReactNode
48
+ renderLoadEarlier?: (props: LoadEarlierMessagesProps) => React.ReactNode
51
49
  /** Custom typing indicator */
52
- renderTypingIndicator?(): React.ReactNode
50
+ renderTypingIndicator?: () => React.ReactNode
53
51
  /** Scroll to bottom custom component */
54
- scrollToBottomComponent?(): React.ReactNode
52
+ scrollToBottomComponent?: () => React.ReactNode
55
53
  /** Callback when quick reply is sent */
56
- onQuickReply?(replies: Reply[]): void
54
+ onQuickReply?: (replies: Reply[]) => void
57
55
  /** Props to pass to the LoadEarlierMessages component. The LoadEarlierMessages button is only visible when isAvailable is true. Includes isAvailable (controls button visibility), isInfiniteScrollEnabled (infinite scroll up when reach the top of messages container, automatically call onPress function if it exists - not yet supported for web), onPress (callback when button is pressed), isLoading (display loading indicator), label (override default "Load earlier messages" text), and styling props (containerStyle, wrapperStyle, textStyle, activityIndicatorStyle, activityIndicatorColor, activityIndicatorSize). */
58
56
  loadEarlierMessagesProps?: LoadEarlierMessagesProps
59
- /** Custom scroll event handler */
60
- handleOnScroll?(event: ReanimatedScrollEvent): void
61
57
  /** Style for TypingIndicator component */
62
58
  typingIndicatorStyle?: StyleProp<ViewStyle>
63
59
  }
@@ -16,8 +16,8 @@ import {
16
16
  import { BaseButton, GestureHandlerRootView, Text } from 'react-native-gesture-handler'
17
17
  import { useSafeAreaInsets } from 'react-native-safe-area-context'
18
18
  import Zoom from 'react-native-zoom-reanimated'
19
+ import { IMessage } from './Models'
19
20
  import commonStyles from './styles'
20
- import { IMessage } from './types'
21
21
 
22
22
  const styles = StyleSheet.create({
23
23
  image: {
@@ -9,7 +9,7 @@ import {
9
9
 
10
10
  import { Match } from 'autolinker/dist/es2015'
11
11
  import Autolink, { AutolinkProps } from 'react-native-autolink'
12
- import { LeftRightStyle, IMessage } from './types'
12
+ import { LeftRightStyle, IMessage } from './Models'
13
13
 
14
14
  export type MessageTextProps<TMessage extends IMessage> = {
15
15
  position?: 'left' | 'right'
@@ -1,6 +1,6 @@
1
1
  import React, { useMemo } from 'react'
2
2
  import { View, Text, StyleSheet } from 'react-native'
3
- import Color from './Color'
3
+ import { Color } from './Color'
4
4
 
5
5
  const styles = StyleSheet.create({
6
6
  container: {