react-native-gifted-chat 2.7.2 → 2.8.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 +6 -6
- package/lib/Day/index.d.ts +1 -1
- package/lib/Day/index.js +2 -2
- package/lib/Day/index.js.map +1 -1
- package/lib/GiftedChat/index.d.ts +1 -1
- package/lib/GiftedChat/index.js +6 -3
- package/lib/GiftedChat/index.js.map +1 -1
- package/lib/GiftedChat/types.d.ts +4 -4
- package/lib/GiftedChatContext.d.ts +1 -2
- package/lib/GiftedChatContext.js +3 -3
- package/lib/GiftedChatContext.js.map +1 -1
- package/lib/InputToolbar.js +1 -0
- package/lib/InputToolbar.js.map +1 -1
- package/lib/MessageContainer/components/Item/index.d.ts +2 -1
- package/lib/MessageContainer/components/Item/index.js +2 -5
- package/lib/MessageContainer/components/Item/index.js.map +1 -1
- package/lib/MessageContainer/components/Item/types.d.ts +4 -5
- package/lib/MessageContainer/index.js +45 -29
- package/lib/MessageContainer/index.js.map +1 -1
- package/lib/MessageContainer/types.d.ts +5 -5
- package/lib/Time.d.ts +1 -1
- package/lib/Time.js +3 -3
- package/lib/Time.js.map +1 -1
- package/package.json +1 -3
- package/src/Day/index.tsx +2 -2
- package/src/GiftedChat/index.tsx +13 -10
- package/src/GiftedChat/types.ts +4 -4
- package/src/GiftedChatContext.ts +3 -3
- package/src/InputToolbar.tsx +1 -0
- package/src/MessageContainer/components/Item/index.tsx +4 -16
- package/src/MessageContainer/components/Item/types.ts +4 -5
- package/src/MessageContainer/index.tsx +67 -37
- package/src/MessageContainer/types.ts +5 -4
- package/src/Time.tsx +5 -3
- package/src/__tests__/__snapshots__/MessageContainer.test.tsx.snap +77 -279
package/src/GiftedChat/index.tsx
CHANGED
|
@@ -56,13 +56,18 @@ import styles from './styles'
|
|
|
56
56
|
dayjs.extend(localizedFormat)
|
|
57
57
|
|
|
58
58
|
function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
59
|
-
props: GiftedChatProps
|
|
59
|
+
props: GiftedChatProps<TMessage>
|
|
60
60
|
) {
|
|
61
61
|
const {
|
|
62
62
|
messages = [],
|
|
63
63
|
initialText = '',
|
|
64
64
|
isTyping,
|
|
65
|
-
|
|
65
|
+
|
|
66
|
+
// "random" function from here: https://stackoverflow.com/a/8084248/3452513
|
|
67
|
+
// we do not use uuid since it would add extra native dependency (https://www.npmjs.com/package/react-native-get-random-values)
|
|
68
|
+
// lib's user can decide which algorithm to use and pass it as a prop
|
|
69
|
+
messageIdGenerator = () => (Math.random() + 1).toString(36).substring(7),
|
|
70
|
+
|
|
66
71
|
user = {},
|
|
67
72
|
onSend,
|
|
68
73
|
locale = 'en',
|
|
@@ -89,9 +94,9 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
89
94
|
const actionSheetRef = useRef<ActionSheetProviderRef>(null)
|
|
90
95
|
|
|
91
96
|
const messageContainerRef = useMemo(
|
|
92
|
-
() => props.messageContainerRef || createRef<AnimatedList
|
|
97
|
+
() => props.messageContainerRef || createRef<AnimatedList<TMessage>>(),
|
|
93
98
|
[props.messageContainerRef]
|
|
94
|
-
)
|
|
99
|
+
) as RefObject<AnimatedList<TMessage>>
|
|
95
100
|
|
|
96
101
|
const textInputRef = useMemo(
|
|
97
102
|
() => props.textInputRef || createRef<TextInput>(),
|
|
@@ -200,9 +205,9 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
200
205
|
|
|
201
206
|
const { messagesContainerStyle, ...messagesContainerProps } = props
|
|
202
207
|
|
|
203
|
-
|
|
208
|
+
return (
|
|
204
209
|
<View style={[stylesCommon.fill, messagesContainerStyle]}>
|
|
205
|
-
<MessageContainer
|
|
210
|
+
<MessageContainer<TMessage>
|
|
206
211
|
{...messagesContainerProps}
|
|
207
212
|
invertibleScrollViewProps={{
|
|
208
213
|
inverted,
|
|
@@ -215,8 +220,6 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
215
220
|
{renderChatFooter?.()}
|
|
216
221
|
</View>
|
|
217
222
|
)
|
|
218
|
-
|
|
219
|
-
return fragment
|
|
220
223
|
}, [
|
|
221
224
|
isInitialized,
|
|
222
225
|
isTyping,
|
|
@@ -444,10 +447,10 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
444
447
|
)
|
|
445
448
|
}
|
|
446
449
|
|
|
447
|
-
function GiftedChatWrapper (props: GiftedChatProps) {
|
|
450
|
+
function GiftedChatWrapper<TMessage extends IMessage = IMessage> (props: GiftedChatProps<TMessage>) {
|
|
448
451
|
return (
|
|
449
452
|
<KeyboardProvider>
|
|
450
|
-
<GiftedChat {...props} />
|
|
453
|
+
<GiftedChat<TMessage> {...props} />
|
|
451
454
|
</KeyboardProvider>
|
|
452
455
|
)
|
|
453
456
|
}
|
package/src/GiftedChat/types.ts
CHANGED
|
@@ -30,12 +30,12 @@ import { QuickRepliesProps } from '../QuickReplies'
|
|
|
30
30
|
import { SendProps } from '../Send'
|
|
31
31
|
import { SystemMessageProps } from '../SystemMessage'
|
|
32
32
|
import { TimeProps } from '../Time'
|
|
33
|
-
import
|
|
33
|
+
import { AnimatedList, ListViewProps, MessageContainerProps } from '../MessageContainer'
|
|
34
34
|
import Bubble from '../Bubble'
|
|
35
35
|
|
|
36
|
-
export interface GiftedChatProps<TMessage extends IMessage
|
|
36
|
+
export interface GiftedChatProps<TMessage extends IMessage> extends Partial<MessageContainerProps<TMessage>> {
|
|
37
37
|
/* Message container ref */
|
|
38
|
-
messageContainerRef?: RefObject<AnimatedList
|
|
38
|
+
messageContainerRef?: RefObject<AnimatedList<TMessage>>
|
|
39
39
|
/* text input ref */
|
|
40
40
|
textInputRef?: RefObject<TextInput>
|
|
41
41
|
/* Messages to display */
|
|
@@ -171,7 +171,7 @@ export interface GiftedChatProps<TMessage extends IMessage = IMessage> extends P
|
|
|
171
171
|
/* Custom time inside a message */
|
|
172
172
|
renderTime?(props: TimeProps<TMessage>): React.ReactNode
|
|
173
173
|
/* Custom footer component on the ListView, e.g. 'User is typing...' */
|
|
174
|
-
renderFooter?(): React.ReactNode
|
|
174
|
+
renderFooter?(props: MessageContainerProps<TMessage>): React.ReactNode
|
|
175
175
|
/* Custom component to render in the ListView when messages are empty */
|
|
176
176
|
renderChatEmpty?(): React.ReactNode
|
|
177
177
|
/* Custom component to render below the MessageContainer (separate from the ListView) */
|
package/src/GiftedChatContext.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { createContext, useContext } from 'react'
|
|
2
2
|
import {
|
|
3
3
|
ActionSheetOptions,
|
|
4
4
|
} from '@expo/react-native-action-sheet'
|
|
@@ -13,11 +13,11 @@ export interface IGiftedChatContext {
|
|
|
13
13
|
getLocale(): string
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
export const GiftedChatContext =
|
|
16
|
+
export const GiftedChatContext = createContext<IGiftedChatContext>({
|
|
17
17
|
getLocale: () => 'en',
|
|
18
18
|
actionSheet: () => ({
|
|
19
19
|
showActionSheetWithOptions: () => {},
|
|
20
20
|
}),
|
|
21
21
|
})
|
|
22
22
|
|
|
23
|
-
export const useChatContext = () =>
|
|
23
|
+
export const useChatContext = () => useContext(GiftedChatContext)
|
package/src/InputToolbar.tsx
CHANGED
|
@@ -91,9 +91,8 @@ const DayWrapper = forwardRef<View, MessageProps<IMessage>>((props, ref) => {
|
|
|
91
91
|
)
|
|
92
92
|
})
|
|
93
93
|
|
|
94
|
-
const Item = (props: ItemProps) => {
|
|
94
|
+
const Item = <TMessage extends IMessage>(props: ItemProps<TMessage>) => {
|
|
95
95
|
const {
|
|
96
|
-
onRefDayWrapper,
|
|
97
96
|
renderMessage: renderMessageProp,
|
|
98
97
|
scrolledY,
|
|
99
98
|
daysPositions,
|
|
@@ -134,29 +133,18 @@ const Item = (props: ItemProps) => {
|
|
|
134
133
|
),
|
|
135
134
|
}), [relativeScrolledPositionToBottomOfDay, dayContainerHeight, dayTopOffset])
|
|
136
135
|
|
|
137
|
-
const handleRef = useCallback((ref: unknown) => {
|
|
138
|
-
onRefDayWrapper(
|
|
139
|
-
ref,
|
|
140
|
-
props.currentMessage._id,
|
|
141
|
-
new Date(props.currentMessage.createdAt).getTime()
|
|
142
|
-
)
|
|
143
|
-
}, [onRefDayWrapper, props.currentMessage])
|
|
144
|
-
|
|
145
136
|
return (
|
|
146
137
|
<View key={props.currentMessage._id.toString()}>
|
|
147
138
|
<Animated.View
|
|
148
139
|
style={style}
|
|
149
140
|
onLayout={handleLayoutDayContainer}
|
|
150
141
|
>
|
|
151
|
-
<DayWrapper
|
|
152
|
-
{...rest as MessageProps<IMessage>}
|
|
153
|
-
ref={handleRef}
|
|
154
|
-
/>
|
|
142
|
+
<DayWrapper {...rest as MessageProps<TMessage>} />
|
|
155
143
|
</Animated.View>
|
|
156
144
|
{
|
|
157
145
|
renderMessageProp
|
|
158
|
-
? renderMessageProp(rest as MessageProps<
|
|
159
|
-
: <Message {...rest as MessageProps<
|
|
146
|
+
? renderMessageProp(rest as MessageProps<TMessage>)
|
|
147
|
+
: <Message {...rest as MessageProps<TMessage>} />
|
|
160
148
|
}
|
|
161
149
|
</View>
|
|
162
150
|
)
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { MessageContainerProps, DaysPositions } from '../../types'
|
|
2
2
|
import { IMessage } from '../../../types'
|
|
3
3
|
|
|
4
|
-
export interface ItemProps extends MessageContainerProps<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
nextMessage?: IMessage
|
|
4
|
+
export interface ItemProps<TMessage extends IMessage> extends MessageContainerProps<TMessage> {
|
|
5
|
+
currentMessage: TMessage
|
|
6
|
+
previousMessage?: TMessage
|
|
7
|
+
nextMessage?: TMessage
|
|
9
8
|
position: 'left' | 'right'
|
|
10
9
|
scrolledY: { value: number }
|
|
11
10
|
daysPositions: { value: DaysPositions }
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import React, { useCallback, useMemo, useState } from 'react'
|
|
1
|
+
import React, { useCallback, useEffect, useMemo, useState } from 'react'
|
|
2
2
|
import {
|
|
3
3
|
View,
|
|
4
4
|
TouchableOpacity,
|
|
5
5
|
Text,
|
|
6
6
|
Platform,
|
|
7
7
|
LayoutChangeEvent,
|
|
8
|
+
ListRenderItemInfo,
|
|
9
|
+
FlatList,
|
|
10
|
+
CellRendererProps,
|
|
8
11
|
} from 'react-native'
|
|
9
|
-
import { FlashList, ListRenderItemInfo } from '@shopify/flash-list'
|
|
10
12
|
import Animated, { runOnJS, useAnimatedScrollHandler, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated'
|
|
11
13
|
import { ReanimatedScrollEvent } from 'react-native-reanimated/lib/typescript/hook/commonTypes'
|
|
12
14
|
import DayAnimated from './components/DayAnimated'
|
|
@@ -21,10 +23,11 @@ import { ItemProps } from './components/Item/types'
|
|
|
21
23
|
import { warning } from '../logging'
|
|
22
24
|
import stylesCommon from '../styles'
|
|
23
25
|
import styles from './styles'
|
|
26
|
+
import { isSameDay } from '../utils'
|
|
24
27
|
|
|
25
28
|
export * from './types'
|
|
26
29
|
|
|
27
|
-
const
|
|
30
|
+
const AnimatedFlatList = Animated.createAnimatedComponent(FlatList)
|
|
28
31
|
|
|
29
32
|
function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageContainerProps<TMessage>) {
|
|
30
33
|
const {
|
|
@@ -77,7 +80,7 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
|
|
|
77
80
|
}, [renderFooterProp, renderTypingIndicator, props])
|
|
78
81
|
|
|
79
82
|
const renderLoadEarlier = useCallback(() => {
|
|
80
|
-
if (loadEarlier
|
|
83
|
+
if (loadEarlier) {
|
|
81
84
|
if (renderLoadEarlierProp)
|
|
82
85
|
return renderLoadEarlierProp(props)
|
|
83
86
|
|
|
@@ -136,31 +139,6 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
|
|
|
136
139
|
makeScrollToBottomHidden()
|
|
137
140
|
}, [handleOnScrollProp, inverted, scrollToBottomOffset, scrollToBottomOpacity])
|
|
138
141
|
|
|
139
|
-
const handleLayoutDayWrapper = useCallback((ref: unknown, id: string | number, createdAt: number) => {
|
|
140
|
-
setTimeout(() => { // do not delete "setTimeout". It's necessary for get correct layout.
|
|
141
|
-
const itemLayout = forwardRef?.current?.recyclerlistview_unsafe?.getLayout(messages.findIndex(m => m._id === id))
|
|
142
|
-
|
|
143
|
-
if (ref && itemLayout)
|
|
144
|
-
daysPositions.modify(value => {
|
|
145
|
-
'worklet'
|
|
146
|
-
|
|
147
|
-
// @ts-expect-error: https://docs.swmansion.com/react-native-reanimated/docs/core/useSharedValue#remarks
|
|
148
|
-
value[id] = {
|
|
149
|
-
...itemLayout,
|
|
150
|
-
createdAt,
|
|
151
|
-
}
|
|
152
|
-
return value
|
|
153
|
-
})
|
|
154
|
-
else if (daysPositions.value[id] != null)
|
|
155
|
-
daysPositions.modify(value => {
|
|
156
|
-
'worklet'
|
|
157
|
-
|
|
158
|
-
delete value[id]
|
|
159
|
-
return value
|
|
160
|
-
})
|
|
161
|
-
}, 100)
|
|
162
|
-
}, [messages, daysPositions, forwardRef])
|
|
163
|
-
|
|
164
142
|
const renderItem = useCallback(({ item, index }: ListRenderItemInfo<unknown>): React.ReactElement | null => {
|
|
165
143
|
const messageItem = item as TMessage
|
|
166
144
|
|
|
@@ -185,25 +163,24 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
|
|
|
185
163
|
const nextMessage =
|
|
186
164
|
(inverted ? messages[index - 1] : messages[index + 1]) || {}
|
|
187
165
|
|
|
188
|
-
const messageProps: ItemProps = {
|
|
166
|
+
const messageProps: ItemProps<TMessage> = {
|
|
189
167
|
...restProps,
|
|
190
168
|
currentMessage: messageItem,
|
|
191
169
|
previousMessage,
|
|
192
170
|
nextMessage,
|
|
193
171
|
position: messageItem.user._id === user._id ? 'right' : 'left',
|
|
194
|
-
onRefDayWrapper: handleLayoutDayWrapper,
|
|
195
172
|
scrolledY,
|
|
196
173
|
daysPositions,
|
|
197
174
|
listHeight,
|
|
198
175
|
}
|
|
199
176
|
|
|
200
177
|
return (
|
|
201
|
-
<Item {...messageProps} />
|
|
178
|
+
<Item<TMessage> {...messageProps} />
|
|
202
179
|
)
|
|
203
180
|
}
|
|
204
181
|
|
|
205
182
|
return null
|
|
206
|
-
}, [props, inverted,
|
|
183
|
+
}, [props, inverted, scrolledY, daysPositions, listHeight, user])
|
|
207
184
|
|
|
208
185
|
const renderChatEmpty = useCallback(() => {
|
|
209
186
|
if (renderChatEmptyProp)
|
|
@@ -288,6 +265,37 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
|
|
|
288
265
|
|
|
289
266
|
const keyExtractor = useCallback((item: unknown) => (item as TMessage)._id.toString(), [])
|
|
290
267
|
|
|
268
|
+
const renderCell = useCallback((props: CellRendererProps<unknown>) => {
|
|
269
|
+
const handleOnLayout = (event: LayoutChangeEvent) => {
|
|
270
|
+
const prevMessage = messages[props.index + (inverted ? 1 : -1)]
|
|
271
|
+
if (prevMessage && isSameDay(props.item as IMessage, prevMessage))
|
|
272
|
+
return
|
|
273
|
+
|
|
274
|
+
const { y, height } = event.nativeEvent.layout
|
|
275
|
+
|
|
276
|
+
const newValue = {
|
|
277
|
+
y,
|
|
278
|
+
height,
|
|
279
|
+
createdAt: new Date((props.item as IMessage).createdAt).getTime(),
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
daysPositions.modify(value => {
|
|
283
|
+
'worklet'
|
|
284
|
+
|
|
285
|
+
// @ts-expect-error: https://docs.swmansion.com/react-native-reanimated/docs/core/useSharedValue#remarks
|
|
286
|
+
value[props.item._id] = newValue
|
|
287
|
+
return value
|
|
288
|
+
})
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return (
|
|
292
|
+
<Animated.View
|
|
293
|
+
{...props}
|
|
294
|
+
onLayout={handleOnLayout}
|
|
295
|
+
/>
|
|
296
|
+
)
|
|
297
|
+
}, [daysPositions, messages, inverted])
|
|
298
|
+
|
|
291
299
|
const scrollHandler = useAnimatedScrollHandler({
|
|
292
300
|
onScroll: event => {
|
|
293
301
|
scrolledY.value = event.contentOffset.y
|
|
@@ -296,6 +304,28 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
|
|
|
296
304
|
},
|
|
297
305
|
}, [handleOnScroll])
|
|
298
306
|
|
|
307
|
+
// removes unrendered days positions when messages are added/removed
|
|
308
|
+
useEffect(() => {
|
|
309
|
+
Object.keys(daysPositions.value).forEach(key => {
|
|
310
|
+
const messageIndex = messages.findIndex(m => m._id === key)
|
|
311
|
+
let shouldRemove = messageIndex === -1
|
|
312
|
+
|
|
313
|
+
if (!shouldRemove) {
|
|
314
|
+
const prevMessage = messages[messageIndex + (inverted ? 1 : -1)]
|
|
315
|
+
const message = messages[messageIndex]
|
|
316
|
+
shouldRemove = !!prevMessage && isSameDay(message, prevMessage)
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if (shouldRemove)
|
|
320
|
+
daysPositions.modify(value => {
|
|
321
|
+
'worklet'
|
|
322
|
+
|
|
323
|
+
delete value[key]
|
|
324
|
+
return value
|
|
325
|
+
})
|
|
326
|
+
})
|
|
327
|
+
}, [messages, daysPositions, inverted])
|
|
328
|
+
|
|
299
329
|
return (
|
|
300
330
|
<View
|
|
301
331
|
style={[
|
|
@@ -303,8 +333,8 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
|
|
|
303
333
|
alignTop ? styles.containerAlignTop : stylesCommon.fill,
|
|
304
334
|
]}
|
|
305
335
|
>
|
|
306
|
-
<
|
|
307
|
-
ref={forwardRef}
|
|
336
|
+
<AnimatedFlatList
|
|
337
|
+
ref={forwardRef as React.Ref<FlatList<unknown>>}
|
|
308
338
|
extraData={[extraData, isTyping]}
|
|
309
339
|
keyExtractor={keyExtractor}
|
|
310
340
|
automaticallyAdjustContentInsets={false}
|
|
@@ -321,12 +351,12 @@ function MessageContainer<TMessage extends IMessage = IMessage> (props: MessageC
|
|
|
321
351
|
inverted ? ListFooterComponent : ListHeaderComponent
|
|
322
352
|
}
|
|
323
353
|
onScroll={scrollHandler}
|
|
324
|
-
scrollEventThrottle={
|
|
354
|
+
scrollEventThrottle={1}
|
|
325
355
|
onEndReached={onEndReached}
|
|
326
356
|
onEndReachedThreshold={0.1}
|
|
327
|
-
estimatedItemSize={100}
|
|
328
357
|
{...listViewProps}
|
|
329
358
|
onLayout={onLayoutList}
|
|
359
|
+
CellRendererComponent={renderCell}
|
|
330
360
|
/>
|
|
331
361
|
{isScrollToBottomEnabled
|
|
332
362
|
? renderScrollToBottomWrapper()
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
import React, { Component, RefObject } from 'react'
|
|
2
2
|
import {
|
|
3
|
+
FlatListProps,
|
|
3
4
|
LayoutChangeEvent,
|
|
4
5
|
StyleProp,
|
|
5
6
|
ViewStyle,
|
|
6
7
|
} from 'react-native'
|
|
7
|
-
import { FlashList, FlashListProps } from '@shopify/flash-list'
|
|
8
8
|
|
|
9
9
|
import { LoadEarlierProps } from '../LoadEarlier'
|
|
10
10
|
import { MessageProps } from '../Message'
|
|
11
11
|
import { User, IMessage, Reply } from '../types'
|
|
12
12
|
import { ReanimatedScrollEvent } from 'react-native-reanimated/lib/typescript/hook/commonTypes'
|
|
13
|
+
import { FlatList } from 'react-native-reanimated/lib/typescript/Animated'
|
|
13
14
|
import { AnimateProps } from 'react-native-reanimated'
|
|
14
15
|
|
|
15
16
|
export type ListViewProps = {
|
|
16
17
|
onLayout?: (event: LayoutChangeEvent) => void
|
|
17
18
|
} & object
|
|
18
19
|
|
|
19
|
-
export type AnimatedList = Component<AnimateProps<
|
|
20
|
+
export type AnimatedList<TMessage> = Component<AnimateProps<FlatListProps<TMessage>>, unknown, unknown> & FlatList<FlatListProps<TMessage>>
|
|
20
21
|
|
|
21
|
-
export interface MessageContainerProps<TMessage extends IMessage> {
|
|
22
|
-
forwardRef?: RefObject<AnimatedList
|
|
22
|
+
export interface MessageContainerProps<TMessage extends IMessage = IMessage> {
|
|
23
|
+
forwardRef?: RefObject<AnimatedList<TMessage>>
|
|
23
24
|
messages?: TMessage[]
|
|
24
25
|
isTyping?: boolean
|
|
25
26
|
user?: User
|
package/src/Time.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from 'react'
|
|
2
2
|
import { StyleSheet, Text, View, ViewStyle, TextStyle } from 'react-native'
|
|
3
3
|
import dayjs from 'dayjs'
|
|
4
4
|
|
|
@@ -14,6 +14,7 @@ const { containerStyle } = StyleSheet.create({
|
|
|
14
14
|
marginBottom: 5,
|
|
15
15
|
},
|
|
16
16
|
})
|
|
17
|
+
|
|
17
18
|
const { textStyle } = StyleSheet.create({
|
|
18
19
|
textStyle: {
|
|
19
20
|
fontSize: 10,
|
|
@@ -58,6 +59,7 @@ export function Time<TMessage extends IMessage = IMessage> ({
|
|
|
58
59
|
timeTextStyle,
|
|
59
60
|
}: TimeProps<TMessage>) {
|
|
60
61
|
const { getLocale } = useChatContext()
|
|
62
|
+
|
|
61
63
|
if (currentMessage == null)
|
|
62
64
|
return null
|
|
63
65
|
|
|
@@ -65,13 +67,13 @@ export function Time<TMessage extends IMessage = IMessage> ({
|
|
|
65
67
|
<View
|
|
66
68
|
style={[
|
|
67
69
|
styles[position].container,
|
|
68
|
-
containerStyle
|
|
70
|
+
containerStyle?.[position],
|
|
69
71
|
]}
|
|
70
72
|
>
|
|
71
73
|
<Text
|
|
72
74
|
style={[
|
|
73
75
|
styles[position].text,
|
|
74
|
-
timeTextStyle
|
|
76
|
+
timeTextStyle?.[position],
|
|
75
77
|
]}
|
|
76
78
|
>
|
|
77
79
|
{dayjs(currentMessage.createdAt).locale(getLocale()).format(timeFormat)}
|