Add text chat to a video call built on React and daily-js
Tags: javascript, webdev, react, tutorial
Published: 2020-12-09 18:34:03

When Paul [built a custom video chat app](https://dev.to/trydaily/build-a-video-chat-app-in-minutes-with-react-and-daily-js-481c) using React and the daily-js library, he used [the Daily call object](https://docs.daily.co/docs/build-a-custom-video-chat-interface). 

The Daily call object is like a direct line to the Daily API. It gives us the finest-grained control over a video call, letting us access its lowest level foundations, like participant video and audio tracks. With that great access comes great flexibility! But, it also means that features like text chat need to be added from scratch. 

This post walks you through how to do that! 

![text chat pops up with knock knock joke gif](https://dev-to-uploads.s3.amazonaws.com/i/vpyw558s4gc2v0tptkaz.gif)

##What we'll build 
We're adding to Paul's demo React video app. When a user clicks to start a call, the app passes a Daily room URL to a new Daily call object, then joins the call. The call object tracks important information about the meeting, like other participants (including their audio and video tracks) and the things they do on the call (e.g. muting their mic or leaving), and provides methods for interacting with the meeting. 

We'll use the [`sendAppMessage`](https://docs.daily.co/reference#introduction) method and corresponding ["app-message"](https://docs.daily.co/reference#app-message) event to add text chat to the app. 

##What you'll need to build it 
* Daily account: [Sign up for an account](https://dashboard.daily.co/signup) if you don’t have one already.
* Cloned `daily-demos/call-object-react` Github repository: The fastest way to follow along with this tutorial and get a demo app up and running is to clone [this repo](https://github.com/daily-demos/call-object-react).
* Familiarity with React: In this post we skip over a lot of the code that isn’t related to Daily, so it could be worth brushing up on React and/or hooks [0].

With that, we're ready to start! 

##Add text chat functionality 
Our `<Chat>` is a form that does a few things with the participant `<input>`, meaning their chat message. First, via React’s useState hook and our `handleChange` function, it tracks their input in the component state `inputValue`.  

```javascript 
const [inputValue, setInputValue] = useState('');

const handleChange = (event) => {
   setInputValue(event.target.value);
 };
```

When a participant sends a message, they call `handleSubmit`, which broadcasts the message, stored in `inputValue` to other participants on the call using Daily’s [`sendAppMessage`](https://docs.daily.co/reference#introduction) method. 

```javascript 
callObject.sendAppMessage({ message: inputValue }, '*');
```

`handleSubmit` also updates the sender’s `chatHistory` state.  

```javascript 
const name = callObject.participants().local.user_name
     ? callObject.participants().local.user_name
     : 'Guest';
   setChatHistory([
     ...chatHistory,
     {
       sender: name,
       message: inputValue,
     },
   ]);
   setInputValue('');
```

In the return statement, `<Chat>` maps over every value in `chatHistory` to display the messages.

```javascript 
{chatHistory.map((entry, index) => (
       <div key={`entry-${index}`} className="messageList">
         <b>{entry.sender}</b>: {entry.message}
       </div>
 ))}
```
That covers sending messages. Now, we're ready to tackle making sure the app notifies recipients and displays their messages. 

##Alert participants to new messages
After the Daily `sendAppMessage` fires, it triggers the Daily “app-message” event. Our `handleAppMessage` event listener reacts to every "app-message." The handler gets the name of the sender from the Daily call object, and updates recipients’ chat histories using `setChatHistory.`

```javascript 
const participants = callObject.participants();
     const name = participants[event.fromId].user_name
       ? participants[event.fromId].user_name
       : 'Guest';
     setChatHistory([
       ...chatHistory,
       {
         sender: name,
         message: event.data.message,
       },
     ]);

```

After updating state, the function calls the `props.notification()` passed down from the parent Tray.js component to highlight the recipient’s chat icon. 

![chat icon flashes red and grey](https://dev-to-uploads.s3.amazonaws.com/i/jr7pf5zga0btbjzdpncv.gif)

We added that chat icon in Tray.js, where we pass state booleans and controller functions as props to Chat.js that determine whether the icon is highlighted or the chat window should be displayed (if it’s been clicked). 

```javascript 
const [displayChat, setChatDisplay] = useState(false);
const [highlightedChat, setChatHighlight] = useState(false);

function toggleChat() {
   setChatDisplay(!displayChat);
   if (highlightedChat) {
     setChatHighlight(!highlightedChat);
   }
 }
 
function handleNewChat() {
   setChatHighlight(!highlightedChat);
 }
 
// Relevant component snippets 
<TrayButton
       type={TYPE_CHAT}
       disabled={props.disabled}
       highlighted={highlightedChat}
       onClick={toggleChat}
     />
     <Chat onClickDisplay={displayChat} notification={handleNewChat} />
``` 
##Want to chat more? 
There are so many ways to keep customizing Daily calls. While we hope this post is a good springboard for adding text chat to your video apps, you might be interested in more advanced functionality, like enabling file exchange or a chat history that persists once a call ends. A third-party chat integration would be the best way to do that. Stay tuned for more!

For now, experiment with [our repository](https://github.com/daily-demos/call-object-react), and please send feedback our way any time at `help@daily.co`. 

[0] If you’d like to get familiar with React and come back later, check out the many great resources on DEV (like [Ali Spittel’s intro](https://dev.to/aspittel/a-complete-beginners-guide-to-react-2cl6)), or the React docs for [more on hooks](https://reactjs.org/docs/hooks-intro.html).