UNPKG

@qte/react-native-gifted-chat

Version:

Performant fork of react-native-gifted-chat with FlashList support

229 lines 9.26 kB
import React from 'react'; import { Text, TouchableWithoutFeedback, View, } from 'react-native'; import { GiftedChatContext } from '../GiftedChatContext'; import { QuickReplies } from '../QuickReplies'; import { MessageText } from '../MessageText'; import { MessageImage } from '../MessageImage'; import { MessageVideo } from '../MessageVideo'; import { MessageAudio } from '../MessageAudio'; import { Time } from '../Time'; import { isSameUser, isSameDay } from '../utils'; import stylesCommon from '../styles'; import styles from './styles'; export * from './types'; class Bubble extends React.Component { constructor() { super(...arguments); this.onPress = () => { if (this.props.onPress) this.props.onPress(this.context, this.props.currentMessage); }; this.onLongPress = () => { const { currentMessage, onLongPress, optionTitles, } = this.props; if (onLongPress) { onLongPress(this.context, currentMessage); return; } if (!optionTitles?.length) return; const options = optionTitles; const cancelButtonIndex = options.length - 1; this.context.actionSheet().showActionSheetWithOptions({ options, cancelButtonIndex, }, (buttonIndex) => { console.log('onLongPress', { buttonIndex }); }); }; } styledBubbleToNext() { const { currentMessage, nextMessage, position, containerToNextStyle } = this.props; if (currentMessage && nextMessage && position && isSameUser(currentMessage, nextMessage) && isSameDay(currentMessage, nextMessage)) return [ styles[position].containerToNext, containerToNextStyle?.[position], ]; return null; } styledBubbleToPrevious() { const { currentMessage, previousMessage, position, containerToPreviousStyle, } = this.props; if (currentMessage && previousMessage && position && isSameUser(currentMessage, previousMessage) && isSameDay(currentMessage, previousMessage)) return [ styles[position].containerToPrevious, containerToPreviousStyle && containerToPreviousStyle[position], ]; return null; } renderQuickReplies() { const { currentMessage, onQuickReply, nextMessage, renderQuickReplySend, quickReplyStyle, quickReplyTextStyle, quickReplyContainerStyle, } = this.props; if (currentMessage?.quickReplies) { const { /* eslint-disable @typescript-eslint/no-unused-vars */ containerStyle, wrapperStyle, /* eslint-enable @typescript-eslint/no-unused-vars */ ...quickReplyProps } = this.props; if (this.props.renderQuickReplies) return this.props.renderQuickReplies(quickReplyProps); return (<QuickReplies currentMessage={currentMessage} onQuickReply={onQuickReply} renderQuickReplySend={renderQuickReplySend} quickReplyStyle={quickReplyStyle} quickReplyTextStyle={quickReplyTextStyle} quickReplyContainerStyle={quickReplyContainerStyle} nextMessage={nextMessage}/>); } return null; } renderMessageText() { if (this.props.currentMessage?.text) { const { /* eslint-disable @typescript-eslint/no-unused-vars */ containerStyle, wrapperStyle, optionTitles, /* eslint-enable @typescript-eslint/no-unused-vars */ ...messageTextProps } = this.props; if (this.props.renderMessageText) return this.props.renderMessageText(messageTextProps); return <MessageText {...messageTextProps}/>; } return null; } renderMessageImage() { if (this.props.currentMessage?.image) { const { /* eslint-disable @typescript-eslint/no-unused-vars */ containerStyle, wrapperStyle, /* eslint-enable @typescript-eslint/no-unused-vars */ ...messageImageProps } = this.props; if (this.props.renderMessageImage) return this.props.renderMessageImage(messageImageProps); return <MessageImage {...messageImageProps}/>; } return null; } renderMessageVideo() { if (!this.props.currentMessage?.video) return null; const { /* eslint-disable @typescript-eslint/no-unused-vars */ containerStyle, wrapperStyle, /* eslint-enable @typescript-eslint/no-unused-vars */ ...messageVideoProps } = this.props; if (this.props.renderMessageVideo) return this.props.renderMessageVideo(messageVideoProps); return <MessageVideo />; } renderMessageAudio() { if (!this.props.currentMessage?.audio) return null; const { /* eslint-disable @typescript-eslint/no-unused-vars */ containerStyle, wrapperStyle, /* eslint-enable @typescript-eslint/no-unused-vars */ ...messageAudioProps } = this.props; if (this.props.renderMessageAudio) return this.props.renderMessageAudio(messageAudioProps); return <MessageAudio />; } renderTicks() { const { currentMessage, renderTicks, user, } = this.props; if (renderTicks && currentMessage) return renderTicks(currentMessage); if (user && currentMessage?.user && currentMessage.user._id !== user._id) return null; if (currentMessage && (currentMessage.sent || currentMessage.received || currentMessage.pending)) return (<View style={styles.content.tickView}> {!!currentMessage.sent && (<Text style={[styles.content.tick, this.props.tickStyle]}> {'✓'} </Text>)} {!!currentMessage.received && (<Text style={[styles.content.tick, this.props.tickStyle]}> {'✓'} </Text>)} {!!currentMessage.pending && (<Text style={[styles.content.tick, this.props.tickStyle]}> {'🕓'} </Text>)} </View>); return null; } renderTime() { if (this.props.currentMessage?.createdAt) { const { /* eslint-disable @typescript-eslint/no-unused-vars */ containerStyle, wrapperStyle, textStyle, /* eslint-enable @typescript-eslint/no-unused-vars */ ...timeProps } = this.props; if (this.props.renderTime) return this.props.renderTime(timeProps); return <Time {...timeProps}/>; } return null; } renderUsername() { const { currentMessage, user, renderUsername, } = this.props; if (this.props.renderUsernameOnMessage && currentMessage) { if (user && currentMessage.user._id === user._id) return null; if (renderUsername) return renderUsername(currentMessage.user); return (<View style={styles.content.usernameView}> <Text style={[styles.content.username, this.props.usernameStyle]}> {'~ '} {currentMessage.user.name} </Text> </View>); } return null; } renderCustomView() { if (this.props.renderCustomView) return this.props.renderCustomView(this.props); return null; } renderBubbleContent() { return (<View> {!this.props.isCustomViewBottom && this.renderCustomView()} {this.renderMessageImage()} {this.renderMessageVideo()} {this.renderMessageAudio()} {this.renderMessageText()} {this.props.isCustomViewBottom && this.renderCustomView()} </View>); } render() { const { position, containerStyle, wrapperStyle, bottomContainerStyle, } = this.props; return (<View style={[ stylesCommon.fill, styles[position].container, containerStyle && containerStyle[position], ]}> <View style={[ styles[position].wrapper, this.styledBubbleToNext(), this.styledBubbleToPrevious(), wrapperStyle && wrapperStyle[position], ]}> <TouchableWithoutFeedback onPress={this.onPress} onLongPress={this.onLongPress} accessibilityRole='text' {...this.props.touchableProps}> <View> {this.renderBubbleContent()} <View style={[ styles[position].bottom, bottomContainerStyle && bottomContainerStyle[position], ]}> {this.renderUsername()} {this.renderTime()} {this.renderTicks()} </View> </View> </TouchableWithoutFeedback> </View> {this.renderQuickReplies()} </View>); } } Bubble.contextType = GiftedChatContext; export default Bubble; //# sourceMappingURL=index.js.map