UNPKG

react-native-lifetime-livechat

Version:

LiveChat implementation for LifeTime application

220 lines (193 loc) 5.61 kB
/* eslint no-console: 0, no-param-reassign: 0, no-use-before-define: ["error", { "variables": false }], no-return-assign: 0, react/no-string-refs: 0, react/sort-comp: 0 */ import PropTypes from 'prop-types'; import React from 'react'; import {FlatList, View, StyleSheet, TouchableOpacity, Text} from 'react-native'; import LoadEarlier from './LoadEarlier'; import LoadAfter from './LoadAfter'; import Message from './Message'; export default class MessageContainer extends React.PureComponent { state = { showScrollBottom: false, }; constructor(props) { super(props); this.renderRow = this.renderRow.bind(this); this.renderFooter = this.renderFooter.bind(this); this.renderLoadEarlier = this.renderLoadEarlier.bind(this); this.renderHeaderWrapper = this.renderHeaderWrapper.bind(this); } handleOnScroll = (event) => { if (event.nativeEvent.contentOffset.y > this.props.scrollToBottomOffset) { this.setState({ showScrollBottom: true }); } else { this.setState({ showScrollBottom: false }); } }; renderFooter() { const loadAfterProps = { ...this.props, }; if (!this.props.loadAfter) return null; return ( <View style={styles.headerWrapper}> <LoadAfter key={Math.random()} {...loadAfterProps} /> </View> ); } renderLoadEarlier() { if (this.props.loadEarlier === true) { const loadEarlierProps = { ...this.props, }; if (this.props.renderLoadEarlier) { return this.props.renderLoadEarlier(loadEarlierProps); } return <LoadEarlier key={Math.random()} {...loadEarlierProps} />; } return null; } scrollTo(index) { if (this.flatListRef) { this.flatListRef.scrollToOffset({index: index}); } } scrollToOffset(options) { if (this.flatListRef && options) { this.flatListRef.scrollToOffset(options); } } renderRow({ item, index }) { if (!item._id && item._id !== 0) { console.warn('GiftedChat: `_id` is missing for message', JSON.stringify(item)); } if (!item.user) { if (!item.system) { console.warn('GiftedChat: `user` is missing for message', JSON.stringify(item)); } item.user = {}; } const { messages, ...restProps } = this.props; const previousMessage = messages[index + 1] || {}; const nextMessage = messages[index - 1] || {}; const messageProps = { ...restProps, key: item._id, currentMessage: item, previousMessage, nextMessage, position: item.user._id === this.props.user._id ? 'right' : 'left', }; if (this.props.renderMessage) { return this.props.renderMessage(messageProps); } return <Message {...messageProps} />; } renderHeaderWrapper() { return <View style={styles.headerWrapper}> {this.renderLoadEarlier()} </View>; } scrollToBottom = () => { if (this.props.onJumpBackClicked) { this.props.onJumpBackClicked(); } this.scrollTo({ offset: 0, animated: 'true' }); }; renderScrollToBottomWrapper() { return ( <View style={styles.scrollToBottomStyle}> <TouchableOpacity onPress={this.scrollToBottom} hitSlop={{ top: 5, left: 5, right: 5, bottom: 5 }}> <Text>Jump back</Text> </TouchableOpacity> </View> ); } render() { if (this.props.messages.length === 0) { return <View style={styles.container} />; } return ( <View style={styles.container}> {this.state.showScrollBottom && this.props.scrollToBottom ? this.renderScrollToBottomWrapper() : null} <FlatList ref={(ref) => (this.flatListRef = ref)} keyExtractor={(item) => item._id} enableEmptySections automaticallyAdjustContentInsets={false} inverted={this.props.inverted} data={this.props.messages} style={styles.listStyle} onScroll={this.handleOnScroll} contentContainerStyle={styles.contentContainerStyle} renderItem={this.renderRow} {...this.props.invertibleScrollViewProps} ListFooterComponent={this.renderHeaderWrapper()} ListHeaderComponent={this.renderFooter()} {...this.props.listViewProps} /> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1, }, contentContainerStyle: { justifyContent: 'flex-end', }, headerWrapper: { flex: 1, }, listStyle: { flex: 1, }, scrollToBottomStyle: { opacity: 0.8, position: 'absolute', paddingHorizontal: 15, paddingVertical: 8, right: 10, bottom: 30, zIndex: 999, height: 40, //width: 40, fontSize: 10, borderRadius: 20, backgroundColor: 'white', alignItems: 'center', justifyContent: 'center', shadowColor: 'black', shadowOpacity: 0.5, shadowOffset: { width: 0, height: 0 }, shadowRadius: 1, }, }); MessageContainer.defaultProps = { messages: [], user: {}, renderMessage: null, onLoadEarlier: () => {}, inverted: true, loadEarlier: false, listViewProps: {}, invertibleScrollViewProps: {}, // TODO: support or not? }; MessageContainer.propTypes = { messages: PropTypes.arrayOf(PropTypes.object), user: PropTypes.object, renderMessage: PropTypes.func, renderLoadEarlier: PropTypes.func, onLoadEarlier: PropTypes.func, listViewProps: PropTypes.object, inverted: PropTypes.bool, loadEarlier: PropTypes.bool, invertibleScrollViewProps: PropTypes.object, // TODO: support or not? };