Playing
04. Building a chat textarea

Transcript

00:00
Let's get to work on this text area, which, for a chat interface, needs to work in a very specific way. We don't want to have to click a submit button every time we want to send a message into the chat, so we need to be able to hit return on the keyboard to send these.
00:12
But we also want to allow for multi-line messages. Okay, let's break this up into a component so we can focus on its functionality. I'm going to go ahead and create out a directory in here called chat, since Breeze gives us a ton of components already. And inside of here, we're going to create a view component out called chat text area.
00:31
Okay, now we've created this, let's get rid of these scope styles. We're not going to need these. And let's just output a basic text area directly into here. Let's output a text area and we'll just leave it at that for now. Okay, so over in our room, let's just output this text area component or chat text area component.
00:51
And that's auto imported for me, but obviously you're going to go ahead and import that if it isn't. Okay, so now that we've done that, yeah, we have a text area. But when we hit return, the nature of a text area is obviously it goes to the next line. Let's just apply some styles to this and then we'll look at this functionality.
01:08
So I'm going to grab the styles from the text input component, which already exists within this starter kit. And we're going to break this up and just move it over here. So let's apply these directly to here, start to pull everything down so we can focus on all of the events we need to focus on. And we'll also give this an idea of body so we can hook it up to a label and then we will set some rows here as well.
01:32
So let's just set them to four. So there we go. We have a text area and I'm just going to slightly dim down that. Okay, so we want to go over to our room and set a class on here of width full so we can override that style. It's just going to pull it out here and we can do other things.
01:51
We can either do that directly inside of the component or we can do this outside and have props get passed down and attributes automatically set. So we're just going to say say something in here. Okay, great. Okay, so we have this looking nice, but obviously it still doesn't work properly. Let's get started on all of the events that we need to listen to.
02:12
Now, the first thing we need to know is when the enter key is here on the keyboard. So we just use a simple event within view and we're going to say key down and then enter. So that is the enter key being pressed and we're going to prevent the default behavior here because we don't want this to go down to the next line. So we're going to say handle enter and we'll create out a function just up here that goes ahead and handles what we need to do when enter is pressed.
02:40
At the moment, we'll do nothing and let's type something, hit enter. And as you can see, I cannot go down to the next line, which is great. So we've already solved that problem. The next thing we want to do is submit this or fire an event to say that this is valid. So we have some valid content in there, but only when it has some content.
03:00
So let's go ahead and fire this event first of all, and then we'll see why this is going to be a problem. So up in our component, let's define out our emits, which means that we now have access to this emit method and we can emit a event, whatever we want to do. And this is going to be the value of what we've typed, which we'll get to in a second. OK, so let's bring up our console and let's see what happens when we type something and hit enter.
03:25
OK, so nothing at the moment because we're not handling that. Let's go back over to our room and once again, pull these down so we can start to handle these events. So we're going to say V on valid. This is where we are going to then send that message through with an HTTP request to store it. For now, I'm just going to console log on the event data, which will be the value that we passed just here.
03:48
OK, let's go over and hit ABC, enter. And there we go. So we know that this is working. The only problem is if I don't have any content in here and I hit enter, it still fires this event off. And that's not a valid message. So let's first of all, hook up our text area to a ref so we can actually get this data. Let's go ahead and say V model and we will call this model.
04:11
And let's go up here and create out a ref using view. And again, you want to import that at the top. By default, we'll just send that as an empty string. And now in here, what we can do is access the model value that we've typed and emit that once it's valid. So now when I hit anything, so if I say hello, you see it logs hello, say yo, it logs yo.
04:34
So working nicely so far. OK, so just really quickly, once we have submitted a message, we want to go ahead and reset the model value back to an empty string. So that's going to give us a more chat like interface where we can type something and it clears out the text area. Now, we only want to do this when we actually have a value.
04:55
So let's put all of this into an if statement and all we need to do is just say model value and length. So as long as it has some length, we go ahead and submit it. That means that now if I hit enter here, nothing happens. Ignore this. And when I do type a message, hit enter. It works nicely.
05:13
Now, the next thing is we want to be able to go down to the next line. So if I type in hello and press shift and enter, you can see that already this is being picked up by view. It's the enter key being pressed. So it's sending it anyway. That's not what we want. So we want to add another ref in here to say if shift is being pressed.
05:31
And of course, by default, that's going to be false. What we can then do is do very similar events to just swap this value over. So we want to say V on key down and shift. So when the shift key is here, we want to set shift to true.
05:48
And what we might be thinking is, well, when we have a key up on shift, we're going to set shift to false. Now, let's just go and apply some sort of style to this text area when shift is being pressed. We would wrap this or just dump the value out. But since we're passing props down that need to be inherited with this text area, it's not going to work.
06:06
Let's just add in a class here of background blue 500 when the shift key is being pressed. OK, if we come over and I hit just the shift key and hold it down, you can see the background changes to blue. When I lift this off of my keyboard, nothing happens. Now that's a problem. The reason that this happens is because this shift modifier on key up doesn't quite work.
06:27
So we just want to say on any key up, we're going to reset shift back to false. What that's now going to do is when I hit shift on the keyboard and hold it and then I release, it is going to work. So now when I type in hello and press shift, I'm ready to press enter to go down to the next line. Now, that's not going to work at the moment.
06:46
And the reason being is that handle enter is always being called any time we press enter, regardless of if we've got shift pressed. So we need another if statement to manually add a new line if shift is being pressed. So let's say shift and value. And if shift is being pressed down, let's take the model value and reassign it to the current value.
07:10
But we'll add on or concatenate on just a new line. Once we've done that, we can go ahead and return because we do not then want to go ahead and send this. So now that we've intercepted this, let's go back over and try this out. So I'm going to type in hello, hit shift and enter. That's added a new line.
07:27
It's unshifted shift. And then I can just continue typing. Then I can press enter and it works. So this is working nicely. However, what we don't want to happen is for the user to press shift when the value is empty. Let me show you what I mean. I'm first of all, just going to get rid of this background because it's going to get annoying. OK, so let's go ahead and just press shift and enter.
07:51
And you can see that I can basically create a new line before my message. Now, you might want that functionality, but we're going to go ahead and get rid of that by also checking that we have a model value. So let's say model value length. And that means that we have to have some content before we press shift and add a new line. So now if I hit shift and enter, nothing happens, but I can press any other key, hit shift and enter.
08:16
And of course, go down to the next line. So that is our text area complete. We're going to come back to this later because we're going to need to detect when the user is typing. But if we go to our room now, we've got this event which we can use to grab the data within here, which is the message. And we can do something with this data, obviously, rather than just console log it out.
21 episodes1 hr 41 mins

Overview

Using the power of Reverb, let’s build a realtime multi-room chat with Laravel and Vue with Inertia, pulling in Pinia for state management.

We’ll cover:

  • Using the Intersection Observer API to automatically load previous chat messages
  • State management with Pinia
  • Using presence channels to show online users for each room
  • Client-to client communication to show who’s typing
  • Using flexbox tricks to keep messages scrolled into view as they roll in
Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!

Episode discussion

No comments, yet. Be the first!