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