Chats

This is the screen displaying the list of open chats. The special thing to note here is we are using a second navigator to display selected chats on top of the chats list. This means we need a StackNavigator in our Chats component that will contain two screens: ChatList and Chat. When a user taps on a chat from ChatList, StackNavigator will display the selected chat on top of ChatList making the list of chats available through a standard < back button in the header.

For listing the chats, we will use <FlatList />, a performant interface for rendering simple, flat lists, supporting the most of the features from <ListView />:

/*** src/screens/Chats.js ***/

import React, { PropTypes } from 'react'
import { View, Text, FlatList, ActivityIndicator } from 'react-native'
import { observer, inject } from 'mobx-react/native'
import { StackNavigator } from 'react-navigation'
import Icon from 'react-native-vector-icons/FontAwesome'
import notifications from '../notifications'

import ListItem from '../components/ListItem'
import Chat from './Chat'

@inject('chats') @observer
class ChatList extends React.Component {
  imgPlaceholder = 
  'https://cdn.pixabay.com/photo/2017/03/21/02/00/user-
                    2160923_960_720.png'

  componentWillMount() {
    notifications.onNotification((notif)=>{
      this.props.navigation.goBack();
      this.props.navigation.navigate('Chat', {
        id: notif.chatId,
        name: notif.name || '',
        image: notif.image || this.imgPlaceholder
      })
    });
  }

  render () {
    return (
      <View>
        {
          this.props.chats.list &&
          <FlatList
            data={this.props.chats.list.toJS()}
            keyExtractor={(item, index) => item.id}
            renderItem={({item}) => {
              return (
                <ListItem
                  text={item.name}
                  image={item.image || this.imgPlaceholder}
                  onPress={() => this.props.navigation.navigate('Chat', 
                  {
                    id: item.id,
                    name: item.name,
                    image: item.image || this.imgPlaceholder,
                    contactId: item.contactId
                  })}
                />
              )
            }}
          />
        }
        {
          this.props.chats.downloadingChats &&
          <ActivityIndicator style={{marginTop: 20}}/>
        }
      </View>
    )
  }
}

const Navigator = StackNavigator({
  Chats: {
    screen: ChatList,
    navigationOptions: ({navigation}) => ({
      title: 'Chats',
    }),
  },
  Chat: {
    screen: Chat
  }
});

export default class Chats extends React.Component {
  static navigationOptions = {
    tabBarLabel: 'Chats',
    tabBarIcon: ({ tintColor }) => (
      <Icon name="comment-o" size={30} color={tintColor}/>
    )
  };

  render() {
      return <Navigator />
  }
}

The first thing we notice is that we are injecting the chats store where the list of chats is saved: @inject('chats') @observer. We need this to build our <FlatList />, based on this.props.chats.list, but as the list of chats is an observable MobX object, we need to transform it using its toJS() method to make a JavaScript array out of it.

On the componentWillMount() function, we will invoke onNotification on the notifications module to open the corresponding chat every time the user presses a push notification on her device. Therefore, we will use the navigate() method on the navigator to open the proper chat screen including the name of the contact and her avatar.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.58.51.228