Typing Notification Goal0:33
So both of us have access to this project. But now, if we are both signed in at the same time, I would like my wife to see a notification when I'm typing. So as I would type here, yeah, on the other end, she would get a little notification that says Jeffrey Wei is currently typing. Something like that. Alright, let's see what we can do here. Here's that little chat box, right? So why don't we say, when the user keys down, so when they start typing into this input, we will, what do we want to say here, notifyPeers?
Whisper on Keydown0:56
So why don't we say, when the user keys down, so when they start typing into this input, we will, what do we want to say here, notify peers? Or how about tapParticipants? You know, any kind of fun name that you want to use there. Some people will just stick with onKeyDown, you can do that as well if you prefer. Alright, let's go ahead and add that here, tapParticipants. And now let's grab our channel, or we can cache that at some point, we could use a computed property, anything you want. But anyways, grab our private channel, and now we're going to use this nice terminology here, whisper.
Now what you could do, like some people might want to do this where you actually pass through what they are typing. So this would be whatever the user has currently typed will be sent through, but you definitely don't want to do that, right? If somebody else is typing, you shouldn't be able to see their draft, what they're experimenting with sending through. So we definitely don't want to do that. Alright, so we'll refactor, and hopefully that makes sense. So when you key down, we will get our channel and then whisper to the other clients that we are currently typing.
Listen for Whispers3:26
Now we need to do the next step, which is listen for a whisper. So we can do that right up here. We could say, listen for a whisper, the name is typing, and then what do we want to do in response? We'll say alert, somebody is typing, and a quick refactor there. So now let's go back to Chrome. Once again, I'll give both of these a hard refresh, and now if I type a key here, you'll see right up here Chrome is letting us know that we have an alert, and there it is. Let's do it again here. I will type a little bit, switch over, and now we're notified.
Show Active Typist3:58
Let's do it again here. I will type a little bit, switch over, and now we're notified. So the next step is, let's do this. How about, so now maybe here, this is where ultimately we'd have something like JohnDoe is typing. So yeah, something like this is ultimately what we want, but of course it should be dynamic. So what we'll say here is maybe, do we have an active participant? Or how about active peer? How about that? So if we have an active peer, then we'll say activePeer.name is typing.
How about that? So if we have an activePeer, then we'll say activePeer.name is typing. We'll try something like that. All right, so it sounds like by default there are no active peers, however, if a random user, anyone in this project starts typing, we will make an announcement, and then up here we will listen for that announcement. However, this time we won't do an alert. We'll say this.activePeer equals the event, and in this case that would just be an object that contains the name. Of course, if you need to, you can overwrite that or limit it however you need to.
If we do it on this end, we get the exact same thing. But now, of course, we do need to make this disappear at some point. So maybe we could say, well, yes, update activePeer, but how about after three seconds or so, whatever interval you want, we will reset that. So we'll say this, let's do it like this, this.activePeer is back to false, and we'll do that after about three seconds. Okay, so give that a refresh one more time. I will start typing, one, two, three, and it disappears. However, we want it to be a little more relevant, so if I do something like this, what's going to happen after three seconds if I keep typing?
Fix Timer Flicker6:04
However, we want it to be a little more relevant, so if I do something like this, what's going to happen after three seconds if I keep typing? Yeah, can you see that there? Hopefully that's coming through in the screencast. It keeps flashing because all of those timers keep getting set, we're building up memory, they keep resetting, not what we want. So it sounds like we need to clear it. So we could say here timer or be a little more specific, like typingTimer, set that to false, assign it here, and we're mostly doing this so that we can clear it if we need to.
to false, assign it here, and we're mostly doing this so that we can clear it if we need to. So we could say something like, well, if there already is a typingTimer in effect, then let's make sure we clear that because we're going to start over and basically reset the clock. So if that's the case, clear the timeout, this.typingTimer, and format. Does that make sense? If a person is typing, all right, well, let's update to the activePeer. Next, if we already have a timer, then go ahead and clear that out, and then we'll create a brand new one.
Expose User to JS7:26
Okay, you get the idea. So now let's just do a quick thing here to show the user, and this will just depend upon how you've built your app. I'm going to do something up here. Sometimes I'll do this. We'll say window.app. So we'll have a global app object where we will echo out some data here. So we'll say the user is auth()->user(). So just grab the standard User object with Laravel, and then we will encode that and pass it to our JavaScript.
So just grab the standard User object with Laravel, and then we will encode that and pass it to our JavaScript. So now we'll give that a refresh and look at the source, and you can see we have that object. But anyways, now that we have access to that, rather than hard-coding foobar, I could instead say the name is the current user's name. All right, let's come back to Chrome, give this all a refresh, and once again, actually real quick, let's clear all of this out. Okay. Anyways, now as I start typing, they are notified, oh, Jeffrey's working on this.
Recap and Refactor9:20
All right, two final things. Let's do our 30-second recap, and then we'll finish up by cleaning some things up, like maybe extracting a method, maybe renaming, I'm not sure. Okay, our recap. We're in a project, we want to notify others when we are currently typing. So immediately we can say, well, we have to detect if you are typing. So on keydown, we will tap the other participants. If we take a look at that, we do that by getting our channel, and then whispering to the other clients that we're typing, and specifically whoever the currently signed in user is the person creating the new task.
clients that we're typing, and specifically whoever the currently signed in User is the person creating the new task. Next, if we scroll up, we check on that. All right, well, if activePeer is no longer false, and it's equal to that object, we will echo out that this person is currently typing. And that's all there is to it. All right, so let's do some refactoring, and we will call it a day. Now here I can see I'm using one term of participants and another term of peer. Not a big deal, but maybe instead we should say tagPeers. If we're going to use the name or the term peer, then let's keep it consistent.
And then I will go back and rename it. So let's see, if we detect that somebody else in our project, some peer is typing, what do we do? Well, let's just break it down. Clearing a timeout, that's a side effect. What we're really doing right now is flashing the active peer. So maybe we can call this flashActivePeer, or flashPeerIndicator, I don't know. This is fine, though. I think that'll work. And let's make sure we accept the event there, the client event.
I think that'll work. And let's make sure we accept the event there, the client event. Next here, this is just a tiny refactor, but I bet we can get away with just not doing that at all. So let's see what that would look like. Yeah, and we'll do a reformat there. Doesn't look too bad. Next I can see in a couple places, we're doing this long string here to calculate the channel and then to load it. So we have it there, there.
and then to load it. So we have it there, there. Is there a third place? No. So not a biggie, but you know what? Let's still move that to a computed property. I think it'll read better after that. So I will call it channel. And yeah, we're basically just going to return this. Now I could say, well, when our view component is created, get the channel and listen for.
And yeah, we're basically just going to return this. Now I could say, well, when our view component is created, get the channel and listen for when a new task is created, and then listen for if somebody is typing. OK, next, right down here, exact same thing. This this.channel.whisper. And then this is fine. Would it look OK on its own line? It's not too bad there. I would prefer it on its own line. If it gets a little longer, it's much cleaner to read it if you separate it.
