react-native-android-chat-tutorial

How to Build an Android Chat App with React Native: Typing Indicators (Part Five)

So now that we’ve built our basic Android chat app with React Native, we’re going to start adding additional features using ChatEngine plugins. Plugins are pre-built small features that can be easily integrated into your chat app. You can find them all in our ChatEngine plugin library.

What is a Typing Indicator?

A typing indicator is a realtime indicator of whether a user is currently typing a message. Under the hood, the typing indicator translates keystroke events into ChatEngine custom events and reflects it in the user interface, in this case with a “User XYZ is typing… “, or “Typing… ” indicator.

Using the ChatEngine Typing Indicator Plugin – Basic Example

The complete documentation for the ChatEngine Typing Indicator plugin is available here. In this section, we’ll quickly walk through a simple example to show you its basic functionality, then after that, we’ll move onto integrating the typing indicator into our existing sample Android chat app.

First, NPM install the plugin:

npm install chat-engine-typing-indicator

Next, you’ll need to require the library in your code:

require('chat-engine-typing-indicator')

Add the plugin to your ChatEngine code:

chat = new ChatEngine.Chat("mychannel");
chat.plugin(ChatEngineCore.plugin['chat-engine-typing-indicator']());

With that, now the events and state are accessible to the JavaScript application code.

// typing boolean
chat.isTyping;
// False

chat.on('$typingIndicator.startTyping', (payload) => {
    console.log(payload.user, "is typing...");
});

chat.on('$typingIndicator.stopTyping', (payload) => {
    console.log(payload.user, "is not typing.");
});

And that’s it!

Diving Deeper – Typing Indicator in the Sample Application

In our existing Android app, we’ll use slightly more code for integrating a typing indicator above the message entry box. This is because although the two components are related, the text entry box is the source of the events, while the text label is the receiver of the typing events. This decouples the two components and allows us to modify the application more easily if we choose to move things around (or use an image-based indicator instead of a text-based indicator, for example).

Message Entry – The Typing Indicator Event Source

Our first integration point is modifying the message entry box to produce typing indicator events. We use the following code to integrate with the Typing Indicator – see lib/ce-view-messageentry.js in the source code repository to see what we’re doing here.

First, we create a function that the text input can call whenever it is being edited. In it, we add code to fire off typing indicator start and stop events as appropriate.

setChatInput(value) {
    this.setState({chatInput: value});

    if (this.props.typingIndicator) {
        var chat = this.props.chatRoomModel.state.chat;

        if (value !== "") {
            chat.typingIndicator.startTyping();
        } else {
            chat.typingIndicator.stopTyping();
        }
    }
}

Next, we reference that code in the render() function, binding the event handler above to the onChangeText() event.

Note: this is different from the onSubmitEditing() function, which actually sends the message.

render() {
    return (
        <View>
            {this.onTypingIndicator()}
            <View style={styles.footer}>
                <TextInput
                    value={this.state.chatInput}
                    style={styles.messageentry}
                    underlineColorAndroid="transparent"
                    placeholder="Send Message"
                    onChangeText={this.setChatInput}
                    onSubmitEditing={() => {
                        this.sendChat();
                    }}
                />
            </View>
        </View>
    );
}

Now we’re ready to take action in the user interface when those events fire off.

The Typing Indicator Itself

Our second integration point is updating the typing indicator near the message entry box in the specified chat room. We use the following code to integrate with the Typing Indicator – see lib/ce-view-nametypingindicator.js in the source code repository to see what we’re doing here.

This is what we’re trying to do:

There’s a bit of code involved since we want to make the typing indicator its own React component.

In the constructor, we set up the initial state (“not typing”, “no username”), and bind two event handlers to the start and stop typing events so that we can keep the state updated.

class NameTypingIndicator extends React.Component {
    ...

    constructor(props) {
        super(props);

        this.state = {
            isTyping: false,
            userTyping: "",
        };

        this.onStartTyping = (payload) => {
            this.setState({isTyping: true, userTyping: payload.sender})
        };

        this.onStopTyping = (payload) => {
            this.setState({isTyping: false});
        };
    }

Now, it’s a simple matter of displaying the proper text indicator. If the user ID corresponds to “Me”, we just display “Typing… ” since presumably, the user knows their own name. Otherwise, we display the remote user’s display name in the indicator.

renderTypingIndicator() {
    if (this.state.isTyping) {
        if (this.state.userTyping.uuid === ChatEngineProvider._uuid) {
            return (<View><Text>Typing... </Text></View>);
        }

        return (<View><Text> {this.state.userTyping.state.name} is typing... </Text></View>);
    }
}

And that’s it! Chat users can now see when other users are typing in realtime. In future tutorials, we’ll add more plugins, so stay tuned!

Use Cases:

Try PubNub Today