Create Chat Applicaton Using Flask-SocketIO - Chat App Part12

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome back everyone to the code long series on creating a chat application this video is more than an hour long so in case you are looking for a specific topic within flossed socket IO be sure to check out the table of contents from the description below in the previous video we had an overview of what socket IO is in this video we'll come to the implementation part and write the code in case you have not watched the previous video on the concept of polling web sockets and socket IO you may want to go back and do that because we will be using some of those stones today in case you've already watched it or are already familiar with the broad concept or just feel like winging it then let's start to provide more context to the code we will be writing let me explain what we will be doing in the previous video we saw that we can use socket IO to establish a connection between a client and a server the connection could be web socket or pulley so while I have used double headed arrow here the connection does not have to be strictly speaking bi-directional on the client side we will write the code in JavaScript and on the server side we will use flask socket IO one of the underlying implementation details is that when using socket IO both the client and the server receive messages as events so think of events as buckets or mailboxes when we write the code for sending a message we also specify which event bucket is the message supposed to go to and whatever message the server sends the client or the client sends the server through socket IO it will be received by the specific event it was intended for there are two types of events the first category I'm calling it predefined events that's not an official name by the way in this there are basically four events connect/disconnect message and JSON these are four specific types of events and from the name itself you might be able to guess what each event does the second category are custom events we can give custom events whatever name we want and they provide a high level of flexibility will be seeing examples of both predefined events and custom events let's start writing some code first we have to install flask socket IO like we did in the previous videos we will use pip to install it I'm in the folder that we created for this application and I have activated the virtual environment the syntax is pip install and then the name of the extension which is flask socket IO okay so we have installed flasks socket IO and it's dependencies now let's head over to our application file what we have created so far is a user authentication system with a registration page a logout page and we have connected to a database to store user credentials we have intentionally not thought styling at all styling is something we will take care of just before deployment to figure out how to use flask socket IO we refer to the official documentation so I have this page opened already we scroll down to the initialization section this is what we need to add to our code back to our application file based on the documentation we know we need to import socket IO from flask socket IO from the documentation we know flask socket IO requires a secret key and since we have already initialized the app and we have set a secret key right here we don't need to do anything else the next step is to instantiate the socket IO class and pass in the app so let's do that right here there is no magic formula to this the only way we know how to do this is to refer to the documentation of flask socket IO I will leave a link below to the flask socket IO documentation page so be sure to check it out next step is to define events for the server side remember each time a client sends a message it needs to reach one of the event buckets as I call it so let's just add these event buckets at the bottom of the file let's add it right here so how do we create an event bucket or event handler the syntax is somewhat similar to the flask routes we have used so far so we use a decorator symbol and then socket IO dot on inside brackets we put the name of the event and we will use the event message if you recollect message is one of the four predefined events and we write a function to tell fluffs socket IO what actions we want to take this is similar to the way we have defined routes so far let's call this function message this function will receive some message or data so let's call the parameter as data if client sends data to this message event bucket what do we want to do for now lets us simply print the message to the terminal we'll add a couple of line breaks so that's easier to spot it in the terminal while printing it to the terminal is okay for testing but that's not all that useful so what we can also do is broadcast this message the server received to all the connected clients one way to do this is using send the syntax is sent and in brackets the message text which is data let's import sent you so just to be clear what this will do is it will send the message text perceived to the connected clients but remember how we said both the client and the server can only receive socket IO messages in event buckets so which event bucket on the client side will this data go to well turns out send us a special syntax and whenever we use it it will by default push the data to the clients on an event bucket called as message we so far haven't written the code for the client-side when we do it this will be clear before we jump to the client side if you are using socket IO there is one change we need to do to the code below if you have been following along with the series we explained what this line does in one of the previous videos the gist of it is that Python will assign the name underscore underscore main underscore underscore to whatever is the file that's being run as a script or a file that we run directly from the command line since we will be running this particular file directly from the command line the statement will always be true and whatever code we write below it will get executed well we have been using the standard flask development server so far with app dot Ron + socket IO has its own custom drawn method to start up the server which is socket IO dot run again the only way we know how to do this is if we look at the documentation and the author provides excellent documentation for this now if he add debug equals true here what this will do is restart the server every time we have made a change to the file now that we have done the basic work on application dot PI file next let's work on the HTML file for chat but before we start working on the HTML file it's a good thing to have a rough idea of how the elements of the page will be placed it'll make it easier when we later on style and format these pages the way I see this page it will have a navigation bar at the top and then below it will be the main section inside the main section there are three parts the largest of the three sections will be for displaying the message at the bottom will be the place where the user types in the messages which will appear in the display message section on the left hand side there is a sidebar which will show all the rooms that are available so in this project we'll be segregating the conversations into different rooms now that we have a rough idea of the layout let's create chat dot HTML file so let's see the file structure inside templates folder this is where we have saved all the HTML files will create the chat file here the layout of this page will be completely different from the templates we have created so far since this chat page will be a standalone page with a unique layout I will not bother with creating a layout template for this will straight up write the HTML for this we start with a standard HTML file I'm using atoms so I can type HTML and press tab it spits out a basic HTML code let's head over to the body section if you recollect the intended layout of the page there will be some sort of a navigation bar at the top so let's leave a placeholder for that then there is a main section so let's create a div main section and let's change this to an ID inside the main section the entire left-hand side will be a sidebar for displaying and selecting rooms we haven't defined any room so far so this is another placeholder I'm gonna call it a sidebar then we have the right hand side panel I'll just change this to an ID we have a section for displaying messages and we also have a place for typing in the messages let's put an input box here with a unique ID I'm gonna get rid of name and value for now and placeholder will be type here and autocomplete is off next we add a submit button since we want this button to be clickable so the type will remain as button we want to give it an ID so let's call it send message and the button text will display send so let me just add some comments so it's easier the first one is navigation bar then you have the room selection sidebar the whole thing is the message area one part of it is display message and the last part of it is input message so this is the skeleton of the page we need to do one more thing we have to load the socket IO library by adding the link here let's go to the flask socket IO documentation page and grab the link let's copy this line and paste it here that's it for the HTML file next we work on the JavaScript file for flask socket IO let's put the JavaScript we are going to write for socket IO in a separate JS file we have seen the syntax earlier URL underscore for and then the name of the folder the JavaScript and CSS files are by default placed inside a folder called static and to keep the static folder organized will keep the JavaScript files inside a subfolder called as scripts and let's call the JavaScript file socket IO okay let's create the file so let's open the folder structure the JavaScript file the CSS files by default all of them are placed inside a folder called static and to keep the static folder organized we will keep the JavaScript files inside a subfolder called scripts and inside this let's create a JavaScript file called socket IO GS one thing I should clarify right away we will be using plain JavaScript for this project jQuery would have been easier however this is a beginner level project so we will stick with plain JavaScript let's add a standard JavaScript event listener to load when the Dom content is loaded we will use the arrow functions from Atma script 6 this is just a standard way of adding an event listener there's nothing fancy about this or anything unique to flask socket IO first thing we do is create a variable which has instructions on how to connect to socket on your server let's copy this from the documentation page so we copy this line right here so this line is basically a set of instructions on how to connect to the socket IO server on the client side that's all the setup that's required next we can create event buckets one of the first events we'll create as a predefined event called as connect when socket IO connects it automatically triggers a connect event in flask socket IO we saw how to define an event bucket on the server side in JavaScript the syntax is socket dot on then the name of the event which is connect in this case and use an anonymous function connect event will not take any variables what do we want to do when the client connects to the server for now we will just send a message to the server so the syntaxes socket dot sent and then the message text which is I am connected if you notice over here we haven't specified which event bucket in the server will this message I am connected go to well just like we saw on the server side when we use send it will automatically send the message text to an event in the server called as message this event handler that we created right here before we test all of this let's define the message event for the client the syntax is similar to the one we used for connect socket dot on and the name of the event which is message the parameter of the anonymous function this will be the message text so let's call it data what we want to do when the server sends a message to this event pocket for now we will console.log it message received and then the actual text message by the way just a quick note these are back texts these are not single quotes before we can test this we need to make one quick edit to the application file for the chat route let's head on over to the application file and let's scroll to the chat route so this is the chat route first of all right now we just sort of building and testing the chat functionality so we don't want to bother with logging in every time so I'm gonna comment this out where it checks whether the user is authenticated this is by the way just for testing purposes we need to remember to re-enable these lines once we are done before we deploy it instead of having this route just return a text let's have it return the chat dot HTML file we just created all of this should be familiar syntax to you we have seen this a few times already ok now we are ready to test our link let's head on over to the terminal and start the server let's copy this URL and paste it in the browser let's quickly register a user I'll call it user 12 will login the user now if we go to the javascript file called socket IO GS when the client connects we sent a message to the server saying I'm connected and which event bucket does this message go to that's right because we are using sent it would have gone to the default event in the server called as message let's go to the server so this is where the message would have arrived once it receives a message what does it do it prints this data that it received which is the text I'm connected it prints it directly to the terminal let's see if we can see that so that is the message which says I am connected this part seems to be working correctly what else does the server do aside from printing it to the terminal it also uses send to send this message to broadcast this message to all the clients which are connected now which bucket does this go into since we have used to send this message text bit says I am connected it went to the event pocket called as message on the client-side so let's go and see the JavaScript file this is the message event and what does this file do with the message event it prints the message to the console so let's go to the console log we can see that this is a message which was received let's head on over back to application dot bye aside from sending data to the default message event bucket like we have done here we can also send data to custom events to do this instead of using send we would use Emmet what Emmet allows us to do is specify the event bucket we want to send the data to before we can use it let's import it the syntaxes Emmett and then the name of the custom event let's create a custom event called as some event I could have called it anything and then the message text the message text could be this is a custom event message what happens here is whenever this message event receives data so whatever is the data that the client sends it it's gonna do three things it's gonna print it to the terminal it's gonna send it to a predefined event bucket called as message and it will also send to the clients event bucket called as some event this message text so it's gonna do all these three things let's jump to the client-side and write the code for this event bucket the syntax does not change from what we have written earlier its socket dot on then the name of the event which is some event then let's call the data we received as data and for now let's just cancel off the message okay so let's see this in action I will save this file I will also save application dot pi so let's refresh the page so you can see that the custom event bucket called as some event received data we emitted from the server and at console logged it so this is the message that we see right here let's make this chat application more useful as of now if you notice we're not making use of this input box nor are we using the sent button so the first thing is the ability to send a message by clicking on the send button right here we will head on over to our JavaScript file so let's add a standard JavaScript event listener for clicks to this button right here I'm gonna add a standard event listener for clicks to that button let's check what the ID of the button is I'll go to our HTML file and this is where we define the button when I'll copy the ID and paste it here so what is the event we are listening for we are listening for on click she'll use an anonymous function and on click we wanted to trigger a function which grabs the text in the input box and sends this text to the server going back to the browser whenever I press the send button I wanted to grab this text whatever we have typed in here and I want to take that text and send it to the server so let's do that again this is standard JavaScript this is not related to flask soccer are you in any way document dot query selector so let's get the ID of the input box I'll go back to the HTML file this is the input box right here I'm gonna copy this ID and paste it here and we want the text or the value which is inside the input box okay let's go to our application file and see what happens when this message is received by the server okay I'm gonna comment this out we don't want to keep printing it to the terminal we also don't need a custom event here so I'm gonna remove this so now when the server receives data in this message event bucket all it does is it takes the data as is and it sends it to all the clients let's go to the client side and see what we can do with the data that we received back from the server back to socket dot IO this is where the message will come so rather than display the message received in the browser is console the way that we are doing it right here let's display the message received on the screen itself so I'm gonna remove this now a word of warning since we are not using jQuery for this tutorial we would have to write a few additional lines of code first we create the paragraph element let's call the element B and document dot create element and the element we want to create is B let's create a line break and I'm gonna call it BR and syntax is the same as the one we used for para element next let's set the inner HTML of the element to the message text so where do we get that from that is this parameter right here called as data so the inner value of the paragraph tag will be data finally let's append it to the area where the messages are displayed so how do we do it again document dot query selector we need the ID of the area where the message has to be displayed so we go to the HTML file and we crab this ID right here and paste it here and we want to append this to the para element to be created okay so let's test this we'll go back to the browser refresh the page so we can see the message we had set for the connect event appearing now let's try testing one two three let's try one more okay so no surprises there now these messages would be a whole lot more useful in a chat application if we knew who was typing the message so we need to figure out a way to append the username to each of these messages so let's go to application dot by and figure out how to do this okay before we talk about sending the username to the client we need to figure out how and there is a username saved and how do we retrieve this value if you're watching this video as a standalone piece then you need to figure out how you have stored the username in your application and how will you access it if you're not sure how to create a user authentication system you can click on the link above for part 5 of the video series from part 5 to part 7 of the series we created a user authentication system anyways for those of you who are following along with the series then the username you would remember is saved in our Postgres sequel database and we are managing the session through flask login extension so if you recollect and we had covered this in part 9 of the video series the username can be accessed by the current user object and then we want the user name this will give us the username if you want to refresh your knowledge of flask login basics you can use the link above to get to part 9 of the video series where we covered it okay now that we have the username how do we pass this value to the clients there are several ways to do it one way is to trigger a custom event in socket IO on connect and send across the username the more common way would be just to pass on the user name along with the template this is a straightforward method so let's do that I'm gonna cut it from here and we're gonna go to the chat route right here this is where we render the template so along with the HTML file let's pass the value of the username and I'll just paste what I cut from below this variable called username holds the name of the current user and it's gonna be accessible in chat dot HTML file let's go to chapter HTML if you want the value displayed on the page maybe something in form of a greeting we can for example have a paragraph tag like this with some ID and display the username like this ginger will render the username of the current user and then we can just grab this value using query selector so that's easy enough this is the easiest way to do it but perhaps we don't want the user name displayed on the screen in which case we can use plain JavaScript so what we can do is we can use standard ginger syntax to display the username variable and store that value in a constant which could be called anything but I'm calling it username and do note that this is not a single port this is a back deck and you would find backtick on your keyboard generally below the Escape key okay the other thing is some of you might be wondering why did we escape this by adding pipe e like this so this will change any special character in the username value to its unicode values which can prevent unexpected behavior that can be caused if this username variable had any special characters in it this form of HTML escaping is good practice the reason why we are not escaping it here is because be used WT forms and WT forms will always return values in Python unicode strings so if the username had any special characters it would have already been substituted with unicode characters here so that's why we don't need the pipe e for this particular example now in case you did not understand any of it don't worry it's not relevant for now the only reason I covered it is because sometimes people ask me this question all right now we have passed the username value from flask to this template we can now use this value directly in our JavaScript file so let's go to our javascript file and use the username variable since we have declared the variable username in the HTML file in this javascript file whenever we want user name we can just type in username directly let's do something with this username value every time the user sends a message we want this username to be also passed on along with the message text otherwise our chat application will be a bunch of messages and no one will know who's sending what by the way we can delete this since we're not using this connect event let's go to the section where we will be sending the message text to the server instead of just sending the message text like the way we are doing right here we can also sort of send a dictionary with JSON data and this is the format that we use for it so this is the message key and this is the value let's also add one for username and this key which I'm calling as username will have the value of username so this username right here is this constant right here which is the value of the current username okay so this is what we are passing along to the server now let's see how this data will appear on the server side for this we head back over to our application file and I'm gonna comment this back in let's go to the server and type a message refresh the page and let's type in a desk message this is the format in which the server receives a message this is the message text and this is the username so now what's being sent back to the server is no longer a simple message text but you are sending a bit more complicated data format let's jump back to the client-side and do something more with us we need to make some edits here in order to access the message text I will have to say data dot msg and msg is the key which is used right here so this will hold the message text we would eventually want to format the username and the text separately this is a design aspect and ideally we want to complete the functionality first before we worry about the design however for now let's complete this exercise will create a span element for the username so let's create it right here I'm gonna call it span username I could have called it anything and it's a span element so document dot create element and then span we set the inner HTML of the span element to be username and like message text to access the username the syntax is data dot username and this data is this data right here and finally we modified this element right here to also include the username we also add a couple of line breaks let's also add a line break after the message text let's go back to the browser and see how the whole thing works now so let's enter a hollow world you see the user name and then a line break and then you see the hello world now along with the user name and the message text what if we want to add time when the message was sent how would we do it we have already seen with message text on how to send data to the server so it's not going to be a big change to add time there's nothing new to see or learn there now an alternative method would be to append time from the server side to see how we do this let's go back to application dot PI to send the time along with the message text we will use pythons time module there are two functions we need to import from time first as local time and second string for time we will use this to format the way the time is displayed okay let's scroll down to our message event here let me ask you a question how do we access the message text and the username so far we have not been using this data which we received from the client we received this data and we just send it across to the client we are not manipulating this data in any way but what if we wanted to access the message text and the username we can use the standard Python syntax to access the message and the username so instead of just data so message to access the value of the message it's going to be data and then message similarly to access username we're gonna say data and then username now if this is the format to this we can easily add time now before we do this let's figure out the format that we want so let's go to Google and Google Python time module this is the documentation for the latest version of Python so let's use this you this is what we are looking for we can use this to decide which format we want time to appear in for example if I use percentage and the lowercase B it's gonna give us the abbreviated month name percentage D will show us the day of the month now let's say we want the R and the minutes so this would give us the R and this would give us the minutes if you use percentage P since you're not using a 24-hour clock it's gonna tell us whether it's a.m. or p.m. so let's go use this in our application file I'm gonna call this key timestamp and the syntax to display the time is string for time and then present B is gonna give us the abbreviated name of the month - % D the day of the month % I is gonna give us the R and then we put a colon and then present M it's gonna show us some minutes and let's add a percent B which will show us a.m. or p.m. and we want the whole thing to be applied to local time if you have any doubts on this you can always refer to the documentation on Python this is the standard module I'm using there's not related to flask soccer are you in anyway let's head on over to our javascript file to use this data will wrap time inside a span tag the only reason I'm doing it is because it's easier for formatting so when we come to that it just makes it easier instead of having to come back here and edit it again I'm gonna call this element span underscore timestamp and this is another span element let's set the inner HTML for the span tag to the timestamp you received from the server and the syntax is gonna be the same as it was for message and username data dot time underscore stamp and this time underscore stamp is this right here and finally let's append the time to the paragraph element let's go back to the browser let's refresh it and show me the time so there you have it let's try another message do you see the time is also getting updated now the last thing that we will cover in socket IO is the concept of rooms for this let's go back to application PI now to join and leave a room is pretty simple with flasks sake Rio we just need to import join room and leave room let's write events for both join and leave room so we will call the event and join let's also call the function join and it will accept an input let's call that input data to get a user to join a room the syntax is simple we just typed join room and then the name of the room the user has selected so this room variable has to be something we received from the client and therefore we use the Python syntax to access the value of the room this is the same way that we had done it over here for message data and the username that's all that's required to have someone join the room any message that is sent to this room will be received by the user who has joined the room people who have not joined the room will not receive the message when someone joins a room the idly should send out a notification to everyone else in the room announcing that a new person has joined in we can use send for this the syntax is similar to the one we used for the message event right here so the message will be the user the username will be sent by the client so data a username has joined the name of the room again this is also something we received from the client so data and then room and we send us only to a specific room so this message right here will only go to one specific room which is this room right here okay let's also quickly create a event handler for leave the syntax is almost identical to the one we have done for join I'm gonna call the event as leave and the function I will also call it leave they will also accept an input which is data the syntax for leaving a room is fairly straightforward exactly like join room you have to specify which room the person is leaving and this information we would have received from the client we can copy this message paste it here instead of has joined has left the room so that's how you join and leave a room when it comes to room we can also build the application in a way that users can create their own rooms or we can provide predefined rooms second execution is easier and if you understand how this is done we can also easily update our code to allow users to create their own rooms so for the second approach of predefined rooms we need to maintain a list of rooms so let's go create a predefined list of rooms so I'll do it after we have initialized flask sake Rio let's have four rooms to start with large news games and coding if you are pre defining the rooms beforehand like the way we have done here then we need to pass this to the template so this is where we render the chat dot HTML file along with the username value will also pass in the names of the rooms ok we will need to add this to the template so let's head over to chat HTML this is where the sidebars and this is the place we have kept aside just to list out the rooms let's add a h4 so since we are getting a list of rooms we're gonna use ginger syntax to loop through all the names of the rooms it's a simple for loop so the syntax is for let's call it room in the list bitch's rooms let's close the for loop we will display each of the names of the room in a paragraph tag let me set the class as select room now to display the names of the room we'll just use ginger syntax and we want the names of the room to appear in title case what this does is that it turns the names of all the rooms into title case that's it for the template now let's head over to the JavaScript file okay this one displays incoming messages we can get rid of this section since this was just for demonstration purposes let's write the code for a room selection here this is how this will work the user will click on the name of the room on the HTML file to join the room then he clicks on the name of the room he wants to join we first need to check whether the user is already in the room and if he is already in the room we need to show him an appropriate notification if not then the user exits the current room he is in or he leaves the room he is currently in and then he joins the new room the starting point for the whole thing is to listen for clicks to the room name we'll use document query selector all and then we include the name of the class let's get that from the HTML file we will copy this and paste it here for each para tag we want to execute a function on click we create a variable called new room and store the name of the room the user wants to join before we let him join this room let's see if the user already is in this room for this to work we will need to store the name of the room the user currently is in and we will store it in a variable called as room so we haven't created this variable right now we will need to do it after we write this code this variable room will contain the value of the current room the user is in and this new room stores the name of the room which the user wants to join if this conditional statement is true that means the user is already in the room that he wants to join we can send him a notification that he's already in the same room printing these kind of notification messages let's call it system notification is something that we will have to do a couple of times in this program every time he joins the room we need to send a notification when a user leaves the room you'll have to send a notification so we will write a function for it later which will create the element and append it to the Dom for now lets us create the tag called message and the message will say you are already in the name of the room now remember these are backticks these are not single quotation marks so once we have this variable we can pass it to a function which will print the system message we haven't written the print system message function yet but that's again something that we will do in a bit so what I'm saying is that we will write a function called as print system message and the objective of that function would be to take some sort of a string and display it on the screen for the user then let's continue the logic so if he is not in the room that he wants to join then he needs to exit his current room and then he needs to join the new room to leave the current room we need to send a message to this leave room event bucket in the server then we need to send a message to the join event bucket in the server case so let's go back to our file since we will be leaving and joining rooms a few times it's easier to write a function for it rather than duplicate the code multiple times for now let's just pretend that we have already written these functions so the function to leave room will be called as leave room and then we pass in the name of the current room he is in and that value if you remember is called as room and let's also pretend that we have written a function to join the room and it will take in the value of the new room the user needs to join so that is this value right here I will paste it here and finally we will update the name of the current room - the name of the room that the user has joined ok so we need to do multiple things we need to create a variable called as room which will store the value of the current room that the user is in we need to write a function for print system message we need to write a function for leave room and then we need to write a function called as join room since this variable has to be a global variable let's declare it at the beginning of the file next we need to write three functions one to print sister message another to leave a room and finally want to join the room start with leaving the room which will take in the value of the room which the user wants to be removed from we need to emit a message to the leave event in the server so let's see what sort of data does the function expect this function expects the data that we pass in to at least have the username and the name of the room that the user is exiting let's write the Emmett the syntax is socket dot omit remember because we are sending it to a custom event called as leaf we'll have to use Emmett here and not send if you send it will by default go into the message pocket but we wanted to go into a custom event pocket called as leaf so it's gonna be emit and then the name of the custom event which is leaf and the two values we need to pass in which is username and then the name of the room okay that's all that's required to leave the room now let's look at joining the room the join room function would also take in the name of the room that the user wants to join we use a similar syntax as leaf room socket dot emit and the name of the event the custom event on the server was called join and then just like we did it for the leave room we will pass in the user name and we will pass in the name of the room so this works well when we want the user to leave and join the room but when a user joins the room we can clear the display message section so when the user goes and selects a new room we want this display message section to be cleared so that he can start a fresh conversation in this new room again we can use standard plain JavaScript to do this so it's document dot query selector then we need to get the ID of the display method section so let's go to the HTML file and get it so this is a display message section and this is the ID let's copy this and paste it here and we want the innerhtml of this display message section to be blank okay if you are congregating our user is in two discreet rooms then there is an additional variable we need to pass in both to the client and the server can you see which one is it okay I'll give you a hint it's something to do with this section right here can you see what is it that we need to add to the section that's right when we send a message to the server aside from the message text and the name of the user we also now need to add the information about the room we will use the same format as message and username let's call the Kia's room and the value would be that of the variable room let's also add information about the room on the server side so we go back to application dot by this is the outbound message bucket so aside from message username and the time stamp we now also need to pass in the name of the room so we have seen the syntax earlier this data which is being passed in it will have the value of true and this is how we access it now before we test it let's finish writing the last function on the client side that is the printing of system messages so this is where we use the function so I'm going to copy this let's pace the name of the function and it will take in a string this is gonna be the message which it needs to display first let's create a paragraph tag then let's set the inner HTML to the system message we want to show the user and finally let's append it to this display message section that we have used right here so I'm gonna copy this I'm sorry this should be this is an ID mmm have I made this error somewhere else this was in an ID or a class I think it was a class let's go back and check yeah it's a class let me corrected okay so coming back we want to append this paragraph tag to this ID right here append and then the para element now we should be able to click on any of the names of the room and join that specific room so let's go test this out I'm gonna refresh the page so I can see the names of the four rooms that we have defined right here these are the names of the four rooms all of these names are in lowercase the reason why it appears as title case in the HTML file is because we used ginger syntax to convert the names to title case ok so far so good one thing I will admit up front that the UI for this whole section is absolutely horrendous this is something that we will work on before deployment right now we are just focused on the functionality and we want this app to work the way we want it to work so with that let's make the user join the games room okay so we see the notification if you remember for previous examples this should have been the user name and this is the time since system messages don't have any kind of user name associated with it we see that both the user name and the time the appear is undefined this is something that we need to fix but aside from that the message seems to be appearing the way it should let's see if the user can rejoin the game's room again so it does tell the user that he is already in the games room to see whether we received notifications about a user leaving a room and joining a room we need to log in another user I'll start a incognito window just move it here let me just copy this I'll go to the login page and I will login a user in the previous video we had created I think user 10 and the password was test now we will make user 10 also join the games room so both these users receive the same notification that the user 10 has joined the games room now let's try to send a test message from both sides I'm gonna close the console for now user 12 says games people play okay you see that the message appears for both the users so let's try it from the second users perspective we can see that both the users are able to see this message so let's say this user user in this window says enough of playing around let's get some work done on coding the user goes to the coding room so you see here he got a notification that someone has left the games room and this user who joined the coding room he gets a notification that he has joined the room and as we saw in the games example this notification is gonna go to everyone in the room the entire display message area where he was sending messages in the games room all that has been cleared he can start a fresh conversation in this room this user in this window is in coding room and this user is in the games room so by design if I send a message in the coding room someone in the games room should not be able to see the messages and vice-versa let's test this out can you see this as we expected since they are in two different rooms this user will not see the message which someone else has typed in another room so let's try it out here also is anyone there and no one is there okay the join room leave room and the system notification seems to work as expected for system notification we have this issue of undefined so there are some improvements to the user experience that we can do and I'm not talking about the layout right now to begin with when the user first logs into the application he's not in any room consequently he can't type any messages a better design would be when a user logs in lets automatically log in the user into one of these four rooms we can do that from the client side let's head on over to our javascript file when the user first logs in he shouldn't have to pick a room the user should be able to chat right away to do this let's log users to one of the four rooms let's say the lounge and once the user is in the lounge he can continue to chat in the lounge or he can select another room to do this let's set the variable room to launch and then we can use the join room function we wrote to add the user to the launch so that's the first improvement that we wanted to do the second thing was we need to remove the undefined that comes for system notifications this is the section which displays the incoming message we can make some edits to it to remove the text undefined there appears twice for all system messages we will add a conditional statement so if the data that we receive from the server has a user name key in it then this is not a system notification it's a message which another user has sent to all of the users in the room to do that we will write the conditional statement if data dot user name as in if the data has the user name key in it so this entire thing can go here on the other hand the data that we received does not have a user name in it then it's a system generated message so it would be something like someone has joined a room or someone has left a room for these messages let's use the function we wrote to print system messages and just pass in the message text there will be no username or timestamp associated with us let's go copy the name of the function we wrote to print system messages you so what is the variable that we pass in which would be the message text in this data to access that just like username it would be data dot message so this right here is essentially either this or it could be something for leaving a room let's test this again user connects he's automatically logged into the lounge room we can see that the undefined text which used to come above and below it is gone let's meet the other user also join this room so this was the lounge so over here if you see it still says undefined that's because Google is caching the JavaScript file so to avoid it if you keep the developer console open and you can just minimize it to the bottom and then you refresh it you see that the message is gone so by default Google does cache the JavaScript file let's send a message you can see both the people receive it and vice versa also if the user were to join another room which is coding this is working exactly like we wanted to so if he joined a new room you see the notification without the undefined message and this message area has cleared well user while the user in this window will see the same notification without the undefined text at the top and the bottom we can keep improving this application and so many more ways aside from the aesthetics of it which definitely needs to be fixed if this is gonna be usable but there are still more improvements you can do even when it comes to functionality to make the app easier to use for example every time I send a message this input box does not clear so that's something that we should fix after we hit the send button this input box should empty itself out the other thing is idlyís should be able to type a message here and just press ENTER for that message to be sent to all the other users so these are some of the fixes that we can do I'll show you how to fix these two specific issues let's go back to our JavaScript file first thing is we need to clear the input box after the message is sent so this is where the message is sent and after this let's clear the input area we again use document query selector let's grab the ID of the input message box so this is the input message and this is the ID we copy this from here and paste it here and we set the value to blank next thing we wanted to do was when the user types in a message the user should be able to press enter or hit the return key instead of having to click on the send button we can use JavaScript for this and write the code in this file itself however since this functionality has nothing to do with socket IO at all we will keep this JavaScript in a separate file so let's create a new file will open the folder view let's create a new file this file will be inside the script folder itself and let's call this file chat underscore page dot GS we're gonna need this file name so let's copy it and let's create the file I'm gonna close the folder view so to this we can add a standard event listener which we listen to when the Dom content is loaded let's write an anonymous function it will not have any parameters we write some code here to make the Enter key equate to the click on the send button first we create a variable for the message area we use document dot query selector let's grab the ID of the input box and paste it here next let's add an event listener to check if the Enter key was the last key which was pressed this is just standard JavaScript so I'll just write the code the event listener will listen for key up we want to prevent the default and check whether the key code was 13 this is the key code for the Enter key and if the last key up was the Enter key let's have the JavaScript click on the send button so again it's document dot query selector we need the ID of the button so let's grab it from the HTML file and this is the ID of the button so let's copy this and paste it here so what we want this to do we wanted to click the button what this entire chunk of code does is whenever the user presses the enter key or the return key it will send the message to the server without having to click on the send button for this to work we need to include this JavaScript in the HTML file she will include the custom Gia's file here the syntax we have seen earlier its script and then source URL underscore for the file that we are looking at is inside a folder called static and inside static it's inside a folder called as scripts then the name of the file the name of the file we can see it from here it's chat underscore page dot GS let's go back to the browser and test this okay so we don't seem to have broken anything and the input area is emptying out after we depress the message and the best part is we can just hit the enter key and we don't have to do a tab enter or take the mouse and click on the send button again there are lots of other changes that we can do for example when I switch rooms I still can't start typing it I need to come here and click inside the box before I can start typing this again is needlessly painful for the user this can be fixed by adding an auto focus attribute to the input box so this way the user doesn't have to click inside the input box every time he joins or leaves the room we can do this both from the HTML file or from the JavaScript itself we have done previously for the t HTML file let me just show you how to do it using JavaScript this is the function where the user joins the room he joins a room here then we clear the input message area after this let's put a auto focus on the text box its document dot query selector and then we need to get the ID of the input box let's grab it from the HTML file this is the input box let's copy this paste it here we want it to be in focus we will refresh the page the input box is highlighted automatically and we can type in without having to click the input box let's switch a room let's go to the coding room again you see I'm in the moment I switch a room the input box is automatically in focus and the user can type directly there are lots of these incremental changes that we can make to our app to make it more intuitive to use and improve the overall user experience this is going to be a never-ending process we would look at the analytics for this app how people are using it we're already getting stuck and we keep testing we keep running a be tests and multivariate tests to figure out what is the best possible experience we can deliver from this app at least from a functionality perspective this is all that we want the simple chat application to do now let's talk about styling when I started this video series my initial thought was to go through each line of CSS and style element on the app but a lot of it is just trial and error a lot of it as value judgment in terms of what looks good so I'm not sure how much value will be added by this iterative exercise of trying to figure what sort of styling elements should be used I'll publish the CSS file online so you can apply it to your file too so here's the deal in case you're not sure of any of the syntax that I have used let me know in the comments if I find time I'll make an entirely new video just to cover that particular aspect or maybe I'll do a general video on how I go about styling a page at any rate the entire code along with the CSS file is available for download I will leave a link below I've already applied all the changes to the app and this is what the final app will look like in the next video we will talk about the final part of the project deploying the application on Heroku if you found this video useful please hit the like button subscribe to the channel and share it with your friends let me add all the changes that I have done stop the server and commit the changes add socket IO functionality that's it for this video the next one the final one we will deploy the app and Haruko see you in the next video
Info
Channel: Sandeep Sudhakaran
Views: 24,675
Rating: undefined out of 5
Keywords: flask-socketio, chat application, flask, python
Id: zQDzNNt6xd4
Channel Id: undefined
Length: 66min 0sec (3960 seconds)
Published: Thu May 09 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.