Adding User Interactivity to a Chatroom with Laravel, Vue.js and Stream Chat

In my last tutorial here, we created a chatroom application using Laravel, Vue.js, and Stream Chat. Although we only covered the basics of getting our chatroom up and running, Stream Chat offers a lot of other functionality.

In this tutorial, we will explore some of those functionalities, and we’ll be adding them to our chatroom application. We’d add the following functionality:

  • Add a leave channel functionality
  • Add functionality to join channel manually
  • Show a typing indicator when the user is typing
  • Display a notification when a user enters chat
  • Display a notification when a user leaves the chat

Adding the Leave Channel Functionality

Currently, in our application, users are added to the chatroom as soon as they register. But typically, in a chatroom application, users should have the ability to join or leave any channel of their choice explicitly.

To implement this functionality, we need to tell Stream Chat to remove or allow a user to join different channels as they want. Let’s see this in action.

Add the following code within the class definition of ChatController.php:

https://gist.github.com/ammezie/ddff82db5faa3a3c24f5f44ed78079d5

We created a new leaveChannel method to handle removing users from a particular channel. This method calls the removeMembers function on the current channel instance, which gets set as soon as the controller is invoked. The removeMembers function accepts an array of user IDs (username in our case) we want to remove from the channel.

Still, inside the ChatController, update the generateToken method as below:

https://gist.github.com/ammezie/641a0b29d3b9a94c8158202e517a3357

Next, we need to create the endpoint that will trigger the leave channel functionality. Add the code below inside routes/api.php:

https://gist.github.com/ammezie/108007341f36383b2d0ee5b5bfb548dc

Now that all our backend needs are set up, we need to add a button on our frontend that will be used by users when they want to leave the channel. Inside the ChatRoom component, add the following code underneath the member's list:

https://gist.github.com/ammezie/583134af9092848778acf309b4c3411a

Here, we add a simple button to allow users to leave the channel. On click of this button, the leaveChannel method will be triggered. Let’s create the method:

https://gist.github.com/ammezie/d8d9678b923f2cec841e5563988c4b6e

This makes a POST request to our leavel-channel endpoint with the username of the user leaving the channel. Then redirect the user to the dashboard route.

Lastly, let’s update the channel members list by removing the user that left from the list. We’ll implement that inside the initializeChannel method. Add the code below immediately after where we are listening for when a new member is added to the channel:

https://gist.github.com/ammezie/a7fafeec81da87270047c87ef6b05d04

Here, we are listening for the member.removed event and filter the members to not include the user that left.

Joining a Channel

Stream Chat also provides an addMembers function (which we saw in the last tutorial) for adding users a channel. Add the following code inside ChatController.php:

https://gist.github.com/ammezie/309bf080d2ac45205e6585bb2c9db440

In this method, we create the username by extracting part of the information sent to us before calling the addMembers function on the current channel instance. To trigger this method, open api.php and add the code below:

https://gist.github.com/ammezie/4eb25bba9dcc751aed9d2fbeb55bb78b

Next, we need a button on the user side to trigger this action. We’ll add it to the dashboard page. This is the page the user gets redirected to when they leave a channel. Create a dashboard.blade.php file in the resources/views directory and add the following code to it:

https://gist.github.com/ammezie/226a5af53cd7726923a7f1043125304f

We created a small form and button to trigger the endpoint; we just created and passed along the necessary information to it. To round up this functionality, let’s add the required route and controller code to render this page. Open routes/web.php and add the following code to it:

https://gist.github.com/ammezie/25f145460bc42039c3c64020ed75905a

Next, add the following code inside HomeController.php:

https://gist.github.com/ammezie/e96a7b0bc234e3269c2aaa66a95b4e26

Displaying User Joined/Left Notification

When a user joins a chatroom, a cool feature to have is one where we can see the user name of the person that just entered. This can come in handy for introductions and other formalities so users won’t get lost in the chats.

Stream Chat triggers certain events, which we can listen to and perform any necessary action accordingly. We have seen a couple of these events in the last tutorial. To know when a user joins a channel, we listen for the member.added. event.

Inside the template section of resources/views/js/ChatRoom.vue`, add the following code immediately before the message form:

https://gist.github.com/ammezie/b2e5a289517556f85c68eb4563b2f443

This will display the user joins notification only if the status property has been set.

Next, inside the script section of resources/views/js/ChatRoom.vue, let’s start by adding a new status property to the component’s data:

https://gist.github.com/ammezie/3a45f0ac9f35f77ae4bfb217a893ba87

Then inside the initializeChannel method, we’re already listening for the member.added event, all we need to do is update it as below:

https://gist.github.com/ammezie/ff925f637d15bf8ceb0d69d0ee0919ea

The status property is initially set to an empty string. Once a new member joins the channel, we set status property accordingly.

Similarly, to display a notification when a user leaves a channel, we’re already listening for the member.removed event, all we need to do is update it as below:

https://gist.github.com/ammezie/187547bedb9b4194d5662232bec2779d

Now, whenever a user leaves the channel, we’ll set status accordingly.

Adding a Typing Indicator

Another handy feature of chat applications is the ability to know when a user has started typing a response to a message — that way, we can anticipate better instead of having to sit and wonder.

Stream Chat provides two events regarding typing: typing.start and typing.stop, which we can use to check if a user is typing or not. Let’s add two additional data properties to the ChatRoom component:

https://gist.github.com/ammezie/23f6c87a4bf64cfdd373fe848491f730

isTyping will be used to indicate whether a user is typing or not, while typing will hold the response gotten as a result of triggering the events.

Next, let’s update the message field so we can keep track of when a user is typing or not:

https://gist.github.com/ammezie/f363ba55ae8ad94e29ae76d11f413ff0

We add two keyboard events: @keydown and @keyup, which are Vue.js equivalent of the JavaScript keyboard onkeydown and onkeyup events, respectively. On keydown, the startedTyping method will be triggered, and on keyup, the stoppedTyping method will be triggered.

Next, let’s create those methods:

https://gist.github.com/ammezie/1cf6321d4383c4515b2412466cb41f3c

When the user starts typing (keydown), we need to trigger a typing.start event using the keystrokes function on the channel instance. Similarly, when the user stops typing (keyup) for more than two seconds, we need to trigger a typing.stop event using the stopTyping function on the channel instance.

To wrap up, we need to listen to these events as they are triggered. We’ll do that in the initializeChannel method:

https://gist.github.com/ammezie/764627a159dc02370df9e10d8c3d61c7

Lastly, we need a way to display the typing indicator. Add the following code immediately after the message form:

https://gist.github.com/ammezie/c3928640ec60d48e19b32c944df16bd4

We conditionally show the text {username} is typing when isTyping is true and if the user typing is not the same one viewing it.

Testing the App

Now, let’s test what we’ve been building so far. First, let’s compile our JavaScript:

https://gist.github.com/ammezie/47b9a2cfa2a82c131a5ec8aef8753a08

Next, let’s start our application:

https://gist.github.com/ammezie/111848d6582261e48384f1dfe731da24

Navigate to http://127.0.0.1:8000.

Final Thoughts

In this tutorial, we’ve looked into adding various functionality we can add to our chatroom application using Stream Chat. We’ve used events and functions provided by Stream Chat to help enhance our application, and the knowledge gained can be used to create more complex chat applications. To learn more about Stream Chat, check out the docs.

The complete code for this tutorial is available on GitHub.

Tutorials

Chat