react-native-gifted-chat 2.4.1 → 2.6.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 (159) hide show
  1. package/README.md +34 -14
  2. package/lib/Actions.d.ts +5 -6
  3. package/lib/Actions.js +16 -13
  4. package/lib/Actions.js.map +1 -1
  5. package/lib/Avatar.d.ts +9 -25
  6. package/lib/Avatar.js +12 -18
  7. package/lib/Avatar.js.flow +1 -1
  8. package/lib/Avatar.js.map +1 -1
  9. package/lib/Bubble.d.ts +29 -30
  10. package/lib/Bubble.js +99 -92
  11. package/lib/Bubble.js.flow +2 -2
  12. package/lib/Bubble.js.map +1 -1
  13. package/lib/Composer.d.ts +1 -1
  14. package/lib/Composer.js +30 -32
  15. package/lib/Composer.js.map +1 -1
  16. package/lib/Constant.js +1 -0
  17. package/lib/Constant.js.map +1 -1
  18. package/lib/Day.d.ts +3 -15
  19. package/lib/Day.js +2 -14
  20. package/lib/Day.js.flow +1 -1
  21. package/lib/Day.js.map +1 -1
  22. package/lib/GiftedAvatar.d.ts +7 -7
  23. package/lib/GiftedAvatar.js +30 -29
  24. package/lib/GiftedAvatar.js.map +1 -1
  25. package/lib/GiftedChat.d.ts +15 -89
  26. package/lib/GiftedChat.js +204 -350
  27. package/lib/GiftedChat.js.flow +1 -3
  28. package/lib/GiftedChat.js.map +1 -1
  29. package/lib/GiftedChatContext.d.ts +2 -1
  30. package/lib/GiftedChatContext.js.map +1 -1
  31. package/lib/InputToolbar.d.ts +7 -5
  32. package/lib/InputToolbar.js +41 -34
  33. package/lib/InputToolbar.js.map +1 -1
  34. package/lib/LoadEarlier.d.ts +4 -4
  35. package/lib/LoadEarlier.js +8 -6
  36. package/lib/LoadEarlier.js.map +1 -1
  37. package/lib/Message.d.ts +8 -9
  38. package/lib/Message.js +47 -40
  39. package/lib/Message.js.flow +1 -1
  40. package/lib/Message.js.map +1 -1
  41. package/lib/MessageAudio.d.ts +2 -1
  42. package/lib/MessageAudio.js +4 -4
  43. package/lib/MessageAudio.js.flow +1 -1
  44. package/lib/MessageAudio.js.map +1 -1
  45. package/lib/MessageContainer.d.ts +17 -17
  46. package/lib/MessageContainer.js +33 -51
  47. package/lib/MessageContainer.js.map +1 -1
  48. package/lib/MessageImage.d.ts +5 -4
  49. package/lib/MessageImage.js +4 -5
  50. package/lib/MessageImage.js.flow +1 -1
  51. package/lib/MessageImage.js.map +1 -1
  52. package/lib/MessageText.d.ts +11 -10
  53. package/lib/MessageText.js +5 -10
  54. package/lib/MessageText.js.flow +1 -1
  55. package/lib/MessageText.js.map +1 -1
  56. package/lib/MessageVideo.d.ts +2 -1
  57. package/lib/MessageVideo.js +4 -4
  58. package/lib/MessageVideo.js.flow +1 -1
  59. package/lib/MessageVideo.js.map +1 -1
  60. package/lib/Models.d.ts +7 -7
  61. package/lib/QuickReplies.d.ts +3 -3
  62. package/lib/QuickReplies.js +8 -14
  63. package/lib/QuickReplies.js.flow +1 -1
  64. package/lib/QuickReplies.js.map +1 -1
  65. package/lib/Send.d.ts +4 -4
  66. package/lib/Send.js +6 -9
  67. package/lib/Send.js.map +1 -1
  68. package/lib/SystemMessage.d.ts +6 -5
  69. package/lib/SystemMessage.js +1 -2
  70. package/lib/SystemMessage.js.flow +1 -1
  71. package/lib/SystemMessage.js.map +1 -1
  72. package/lib/Time.d.ts +7 -6
  73. package/lib/Time.js +1 -3
  74. package/lib/Time.js.flow +1 -1
  75. package/lib/Time.js.map +1 -1
  76. package/lib/TypingIndicator.d.ts +2 -1
  77. package/lib/TypingIndicator.js +5 -5
  78. package/lib/TypingIndicator.js.map +1 -1
  79. package/lib/hooks/useUpdateLayoutEffect.js +2 -4
  80. package/lib/hooks/useUpdateLayoutEffect.js.map +1 -1
  81. package/lib/index.d.ts +1 -0
  82. package/lib/index.js +1 -0
  83. package/lib/index.js.map +1 -1
  84. package/lib/logging.d.ts +2 -2
  85. package/lib/logging.js.map +1 -1
  86. package/lib/types.js.flow +1 -1
  87. package/lib/utils.d.ts +1 -1
  88. package/lib/utils.js +2 -4
  89. package/lib/utils.js.map +1 -1
  90. package/package.json +86 -59
  91. package/src/Actions.tsx +114 -0
  92. package/src/Avatar.tsx +178 -0
  93. package/src/Bubble.tsx +596 -0
  94. package/src/Color.ts +17 -0
  95. package/src/Composer.tsx +147 -0
  96. package/src/Constant.ts +18 -0
  97. package/src/Day.tsx +71 -0
  98. package/src/GiftedAvatar.tsx +205 -0
  99. package/src/GiftedChat.tsx +670 -0
  100. package/src/GiftedChatContext.ts +23 -0
  101. package/src/InputToolbar.tsx +113 -0
  102. package/src/LoadEarlier.tsx +108 -0
  103. package/src/Message.tsx +229 -0
  104. package/src/MessageAudio.tsx +19 -0
  105. package/src/MessageContainer.tsx +362 -0
  106. package/src/MessageImage.tsx +78 -0
  107. package/src/MessageText.tsx +187 -0
  108. package/src/MessageVideo.tsx +19 -0
  109. package/src/Models.ts +84 -0
  110. package/src/QuickReplies.tsx +186 -0
  111. package/src/Send.tsx +102 -0
  112. package/src/SystemMessage.tsx +61 -0
  113. package/src/Time.tsx +97 -0
  114. package/src/TypingIndicator.tsx +108 -0
  115. package/src/__tests__/Actions.test.tsx +10 -0
  116. package/src/__tests__/Avatar.test.tsx +13 -0
  117. package/src/__tests__/Bubble.test.tsx +23 -0
  118. package/src/__tests__/Color.test.tsx +5 -0
  119. package/src/__tests__/Composer.test.tsx +11 -0
  120. package/src/__tests__/Constant.test.tsx +5 -0
  121. package/src/__tests__/Day.test.tsx +23 -0
  122. package/src/__tests__/GiftedAvatar.test.tsx +11 -0
  123. package/src/__tests__/GiftedChat.test.tsx +36 -0
  124. package/src/__tests__/InputToolbar.test.tsx +11 -0
  125. package/src/__tests__/LoadEarlier.test.tsx +11 -0
  126. package/src/__tests__/Message.test.tsx +77 -0
  127. package/src/__tests__/MessageContainer.test.tsx +11 -0
  128. package/src/__tests__/MessageImage.test.tsx +27 -0
  129. package/src/__tests__/MessageText.test.tsx +11 -0
  130. package/src/__tests__/Send.test.tsx +22 -0
  131. package/src/__tests__/SystemMessage.test.tsx +27 -0
  132. package/src/__tests__/Time.test.tsx +29 -0
  133. package/src/__tests__/__snapshots__/Actions.test.tsx.snap +76 -0
  134. package/src/__tests__/__snapshots__/Avatar.test.tsx.snap +17 -0
  135. package/src/__tests__/__snapshots__/Bubble.test.tsx.snap +145 -0
  136. package/src/__tests__/__snapshots__/Color.test.tsx.snap +21 -0
  137. package/src/__tests__/__snapshots__/Composer.test.tsx.snap +35 -0
  138. package/src/__tests__/__snapshots__/Constant.test.tsx.snap +16 -0
  139. package/src/__tests__/__snapshots__/Day.test.tsx.snap +37 -0
  140. package/src/__tests__/__snapshots__/GiftedAvatar.test.tsx.snap +22 -0
  141. package/src/__tests__/__snapshots__/GiftedChat.test.tsx.snap +15 -0
  142. package/src/__tests__/__snapshots__/InputToolbar.test.tsx.snap +60 -0
  143. package/src/__tests__/__snapshots__/LoadEarlier.test.tsx.snap +74 -0
  144. package/src/__tests__/__snapshots__/Message.test.tsx.snap +628 -0
  145. package/src/__tests__/__snapshots__/MessageContainer.test.tsx.snap +127 -0
  146. package/src/__tests__/__snapshots__/MessageImage.test.tsx.snap +38 -0
  147. package/src/__tests__/__snapshots__/MessageText.test.tsx.snap +30 -0
  148. package/src/__tests__/__snapshots__/Send.test.tsx.snap +129 -0
  149. package/src/__tests__/__snapshots__/SystemMessage.test.tsx.snap +38 -0
  150. package/src/__tests__/__snapshots__/Time.test.tsx.snap +33 -0
  151. package/src/__tests__/data.ts +8 -0
  152. package/src/__tests__/utils.test.ts +31 -0
  153. package/src/hooks/useUpdateLayoutEffect.ts +21 -0
  154. package/src/index.ts +4 -0
  155. package/src/logging.ts +8 -0
  156. package/src/utils.ts +39 -0
  157. package/.eslintignore +0 -2
  158. package/.eslintrc.js +0 -21
  159. package/jest.config.js +0 -15
