This episode is for members only

Level up with a premium membership

Join now
Already a member? Sign in to continue
Playing
13. Whispering typing status

Transcript

00:00
So the concept of whispering within real-time WebSocket connections is sending things to
00:06
clients without going through the backend. We know at the moment that we are broadcasting our message created event to our server directly. Now when we are typing, because we're potentially going to be sending loads of events, we don't want to broadcast this every single time we hit a keystroke. That's going to be really inefficient. So what we want to do is we want
00:30
to whisper, which will send the message directly to other clients without going through our backend code. It will still go through our server, but it will just broadcast a message to all clients. Now to do this, we're going to directly use Echo within our Alpine component here that we've built. So how do we do this? Well, the first thing that we need to do is connect
00:52
to our client. So we're going to use Echo, which exists on our window object. We just remind ourselves over in Echo.js, you can see this is set to our window object. Now when we've been doing this within LiveWire, it's been using this behind the scenes, but we can also directly access it if we don't need to use LiveWire, which in our case we don't. So we're going to connect up to
01:14
a private channel directly in here, which is chat.room. and then the ID of the room. Now because we're working within room show, we can just access the room ID directly to connect up to that channel. Then what we can do is we can use the whisper event to whisper out some events. So we're going to call that typing. Now the payload that we want to send through is the user who is currently typing.
01:41
So let's output an ID in here and that's just going to be the currently authenticated user's ID. Okay, let's leave it at this for now. Let's make sure we are opening up our debugger when we're running reverb and let's go over and have a look. So I'm just going to type hello and let's go back over to our code and as you can see we've now got this event client typing. Typing here is the event
02:08
name that we gave and you can see that my ID exists within the data here. So we're now sending this to our websocket server without having to go through the back end and create out an event. Okay, so we can do this here when we are typing and we can add in an event here when we've stopped typing. So let's go ahead and do exactly the same thing on exactly the same channel, but this time we're
02:31
going to change around the event and let's call that not typing or finished typing, whatever you want to call it. Okay, now that we've done this we've got an event for when we are typing, when we're not typing and we're going to go ahead and pick this up over in our users component just inside of here. So we want a separate array of IDs of people who are currently typing. Let's go ahead
02:55
and call this typing IDs. So let's create this typing IDs array out and we're pretty much going to replicate the functionality that we had for the IDs of people who are currently in the list. So let's go down and create a method down here to set who is typing. Again, we'll dump this out so we can see this working before we do any visual updates. So set typing, again we're going to get
03:20
the user in here who is typing and we're going to need an on event to hook into echo to pick this up. So we're going to say echo private, so it's slightly different now. We don't use echo whisper or anything like that. We listen on this specific room and that's chat room and then the room ID and remember the event that we want to pick up is we probably lost it now but it's client
03:47
hyphen typing. So let's say client typing and we're going to use a dot here because we're not working with a traditional event name and in here let's just die dump the user out and just see if this works. Okay, let's go over and refresh the page here. I'm also going to pull in the other window that we have and I'm going to start typing in here and you can already see that this has dumped out
04:14
user ID 2. So we now know that Mabel is typing and of course if we did it the other way around it would dump out here. Okay, so now that we've done this we can just do like I said what we did with our users and we can just push to this typing array. So let's say typing IDs and we'll push the user ID to that list of typing IDs. Let's do the same thing for when we're not typing.
04:42
So we call this not typing and again we'll get the user in here who is not typing anymore and we can pretty much just replicate what we did down here and just copy it over. So it just filters out people who are not typing anymore. So let's change this to typing IDs. Typing IDs, we still have the user, we have the ID of that thing and the condition is exactly the same. So now over in our users
05:09
template let's just dump out at the top here who is and isn't typing and we'll see that we need to make a slight adjustment here. So let's output typing IDs and let's have a look. Okay, no one's typing at the moment. Let's set Mabel to typing and what you can see here is we're pushing to this list but we're getting a huge amount of data through. So it's successfully getting rid of this
05:31
but we've got way too many items in here. So what we want to do is over here on the condition that they don't already exist within this list we want to go ahead and push. So we'll return in here if they're already in the list. So let's say in array user ID in this typing IDs we'll just return. So if they're already typing we don't want to just keep pushing them in. Now we could do the same thing
06:00
for when a user joins. So in here we could do exactly the same thing like this but remember when we refresh the page this always overwrites the overall list of IDs. So although this is always going to be unique because of this method we could add that in there as well if we wanted to just to make sure. Even if there was a duplicate ID in our list of people who are joining the query that
06:25
we send to the database fetching our users by ID will only ever return a unique set of data. Okay, so now that we've done this, this should work nicely. So I'm going to just start typing over here and you can see user ID 2 is typing. I stop typing for a while and it disappears. Same over here as well and you can see that that user is currently typing. Now this broadcasts to other
06:47
clients which is absolutely fine because we don't need to see when we're typing. There's no point. Okay, so now that we know that this is working and broadcasting properly we can just update the template to output whether a user is typing or not. Let's make this really simple for now and then we'll go ahead and add in a little icon. Okay, so we want this to sit next to this so let's create
07:10
out a span in here with the user's name so we can separate these two things out and then down here we'll create out a span with typing and we want to apply some classes to this to hide it and show it if the user is currently typing. So let's create out using Laravel's class attribute and in here we just want to give an array of original values so we could say opacity zero but then we can add
07:35
in here on a condition to show any additional classes so we could set an opacity 100 if the user is typing. Now how do we work out whether they're typing? Well we can just use a really simple in array to check if the user who we're iterating through's id exists within those typing ids. So just set a typing piece of text to an opacity zero and set it to an opacity of 100 if they are
08:03
currently typing. That's all we need to do. Okay let's try this out so let's say Mabel I'm typing that shows that she is typing and then of course it disappears and the same for all other connected clients as well. Okay let's make this a little bit more interesting so head over to the github repository and you can grab this svg icon here which looks like this so not great at the moment
08:26
but we can change the styles over and we can just do the same thing to this svg as we've just done with that piece of text so let's go ahead and pull in our class binding in here and as you can see that works if we refresh and start typing we can see that icon doesn't look great at the moment but let's add some additional styles in here so let's go ahead and give this a size of four and
08:52
we could also do stuff like animate this so let's say animate bounce and we'll set the transition to the opacity so when the opacity does go to 100 it transitions from 0 to 100 all optional of course but it just adds something nice. Okay let's check this out and see what we've got so I'm going to start typing over here and as you can see that shows that Mabel is typing she's stopped typing
09:17
I can just carry on typing in here and that will show and of course when we eventually get to the point that we hit enter that instantly goes ahead and sends across that we're not typing and it gets rid of it from over here so there we go all clients now that are connected will receive an event to show who is typing and it will visually show it on the ui
14 episodes1 hr 23 mins

Course overview

Join a room and start chatting! This course covers building a multi-room text chat app with Livewire using Laravel Reverb for real-time updates.

Using presence channels and client-to-client whispering, we’ll also show who’s online, and who’s currently typing.

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!

Comments

No comments, yet. Be the first to leave a comment.