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/src/InputToolbar.tsx
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import React, { useMemo } from 'react'
|
|
2
2
|
import { StyleSheet, View, StyleProp, ViewStyle, useColorScheme } from 'react-native'
|
|
3
3
|
|
|
4
|
-
import { Composer, ComposerProps } from './Composer'
|
|
5
|
-
import { Send, SendProps } from './Send'
|
|
6
4
|
import { Actions, ActionsProps } from './Actions'
|
|
7
5
|
import Color from './Color'
|
|
6
|
+
import { Composer, ComposerProps } from './Composer'
|
|
7
|
+
import { Send, SendProps } from './Send'
|
|
8
8
|
import { IMessage } from './types'
|
|
9
9
|
|
|
10
10
|
export interface InputToolbarProps<TMessage extends IMessage> {
|
package/src/LoadEarlier.tsx
CHANGED
|
@@ -4,13 +4,13 @@ import {
|
|
|
4
4
|
Platform,
|
|
5
5
|
StyleSheet,
|
|
6
6
|
Text,
|
|
7
|
-
TouchableOpacity,
|
|
8
7
|
View,
|
|
9
8
|
StyleProp,
|
|
10
9
|
ViewStyle,
|
|
11
10
|
TextStyle,
|
|
12
11
|
} from 'react-native'
|
|
13
12
|
import Color from './Color'
|
|
13
|
+
import { TouchableOpacity } from './components/TouchableOpacity'
|
|
14
14
|
import stylesCommon from './styles'
|
|
15
15
|
|
|
16
16
|
const styles = StyleSheet.create({
|
|
@@ -52,7 +52,7 @@ export interface LoadEarlierProps {
|
|
|
52
52
|
onLoadEarlier?(): void
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
export
|
|
55
|
+
export const LoadEarlier: React.FC<LoadEarlierProps> = ({
|
|
56
56
|
isLoadingEarlier = false,
|
|
57
57
|
onLoadEarlier = () => {},
|
|
58
58
|
label = 'Load earlier messages',
|
|
@@ -62,7 +62,7 @@ export function LoadEarlier ({
|
|
|
62
62
|
activityIndicatorColor = 'white',
|
|
63
63
|
activityIndicatorSize = 'small',
|
|
64
64
|
activityIndicatorStyle,
|
|
65
|
-
}
|
|
65
|
+
}) => {
|
|
66
66
|
const loadingContent = useMemo(() => (
|
|
67
67
|
<View>
|
|
68
68
|
<Text style={[styles.text, textStyle, { opacity: 0 }]}>
|
package/src/Message/index.tsx
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import React, { memo, useCallback } from 'react'
|
|
2
2
|
import { View } from 'react-native'
|
|
3
|
-
import isEqual from 'lodash.isequal'
|
|
4
3
|
|
|
5
4
|
import { Avatar } from '../Avatar'
|
|
6
5
|
import Bubble from '../Bubble'
|
|
7
6
|
import { SystemMessage } from '../SystemMessage'
|
|
8
7
|
|
|
9
|
-
import { isSameUser } from '../utils'
|
|
10
8
|
import { IMessage } from '../types'
|
|
11
|
-
import {
|
|
9
|
+
import { isSameUser } from '../utils'
|
|
12
10
|
import styles from './styles'
|
|
11
|
+
import { MessageProps } from './types'
|
|
13
12
|
|
|
14
13
|
export * from './types'
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
const Message: React.FC<MessageProps<IMessage>> = (props: MessageProps<IMessage>) => {
|
|
17
16
|
const {
|
|
18
17
|
currentMessage,
|
|
19
18
|
renderBubble: renderBubbleProp,
|
|
@@ -113,17 +112,4 @@ let Message: React.FC<MessageProps<IMessage>> = (props: MessageProps<IMessage>)
|
|
|
113
112
|
)
|
|
114
113
|
}
|
|
115
114
|
|
|
116
|
-
|
|
117
|
-
const shouldUpdate =
|
|
118
|
-
props.shouldUpdateMessage?.(props, nextProps) ||
|
|
119
|
-
!isEqual(props.currentMessage!, nextProps.currentMessage!) ||
|
|
120
|
-
!isEqual(props.previousMessage, nextProps.previousMessage) ||
|
|
121
|
-
!isEqual(props.nextMessage, nextProps.nextMessage)
|
|
122
|
-
|
|
123
|
-
if (shouldUpdate)
|
|
124
|
-
return false
|
|
125
|
-
|
|
126
|
-
return true
|
|
127
|
-
})
|
|
128
|
-
|
|
129
|
-
export default Message
|
|
115
|
+
export default memo(Message)
|
package/src/Message/types.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ViewStyle, LayoutChangeEvent } from 'react-native'
|
|
2
2
|
import { AvatarProps } from '../Avatar'
|
|
3
|
-
import {
|
|
3
|
+
import { BubbleProps } from '../Bubble'
|
|
4
4
|
import { DayProps } from '../Day'
|
|
5
|
+
import { SystemMessageProps } from '../SystemMessage'
|
|
5
6
|
import { IMessage, User, LeftRightStyle } from '../types'
|
|
6
|
-
import { BubbleProps } from '../Bubble'
|
|
7
7
|
|
|
8
8
|
export interface MessageProps<TMessage extends IMessage> {
|
|
9
9
|
showUserAvatar?: boolean
|
package/src/MessageAudio.tsx
CHANGED
|
@@ -2,12 +2,12 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'
|
|
|
2
2
|
import { LayoutChangeEvent } from 'react-native'
|
|
3
3
|
import Animated, { interpolate, useAnimatedStyle, useDerivedValue, useSharedValue, useAnimatedReaction, withTiming, runOnJS } from 'react-native-reanimated'
|
|
4
4
|
import { Day } from '../../../Day'
|
|
5
|
+
import stylesCommon from '../../../styles'
|
|
5
6
|
import { isSameDay } from '../../../utils'
|
|
6
7
|
import { useAbsoluteScrolledPositionToBottomOfDay, useRelativeScrolledPositionToBottomOfDay } from '../Item'
|
|
7
|
-
import { DayAnimatedProps } from './types'
|
|
8
8
|
|
|
9
|
-
import stylesCommon from '../../../styles'
|
|
10
9
|
import styles from './styles'
|
|
10
|
+
import { DayAnimatedProps } from './types'
|
|
11
11
|
|
|
12
12
|
export * from './types'
|
|
13
13
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React, { forwardRef, useCallback, useMemo } from 'react'
|
|
2
2
|
import { LayoutChangeEvent, View } from 'react-native'
|
|
3
|
-
import { IMessage } from '../../../types'
|
|
4
|
-
import Message, { MessageProps } from '../../../Message'
|
|
5
3
|
import Animated, { interpolate, useAnimatedStyle, useDerivedValue, useSharedValue } from 'react-native-reanimated'
|
|
6
|
-
import { DaysPositions } from '../../types'
|
|
7
4
|
import { Day } from '../../../Day'
|
|
5
|
+
import Message, { MessageProps } from '../../../Message'
|
|
6
|
+
import { IMessage } from '../../../types'
|
|
8
7
|
import { isSameDay } from '../../../utils'
|
|
8
|
+
import { DaysPositions } from '../../types'
|
|
9
9
|
import { ItemProps } from './types'
|
|
10
10
|
|
|
11
11
|
export * from './types'
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { MessageContainerProps, DaysPositions } from '../../types'
|
|
2
1
|
import { IMessage } from '../../../types'
|
|
2
|
+
import { MessageContainerProps, DaysPositions } from '../../types'
|
|
3
3
|
|
|
4
4
|
export interface ItemProps<TMessage extends IMessage> extends MessageContainerProps<TMessage> {
|
|
5
5
|
currentMessage: TMessage
|
|
@@ -6,28 +6,28 @@ import {
|
|
|
6
6
|
Platform,
|
|
7
7
|
LayoutChangeEvent,
|
|
8
8
|
ListRenderItemInfo,
|
|
9
|
-
FlatList,
|
|
10
9
|
CellRendererProps,
|
|
11
10
|
} from 'react-native'
|
|
11
|
+
import { FlatList } from 'react-native-gesture-handler'
|
|
12
12
|
import Animated, { runOnJS, useAnimatedScrollHandler, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated'
|
|
13
|
+
import { LoadEarlier } from '../LoadEarlier'
|
|
14
|
+
import { warning } from '../logging'
|
|
13
15
|
import { ReanimatedScrollEvent } from '../reanimatedCompat'
|
|
14
|
-
import DayAnimated from './components/DayAnimated'
|
|
15
|
-
import Item from './components/Item'
|
|
16
16
|
|
|
17
|
-
import
|
|
17
|
+
import stylesCommon from '../styles'
|
|
18
18
|
import { IMessage } from '../types'
|
|
19
19
|
import TypingIndicator from '../TypingIndicator'
|
|
20
|
-
import {
|
|
21
|
-
import
|
|
20
|
+
import { isSameDay, useCallbackThrottled } from '../utils'
|
|
21
|
+
import DayAnimated from './components/DayAnimated'
|
|
22
22
|
|
|
23
|
-
import
|
|
24
|
-
import
|
|
23
|
+
import Item from './components/Item'
|
|
24
|
+
import { ItemProps } from './components/Item/types'
|
|
25
25
|
import styles from './styles'
|
|
26
|
-
import {
|
|
26
|
+
import { MessageContainerProps, DaysPositions } from './types'
|
|
27
27
|
|
|
28
28
|
export * from './types'
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
const AnimatedFlatList = Animated.createAnimatedComponent(FlatList) as React.ComponentType<any>
|
|
32
32
|
|
|
33
33
|
function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageContainerProps<TMessage>) {
|
|
@@ -3,13 +3,13 @@ import {
|
|
|
3
3
|
FlatListProps,
|
|
4
4
|
StyleProp,
|
|
5
5
|
ViewStyle,
|
|
6
|
-
FlatList,
|
|
7
6
|
} from 'react-native'
|
|
7
|
+
import { FlatList } from 'react-native-gesture-handler'
|
|
8
8
|
|
|
9
9
|
import { LoadEarlierProps } from '../LoadEarlier'
|
|
10
10
|
import { MessageProps } from '../Message'
|
|
11
|
-
import { User, IMessage, Reply, DayProps } from '../types'
|
|
12
11
|
import { ReanimatedScrollEvent } from '../reanimatedCompat'
|
|
12
|
+
import { User, IMessage, Reply, DayProps } from '../types'
|
|
13
13
|
import { TypingIndicatorProps } from '../TypingIndicator/types'
|
|
14
14
|
|
|
15
15
|
export type ListProps<TMessage extends IMessage = IMessage> = Partial<FlatListProps<TMessage>>
|
package/src/MessageImage.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useMemo } from 'react'
|
|
1
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
|
2
2
|
import {
|
|
3
3
|
Image,
|
|
4
4
|
StyleSheet,
|
|
@@ -8,11 +8,16 @@ import {
|
|
|
8
8
|
StyleProp,
|
|
9
9
|
ImageStyle,
|
|
10
10
|
ImageURISource,
|
|
11
|
+
Modal,
|
|
12
|
+
TouchableOpacity,
|
|
13
|
+
LayoutChangeEvent,
|
|
14
|
+
useWindowDimensions,
|
|
11
15
|
} from 'react-native'
|
|
12
|
-
|
|
13
|
-
import
|
|
16
|
+
import { BaseButton, GestureHandlerRootView, Text } from 'react-native-gesture-handler'
|
|
17
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
18
|
+
import Zoom from 'react-native-zoom-reanimated'
|
|
19
|
+
import commonStyles from './styles'
|
|
14
20
|
import { IMessage } from './types'
|
|
15
|
-
import stylesCommon from './styles'
|
|
16
21
|
|
|
17
22
|
const styles = StyleSheet.create({
|
|
18
23
|
image: {
|
|
@@ -22,8 +27,25 @@ const styles = StyleSheet.create({
|
|
|
22
27
|
margin: 3,
|
|
23
28
|
resizeMode: 'cover',
|
|
24
29
|
},
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
modalContent: {
|
|
31
|
+
backgroundColor: '#000',
|
|
32
|
+
},
|
|
33
|
+
modalImageContainer: {
|
|
34
|
+
width: '100%',
|
|
35
|
+
height: '100%',
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
closeButtonContainer: {
|
|
39
|
+
flexDirection: 'row',
|
|
40
|
+
justifyContent: 'flex-end',
|
|
41
|
+
},
|
|
42
|
+
closeButtonContent: {
|
|
43
|
+
padding: 10,
|
|
44
|
+
},
|
|
45
|
+
closeButtonIcon: {
|
|
46
|
+
fontSize: 20,
|
|
47
|
+
lineHeight: 20,
|
|
48
|
+
color: 'white',
|
|
27
49
|
},
|
|
28
50
|
})
|
|
29
51
|
|
|
@@ -33,47 +55,127 @@ export interface MessageImageProps<TMessage extends IMessage> {
|
|
|
33
55
|
imageSourceProps?: Partial<ImageURISource>
|
|
34
56
|
imageStyle?: StyleProp<ImageStyle>
|
|
35
57
|
imageProps?: Partial<ImageProps>
|
|
36
|
-
lightboxProps?: LightboxProps
|
|
37
58
|
}
|
|
38
59
|
|
|
39
60
|
export function MessageImage<TMessage extends IMessage = IMessage> ({
|
|
40
61
|
containerStyle,
|
|
41
|
-
lightboxProps,
|
|
42
62
|
imageProps,
|
|
43
63
|
imageSourceProps,
|
|
44
64
|
imageStyle,
|
|
45
65
|
currentMessage,
|
|
46
66
|
}: MessageImageProps<TMessage>) {
|
|
67
|
+
const [isModalVisible, setIsModalVisible] = useState(false)
|
|
68
|
+
const [imageDimensions, setImageDimensions] = useState<{ width: number, height: number }>()
|
|
69
|
+
const windowDimensions = useWindowDimensions()
|
|
70
|
+
|
|
71
|
+
const insets = useSafeAreaInsets()
|
|
72
|
+
|
|
47
73
|
const imageSource = useMemo(() => ({
|
|
48
74
|
...imageSourceProps,
|
|
49
75
|
uri: currentMessage?.image,
|
|
50
76
|
}), [imageSourceProps, currentMessage?.image])
|
|
51
77
|
|
|
78
|
+
const isImageSourceChanged = useRef(true)
|
|
79
|
+
|
|
52
80
|
const computedImageStyle = useMemo(() => [
|
|
53
81
|
styles.image,
|
|
54
82
|
imageStyle,
|
|
55
83
|
], [imageStyle])
|
|
56
84
|
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
85
|
+
const handleImagePress = useCallback(() => {
|
|
86
|
+
if (!imageSource.uri)
|
|
87
|
+
return
|
|
88
|
+
|
|
89
|
+
setIsModalVisible(true)
|
|
90
|
+
|
|
91
|
+
if (isImageSourceChanged.current || !imageDimensions)
|
|
92
|
+
Image.getSize(imageSource.uri, (width, height) => {
|
|
93
|
+
setImageDimensions({ width, height })
|
|
94
|
+
})
|
|
95
|
+
}, [imageSource.uri, imageDimensions])
|
|
96
|
+
|
|
97
|
+
const handleModalClose = useCallback(() => {
|
|
98
|
+
setIsModalVisible(false)
|
|
99
|
+
}, [])
|
|
100
|
+
|
|
101
|
+
const handleImageLayout = useCallback((e: LayoutChangeEvent) => {
|
|
102
|
+
setImageDimensions({
|
|
103
|
+
width: e.nativeEvent.layout.width,
|
|
104
|
+
height: e.nativeEvent.layout.height,
|
|
105
|
+
})
|
|
106
|
+
}, [])
|
|
107
|
+
|
|
108
|
+
const modalImageDimensions = useMemo(() => {
|
|
109
|
+
if (!imageDimensions)
|
|
110
|
+
return undefined
|
|
111
|
+
|
|
112
|
+
const aspectRatio = imageDimensions.width / imageDimensions.height
|
|
113
|
+
|
|
114
|
+
let width = windowDimensions.width
|
|
115
|
+
let height = width / aspectRatio
|
|
116
|
+
|
|
117
|
+
if (height > windowDimensions.height) {
|
|
118
|
+
height = windowDimensions.height
|
|
119
|
+
width = height * aspectRatio
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
width,
|
|
124
|
+
height,
|
|
125
|
+
}
|
|
126
|
+
}, [imageDimensions, windowDimensions.height, windowDimensions.width])
|
|
127
|
+
|
|
128
|
+
useEffect(() => {
|
|
129
|
+
isImageSourceChanged.current = true
|
|
130
|
+
}, [imageSource.uri])
|
|
60
131
|
|
|
61
132
|
if (currentMessage == null)
|
|
62
133
|
return null
|
|
63
134
|
|
|
64
135
|
return (
|
|
65
136
|
<View style={containerStyle}>
|
|
66
|
-
{
|
|
67
|
-
<Lightbox
|
|
68
|
-
activeProps={activePropsStyle}
|
|
69
|
-
{...lightboxProps}
|
|
70
|
-
>
|
|
137
|
+
<TouchableOpacity onPress={handleImagePress}>
|
|
71
138
|
<Image
|
|
72
139
|
{...imageProps}
|
|
73
140
|
style={computedImageStyle}
|
|
74
141
|
source={imageSource}
|
|
142
|
+
onLayout={handleImageLayout}
|
|
75
143
|
/>
|
|
76
|
-
</
|
|
144
|
+
</TouchableOpacity>
|
|
145
|
+
|
|
146
|
+
<Modal
|
|
147
|
+
visible={isModalVisible}
|
|
148
|
+
onRequestClose={handleModalClose}
|
|
149
|
+
animationType='slide'
|
|
150
|
+
transparent={false}
|
|
151
|
+
>
|
|
152
|
+
<GestureHandlerRootView style={commonStyles.fill}>
|
|
153
|
+
<View style={[commonStyles.fill, styles.modalContent, { paddingTop: insets.top, paddingBottom: insets.bottom }]}>
|
|
154
|
+
|
|
155
|
+
{/* close button */}
|
|
156
|
+
<View style={styles.closeButtonContainer}>
|
|
157
|
+
<BaseButton onPress={handleModalClose}>
|
|
158
|
+
<View style={styles.closeButtonContent}>
|
|
159
|
+
<Text style={styles.closeButtonIcon}>
|
|
160
|
+
{'X'}
|
|
161
|
+
</Text>
|
|
162
|
+
</View>
|
|
163
|
+
</BaseButton>
|
|
164
|
+
</View>
|
|
165
|
+
|
|
166
|
+
<View style={[commonStyles.fill, commonStyles.centerItems]}>
|
|
167
|
+
<Zoom>
|
|
168
|
+
<Image
|
|
169
|
+
style={modalImageDimensions}
|
|
170
|
+
source={imageSource}
|
|
171
|
+
resizeMode='contain'
|
|
172
|
+
{...imageProps}
|
|
173
|
+
/>
|
|
174
|
+
</Zoom>
|
|
175
|
+
</View>
|
|
176
|
+
</View>
|
|
177
|
+
</GestureHandlerRootView>
|
|
178
|
+
</Modal>
|
|
77
179
|
</View>
|
|
78
180
|
)
|
|
79
181
|
}
|
package/src/MessageText.tsx
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { useMemo, useCallback } from 'react'
|
|
2
2
|
import {
|
|
3
|
-
Linking,
|
|
4
3
|
StyleSheet,
|
|
5
4
|
StyleProp,
|
|
6
5
|
ViewStyle,
|
|
@@ -8,15 +7,9 @@ import {
|
|
|
8
7
|
View,
|
|
9
8
|
} from 'react-native'
|
|
10
9
|
|
|
11
|
-
import Autolink, { AutolinkProps } from 'react-native-autolink'
|
|
12
10
|
import { Match } from 'autolinker/dist/es2015'
|
|
11
|
+
import Autolink, { AutolinkProps } from 'react-native-autolink'
|
|
13
12
|
import { LeftRightStyle, IMessage } from './types'
|
|
14
|
-
import { error } from './logging'
|
|
15
|
-
|
|
16
|
-
export interface MessageOption {
|
|
17
|
-
title: string
|
|
18
|
-
action: (phone: string) => void
|
|
19
|
-
}
|
|
20
13
|
|
|
21
14
|
export type MessageTextProps<TMessage extends IMessage> = {
|
|
22
15
|
position?: 'left' | 'right'
|
|
@@ -42,60 +35,32 @@ export const MessageText: React.FC<MessageTextProps<IMessage>> = ({
|
|
|
42
35
|
onPress: onPressProp,
|
|
43
36
|
...rest
|
|
44
37
|
}) => {
|
|
45
|
-
const onUrlPress = useCallback((url: string) => {
|
|
46
|
-
if (/^www\./i.test(url))
|
|
47
|
-
url = `https://${url}`
|
|
48
|
-
|
|
49
|
-
Linking.openURL(url).catch(e => {
|
|
50
|
-
error(e, 'No handler for URL:', url)
|
|
51
|
-
})
|
|
52
|
-
}, [])
|
|
53
|
-
|
|
54
|
-
const onPhonePress = useCallback((phone: string) => {
|
|
55
|
-
Linking.openURL(`tel:${phone}`).catch(e => {
|
|
56
|
-
error(e, 'No handler for telephone')
|
|
57
|
-
})
|
|
58
|
-
}, [])
|
|
59
|
-
|
|
60
|
-
const onEmailPress = useCallback((email: string) =>
|
|
61
|
-
Linking.openURL(`mailto:${email}`).catch(e =>
|
|
62
|
-
error(e, 'No handler for mailto')
|
|
63
|
-
), [])
|
|
64
|
-
|
|
65
38
|
const linkStyle = useMemo(() => StyleSheet.flatten([
|
|
66
39
|
styles.link,
|
|
67
40
|
linkStyleProp?.[position],
|
|
68
41
|
]), [position, linkStyleProp])
|
|
69
42
|
|
|
70
|
-
const handlePress = useCallback((url: string, match: Match) => {
|
|
71
|
-
const type = match.getType()
|
|
72
|
-
|
|
73
|
-
if (onPressProp)
|
|
74
|
-
onPressProp(currentMessage, url, match)
|
|
75
|
-
else if (type === 'url')
|
|
76
|
-
onUrlPress(url)
|
|
77
|
-
else if (type === 'phone')
|
|
78
|
-
onPhonePress(url)
|
|
79
|
-
else if (type === 'email')
|
|
80
|
-
onEmailPress(url)
|
|
81
|
-
}, [onUrlPress, onPhonePress, onEmailPress, onPressProp, currentMessage])
|
|
82
|
-
|
|
83
43
|
const style = useMemo(() => [
|
|
84
44
|
styles[`text_${position}`],
|
|
85
45
|
textStyle?.[position],
|
|
86
46
|
customTextStyle,
|
|
87
47
|
], [position, textStyle, customTextStyle])
|
|
88
48
|
|
|
49
|
+
const handlePress = useCallback((url: string, match: Match) => {
|
|
50
|
+
onPressProp?.(currentMessage, url, match)
|
|
51
|
+
}, [onPressProp, currentMessage])
|
|
52
|
+
|
|
89
53
|
return (
|
|
90
54
|
<View style={[styles.container, containerStyle?.[position]]}>
|
|
91
55
|
<Autolink
|
|
92
|
-
style={style}
|
|
93
|
-
{...rest}
|
|
94
|
-
text={currentMessage!.text}
|
|
95
56
|
email
|
|
57
|
+
phone
|
|
96
58
|
link
|
|
59
|
+
{...rest}
|
|
60
|
+
onPress={onPressProp ? handlePress : undefined}
|
|
97
61
|
linkStyle={linkStyle}
|
|
98
|
-
|
|
62
|
+
style={style}
|
|
63
|
+
text={currentMessage!.text}
|
|
99
64
|
/>
|
|
100
65
|
</View>
|
|
101
66
|
)
|
package/src/MessageVideo.tsx
CHANGED
package/src/QuickReplies.tsx
CHANGED
|
@@ -3,15 +3,15 @@ import {
|
|
|
3
3
|
Text,
|
|
4
4
|
StyleSheet,
|
|
5
5
|
View,
|
|
6
|
-
TouchableOpacity,
|
|
7
6
|
StyleProp,
|
|
8
7
|
ViewStyle,
|
|
9
8
|
TextStyle,
|
|
10
9
|
} from 'react-native'
|
|
11
|
-
import { IMessage, Reply } from './types'
|
|
12
10
|
import Color from './Color'
|
|
11
|
+
import { TouchableOpacity } from './components/TouchableOpacity'
|
|
13
12
|
import { warning } from './logging'
|
|
14
13
|
import stylesCommon from './styles'
|
|
14
|
+
import { IMessage, Reply } from './types'
|
|
15
15
|
|
|
16
16
|
const styles = StyleSheet.create({
|
|
17
17
|
container: {
|
package/src/Send.tsx
CHANGED
|
@@ -2,18 +2,17 @@ import React, { useMemo, 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
|
-
TouchableOpacityProps,
|
|
11
9
|
useColorScheme,
|
|
12
10
|
} from 'react-native'
|
|
13
|
-
|
|
14
11
|
import Color from './Color'
|
|
15
|
-
|
|
12
|
+
|
|
13
|
+
import { TouchableOpacity, TouchableOpacityProps } from './components/TouchableOpacity'
|
|
16
14
|
import { TEST_ID } from './Constant'
|
|
15
|
+
import { IMessage } from './types'
|
|
17
16
|
|
|
18
17
|
const styles = StyleSheet.create({
|
|
19
18
|
container: {
|
package/src/SystemMessage.tsx
CHANGED
package/src/Time.tsx
CHANGED
|
@@ -4,8 +4,8 @@ import dayjs from 'dayjs'
|
|
|
4
4
|
|
|
5
5
|
import Color from './Color'
|
|
6
6
|
import { TIME_FORMAT } from './Constant'
|
|
7
|
-
import { LeftRightStyle, IMessage } from './types'
|
|
8
7
|
import { useChatContext } from './GiftedChatContext'
|
|
8
|
+
import { LeftRightStyle, IMessage } from './types'
|
|
9
9
|
|
|
10
10
|
const { containerStyle } = StyleSheet.create({
|
|
11
11
|
containerStyle: {
|
|
@@ -9,10 +9,10 @@ import Animated, {
|
|
|
9
9
|
withSequence,
|
|
10
10
|
withTiming,
|
|
11
11
|
} from 'react-native-reanimated'
|
|
12
|
-
import { TypingIndicatorProps } from './types'
|
|
13
|
-
|
|
14
12
|
import stylesCommon from '../styles'
|
|
13
|
+
|
|
15
14
|
import styles from './styles'
|
|
15
|
+
import { TypingIndicatorProps } from './types'
|
|
16
16
|
|
|
17
17
|
export * from './types'
|
|
18
18
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { render } from '@testing-library/react-native'
|
|
3
2
|
import { View, Text } from 'react-native'
|
|
4
|
-
import
|
|
3
|
+
import { render } from '@testing-library/react-native'
|
|
5
4
|
import { DayProps } from '../Day'
|
|
5
|
+
import DayAnimated from '../MessageContainer/components/DayAnimated'
|
|
6
6
|
|
|
7
7
|
const mockDaysPositions = { value: {} }
|
|
8
8
|
const mockScrolledY = { value: 0 }
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { render } from '@testing-library/react-native'
|
|
3
3
|
|
|
4
|
-
import { GiftedChat } from '../GiftedChat'
|
|
5
4
|
import { useReanimatedKeyboardAnimation } from 'react-native-keyboard-controller'
|
|
5
|
+
import { GiftedChat } from '../GiftedChat'
|
|
6
6
|
|
|
7
7
|
const messages = [
|
|
8
8
|
{
|
|
@@ -36,7 +36,7 @@ it('should render <GiftedChat/> and compare with snapshot', () => {
|
|
|
36
36
|
expect(toJSON()).toMatchSnapshot()
|
|
37
37
|
})
|
|
38
38
|
|
|
39
|
-
it('should render <GiftedChat/> with
|
|
39
|
+
it('should render <GiftedChat/> with isKeyboardInternallyHandled=false', () => {
|
|
40
40
|
(useReanimatedKeyboardAnimation as jest.Mock).mockReturnValue({
|
|
41
41
|
height: {
|
|
42
42
|
value: 0,
|
|
@@ -50,7 +50,7 @@ it('should render <GiftedChat/> with disableKeyboardController=true', () => {
|
|
|
50
50
|
user={{
|
|
51
51
|
_id: 1,
|
|
52
52
|
}}
|
|
53
|
-
|
|
53
|
+
isKeyboardInternallyHandled={false}
|
|
54
54
|
/>
|
|
55
55
|
)
|
|
56
56
|
|
|
@@ -22,7 +22,34 @@ exports[`should render <Actions /> and compare with snapshot 1`] = `
|
|
|
22
22
|
accessible={true}
|
|
23
23
|
collapsable={false}
|
|
24
24
|
focusable={true}
|
|
25
|
+
jestAnimatedProps={
|
|
26
|
+
{
|
|
27
|
+
"value": {},
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
jestAnimatedStyle={
|
|
31
|
+
{
|
|
32
|
+
"value": {
|
|
33
|
+
"opacity": 1,
|
|
34
|
+
},
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
jestInlineStyle={
|
|
38
|
+
[
|
|
39
|
+
[
|
|
40
|
+
{
|
|
41
|
+
"height": 26,
|
|
42
|
+
"marginBottom": 10,
|
|
43
|
+
"marginLeft": 10,
|
|
44
|
+
"width": 26,
|
|
45
|
+
},
|
|
46
|
+
undefined,
|
|
47
|
+
],
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
onBlur={[Function]}
|
|
25
51
|
onClick={[Function]}
|
|
52
|
+
onFocus={[Function]}
|
|
26
53
|
onResponderGrant={[Function]}
|
|
27
54
|
onResponderMove={[Function]}
|
|
28
55
|
onResponderRelease={[Function]}
|
|
@@ -30,13 +57,18 @@ exports[`should render <Actions /> and compare with snapshot 1`] = `
|
|
|
30
57
|
onResponderTerminationRequest={[Function]}
|
|
31
58
|
onStartShouldSetResponder={[Function]}
|
|
32
59
|
style={
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
60
|
+
[
|
|
61
|
+
{
|
|
62
|
+
"height": 26,
|
|
63
|
+
"marginBottom": 10,
|
|
64
|
+
"marginLeft": 10,
|
|
65
|
+
"width": 26,
|
|
66
|
+
},
|
|
67
|
+
undefined,
|
|
68
|
+
{
|
|
69
|
+
"opacity": 1,
|
|
70
|
+
},
|
|
71
|
+
]
|
|
40
72
|
}
|
|
41
73
|
>
|
|
42
74
|
<View
|