react-native-gifted-chat 2.7.3 → 2.8.1
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 +14 -6
- package/lib/Bubble/index.d.ts +2 -26
- package/lib/Bubble/index.js +151 -123
- package/lib/Bubble/index.js.map +1 -1
- 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 +1 -2
- package/lib/GiftedChat/index.js.map +1 -1
- package/lib/GiftedChat/types.d.ts +7 -7
- 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/Message/index.js +7 -12
- package/lib/Message/index.js.map +1 -1
- package/lib/Message/types.d.ts +2 -2
- package/lib/MessageContainer/components/Item/index.d.ts +2 -1
- package/lib/MessageContainer/components/Item/index.js +5 -6
- 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 +61 -33
- package/lib/MessageContainer/index.js.map +1 -1
- package/lib/MessageContainer/types.d.ts +5 -5
- package/lib/MessageText.js +2 -2
- package/lib/MessageText.js.map +1 -1
- package/lib/Time.d.ts +1 -1
- package/lib/Time.js +3 -3
- package/lib/Time.js.map +1 -1
- package/package.json +13 -15
- package/src/Bubble/index.tsx +170 -146
- package/src/Day/index.tsx +2 -2
- package/src/GiftedChat/index.tsx +7 -9
- package/src/GiftedChat/types.ts +7 -7
- package/src/GiftedChatContext.ts +3 -3
- package/src/InputToolbar.tsx +1 -0
- package/src/Message/index.tsx +10 -16
- package/src/Message/types.ts +2 -2
- package/src/MessageContainer/components/Item/index.tsx +5 -16
- package/src/MessageContainer/components/Item/types.ts +4 -5
- package/src/MessageContainer/index.tsx +98 -54
- package/src/MessageContainer/types.ts +5 -4
- package/src/MessageText.tsx +2 -2
- package/src/Time.tsx +5 -3
- package/src/__tests__/__snapshots__/MessageContainer.test.tsx.snap +72 -279
package/src/Bubble/index.tsx
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { useCallback } from 'react'
|
|
2
2
|
import {
|
|
3
3
|
Text,
|
|
4
4
|
TouchableWithoutFeedback,
|
|
5
5
|
View,
|
|
6
6
|
} from 'react-native'
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { useChatContext } from '../GiftedChatContext'
|
|
9
9
|
import { QuickReplies } from '../QuickReplies'
|
|
10
10
|
import { MessageText } from '../MessageText'
|
|
11
11
|
import { MessageImage } from '../MessageImage'
|
|
@@ -22,25 +22,39 @@ import styles from './styles'
|
|
|
22
22
|
|
|
23
23
|
export * from './types'
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
const Bubble: React.FC<BubbleProps<IMessage>> = (props: BubbleProps<IMessage>) => {
|
|
26
|
+
const {
|
|
27
|
+
currentMessage,
|
|
28
|
+
nextMessage,
|
|
29
|
+
position,
|
|
30
|
+
containerToNextStyle,
|
|
31
|
+
previousMessage,
|
|
32
|
+
containerToPreviousStyle,
|
|
33
|
+
onQuickReply,
|
|
34
|
+
renderQuickReplySend,
|
|
35
|
+
quickReplyStyle,
|
|
36
|
+
quickReplyTextStyle,
|
|
37
|
+
quickReplyContainerStyle,
|
|
38
|
+
containerStyle,
|
|
39
|
+
wrapperStyle,
|
|
40
|
+
bottomContainerStyle,
|
|
41
|
+
} = props
|
|
42
|
+
|
|
43
|
+
const context = useChatContext()
|
|
44
|
+
|
|
45
|
+
const onPress = useCallback(() => {
|
|
46
|
+
if (props.onPress)
|
|
47
|
+
props.onPress(context, currentMessage)
|
|
48
|
+
}, [context, props, currentMessage])
|
|
49
|
+
|
|
50
|
+
const onLongPress = useCallback(() => {
|
|
36
51
|
const {
|
|
37
|
-
currentMessage,
|
|
38
52
|
onLongPress,
|
|
39
53
|
optionTitles,
|
|
40
|
-
} =
|
|
54
|
+
} = props
|
|
41
55
|
|
|
42
56
|
if (onLongPress) {
|
|
43
|
-
onLongPress(
|
|
57
|
+
onLongPress(context, currentMessage)
|
|
44
58
|
return
|
|
45
59
|
}
|
|
46
60
|
|
|
@@ -51,7 +65,7 @@ export default class Bubble<
|
|
|
51
65
|
const cancelButtonIndex = options.length - 1
|
|
52
66
|
|
|
53
67
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
54
|
-
;(
|
|
68
|
+
;(context as any).actionSheet().showActionSheetWithOptions(
|
|
55
69
|
{
|
|
56
70
|
options,
|
|
57
71
|
cancelButtonIndex,
|
|
@@ -60,11 +74,13 @@ export default class Bubble<
|
|
|
60
74
|
console.log('onLongPress', { buttonIndex })
|
|
61
75
|
}
|
|
62
76
|
)
|
|
63
|
-
}
|
|
77
|
+
}, [
|
|
78
|
+
currentMessage,
|
|
79
|
+
context,
|
|
80
|
+
props,
|
|
81
|
+
])
|
|
64
82
|
|
|
65
|
-
styledBubbleToNext () {
|
|
66
|
-
const { currentMessage, nextMessage, position, containerToNextStyle } =
|
|
67
|
-
this.props
|
|
83
|
+
const styledBubbleToNext = useCallback(() => {
|
|
68
84
|
if (
|
|
69
85
|
currentMessage &&
|
|
70
86
|
nextMessage &&
|
|
@@ -78,15 +94,14 @@ export default class Bubble<
|
|
|
78
94
|
]
|
|
79
95
|
|
|
80
96
|
return null
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
} = this.props
|
|
97
|
+
}, [
|
|
98
|
+
currentMessage,
|
|
99
|
+
nextMessage,
|
|
100
|
+
position,
|
|
101
|
+
containerToNextStyle,
|
|
102
|
+
])
|
|
103
|
+
|
|
104
|
+
const styledBubbleToPrevious = useCallback(() => {
|
|
90
105
|
if (
|
|
91
106
|
currentMessage &&
|
|
92
107
|
previousMessage &&
|
|
@@ -100,19 +115,14 @@ export default class Bubble<
|
|
|
100
115
|
]
|
|
101
116
|
|
|
102
117
|
return null
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
quickReplyStyle,
|
|
112
|
-
quickReplyTextStyle,
|
|
113
|
-
quickReplyContainerStyle,
|
|
114
|
-
} = this.props
|
|
115
|
-
|
|
118
|
+
}, [
|
|
119
|
+
currentMessage,
|
|
120
|
+
previousMessage,
|
|
121
|
+
position,
|
|
122
|
+
containerToPreviousStyle,
|
|
123
|
+
])
|
|
124
|
+
|
|
125
|
+
const renderQuickReplies = useCallback(() => {
|
|
116
126
|
if (currentMessage?.quickReplies) {
|
|
117
127
|
const {
|
|
118
128
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
@@ -120,10 +130,10 @@ export default class Bubble<
|
|
|
120
130
|
wrapperStyle,
|
|
121
131
|
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
122
132
|
...quickReplyProps
|
|
123
|
-
} =
|
|
133
|
+
} = props
|
|
124
134
|
|
|
125
|
-
if (
|
|
126
|
-
return
|
|
135
|
+
if (props.renderQuickReplies)
|
|
136
|
+
return props.renderQuickReplies(quickReplyProps)
|
|
127
137
|
|
|
128
138
|
return (
|
|
129
139
|
<QuickReplies
|
|
@@ -139,10 +149,19 @@ export default class Bubble<
|
|
|
139
149
|
}
|
|
140
150
|
|
|
141
151
|
return null
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
152
|
+
}, [
|
|
153
|
+
currentMessage,
|
|
154
|
+
onQuickReply,
|
|
155
|
+
renderQuickReplySend,
|
|
156
|
+
quickReplyStyle,
|
|
157
|
+
quickReplyTextStyle,
|
|
158
|
+
quickReplyContainerStyle,
|
|
159
|
+
nextMessage,
|
|
160
|
+
props,
|
|
161
|
+
])
|
|
162
|
+
|
|
163
|
+
const renderMessageText = useCallback(() => {
|
|
164
|
+
if (currentMessage?.text) {
|
|
146
165
|
const {
|
|
147
166
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
148
167
|
containerStyle,
|
|
@@ -150,35 +169,36 @@ export default class Bubble<
|
|
|
150
169
|
optionTitles,
|
|
151
170
|
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
152
171
|
...messageTextProps
|
|
153
|
-
} =
|
|
154
|
-
|
|
155
|
-
|
|
172
|
+
} = props
|
|
173
|
+
|
|
174
|
+
if (props.renderMessageText)
|
|
175
|
+
return props.renderMessageText(messageTextProps)
|
|
156
176
|
|
|
157
177
|
return <MessageText {...messageTextProps} />
|
|
158
178
|
}
|
|
159
179
|
return null
|
|
160
|
-
}
|
|
180
|
+
}, [props, currentMessage])
|
|
161
181
|
|
|
162
|
-
renderMessageImage () {
|
|
163
|
-
if (
|
|
182
|
+
const renderMessageImage = useCallback(() => {
|
|
183
|
+
if (currentMessage?.image) {
|
|
164
184
|
const {
|
|
165
185
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
166
186
|
containerStyle,
|
|
167
187
|
wrapperStyle,
|
|
168
188
|
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
169
189
|
...messageImageProps
|
|
170
|
-
} =
|
|
190
|
+
} = props
|
|
171
191
|
|
|
172
|
-
if (
|
|
173
|
-
return
|
|
192
|
+
if (props.renderMessageImage)
|
|
193
|
+
return props.renderMessageImage(messageImageProps)
|
|
174
194
|
|
|
175
195
|
return <MessageImage {...messageImageProps} />
|
|
176
196
|
}
|
|
177
197
|
return null
|
|
178
|
-
}
|
|
198
|
+
}, [props, currentMessage])
|
|
179
199
|
|
|
180
|
-
renderMessageVideo () {
|
|
181
|
-
if (!
|
|
200
|
+
const renderMessageVideo = useCallback(() => {
|
|
201
|
+
if (!currentMessage?.video)
|
|
182
202
|
return null
|
|
183
203
|
|
|
184
204
|
const {
|
|
@@ -187,16 +207,16 @@ export default class Bubble<
|
|
|
187
207
|
wrapperStyle,
|
|
188
208
|
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
189
209
|
...messageVideoProps
|
|
190
|
-
} =
|
|
210
|
+
} = props
|
|
191
211
|
|
|
192
|
-
if (
|
|
193
|
-
return
|
|
212
|
+
if (props.renderMessageVideo)
|
|
213
|
+
return props.renderMessageVideo(messageVideoProps)
|
|
194
214
|
|
|
195
215
|
return <MessageVideo />
|
|
196
|
-
}
|
|
216
|
+
}, [props, currentMessage])
|
|
197
217
|
|
|
198
|
-
renderMessageAudio () {
|
|
199
|
-
if (!
|
|
218
|
+
const renderMessageAudio = useCallback(() => {
|
|
219
|
+
if (!currentMessage?.audio)
|
|
200
220
|
return null
|
|
201
221
|
|
|
202
222
|
const {
|
|
@@ -205,20 +225,19 @@ export default class Bubble<
|
|
|
205
225
|
wrapperStyle,
|
|
206
226
|
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
207
227
|
...messageAudioProps
|
|
208
|
-
} =
|
|
228
|
+
} = props
|
|
209
229
|
|
|
210
|
-
if (
|
|
211
|
-
return
|
|
230
|
+
if (props.renderMessageAudio)
|
|
231
|
+
return props.renderMessageAudio(messageAudioProps)
|
|
212
232
|
|
|
213
233
|
return <MessageAudio />
|
|
214
|
-
}
|
|
234
|
+
}, [props, currentMessage])
|
|
215
235
|
|
|
216
|
-
renderTicks () {
|
|
236
|
+
const renderTicks = useCallback(() => {
|
|
217
237
|
const {
|
|
218
|
-
currentMessage,
|
|
219
238
|
renderTicks,
|
|
220
239
|
user,
|
|
221
|
-
} =
|
|
240
|
+
} = props
|
|
222
241
|
|
|
223
242
|
if (renderTicks && currentMessage)
|
|
224
243
|
return renderTicks(currentMessage)
|
|
@@ -237,17 +256,17 @@ export default class Bubble<
|
|
|
237
256
|
return (
|
|
238
257
|
<View style={styles.content.tickView}>
|
|
239
258
|
{!!currentMessage.sent && (
|
|
240
|
-
<Text style={[styles.content.tick,
|
|
259
|
+
<Text style={[styles.content.tick, props.tickStyle]}>
|
|
241
260
|
{'✓'}
|
|
242
261
|
</Text>
|
|
243
262
|
)}
|
|
244
263
|
{!!currentMessage.received && (
|
|
245
|
-
<Text style={[styles.content.tick,
|
|
264
|
+
<Text style={[styles.content.tick, props.tickStyle]}>
|
|
246
265
|
{'✓'}
|
|
247
266
|
</Text>
|
|
248
267
|
)}
|
|
249
268
|
{!!currentMessage.pending && (
|
|
250
|
-
<Text style={[styles.content.tick,
|
|
269
|
+
<Text style={[styles.content.tick, props.tickStyle]}>
|
|
251
270
|
{'🕓'}
|
|
252
271
|
</Text>
|
|
253
272
|
)}
|
|
@@ -255,10 +274,13 @@ export default class Bubble<
|
|
|
255
274
|
)
|
|
256
275
|
|
|
257
276
|
return null
|
|
258
|
-
}
|
|
277
|
+
}, [
|
|
278
|
+
props,
|
|
279
|
+
currentMessage,
|
|
280
|
+
])
|
|
259
281
|
|
|
260
|
-
renderTime () {
|
|
261
|
-
if (
|
|
282
|
+
const renderTime = useCallback(() => {
|
|
283
|
+
if (currentMessage?.createdAt) {
|
|
262
284
|
const {
|
|
263
285
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
264
286
|
containerStyle,
|
|
@@ -266,24 +288,23 @@ export default class Bubble<
|
|
|
266
288
|
textStyle,
|
|
267
289
|
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
268
290
|
...timeProps
|
|
269
|
-
} =
|
|
291
|
+
} = props
|
|
270
292
|
|
|
271
|
-
if (
|
|
272
|
-
return
|
|
293
|
+
if (props.renderTime)
|
|
294
|
+
return props.renderTime(timeProps)
|
|
273
295
|
|
|
274
296
|
return <Time {...timeProps} />
|
|
275
297
|
}
|
|
276
298
|
return null
|
|
277
|
-
}
|
|
299
|
+
}, [props, currentMessage])
|
|
278
300
|
|
|
279
|
-
renderUsername () {
|
|
301
|
+
const renderUsername = useCallback(() => {
|
|
280
302
|
const {
|
|
281
|
-
currentMessage,
|
|
282
303
|
user,
|
|
283
304
|
renderUsername,
|
|
284
|
-
} =
|
|
305
|
+
} = props
|
|
285
306
|
|
|
286
|
-
if (
|
|
307
|
+
if (props.renderUsernameOnMessage && currentMessage) {
|
|
287
308
|
if (user && currentMessage.user._id === user._id)
|
|
288
309
|
return null
|
|
289
310
|
|
|
@@ -294,7 +315,7 @@ export default class Bubble<
|
|
|
294
315
|
<View style={styles.content.usernameView}>
|
|
295
316
|
<Text
|
|
296
317
|
style={
|
|
297
|
-
[styles.content.username,
|
|
318
|
+
[styles.content.username, props.usernameStyle]
|
|
298
319
|
}
|
|
299
320
|
>
|
|
300
321
|
{'~ '}
|
|
@@ -305,75 +326,78 @@ export default class Bubble<
|
|
|
305
326
|
}
|
|
306
327
|
|
|
307
328
|
return null
|
|
308
|
-
}
|
|
329
|
+
}, [
|
|
330
|
+
currentMessage,
|
|
331
|
+
props,
|
|
332
|
+
])
|
|
309
333
|
|
|
310
|
-
renderCustomView () {
|
|
311
|
-
if (
|
|
312
|
-
return
|
|
334
|
+
const renderCustomView = useCallback(() => {
|
|
335
|
+
if (props.renderCustomView)
|
|
336
|
+
return props.renderCustomView(props)
|
|
313
337
|
|
|
314
338
|
return null
|
|
315
|
-
}
|
|
339
|
+
}, [props])
|
|
316
340
|
|
|
317
|
-
renderBubbleContent () {
|
|
341
|
+
const renderBubbleContent = useCallback(() => {
|
|
318
342
|
return (
|
|
319
343
|
<View>
|
|
320
|
-
{!
|
|
321
|
-
{
|
|
322
|
-
{
|
|
323
|
-
{
|
|
324
|
-
{
|
|
325
|
-
{
|
|
344
|
+
{!props.isCustomViewBottom && renderCustomView()}
|
|
345
|
+
{renderMessageImage()}
|
|
346
|
+
{renderMessageVideo()}
|
|
347
|
+
{renderMessageAudio()}
|
|
348
|
+
{renderMessageText()}
|
|
349
|
+
{props.isCustomViewBottom && renderCustomView()}
|
|
326
350
|
</View>
|
|
327
351
|
)
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
352
|
+
}, [
|
|
353
|
+
renderCustomView,
|
|
354
|
+
renderMessageImage,
|
|
355
|
+
renderMessageVideo,
|
|
356
|
+
renderMessageAudio,
|
|
357
|
+
renderMessageText,
|
|
358
|
+
props.isCustomViewBottom,
|
|
359
|
+
])
|
|
360
|
+
|
|
361
|
+
return (
|
|
362
|
+
<View
|
|
363
|
+
style={[
|
|
364
|
+
stylesCommon.fill,
|
|
365
|
+
styles[position].container,
|
|
366
|
+
containerStyle && containerStyle[position],
|
|
367
|
+
]}
|
|
368
|
+
>
|
|
339
369
|
<View
|
|
340
370
|
style={[
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
371
|
+
styles[position].wrapper,
|
|
372
|
+
styledBubbleToNext(),
|
|
373
|
+
styledBubbleToPrevious(),
|
|
374
|
+
wrapperStyle && wrapperStyle[position],
|
|
344
375
|
]}
|
|
345
376
|
>
|
|
346
|
-
<
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
wrapperStyle && wrapperStyle[position],
|
|
352
|
-
]}
|
|
377
|
+
<TouchableWithoutFeedback
|
|
378
|
+
onPress={onPress}
|
|
379
|
+
onLongPress={onLongPress}
|
|
380
|
+
accessibilityRole='text'
|
|
381
|
+
{...props.touchableProps}
|
|
353
382
|
>
|
|
354
|
-
<
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
bottomContainerStyle && bottomContainerStyle[position],
|
|
366
|
-
]}
|
|
367
|
-
>
|
|
368
|
-
{this.renderUsername()}
|
|
369
|
-
{this.renderTime()}
|
|
370
|
-
{this.renderTicks()}
|
|
371
|
-
</View>
|
|
383
|
+
<View>
|
|
384
|
+
{renderBubbleContent()}
|
|
385
|
+
<View
|
|
386
|
+
style={[
|
|
387
|
+
styles[position].bottom,
|
|
388
|
+
bottomContainerStyle && bottomContainerStyle[position],
|
|
389
|
+
]}
|
|
390
|
+
>
|
|
391
|
+
{renderUsername()}
|
|
392
|
+
{renderTime()}
|
|
393
|
+
{renderTicks()}
|
|
372
394
|
</View>
|
|
373
|
-
</
|
|
374
|
-
</
|
|
375
|
-
{this.renderQuickReplies()}
|
|
395
|
+
</View>
|
|
396
|
+
</TouchableWithoutFeedback>
|
|
376
397
|
</View>
|
|
377
|
-
|
|
378
|
-
|
|
398
|
+
{renderQuickReplies()}
|
|
399
|
+
</View>
|
|
400
|
+
)
|
|
379
401
|
}
|
|
402
|
+
|
|
403
|
+
export default Bubble
|
package/src/Day/index.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React, { useMemo } from 'react'
|
|
2
2
|
import {
|
|
3
3
|
Text,
|
|
4
4
|
View,
|
|
@@ -29,7 +29,7 @@ export function Day ({
|
|
|
29
29
|
}: DayProps) {
|
|
30
30
|
const { getLocale } = useChatContext()
|
|
31
31
|
|
|
32
|
-
const dateStr =
|
|
32
|
+
const dateStr = useMemo(() => {
|
|
33
33
|
if (createdAt == null)
|
|
34
34
|
return null
|
|
35
35
|
|
package/src/GiftedChat/index.tsx
CHANGED
|
@@ -56,7 +56,7 @@ 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 = [],
|
|
@@ -94,9 +94,9 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
94
94
|
const actionSheetRef = useRef<ActionSheetProviderRef>(null)
|
|
95
95
|
|
|
96
96
|
const messageContainerRef = useMemo(
|
|
97
|
-
() => props.messageContainerRef || createRef<AnimatedList
|
|
97
|
+
() => props.messageContainerRef || createRef<AnimatedList<TMessage>>(),
|
|
98
98
|
[props.messageContainerRef]
|
|
99
|
-
)
|
|
99
|
+
) as RefObject<AnimatedList<TMessage>>
|
|
100
100
|
|
|
101
101
|
const textInputRef = useMemo(
|
|
102
102
|
() => props.textInputRef || createRef<TextInput>(),
|
|
@@ -205,9 +205,9 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
205
205
|
|
|
206
206
|
const { messagesContainerStyle, ...messagesContainerProps } = props
|
|
207
207
|
|
|
208
|
-
|
|
208
|
+
return (
|
|
209
209
|
<View style={[stylesCommon.fill, messagesContainerStyle]}>
|
|
210
|
-
<MessageContainer
|
|
210
|
+
<MessageContainer<TMessage>
|
|
211
211
|
{...messagesContainerProps}
|
|
212
212
|
invertibleScrollViewProps={{
|
|
213
213
|
inverted,
|
|
@@ -220,8 +220,6 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
220
220
|
{renderChatFooter?.()}
|
|
221
221
|
</View>
|
|
222
222
|
)
|
|
223
|
-
|
|
224
|
-
return fragment
|
|
225
223
|
}, [
|
|
226
224
|
isInitialized,
|
|
227
225
|
isTyping,
|
|
@@ -449,10 +447,10 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
|
|
|
449
447
|
)
|
|
450
448
|
}
|
|
451
449
|
|
|
452
|
-
function GiftedChatWrapper (props: GiftedChatProps) {
|
|
450
|
+
function GiftedChatWrapper<TMessage extends IMessage = IMessage> (props: GiftedChatProps<TMessage>) {
|
|
453
451
|
return (
|
|
454
452
|
<KeyboardProvider>
|
|
455
|
-
<GiftedChat {...props} />
|
|
453
|
+
<GiftedChat<TMessage> {...props} />
|
|
456
454
|
</KeyboardProvider>
|
|
457
455
|
)
|
|
458
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
|
|
34
|
-
import
|
|
33
|
+
import { AnimatedList, ListViewProps, MessageContainerProps } from '../MessageContainer'
|
|
34
|
+
import { BubbleProps } 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 */
|
|
@@ -144,7 +144,7 @@ export interface GiftedChatProps<TMessage extends IMessage = IMessage> extends P
|
|
|
144
144
|
/* Custom message avatar; set to null to not render any avatar for the message */
|
|
145
145
|
renderAvatar?: null | ((props: AvatarProps<TMessage>) => React.ReactNode)
|
|
146
146
|
/* Custom message bubble */
|
|
147
|
-
renderBubble?(props:
|
|
147
|
+
renderBubble?(props: BubbleProps<TMessage>): React.ReactNode
|
|
148
148
|
/* Custom system message */
|
|
149
149
|
renderSystemMessage?(props: SystemMessageProps<TMessage>): React.ReactNode
|
|
150
150
|
/* Callback when a message bubble is pressed; default is to do nothing */
|
|
@@ -165,13 +165,13 @@ export interface GiftedChatProps<TMessage extends IMessage = IMessage> extends P
|
|
|
165
165
|
/* Custom message video */
|
|
166
166
|
renderMessageAudio?(props: MessageAudioProps<TMessage>): React.ReactNode
|
|
167
167
|
/* Custom view inside the bubble */
|
|
168
|
-
renderCustomView?(props:
|
|
168
|
+
renderCustomView?(props: BubbleProps<TMessage>): React.ReactNode
|
|
169
169
|
/* Custom day above a message */
|
|
170
170
|
renderDay?(props: DayProps): React.ReactNode
|
|
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
package/src/Message/index.tsx
CHANGED
|
@@ -114,22 +114,16 @@ let Message: React.FC<MessageProps<IMessage>> = (props: MessageProps<IMessage>)
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
Message = memo(Message, (props, nextProps) => {
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
shouldUpdate ||
|
|
128
|
-
!isEqual(current, next) ||
|
|
129
|
-
!isEqual(previousMessage, nextPropsPreviousMessage) ||
|
|
130
|
-
!isEqual(nextMessage, nextPropsMessage)
|
|
131
|
-
|
|
132
|
-
return shouldUpdate
|
|
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
|
|
133
127
|
})
|
|
134
128
|
|
|
135
129
|
export default Message
|