package/src/Bubble.tsx ADDED
@@ -0,0 +1,596 @@
1
+ import PropTypes from 'prop-types'
2
+ import React from 'react'
3
+ import {
4
+ Text,
5
+ StyleSheet,
6
+ TouchableWithoutFeedback,
7
+ View,
8
+ StyleProp,
9
+ ViewStyle,
10
+ TextStyle,
11
+ } from 'react-native'
12
+
13
+ import { GiftedChatContext } from './GiftedChatContext'
14
+ import { QuickReplies, QuickRepliesProps } from './QuickReplies'
15
+ import { MessageText, MessageTextProps } from './MessageText'
16
+ import { MessageImage, MessageImageProps } from './MessageImage'
17
+ import { MessageVideo } from './MessageVideo'
18
+ import { MessageAudio } from './MessageAudio'
19
+ import { Time, TimeProps } from './Time'
20
+
21
+ import Color from './Color'
22
+ import { StylePropType, isSameUser, isSameDay } from './utils'
23
+ import {
24
+ User,
25
+ IMessage,
26
+ LeftRightStyle,
27
+ Reply,
28
+ Omit,
29
+ MessageVideoProps,
30
+ MessageAudioProps,
31
+ } from './Models'
32
+
33
+ const styles = {
34
+ left: StyleSheet.create({
35
+ container: {
36
+ flex: 1,
37
+ alignItems: 'flex-start',
38
+ },
39
+ wrapper: {
40
+ borderRadius: 15,
41
+ backgroundColor: Color.leftBubbleBackground,
42
+ marginRight: 60,
43
+ minHeight: 20,
44
+ justifyContent: 'flex-end',
45
+ },
46
+ containerToNext: {
47
+ borderBottomLeftRadius: 3,
48
+ },
49
+ containerToPrevious: {
50
+ borderTopLeftRadius: 3,
51
+ },
52
+ bottom: {
53
+ flexDirection: 'row',
54
+ justifyContent: 'flex-start',
55
+ },
56
+ }),
57
+ right: StyleSheet.create({
58
+ container: {
59
+ flex: 1,
60
+ alignItems: 'flex-end',
61
+ },
62
+ wrapper: {
63
+ borderRadius: 15,
64
+ backgroundColor: Color.defaultBlue,
65
+ marginLeft: 60,
66
+ minHeight: 20,
67
+ justifyContent: 'flex-end',
68
+ },
69
+ containerToNext: {
70
+ borderBottomRightRadius: 3,
71
+ },
72
+ containerToPrevious: {
73
+ borderTopRightRadius: 3,
74
+ },
75
+ bottom: {
76
+ flexDirection: 'row',
77
+ justifyContent: 'flex-end',
78
+ },
79
+ }),
80
+ content: StyleSheet.create({
81
+ tick: {
82
+ fontSize: 10,
83
+ backgroundColor: Color.backgroundTransparent,
84
+ color: Color.white,
85
+ },
86
+ tickView: {
87
+ flexDirection: 'row',
88
+ marginRight: 10,
89
+ },
90
+ username: {
91
+ top: -3,
92
+ left: 0,
93
+ fontSize: 12,
94
+ backgroundColor: 'transparent',
95
+ color: '#aaa',
96
+ },
97
+ usernameView: {
98
+ flexDirection: 'row',
99
+ marginHorizontal: 10,
100
+ },
101
+ }),
102
+ }
103
+
104
+ /* eslint-disable no-use-before-define */
105
+ export type RenderMessageImageProps<TMessage extends IMessage> = Omit<
106
+ BubbleProps<TMessage>,
107
+ 'containerStyle' | 'wrapperStyle'
108
+ > &
109
+ MessageImageProps<TMessage>
110
+
111
+ export type RenderMessageVideoProps<TMessage extends IMessage> = Omit<
112
+ BubbleProps<TMessage>,
113
+ 'containerStyle' | 'wrapperStyle'
114
+ > &
115
+ MessageVideoProps<TMessage>
116
+
117
+ export type RenderMessageAudioProps<TMessage extends IMessage> = Omit<
118
+ BubbleProps<TMessage>,
119
+ 'containerStyle' | 'wrapperStyle'
120
+ > &
121
+ MessageAudioProps<TMessage>
122
+
123
+ export type RenderMessageTextProps<TMessage extends IMessage> = Omit<
124
+ BubbleProps<TMessage>,
125
+ 'containerStyle' | 'wrapperStyle'
126
+ > &
127
+ MessageTextProps<TMessage>
128
+ /* eslint-enable no-use-before-define */
129
+
130
+ export interface BubbleProps<TMessage extends IMessage> {
131
+ user?: User
132
+ touchableProps?: object
133
+ renderUsernameOnMessage?: boolean
134
+ isCustomViewBottom?: boolean
135
+ inverted?: boolean
136
+ position: 'left' | 'right'
137
+ currentMessage: TMessage
138
+ nextMessage?: TMessage
139
+ previousMessage?: TMessage
140
+ optionTitles?: string[]
141
+ containerStyle?: LeftRightStyle<ViewStyle>
142
+ wrapperStyle?: LeftRightStyle<ViewStyle>
143
+ textStyle?: LeftRightStyle<TextStyle>
144
+ bottomContainerStyle?: LeftRightStyle<ViewStyle>
145
+ tickStyle?: StyleProp<TextStyle>
146
+ containerToNextStyle?: LeftRightStyle<ViewStyle>
147
+ containerToPreviousStyle?: LeftRightStyle<ViewStyle>
148
+ usernameStyle?: TextStyle
149
+ quickReplyStyle?: StyleProp<ViewStyle>
150
+ quickReplyTextStyle?: StyleProp<TextStyle>
151
+ quickReplyContainerStyle?: StyleProp<ViewStyle>
152
+ onPress?(context?: unknown, message?: unknown): void
153
+ onLongPress?(context?: unknown, message?: unknown): void
154
+ onQuickReply?(replies: Reply[]): void
155
+ renderMessageImage?(
156
+ props: RenderMessageImageProps<TMessage>,
157
+ ): React.ReactNode
158
+ renderMessageVideo?(
159
+ props: RenderMessageVideoProps<TMessage>,
160
+ ): React.ReactNode
161
+ renderMessageAudio?(
162
+ props: RenderMessageAudioProps<TMessage>,
163
+ ): React.ReactNode
164
+ renderMessageText?(props: RenderMessageTextProps<TMessage>): React.ReactNode
165
+ renderCustomView?(bubbleProps: BubbleProps<TMessage>): React.ReactNode
166
+ renderTime?(timeProps: TimeProps<TMessage>): React.ReactNode
167
+ renderTicks?(currentMessage: TMessage): React.ReactNode
168
+ renderUsername?(user?: TMessage['user']): React.ReactNode
169
+ renderQuickReplySend?(): React.ReactNode
170
+ renderQuickReplies?(
171
+ quickReplies: QuickRepliesProps<TMessage>,
172
+ ): React.ReactNode
173
+ }
174
+
175
+ export default class Bubble<
176
+ TMessage extends IMessage = IMessage,
177
+ > extends React.Component<BubbleProps<TMessage>> {
178
+ static contextType = GiftedChatContext
179
+
180
+ static defaultProps = {
181
+ touchableProps: {},
182
+ onPress: null,
183
+ onLongPress: null,
184
+ renderMessageImage: null,
185
+ renderMessageVideo: null,
186
+ renderMessageAudio: null,
187
+ renderMessageText: null,
188
+ renderCustomView: null,
189
+ renderUsername: null,
190
+ renderTicks: null,
191
+ renderTime: null,
192
+ renderQuickReplies: null,
193
+ onQuickReply: null,
194
+ position: 'left',
195
+ currentMessage: {
196
+ text: null,
197
+ createdAt: null,
198
+ image: null,
199
+ },
200
+ nextMessage: {},
201
+ previousMessage: {},
202
+ containerStyle: {},
203
+ wrapperStyle: {},
204
+ bottomContainerStyle: {},
205
+ tickStyle: {},
206
+ usernameStyle: {},
207
+ containerToNextStyle: {},
208
+ containerToPreviousStyle: {},
209
+ }
210
+
211
+ static propTypes = {
212
+ user: PropTypes.object.isRequired,
213
+ touchableProps: PropTypes.object,
214
+ onLongPress: PropTypes.func,
215
+ renderMessageImage: PropTypes.func,
216
+ renderMessageVideo: PropTypes.func,
217
+ renderMessageAudio: PropTypes.func,
218
+ renderMessageText: PropTypes.func,
219
+ renderCustomView: PropTypes.func,
220
+ isCustomViewBottom: PropTypes.bool,
221
+ renderUsernameOnMessage: PropTypes.bool,
222
+ renderUsername: PropTypes.func,
223
+ renderTime: PropTypes.func,
224
+ renderTicks: PropTypes.func,
225
+ renderQuickReplies: PropTypes.func,
226
+ onQuickReply: PropTypes.func,
227
+ position: PropTypes.oneOf(['left', 'right']),
228
+ optionTitles: PropTypes.arrayOf(PropTypes.string),
229
+ currentMessage: PropTypes.object,
230
+ nextMessage: PropTypes.object,
231
+ previousMessage: PropTypes.object,
232
+ containerStyle: PropTypes.shape({
233
+ left: StylePropType,
234
+ right: StylePropType,
235
+ }),
236
+ wrapperStyle: PropTypes.shape({
237
+ left: StylePropType,
238
+ right: StylePropType,
239
+ }),
240
+ bottomContainerStyle: PropTypes.shape({
241
+ left: StylePropType,
242
+ right: StylePropType,
243
+ }),
244
+ tickStyle: StylePropType,
245
+ usernameStyle: StylePropType,
246
+ containerToNextStyle: PropTypes.shape({
247
+ left: StylePropType,
248
+ right: StylePropType,
249
+ }),
250
+ containerToPreviousStyle: PropTypes.shape({
251
+ left: StylePropType,
252
+ right: StylePropType,
253
+ }),
254
+ }
255
+
256
+ onPress = () => {
257
+ if (this.props.onPress)
258
+ this.props.onPress(this.context, this.props.currentMessage)
259
+ }
260
+
261
+ onLongPress = () => {
262
+ const {
263
+ currentMessage,
264
+ onLongPress,
265
+ optionTitles,
266
+ } = this.props
267
+
268
+ if (onLongPress) {
269
+ onLongPress(this.context, currentMessage)
270
+ return
271
+ }
272
+
273
+ if (!optionTitles?.length)
274
+ return
275
+
276
+ const options = optionTitles
277
+ const cancelButtonIndex = options.length - 1
278
+
279
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
280
+ ;(this.context as any).actionSheet().showActionSheetWithOptions(
281
+ {
282
+ options,
283
+ cancelButtonIndex,
284
+ },
285
+ (buttonIndex: number) => {
286
+ console.log('onLongPress', { buttonIndex })
287
+ }
288
+ )
289
+ }
290
+
291
+ styledBubbleToNext () {
292
+ const { currentMessage, nextMessage, position, containerToNextStyle } =
293
+ this.props
294
+ if (
295
+ currentMessage &&
296
+ nextMessage &&
297
+ position &&
298
+ isSameUser(currentMessage, nextMessage) &&
299
+ isSameDay(currentMessage, nextMessage)
300
+ )
301
+ return [
302
+ styles[position].containerToNext,
303
+ containerToNextStyle?.[position],
304
+ ]
305
+
306
+ return null
307
+ }
308
+
309
+ styledBubbleToPrevious () {
310
+ const {
311
+ currentMessage,
312
+ previousMessage,
313
+ position,
314
+ containerToPreviousStyle,
315
+ } = this.props
316
+ if (
317
+ currentMessage &&
318
+ previousMessage &&
319
+ position &&
320
+ isSameUser(currentMessage, previousMessage) &&
321
+ isSameDay(currentMessage, previousMessage)
322
+ )
323
+ return [
324
+ styles[position].containerToPrevious,
325
+ containerToPreviousStyle && containerToPreviousStyle[position],
326
+ ]
327
+
328
+ return null
329
+ }
330
+
331
+ renderQuickReplies () {
332
+ const {
333
+ currentMessage,
334
+ onQuickReply,
335
+ nextMessage,
336
+ renderQuickReplySend,
337
+ quickReplyStyle,
338
+ quickReplyTextStyle,
339
+ quickReplyContainerStyle,
340
+ } = this.props
341
+ if (currentMessage && currentMessage.quickReplies) {
342
+ const {
343
+ /* eslint-disable @typescript-eslint/no-unused-vars */
344
+ containerStyle,
345
+ wrapperStyle,
346
+ /* eslint-enable @typescript-eslint/no-unused-vars */
347
+ ...quickReplyProps
348
+ } = this.props
349
+
350
+ if (this.props.renderQuickReplies)
351
+ return this.props.renderQuickReplies(quickReplyProps)
352
+
353
+ return (
354
+ <QuickReplies
355
+ currentMessage={currentMessage}
356
+ onQuickReply={onQuickReply}
357
+ renderQuickReplySend={renderQuickReplySend}
358
+ quickReplyStyle={quickReplyStyle}
359
+ quickReplyTextStyle={quickReplyTextStyle}
360
+ quickReplyContainerStyle={quickReplyContainerStyle}
361
+ nextMessage={nextMessage}
362
+ />
363
+ )
364
+ }
365
+ return null
366
+ }
367
+
368
+ renderMessageText () {
369
+ if (this.props.currentMessage && this.props.currentMessage.text) {
370
+ const {
371
+ /* eslint-disable @typescript-eslint/no-unused-vars */
372
+ containerStyle,
373
+ wrapperStyle,
374
+ optionTitles,
375
+ /* eslint-enable @typescript-eslint/no-unused-vars */
376
+ ...messageTextProps
377
+ } = this.props
378
+ if (this.props.renderMessageText)
379
+ return this.props.renderMessageText(messageTextProps)
380
+
381
+ return <MessageText {...messageTextProps} />
382
+ }
383
+ return null
384
+ }
385
+
386
+ renderMessageImage () {
387
+ if (this.props.currentMessage && this.props.currentMessage.image) {
388
+ const {
389
+ /* eslint-disable @typescript-eslint/no-unused-vars */
390
+ containerStyle,
391
+ wrapperStyle,
392
+ /* eslint-enable @typescript-eslint/no-unused-vars */
393
+ ...messageImageProps
394
+ } = this.props
395
+
396
+ if (this.props.renderMessageImage)
397
+ return this.props.renderMessageImage(messageImageProps)
398
+
399
+ return <MessageImage {...messageImageProps} />
400
+ }
401
+ return null
402
+ }
403
+
404
+ renderMessageVideo () {
405
+ if (!this.props.currentMessage?.video)
406
+ return null
407
+
408
+ const {
409
+ /* eslint-disable @typescript-eslint/no-unused-vars */
410
+ containerStyle,
411
+ wrapperStyle,
412
+ /* eslint-enable @typescript-eslint/no-unused-vars */
413
+ ...messageVideoProps
414
+ } = this.props
415
+
416
+ if (this.props.renderMessageVideo)
417
+ return this.props.renderMessageVideo(messageVideoProps)
418
+
419
+ return <MessageVideo />
420
+ }
421
+
422
+ renderMessageAudio () {
423
+ if (!this.props.currentMessage?.audio)
424
+ return null
425
+
426
+ const {
427
+ /* eslint-disable @typescript-eslint/no-unused-vars */
428
+ containerStyle,
429
+ wrapperStyle,
430
+ /* eslint-enable @typescript-eslint/no-unused-vars */
431
+ ...messageAudioProps
432
+ } = this.props
433
+
434
+ if (this.props.renderMessageAudio)
435
+ return this.props.renderMessageAudio(messageAudioProps)
436
+
437
+ return <MessageAudio />
438
+ }
439
+
440
+ renderTicks () {
441
+ const { currentMessage, renderTicks, user } = this.props
442
+ if (renderTicks && currentMessage)
443
+ return renderTicks(currentMessage)
444
+
445
+ if (
446
+ currentMessage &&
447
+ user &&
448
+ currentMessage.user &&
449
+ currentMessage.user._id !== user._id
450
+ )
451
+ return null
452
+
453
+ if (
454
+ currentMessage &&
455
+ (currentMessage.sent || currentMessage.received || currentMessage.pending)
456
+ )
457
+ return (
458
+ <View style={styles.content.tickView}>
459
+ {!!currentMessage.sent && (
460
+ <Text style={[styles.content.tick, this.props.tickStyle]}>
461
+ {'✓'}
462
+ </Text>
463
+ )}
464
+ {!!currentMessage.received && (
465
+ <Text style={[styles.content.tick, this.props.tickStyle]}>
466
+ {'✓'}
467
+ </Text>
468
+ )}
469
+ {!!currentMessage.pending && (
470
+ <Text style={[styles.content.tick, this.props.tickStyle]}>
471
+ {'🕓'}
472
+ </Text>
473
+ )}
474
+ </View>
475
+ )
476
+
477
+ return null
478
+ }
479
+
480
+ renderTime () {
481
+ if (this.props.currentMessage && this.props.currentMessage.createdAt) {
482
+ const {
483
+ /* eslint-disable @typescript-eslint/no-unused-vars */
484
+ containerStyle,
485
+ wrapperStyle,
486
+ textStyle,
487
+ /* eslint-enable @typescript-eslint/no-unused-vars */
488
+ ...timeProps
489
+ } = this.props
490
+
491
+ if (this.props.renderTime)
492
+ return this.props.renderTime(timeProps)
493
+
494
+ return <Time {...timeProps} />
495
+ }
496
+ return null
497
+ }
498
+
499
+ renderUsername () {
500
+ const { currentMessage, user, renderUsername } = this.props
501
+ if (this.props.renderUsernameOnMessage && currentMessage) {
502
+ if (user && currentMessage.user._id === user._id)
503
+ return null
504
+
505
+ if (renderUsername)
506
+ return renderUsername(currentMessage.user)
507
+
508
+ return (
509
+ <View style={styles.content.usernameView}>
510
+ <Text
511
+ style={
512
+ [styles.content.username, this.props.usernameStyle] as TextStyle
513
+ }
514
+ >
515
+ {'~ '}
516
+ {currentMessage.user.name}
517
+ </Text>
518
+ </View>
519
+ )
520
+ }
521
+ return null
522
+ }
523
+
524
+ renderCustomView () {
525
+ if (this.props.renderCustomView)
526
+ return this.props.renderCustomView(this.props)
527
+
528
+ return null
529
+ }
530
+
531
+ renderBubbleContent () {
532
+ return this.props.isCustomViewBottom
533
+ ? (
534
+ <View>
535
+ {this.renderMessageImage()}
536
+ {this.renderMessageVideo()}
537
+ {this.renderMessageAudio()}
538
+ {this.renderMessageText()}
539
+ {this.renderCustomView()}
540
+ </View>
541
+ )
542
+ : (
543
+ <View>
544
+ {this.renderCustomView()}
545
+ {this.renderMessageImage()}
546
+ {this.renderMessageVideo()}
547
+ {this.renderMessageAudio()}
548
+ {this.renderMessageText()}
549
+ </View>
550
+ )
551
+ }
552
+
553
+ render () {
554
+ const { position, containerStyle, wrapperStyle, bottomContainerStyle } =
555
+ this.props
556
+ return (
557
+ <View
558
+ style={[
559
+ styles[position].container,
560
+ containerStyle && containerStyle[position],
561
+ ]}
562
+ >
563
+ <View
564
+ style={[
565
+ styles[position].wrapper,
566
+ this.styledBubbleToNext(),
567
+ this.styledBubbleToPrevious(),
568
+ wrapperStyle && wrapperStyle[position],
569
+ ]}
570
+ >
571
+ <TouchableWithoutFeedback
572
+ onPress={this.onPress}
573
+ onLongPress={this.onLongPress}
574
+ accessibilityRole='text'
575
+ {...this.props.touchableProps}
576
+ >
577
+ <View>
578
+ {this.renderBubbleContent()}
579
+ <View
580
+ style={[
581
+ styles[position].bottom,
582
+ bottomContainerStyle && bottomContainerStyle[position],
583
+ ]}
584
+ >
585
+ {this.renderUsername()}
586
+ {this.renderTime()}
587
+ {this.renderTicks()}
588
+ </View>
589
+ </View>
590
+ </TouchableWithoutFeedback>
591
+ </View>
592
+ {this.renderQuickReplies()}
593
+ </View>
594
+ )
595
+ }
596
+ }
package/src/Color.ts ADDED
@@ -0,0 +1,17 @@
1
+ export default {
2
+ defaultColor: '#b2b2b2',
3
+ backgroundTransparent: 'transparent',
4
+ defaultBlue: '#0084ff',
5
+ leftBubbleBackground: '#f0f0f0',
6
+ black: '#000',
7
+ white: '#fff',
8
+ carrot: '#e67e22',
9
+ emerald: '#2ecc71',
10
+ peterRiver: '#3498db',
11
+ wisteria: '#8e44ad',
12
+ alizarin: '#e74c3c',
13
+ turquoise: '#1abc9c',
14
+ midnightBlue: '#2c3e50',
15
+ optionTintColor: '#007AFF',
16
+ timeTextColor: '#aaa',
17
+ }