diff options
| author | Andrew <saintruler@gmail.com> | 2019-03-11 21:00:02 +0400 |
|---|---|---|
| committer | Andrew <saintruler@gmail.com> | 2019-03-11 21:00:02 +0400 |
| commit | 7e7dd5244e8d26485ad7950a89c04c98c4fef83f (patch) | |
| tree | 810730c4650392080fb87a78d3b527201e89fe4b /frontend/app/screens/messaging/chat.js | |
Initial commit/
Diffstat (limited to 'frontend/app/screens/messaging/chat.js')
| -rw-r--r-- | frontend/app/screens/messaging/chat.js | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/frontend/app/screens/messaging/chat.js b/frontend/app/screens/messaging/chat.js new file mode 100644 index 0000000..c6b0b5e --- /dev/null +++ b/frontend/app/screens/messaging/chat.js @@ -0,0 +1,214 @@ +import React from 'react'; +import { + FlatList, + View, + Platform, + Image, + TouchableOpacity, + Keyboard, + InteractionManager, +} from 'react-native'; +import { + RkButton, + RkText, + RkTextInput, + RkAvoidKeyboard, + RkStyleSheet, + RkTheme, +} from 'react-native-ui-kitten'; +import _ from 'lodash'; +import { FontAwesome } from '../../assets/icons'; +import { data } from '../../data'; +import { Avatar } from '../../components/avatar'; +import { scale } from '../../utils/scale'; +import NavigationType from '../../config/navigation/propTypes'; + +const moment = require('moment'); + +export class Chat extends React.Component { + static propTypes = { + navigation: NavigationType.isRequired, + }; + static navigationOptions = ({ navigation }) => { + const userId = navigation.state.params ? navigation.state.params.userId : undefined; + const user = data.getUser(userId); + return ({ + headerTitle: Chat.renderNavigationTitle(navigation, user), + headerRight: Chat.renderNavigationAvatar(navigation, user), + }); + }; + + constructor(props) { + super(props); + const userId = this.props.navigation.getParam('userId', undefined); + this.state = { + data: data.getConversation(userId), + }; + } + + componentDidMount() { + InteractionManager.runAfterInteractions(() => { + this.listRef.scrollToEnd(); + }); + } + + setListRef = (ref) => { + this.listRef = ref; + }; + + extractItemKey = (item) => `${item.id}`; + + scrollToEnd = () => { + if (Platform.OS === 'ios') { + this.listRef.scrollToEnd(); + } else { + _.delay(this.listRef.scrollToEnd, 100); + } + }; + + onInputChanged = (text) => { + this.setState({ message: text }); + }; + + onSendButtonPressed = () => { + if (!this.state.message) { + return; + } + this.state.data.messages.push({ + id: this.state.data.messages.length, time: 0, type: 'out', text: this.state.message, + }); + this.setState({ message: '' }); + this.scrollToEnd(true); + }; + + static onNavigationTitlePressed = (navigation, user) => { + navigation.navigate('ProfileV1', { id: user.id }); + }; + + static onNavigationAvatarPressed = (navigation, user) => { + navigation.navigate('ProfileV1', { id: user.id }); + }; + + static renderNavigationTitle = (navigation, user) => ( + <TouchableOpacity onPress={() => Chat.onNavigationTitlePressed(navigation, user)}> + <View style={styles.header}> + <RkText rkType='header5'>{`${user.firstName} ${user.lastName}`}</RkText> + <RkText rkType='secondary3 secondaryColor'>Online</RkText> + </View> + </TouchableOpacity> + ); + + static renderNavigationAvatar = (navigation, user) => ( + <TouchableOpacity onPress={() => Chat.onNavigationAvatarPressed(navigation, user)}> + <Avatar style={styles.avatar} rkType='small' img={user.photo} /> + </TouchableOpacity> + ); + + renderDate = (date) => ( + <RkText style={styles.time} rkType='secondary7 hintColor'> + {moment().add(date, 'seconds').format('LT')} + </RkText> + ); + + renderItem = ({ item }) => { + const isIncoming = item.type === 'in'; + const backgroundColor = isIncoming + ? RkTheme.current.colors.chat.messageInBackground + : RkTheme.current.colors.chat.messageOutBackground; + const itemStyle = isIncoming ? styles.itemIn : styles.itemOut; + + return ( + <View style={[styles.item, itemStyle]}> + {!isIncoming && this.renderDate(item.time)} + <View style={[styles.balloon, { backgroundColor }]}> + <RkText rkType='primary2 mediumLine chat' style={{ paddingTop: 5 }}>{item.text}</RkText> + </View> + {isIncoming && this.renderDate(item.time)} + </View> + ); + }; + + render = () => ( + <RkAvoidKeyboard + style={styles.container} + onResponderRelease={Keyboard.dismiss}> + <FlatList + ref={this.setListRef} + extraData={this.state} + style={styles.list} + data={this.state.data.messages} + keyExtractor={this.extractItemKey} + renderItem={this.renderItem} + /> + <View style={styles.footer}> + <RkButton style={styles.plus} rkType='clear'> + <RkText rkType='awesome secondaryColor'>{FontAwesome.plus}</RkText> + </RkButton> + <RkTextInput + onFocus={this.scrollToEnd} + onBlur={this.scrollToEnd} + onChangeText={this.onInputChanged} + value={this.state.message} + rkType='row sticker' + placeholder="Add a comment..." + /> + <RkButton onPress={this.onSendButtonPressed} style={styles.send} rkType='circle highlight'> + <Image source={require('../../assets/icons/sendIcon.png')} /> + </RkButton> + </View> + </RkAvoidKeyboard> + + ) +} + +const styles = RkStyleSheet.create(theme => ({ + header: { + alignItems: 'center', + }, + avatar: { + marginRight: 16, + }, + container: { + flex: 1, + backgroundColor: theme.colors.screen.base, + }, + list: { + paddingHorizontal: 17, + }, + footer: { + flexDirection: 'row', + minHeight: 60, + padding: 10, + backgroundColor: theme.colors.screen.alter, + }, + item: { + marginVertical: 14, + flex: 1, + flexDirection: 'row', + }, + itemIn: {}, + itemOut: { + alignSelf: 'flex-end', + }, + balloon: { + maxWidth: scale(250), + paddingHorizontal: 15, + paddingTop: 10, + paddingBottom: 15, + borderRadius: 20, + }, + time: { + alignSelf: 'flex-end', + margin: 15, + }, + plus: { + paddingVertical: 10, + paddingHorizontal: 10, + marginRight: 7, + }, + send: { + width: 40, + height: 40, + marginLeft: 10, + }, +})); |