Build a Secure Realtime Chat App in React Native [3] (tutorial for beginners) 🔴

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
it's friday sorry what hello everyone what's up how is it going welcome to a new live stream and today we're gonna continue uh the build that we started previous week and we are working at the signal clone so if you missed it i'm gonna introduce to what we managed to build so far and in this video we're gonna work on some bonus features on some uh features that we have never touched and a lot of you have asked me to cover so what exactly i'm talking about first of all i'm talking about emojis how to send emojis how to display emojis um how to have this emoji picker for sending messages than sending images in a messenger application this is a common feature in most of the applications that have a messaging feature so i think that it is very important uh for us to know how to implement this feature what is what is involved in this how to pick an image how to send it how to store on the server how to visualize it on our end for another user and so on and the last advanced features for from today's video is sending audio messages this is as well a very important feature because it involves again multiple parts you need to record the audio you need to translate it somehow you need to send it to the server save it there and then on the other part of application to download the audio and play it so in today's video we're gonna cover all of that and by the end of this video you will know how to integrate these features in your application so if you're new to on this channel hi my name is vadim welcome here i'm a full stack developer for over seven years i have experience working in startups and as well working in big corporations like amazon and more recently i decided to share all my knowledge and all my experience with you guys here on youtube so if you find the videos that i'm uh doing valuable please consider subscribing to the channel turn on the notification bell not to miss any future videos because it takes me a lot of time to to prepare everything to put everything together and to present it here live so um if you are planning to follow along which i highly recommend don't just watch this video but try to actually do it yourself you'll need a couple of things first of all you'll need the asset bundle which contains the dummy data images this pdf presentation and much more and you can get it on assets.notjust.dev signal the link you can find in the description below and what else you will need an aws account and amplify cli installed because our back end is using amplify all right so this is the third video in our signal series if you didn't see the part one and part two i highly recommend starting from there in the part 1 we have covered the ui and in the part 2 we have covered the back end so if you are interested only in back end start with at least the part 2 it was full of features uh so you'll enjoy it however yeah it's possible to start from uh from this video as well what you have to do is to clone the repository that you can find in the description below as well uh install the dependencies uh you need to deploy the application on amplify try to find it on on their documentation how to do that and after that we can start from the same point alright so um with that being said i don't know let's get started what do you say [Music] hello everyone in the comments how are you doing today where are you joining us from thank you ricardo so this project is what we can say a full production ready clone this project is um contains a lot of critical features and systems so it's close to production already but it's not there yet like there are some features that that are small maybe sometimes they are boring but they are crucial for for having a production-ready application for example let's say paginations how you will load when there will be like a thousand messages in the chat you'll need some extra logic to just query the first first 10 messages then to query all the hours and like other systems like in-app notifications and push notifications as well as analytics uh testing and stuff like that uh these are advanced stuff that we are not covering in this tutorial uh and this stuff we are covering in the course that i'm working on the course you can join the waiting list following the link in the description in the course there we are building like a very end to end like we're covering all the edge cases we are covering much more features and systems like pagination as i said like filtering searching in-app notifications how to deploy to market how to do testing and so on all right make a discord clone uh thank you all for that suggestion maybe we'll do it updates on the course um working hard on on the course of the one module is filmed the second module with react uh fundamentals is planned i have a application already now i have to film everything and to edit all right so guys let's have a look at our application what's going on there and uh oh my god i almost peeled my coffee all right so let's let's first of all have a look at what do we have so when you where is it okay that's an issue that you will also have is good i'm gonna show you how to solve it so uh if you just clone the project make sure make sure that you're working on it check out on the back end branch or at least you are starting from back end so this branch will contain the code that i'm using to start now because the main branch will be updated in future so once we are here we can um we can do npm install to install the dependencies and then npm start to start the server i already have a dependencies installed so let's let's see it here and let's try to run it on our simulator okay and we have an error uh the issue here is um if you'll see it says that duplicate file or mox and it's coming from somewhere where is it from the back end yep this is the first mock like amplify backhand and valver1 is in another path uh so yeah this is a common issue and what we have to do let me open my notes because [Music] there is no way to remember how to fix these bugs uh okay i should do a blog post about this error okay where is it react native so first of all we will have to install a metro config because this stuff will happen in metro let's stop the server and let's install npm install expo metro config and save dev this is a development dependencies dependency and after that we will create a file in the root project not in the source in the root here called metro.config.gs and you have a code there we need to basically back blacklist one of these mocks and in our situation we're blacklisting everything that starts with current cloud back-end so yeah have a look at the code we are just adding a new rule for blacklisting some files from metro and now let's see npm start run ios okay everything is bundling uh bandar is saying this is the first time i watch you live finally awesome what's the time what's your local time yeah are you planning to build these types of projects with flutter i don't have it in my plans anywhere in the near future but i'm planning to do a video about flutter a live stream i had an idea i was almost sleeping and when i woke up and i have an idea i should do it and i took a note do you have a video on how to handle authorization authentication through the life cycle of react native application i don't have a separate video about that but we we are implementing authentication and authorization in most of our application but we have and we do that with amplify so you can have a look even in this signal clone in the previous video we implemented the authentication with um with some lambda triggers in order to add the user to the database whenever he signs up and so on so it's [Music] it's there so our javascript had finished let's try to reload will it work this time yes it does so let's see what do we have here on the um home page we see a list of people that we have already chatted with here when we want to start a new conversation with a new person we can go on this icon and here we will see a list of users that are registered in the application and once we click here we will open the chat room with them so for example if i open a chatroom from here i see all the messages i can send messages here hello yeah everything works fine and also the messages uh are updating in real time so if i have if i was um to open this application on another device which we will do later in the video to show you how it works and i send a message the message will appear here instantly so that's the real-time messaging part of application yeah as you can see nothing is implementing regarding emojis pictures and audio all right so here is our application also the last messages here on the home screen also updates and everything is implementing with the backend all this data is saved on the back end nothing is dummy data here so um all right let's have a look at the first step so the first step is before we get into the features that i described let's first of all uh finish the header in the chat room and here in the header we need to set the name and the image of a user with who we are chatting with because right now this name and image remains hard coded and also it gives us [Music] any issue here so i figured let's better fix this issue to have it done and then we can move forward so first of all uh we need to remove the set options from the chatroom screen let's open our chat room screen source screens chatroom screen and here we have a navigation set option changing the title and this is because of our error here that cannot update component from inside a function body this should happen in a use effect but we are going to do it in a different way so let's delete it from here completely let's save and now we shouldn't see that error perfect now let's um let's open the navigation uh part where we are declaring this header of this page let's do it like this so let's go to navigation folder and in the index folder here we have chat room header advent of a file so we have our stack navigator we have home header and chatroom header before starting starting working at that i would rather extract this component into a separate file yeah not to mess everything here in the same file just to keep everything clean so navigation let's create a new file here called chat room header dot g s or tsx yes here let's uh [Music] let's copy our chatroom header from navigation index let's paste it here and we're gonna have to import some stuff so first of all of course is react from react from react native we will have to import view image text i see what else react native windows dimensions where is it coming from windows is it from react no it's from react native okay and let's take the okay going back here let's import the use window dimensions what else the i can family fever from expo vector icons anything else no i think that's it so at the end of the file let's export this component export chat from header and back in our navigation index we need to import it import chat room header from uh dot like this directory chatroom header i did the save and my auto formatter automatically put everything from a new line here so don't freak out everything is the same so what does it say has no default export yeah because export default sorry we need to export default and here perfect so we are back to what we had before okay so um all right here in our chatroom header we have the image with where we have um yeah the image here on the top is hard coded we need basically to query the user who but not here like when we go inside chat room yeah i'm speaking about the chat room so we need to query the user who are we charting with and put his name and his image here in the top yeah and speaking about this image and then speaking about the this name okay so how do we clear query here uh we need to know something about the chat room here like chatroom id if i go to the chatroom screen uh i see somewhere here fetch chatroom and we are using the route params.id in order to get the idea of a chatroom and then query the chatroom itself so the same way we need to get access to to that route.params.id in this chatroom header because we are on the same screen we need to get access to it so let's go to back where we are using the chatroom header and that's in our navigation index let's see chatroom header is here so the way we do it right now is just sending to the options an object however if we instead of sending an object we send a function we send the function vet will return an object right navigation will call this function that we we defined here it will call with route and with navigation parameters so navigation we don't need but we need the route right we need the route to send it to this chatroom header okay header title so instead of just passing the the component here because in this situation we cannot send any properties to the chatroom header to send properties to chatroom header we need to define them like a separate arrow function that will return this component and now we can do let's say let's send directly the id chatron header will send by d and it's going to be routes.params.id but for arms can be null so it's going to be like this or i don't know null but it it's gonna be null nonetheless so let's send it like this so back in our chat room header in the props we are console logging the props let's have a look in our debugger here to see if we receive this prop the id so let me reload the application select from here iphone 12 and where is it no we need to get into a yeah here so this is the the console log that i'm referring to so the props contains id and the id contains the id of a chat room and with this id of a chat room which we can right away here the structure as id and also we will need the children because we change from props and let's remove here props from the children here okay so we have id children cancel log id so with this id we need to query the chatroom uh users to see who which users are part of this chat room and then to understand which one is us which one is him and to set the image and the name with his name okay so we have this functionality of querying the user and stuff like that we have it in our components where i think in in message or in chat room item yes in chat room item because chatroom item is here on the home screen and we are querying the user and displaying bower user basically it's the same logic so if i go to chat room item here we have the first use effect fetch users it will fetch all the user that have the same chatroom id as this chatroom id and then it will map to actual users and then knowing the user who is authenticated we can find valverde user because is the one which id does not match with the authenticated user so basically we need the same functionality let's remove this console.log because we have a lot a lot of console logs and our logs are a bit messy there so let's copy this use effect going back to chatroom header let's add the use effect let's import this effect from react and use effect uh we need to import data store from come on datastore from aws amplify from here chatroom user from our source models chatroom idea no we don't have chatroom id we just have id but you know what this id can be null so before doing anything sorry i'm gonna check if id is null don't do anything just to make sure that we receive actually non null id authenticated user uh let's import auf from amplify besides datastore here on the top and set user yeah let's define uh the user in our state for that we will need the use state hook we don't need the console log anymore so const user and set user is going to be a used state that can be a user or null and initially it's going to be null initially is going to be null however when we actually get it we're going to set it in state with that user okay i think but no yeah it's good so user user should come from models user user okay so we have a user in the state and that means that now if we change here the uri to user dot image i hope it should work and the same thing for instead of children here user dot name save let's open for example first chat with jeff yes we see jeff's picture in the header and jeff's name if i go back and open with test i see beautiful elon musk there and yeah it works all right so how's it going guys i see a lot of people are joining a big fan from india hello chandra how are you so yeah the first step is done let's commit it i'm gonna open a new terminal let's do git add and git commit this is what chat room header perfect how are you today guys so yeah back here we remove set options from chatroom screen we extracted it to another file we transform option into a function to be able to pass the route uh to the header component and then based on the chatroom id we fetched the users and said the name and the image about the user in the header yes this is done all right the next step uh just joining did they miss anything important no you didn't miss anything important so um yeah for everyone who is joining i'm gonna do the introduction one more time so today we are doing the third episode of signal and today we're gonna implement some more advanced features than usually and we didn't cover these features in any of the previous builds so what i'm speaking about we are gonna do um emojis how to speak emoji how to send emojis and so on and uh yeah the next step is sending images in um in a chat in a messaging application in this case yeah it's signal so everything from picking an image from your device or even taking a picture with the camera then sending it to the server keeping it on the server and went from bower side from power user downloading the image and displaying it in the application all this flow we're gonna cover in today's video and the last step is another type of messages and pretty popular messages that all the applications containing some messaging functionality content have and here i'm talking about audio messages so we're going to cover how to record audios how to save them how to send them to the server save them on the server and then send them to our user to be able to download and listen so we're gonna cover all these uh features and if you just join you didn't miss anything because we um we were cleaning a bit of a project from the previous time and we finished one feature which was header here with the name and the image of a person so right now we are actually starting working at them at our features and we're gonna start with emojis so for this i'm gonna use them like this okay uh will you kind explain me how i can use github personal access token without having to type it every time i make a commit you would have to set the ssh key i know this sounds complicated and every time i have to do it i don't remember it by memory i just type like github set ssh key or something like that and you will yeah you will generate an ssh key on your machine you will upload it to github and every time you will do a commit github will know that it's you but uh today i did the same and github i did the same on a new machine i didn't have like ssh setup so github actually just opened a login page and i logged in and it it saved automatically the token so i guess they they automated this stuff because it was a bit tricky for beginners but i would have to double check okay what database do you use to store the chat sorry i just joined yeah for the database and the whole backend we have covered it in the previous video and for that we are using aws amplify and behind the scenes amplify uses aws dynamodb which is um yeah key value database that can scale to like millions of reads in under like milliseconds so it's a great database it's a bit tricky to work with it if you're doing it yourself i mean without the amplify part amplify will simplify a lot of stuff for you so you don't have to touch it in most of the cases in the previous video we actually touched the database and we were writing directly there from a lambda function but yeah are we going to save the images in s3 yes of course i'm a beginner i started with a tesla which was a success because i could see my app using expo but now i started the amazon app how can i view what i'm developing please help uh so as i remember correctly amazon was with react native cli so for that you would have to set up android studio because android studio comes with an emulator if you are on windows if you are on on mac os you can do it with android studio or xcode to have ios emulator so um on racknative.dev documentation we have an installation guide how to set up android studio and the emulator how to see your application and so on follow that all right so let's let's move on let's move on with our emojis so uh we're gonna use this library called react native emoji selector so let me open it in our here and pm to have it as a documentation uh all right so yeah let's first of all install the library in our project i'm gonna close everything here yeah it provides this view with all the icons where you can select vikings and you receive the icon from like a callback function on emoji selected and using that we are gonna add these emojis to the message that we are typing it also have like search functionality it has um where is it history and so on all right so yeah i think it has installed successfully i have to upgrade my npm but not today so where are we gonna uh add them [Music] however called the emojis we should add them somewhere on this screen but more specifically we should add it in the message input component because the message input component is these at the bottom here on the page so let's open message input component here and what do we have here uh we have uh a keyboard avoiding view for everything and then uh two components on the left we have the input container everything here and on the right we have this button for the plus sign or for the send okay so our icons that we can take from here [Music] emoji selector they should be below our this row so below this row we can add them here can file variable emoji selector yeah because we will import it from the library that we just installed from react native emoji selector let's open back our thing and as you can see it doesn't look very good because it is um uh how is it called a sibling um uh with the button and the input and this input container so we have they form like three columns as you can see on the screen the thing is that we want to display them below both of them so to solve this we will in encapsulate we will wrap our input container and our pressable we will put it inside that view save and now yes this is a row like this let's add a style to our newly created object here styles let's call it i don't know row because the only thing that we need to define there is root we will not root but row we will take the row from the root because now the root should be column and only this view should be row yeah now i can see that it works but we do not display very well we are very there below the screen so for that let's try to increase the size of a root to make space for everything so the height we can set it to i don't know 50 percent save all right now we can see both the the input message and the icons here the emojis okay this emoji selector you can also specify the number of columns you want to have for them for the emojis so if you set to eight it's going to look a bit better because right now they are too uh big there come on refresh do something yes so going back there yeah now their size is a bit better because we have eight of them eight columns okay now let's add the logic of uh showing this this part and hiding it right so we're gonna for that we're gonna need a state variable to know if the emojis panel is open or not emoji picker is emoji picker open very verbose name set is emoji picker open so that's going to be a used state and initially it's going to be false because initially it should be closed we that in mind now based on this variable we can render conditionally our emoji selector so let's add it here so if emoji picker is open then we're gonna render this one in our case we will just not display it so as you can see it's hidden but if it's hidden then our height of the root should be should be back to auto because we don't want it to to take half of the screen without them being opened so for that reason i'm going to delete height from here and we can go to where this row and let's add one more style besides the row by putting them into an array and here is gonna be the second style for the second style we'll need the width so our width depends on the is if emoji picker is open so if it's open we need to have 50 of a screen if it's close it should be auto to take the space that it actually needs so right now it looks good but we need a way to open uh that uh emoji picker right so when should we open it we should open it whenever we press on this emoji on the left side of the input so let's do that where is it i think it's this one right emote smile emote smile so uh to handle pressing events we're gonna import pressable from here but we already have it so let's put our icon in a pressable and on press what should happen it's going to be a function let's do the logic here because the logic is quite simple we want to set easy emoji picker we just need to revert it if it's open we need to close it if it's close we need to open it so for that we will gonna instead of sending a variable like true here because this will work kinda i don't know why because it's not for the row though but it's for our root why didn't you say that save okay let's go back and open it again and if you press on the hmm with not with height volume come on okay now it's good it opens but it will not close it so we need to take the current current value and transform it to the opposite of a current value like this so if i press it again it disappears if i press it opens and just like that we have this emoji picker however if i press on them nothing happens we need whenever we press on them to add the message to our message input our message input is kept in this message state so shouldn't be that hard where is it emoji selector own emoji selected what should we do with that emoji we need to set message current message and to this current message we're gonna uh yeah we're gonna just add the emoji just like that we will we will concatenate two strings because current message is a string emoji is a string so if i press right now yes i see them there and if i send yeah it works and also you can combine them with text so if i do how's it wave something like that if i send it works whenever i send i think i should close this um emoji picker right so when i send a message here send message besides setting resetting the message itself we will set easy moji picker to false we'll just close it so hey there let's add an emoji send yes the message is there the message input was reset and the emoji picker was hidden all right hello summit so all right without realizing we did that pretty fast so emoji pickers are not that hard i didn't test it on android but it is supposed to work i think on the end of this video we will test everything on android so if you are developing this on android then you find an error you know try to look at the end of a video where we test everything and if we see any issues i'm gonna fix them at that point but for now we can do git add git commit minus m emoji emojis all right that vetto's clean thanks nice work thank you you need test cases bro yes unit tests are very important but i'm i'm not gonna spam i i don't want to say waste time but spend time during a live stream to implement unit tests i might have a tutorial a separate tutorial on the channel regarding unit tests um also in the course that i'm working on where we have time to to put everything like to implement unit tests and so on do you have plan to do a zoom clone a zoom clone i think it should be some in my to-do list someone else required it was suggested it hello hi what to use for back end we are using amplify aws amplify okay okay okay what do we have there emojis done oh the next one the next step is to send mess send the images and this feature involves involves a couple of steps first of all we need to pick an image from the gallery or to take a take a photo with a camera right away uh yeah we need to get this image uploaded to the s3 storage we need to then save a message with a url to them to the image in our database and then from our side we need to query this and display it properly in our chat here do upload apps on play store i mean these applications are for educational purpose only so we are not uploading them anywhere as you can guess we are doing signal clone so i wouldn't recommend even to you to try that however the knowledge that you get here you can apply it to build your own applications and if you are asking if i have ever done that yes we have a couple of applications on market one of that was also on the channel the application was built in a live stream of 12 hours from zero to finish you can find that video on the channel and that application is on market actually i have i didn't look at the advert application in a in a long time maybe there are a lot of users where i don't know do you use react native for large large projects yes i use um react native for my startup which is a huge application used by more than 20 000 users so yeah and if you're questioning ifrac native is good enough for large projects just have a look here like all these applications um are using react native for their uh projects [Music] okay guys so let's get uh let's get going you mean fitinium is built uh in rock native yes petinium is in react native so for our image picker we are gonna use the expo image speaker we have a good documentation here so uh let's start by installing the library export style expo image picker can i get your email address you can contact me at vadim at not just dot dot oh it's not this one i have two keyboards something like that okay our library is added let's have a look yeah first of all is permissions i i gave the address don't spam please all right so uh as i was saying the first step when dealing with images is to make sure that we have access to the user's images so to do that we are gonna use the image picker request media library permission this is permissions to get images from their library and we will use another permission for the camera itself so uh yeah let's take the use effect from the example and we are gonna do that yes in the message input let's add it somewhere on the top here we need to import use effect use effect we need to import the image picker import image speaker i think we need to destructure it from expo image picker no it's yeah everything yeah import everything from as image speaker from expo image speaker and here what do what do we do here if the platform is not web that means that if it's ios or android we will request this permission on the web will not be able to request the permission so that's why okay i think we will have to request one more permission uh [Music] let's rename it to something else library response and here const photo response [Music] image picker request camera permission yes we need both to be able to pick an image from the library and to access the camera so if library are respawns if library.status is not granted or if photoresponse.status is not granted then we will alert them save and now if we open our chatroom uh nothing happens nothing happens because i was testing the application and i already gave it permission but in in your case um this by doing these requests your application will ask you to give permission and you should press yes so if i would remove application it would ask me again but i think that it's clear like this will ask you for the permission and then you will grant them okay so the next steps here is picking an image let's take the example from expo and let's go here and i don't know let's say image picker everything here will be about the image pick image so result is awaiting image picker launch image library async media types uh no i want media types only images for now allow editing i don't know maybe aspect and quality yes and then we will see the result set image set image yeah and after that after we picked it we will set the url the uri of the image of the local image from the device we will set it in state right but before that let's let's wait a bit okay so console.log result now we need to attach this big image image to to to a button here on the screen so this camera i think we will use this camera for it for uh launching the camera but for them how is it called for the library we're going to use another another icon i think it does fever namos library no no how was the name oh my god image yeah that's good so [Music] now this image icon we will wrap it around the pressable and on press this will call them how is it the function called pick image pick image save so let's have a look let's try to press on this um image icon if i press boom it opens our image library and if i go to our device here to see the logs if i select one oh it allows us to even edit it so choose and this is the result so cancel these false uh and uri it has a uri okay good so when we select it we need to keep this uri in state in order to be able to display it so this result if it's not cancelled set image in state yes let's define this state const image set image use state the url will be a string and initially we can declare it as string word null let's do it like this and initially it's going to be null so we set the image and then and then after choosing the image let's display it somewhere near the input to be able to understand that we are actually trying to send an image to be able to cancel it and to see it and when to send it so for that reason i think we're gonna do it before this row it should be on top of a row yes so let's do it here if image is not null if image is not null we're gonna render something i don't know let's start with just an image and the source is gonna have uri image save but we need to import the image from react native save okay let's try again to select an image choose nothing happens nothing happens is it because our source string is not assignable to type string oh yeah i shouldn't call this capital string the image should be lowercase string like a javascript primitive and right now choose no it doesn't work because i think it doesn't have some width and height hundred yeah i think that's good yeah i was expecting that uh because this image is local it will know but it's not in this case in different cases the image knows where we find the height but yeah so yeah we're trying to send this image all right yeah we we can go ahead and do some styling here i don't know we can add it into a view save this view we can give him some style um [Music] styles dot what's gonna be this um image container only one pair of brackets we need and at the end we can also add a button i don't know cancel or something like this let me have a look how our application do it i don't know like this and we have a separate page for it yeah but we can we can add here for example where is expo icons x x or close how is it from indesign or from font awesome yeah this one no and design let's add it here uh and it's gonna be there yeah that's that's okay that's good i'm i'm happy with that so let's style a bit sand image container so first of all it should have flex direction row it should have some margin from other people from everything else around it um it should have a weave not a width let's do a line self stretch to take the whole space and justify content space between to put the bubble part there what else should we add uh how's it called border with one and border color gray light gray and border radius to make it round 10 everything with border rider stand overflow hidden to make that no it doesn't work we will do border radius to the image as well where is it image yeah pretty much okay so whenever we press on this x icon where is it and design style let's give him some margin 10 five five so let's add it inside the pressable and yeah first of all let's add it there and on press we will just reset the our image from state state so we can set image to null as simple as that so if i do if i press here it disappears and i then can choose another one it's displayed here yeah it's good i will do margin vertical because i don't like it it's not a line here now it's better oh yeah i can remove it i can pick another one choose okay all right okay okay okay so the same thing should happen with our icon with an icon that takes a photo so if we look at the image picker here what's the function name launch image library no launch camera yes it's launch camera on moment on momento so um peak image and barber think will be called take photo so it's going to be quite kind of a similar that result but why result is led but not const i don't understand why their examples are wrong okay let's await image picker dot launch camera sync and here we can give some options so media type as well we can take only image and let's set the aspect ratio to four by three quality should we set the quality i don't know and at the end like the result is similar so if result is not cancelled we will set it to state the thing is that my emulator does not support oh we need also to attach it there so our peak image here for for the camera icon we need to do pressable on press equal take photo and yeah camera goes here and the emulator at least ios emulator says that camera not available on simulator on android it should work as far as i remember but i can also test it on my device let's see if it works so i'm going to open expo go expo go hey um havaid let's hope i said it correctly it depends where are you from come on open the application it's loading so let's see okay opening project come on why is it so slow meanwhile while my application is being loaded on the phone to be able to test this uh image picker let's uh update our backend to support these image messages because that is going to take us also some time so it's better to to do them in parallel not to waste any time time is precious so if i open where aws let's open aws and let's go to aws amplify signal clone and let's open our admin ui here admin ui [Music] so first of all we will need to add a new um module to our amplify which is storage because we're gonna use this storage to save these images in cloud to be able to be accessed by anyone i mean by voter party in the chatroom so to do that we simply do in our console amplify ad storage amplify add storage let's have a look and we're going to select the content type which has like images audio video that's basically what we need images and audio and possibly video please provide a friendlier name i'm okay with this default name you can give it a friendlier name to be able to easier find it in aws console who should have access only authenticated users and we should be able to create update read delete uh no i'm not gonna let them delete do you want to add lambda triggers no uh successfully added resource locally so the next step is to do amplify push okay let's do amplify push hi view hi e l m c so yeah are you sure you want to continue yes we have created the storage module meanwhile uh come on hello vladimir thank you very much you too hi hi gufam yeah while we are waiting here to update i don't think we can do any more tasks in parallel on one side we are waiting for the application to load on my device to check it here we are waiting for it to upload to cloud uh regarding the prices there is a question regarding the prices of amplifying um yeah the amplify and aws in general has a free tier and it's for most of the services they have a free tier basically like for example for cognito which is responsible for authentication we have a free tier of around 40 000 you active users per month so i think that's pretty nice and then the charge of per each active user which is a couple of cents per month for each active user so we we did the calculation in another video and it's not that much all right so our application has finished we have added our storage and besides storage let's look at our data here and we see that the message contains the content which is string and this is the we have a string the message itself like the text that we want to display here but right now we're gonna add two different types of uh content so there are two methods to to solve this issue i mean to improve this to message type to be able to handle different types of messages like text audio and image whichever we add come on if ever we add the type here and the type will be either message it's going to be either image or audio or war where we can add i don't know separate like image uh separate field for each of them like image and audio and in this case i think this is better because in this case we can send an image with some content at the same time basically an image and underneath it a comment like a text by saving them in different fields yeah so let's go with that the content is required i think now that we are able to send images and audio the content shouldn't be required so let's uncheck is required from the content image is a string which is a url to the image that we will save to as free it's also not required and audio as well audio is a string basically it will be a url to a file on s3 and as well not required uh image audio yeah probably that's it so let's press save and deploy and deploy and yeah this is going to be deployed in a moment okay so um let's have a look at the amplify amplify docs amplify dogs where is it for react native and libraries and let's look at the storage library it's pretty straightforward to work with storage library and there are two things like uploading files with storage.put and then you give a file name and the content and then downloading the files with storage.get okay have you ever used neo4js no i haven't heard about it now uh i wanted to say now that i'll have more time i might look into it but i'm not sure if i have more time nowadays yeah i'm i'm spending a lot like all my free time and all my non-free time on building the quarters that is going to come pretty soon when it's going to be available thank you i have created similar app with chat features but biggest struggle now is using push notification remote where i need to run background service to check for new messages [Music] so in our in my application at vitinum for push notifications we are using um firebase push notifications because we are not using amplify there so that might be something that you want to research i don't know if that will help yeah so right now let's uh continue with uploading the image to the storage using storage.put okay where is it so we have big image take a photo i'm gonna close them like this okay so on press this is the function that is called whenever we press on this blue button on the action button you check if the message exists it will send the message but before that we should check if image exists image we should send image send image which we're going to define in a moment and here is elsie if image does not does not exist we'll send the message so send image let's implement it here const send image a sync okay so we know the uri of the image that is where we we saw it basically the image is still local on our device i don't think i'll find it somewhere here but we know the uri of it right so before uploading it to yeah here it is so it's file users and so on and cache and until the image itself so based on this url first of all we need to fetch the data transform it to a blob and this blob we will be able to send to our storage because we will not be able to just send a url we will send to the storage the actual image so for that i'm gonna have a new fetch image from or just get image blob is a sync if we will work with the image you arrive at we have instead uh in the get image so if it's null i'm gonna do nothing i'm gonna return null actually otherwise otherwise so first of all let's fetch the the image and i think we need to await oh wait and then the blob is going to be response as well a weight response dot blob and then we can return this blob so in the send image here const blob equal get image blob but again but we are checking it i mean we can have here like to be sure that we will never call it with a new image we can check it shouldn't happen but still okay so now we can work with our storage uh it's gonna be a weight storage dot put here a file name test dot i don't know png and the blob as the second parameter think storage was imported not from where i needed i need it from amplify here storage save storage put test png will it work i don't know let's try i'm gonna select an image choose it's here now if i press on this icon but this icon should where is vika this button has a send icon only the message is true but i need it to have if message is true or if image is true yeah now it's send so let's press send let's have a look in our console anything happening uh in a single statement context no i think that's from the previous one let's go in our amplify admin ui storage here and let's open our bucket by following the link here and let's see if the images are added yeah we have a folder public i'm gonna public and in republic we have test.png and it has 35 bytes and if i download the image let's check if it's the actual image could not be opened could not be opened yeah something is not good there uh two to two because i was looking 35 bytes is too little oh we need to wait because get blob is a thing so wait we were just okay let's give it one more try okay send let's update the page and is it more than 33 35 kilobytes yes it's 13 megabytes and now if i download it if i open boom it's that image okay perfect um what's the catch here uh the catch is that whenever yeah because i'm using test.png we are always replacing the same image so that's a very bad practice basically everyone will see the same image and whenever someone updates it all the images in application will be updated to solve this we can either give here a name a random name but random name even if it's random sometimes it might you might generate two random numbers two similar random numbers and in that case you again replace the same image to solve this issue there is a package npm which generates like kind of random numbers but they are they have a timestamp inside them and the timestamp is always like unique and yeah like if you can look here so the first part is the timestamp then this is i think the machine code address family yeah the last part is the host id so by doing this ids you are making sure that your image names will be unique and you are not overriding them so where is uuid npm let's install that package real quick okay let's do it npm install and we're gonna import this version 4 of uuid somewhere on the top here and if we go back where is it yeah here instead of test i'm gonna switch to this template string to be able to do like this uuid v4 and this is a function call and now if i upload it let's have a look in our folder we should see now two objects test and vapor1 and if i do it again i should see it another one because it's another image but it's not finished yet so one more time yes it's a different one so by using this uid we are generating unique names for the files uh you should take care of the sizes of the images i saw the image is 13 megabytes so don't forget to resize it somehow in the application or on the server that's a good point so uh you can either decrease where is it picking you can probably decrease the quality here like if i'm gonna do 0.5 here that will so let's pick another image basically the same choose send so now it's only six point five one megabytes but this is not this is like an easy solution but this is not the best approach because you are blindly cutting quality in half so if it's a very high quality image it's still going to be heavy and if it's a very low res image you're still cutting it in half a better approach is to post process the images on the server once they are there so you can do that there are services like [Applause] for image i don't remember the name of a server for videos i'm using media convert atv new media convert convert file based content for broadcast and multi-screen delivery so by doing that uh the the flow will be the user uploads the image to s3 for the 2s3 storage when there is an automatic event happening that will trigger a media convert job the media convert will take it and will optimize the size of the image or in this case and speaking about videos more it will save it back on the s3 and it will serve that optimized video or content to the users so yeah that's a good point all right what's going there let's uh okay can we compress the images yeah that's what i was talking about right now so these are the two options okay so our image right now is uploaded to s3 right now we need to send to save a message with a url to this image and to send it to to that user basically to this chat room the same way as we are doing with messages here the same way we should do with [Music] the images once they are uploaded to s3 so to do that we should remember to pull the changes because we updated our data structure and we didn't do amplify pull so let's do amplify pull yes and by doing that we will our data our message will have a image field so we should fill that in and it's going to be similar to sending a message so let's have a look at send message send message let's copy everything and go to send image cost result this result will contain the key let's do a console log result to see what data it contains so uploading a picture choose and send result come on object key yeah it has a key basically it's the same name as we gave to the file here uh i'm not sure if it makes sense to to take it from the result here where we can access it just by saving this name to a variable but let's take it not from from key here key is declared but these values that were used okay so send message first of all we take the user new message new message content so as i was saying this way we are sending both a image and the content at the same time so content is the message image is image is the image basically images image user id is that one chat from id is this one update last message with this message oh but if message is nulled if message is no let's say oh come on no we're going to keep it as if if it's null it's going to be null it shouldn't be replaced with anything else and at the end at the end set message let's put this logic into a function called reset fields reset fields i'm gonna do it somewhere here const reset fields because we call this in two places and it has multiple things to reset for example if set message we need to reset emoji and also now we need to reset the uh set image after sending it we need to set it to null so reset here is reset field for the send image and where we send the message as well let's do reset fields save okay back to yeah oh our image is not image our image is key our image is key right so let's let's try it i don't know will it work reload did the yeah my changes has finished pulling what's going on here why i don't have messages expo goal yes let's go here and let's try to send an image look at this send let's wait a bit the image to upload we can add some visual feedback all right so our message is sent i see only look at this message however if i go to amplify admin ui to the content to the content come on i should see let's select messages content should be something look at this this one and the image column has this image the only thing to do right now is to actually display it besides them the text message okay let's see where we can display it i think it's in the message message tsx this variable is not use my id we already removed it we implemented it the right way so let's import what let's import image from here no not image i mean you can do it with image as well but you will have to first download the image from s3 then after downloading it displaying it in the normal rack native image however aws amplify has this s-free image but i'm not i don't remember it's not from here it's from aws amplifier black native import from because it's it's react native yeah s3 image i think that's how it should be called as free image so this basically is similar to a normal react native image however we can give it a just a key and based on that key it will know to take the image from s3 to download it and to display it so let's go here above the text we will have a condition if message dot image is not null we will render the s3 image with the source i feel that i'm not doing it correctly to be honest with a key not the source with a key [Music] message dot image save and giving some style style i don't know for the weave we can say a hundred percent let let's try with a hundred percent i'm just curious if it's gonna take a hundred percent of the message box and for the height height or we can work with some let's just try with a normal height to see if it works where is that is it here any [Music] uh let me check if at least it has it so instead of content i'm gonna do image yes it has it that means that i'm doing something with the s3 image just to test it with 100 height 100 yes with thank you is it like this i hope so it means with the which d let's have a look at the documentation i feel that i'm doing something wrong as free image all right oh it's image key not key yes because key is a property from react native so we couldn't use just key they did the image key is your web api on aws yes it's on aws using aws amplify yes it's there it's there oh my god i'm so excited uh so for the weave i was trying what a hundred percent and i'm thinking if this will be maximum 75 percent no no max with [Music] doesn't want to work like that but 70 will dimensions help me or some flexbox some flexbox magic um flex one no it should be a line self a line self stretch uh align self no doesn't want doesn't want okay not gonna think too much i'm gonna do [Music] with use window dimensions we've and it's not going to be full with that i don't know 70 percent of it yeah now it's better so instead of height can i keep the aspect ratio aspect ratio of three over four or four over three i don't remember aspect ratio is it three over four or four over three i think it's four over three and does it also have a cover mode no does it inherit set the result yeah resize mode it has it's gonna contain contain does it contain everything cover to test if it does i'm gonna do here four over four yes it contains and if i do cover it covers which means that this is perfect um some somewhat some style what to the image margin but no not margin top it should be vice versa here does it have style margin [Music] 10 no it doesn't have a style i can put it into a view come on come on come on style uh margin bottom 10 yeah like this all right so here we have our images um what did i wanted to try i wanted to try it on my device right reload jazz there is one more thing that i want to to implement when uploading the image to the server i need some visual feedback to see that it's indeed uploading to do that there where message input send image here yeah the the toughest part is to upload the image to storage and this storage.port can notify you on the progress change if we look in the documentation storage so the progress callback this is storage put to track progress of your upload you can use progress callback it's weird uh so progress where the third operation is our options and let me have a look at the here storage boot config any let's define this progress callback function const progress callback equal and it will send us what it will send us the progress and we can use the amount of progress loaded and the amount of progress total let's have a look in the console here and if i press send anything happening send come on uh refresh i can't manage to run the application on my device come on nothing is happening we do not receive that updates let's have a look i can move the progress call back here but i don't think that's the issue progress callback yes yes good so we see that the fraction like how much how many bytes it uploaded from the total amount so based on this information we can keep in state a value called const progress but this is going to be in percentages from zero to one uh where one is a hundred percent set progress use state 0 let's not forget to reset it here we set fields set progress to zero progress callback here we're gonna do a set progress to this value loaded divided by total so by doing this if loaded is going to be equal to total this division is going to be equal to 1 which is a hundred percent and that's actually what we need okay now let's do some visual ui feedback i'm gonna do it somewhere near this image like a like a loading bar here on the bottom probably all right image pressable [Music] let's [Music] let's add them into a view no no no no no i want this to be from here to here so it can be between these two it's going to be a view with some style we're going to close it right away views with some style so the height is going to be a couple of pixels like i don't know three pixels and the color is going to be the color the background color of course background color uh to the color yeah this blue come on where is it here and the weave is going to depend on the progress so it's at 50 progress is going to be with 50 let's just have a look how it looks there so it's on the top let's do a line self flex end will it work yes this moved it to the bottom i want to increase it to five pixels uh add some radius everything with right just looks better border radius five and and i need to align it to the left by doing margin left auto will it work come on no it's still in the middle yeah because yes because we have here this container has space between for that reason we will add it into another view that will span the whole thing by having a flex one flex one will make it span the whole thing and we'll do justify content flex start align itself no not flex and no no no okay i'm not going to do anything here flag start and align align self flex and to put it on the bottom flexbox master yes it's there yeah okay so now we need to set instead of 50 we'll do here a template string like this and we're gonna say progress progress multiply by a hundred so from zero to one we will map it to zero to a hundred if i press send now the file is loading slowly but boom and it's there so now we have some visual feedback to see how how the image is sent if there is no image i see here that we display them [Music] some space here which is not very nice so i can do this i can do this message.content conditionally will it solve that issue text rings message content transforming it to a boolean no because why because why if message content oh because we have here margin bottom 10 margin bottom depending on the message content again so if it has it's going to be 10 otherwise it's going to be 0. yeah this is better hello here is a beautiful picture sand some loading stuff going on there and yeah it's there perfect all right so sorry guys for not checking the chat focused to make sure that this is working in a moment we're gonna have like a five a couple of minutes discussion i really want to make it work on my device because i always put it to download i forget about it the screen closes and i lose it but it's very slow like it's 0.15 percent downloading okay let me try to close everything oh my god do you also have so many apps open or is it only me so expogo let's try can i upload videos like this the way you did with pictures yes it's basically the same so the only difference is to make the difference like if it's a video you need to render it not in a s3 image but in a video player but the uploading part is pretty similar because in the uploading part we have the only the only thing that is different is that come on in the pic image and take a photo we said that we want only images but if you set it to wall it's gonna take the videos as well you're gonna be able to take videos as well and when setting them the extension have a check like if it's a video it should be mp4 or something like that this and if it's an image it should be png or better just based on the image uri get the last part which contains the i cannot make it work come on come on come on what if you had used activity in the kendra instead of to show progress yeah that's also possible but with activity indicator i mean technically it's it's possible but from a ux standpoint an activity indicator doesn't show you as a user how much should i wait more like what's the progress is it just 20 and i have to wait like three more minutes or is it like one more second so this progress bar will show you how much is finished and how much you should wait so from ux standpoint it's better to do it like this um jake jake jake jake let me try to find your first question to to be able to understand what's not clear so uh one moment how do you bind the id from the auf table to the separate database okay that's a good question um so yeah as basically we how to explain it in an easier way our lambda function will be triggered by cognito every time a user confirms confirms his account and when cognito triggers the lambda function cognito sends as a event variable data about the user basically here is the user who has just signed up then in in our lambda function if we go to the back end where we implemented it function source custom in the event we will receive this user attributes the same user attributes that we can get using the auf module in our react native so by taking this sub uh we we save it is in the user id so event request user sub so this is how we bind the id in our database with id in cognito authentication i don't know if that made it more clear but come on expo please i want to show to the people how we can chat together how we can send the images tunnel let's try something i get distracted and i lose the progress here it's like a game uh question of a subject but i'd love to see some live video chat features in the application regarding live calls i mean video calls and audio calls i think that's going to be a separate project or even in signal but it's going to be a separate video i also want that i still need to do more research to be prepared for that to try and test some libraries but yeah a lot of people want that so expo please oh uh someone suggested an interesting feature timeout expo sorry for that we have internet what's going on i think it's better yeah the suggestion from me is coming is to see the message loading in the list of messages above above because you may want to type something while the previous message is uploading that's also a possibility like um but i think that will kinda i'll have to mess some with some ui there but that's totally possible like you can select an image here you can press send and it will appear right away in the messages here and behind the scenes it will upload yeah that's also a way to do it ah oh good question is it necessary to learn all javascript frameworks like rectangular vue.js or just one i don't see any value in learning all of them it's not like i don't know having badges in military that the more you have the better it is i think it's much better if you pick one and study and master it like be really really good in that in the beginning while you don't still don't know which one you would prefer to work in you can try you can try all of them but like that means that i don't know you'll spend a couple of days in them like maybe a week you'll build a simple project in in a in a framework and then once you understand like which one you like working with then like go all in in that and ignore anything else i know like in the beginning like you have this uh like this fear of okay i'm learning this but maybe this is not the best maybe i should learn that and you look on twitter like someone else is working in view okay let's start with you or someone else is working with angular or flutter or anything and you feel like you need to know everything no like pick something that will solve your problems or i don't know will get you a job and stick to that and once you master it like then you can expand but again like if you know react i don't see the value in expanding by learning um angular because reactant angular will solve the same problem but if you know react and you are master of react expand to mobile development and learn react native or improve your backend skills and learn aw aws but by doing this like you evolve in different directions not in the same one with okay you can do front end with both react angular and view who cares like people just need to solve problems uh yeah we can see yeah i'm not doing anything i'm just trying to run this on my on my device and i cannot manage oh yes i understand why now i cannot manage because i'm not on the same uh-huh but if i will do lan i'm not doing anything important guys i'm just trying to run it here no no no no okay come on please please no update available yes let's go let's go two percent three percent four percent yes would be best to separate the relationship of user table with rest of the table so that in future one can swap out of provider with a different of provider uh the thing is that everything related to authentication like username password and so on has nothing to do it is separate from our users in the database users in the database contain only where is it name image status and that's it they do not contain password and so on they are separate from the authentication provider which is managed by the aws ko nito just cognito so what's going on here what's going here let's refresh it and it's showing here so it's managed by this one signal clone users no users found yeah because it's a different pool signal yeah users they're here so these users with their passwords and so on are different from the database users all right finally finally finally we have it here so i think it's this one let's try uh support okay i'm gonna try to take a picture of what of you guys use this photo hi guys and not doing anything everything should happen automatically on our screen here boom image here it is awesome everything works and i can also do it like this all right so that means that everything is working both taking a picture uh picking a picture from the library sending it saving it in our database man i cannot do looking dope i cannot stop doing that oh my god okay so um man it works images like uh how is it called emojis i can chat with myself that's that's the best i don't need friends oh for that okay okay how can you use your project now in your phone i can use my project on the phone because i'm using expo and xbox has this expo go application you can find the expo goal on the market and by having expo go application you can run it you can see all the projects here and you can run it and it runs the development project so basically if i change something in the code it will automatically update on my device here you just made your mama proud thank you so what do we have there man this this application oh my god it's like take it adjust the designs and you have a messaging application go compete with whatsapp and signal and everyone else thank you pankaj he is following your spotify clone but on changing song up crashes on unloading the song can you please tell why it might be happening oh can you please ask the question on on discord tag me there i'll try to follow you i'll try to follow up there because right now i definitely don't know why it's happening with it all right so what do we have we can safely do it and did we implement everything related to image uploads did they promise something that i forgot to implement to test or something image upload okay hit commit not status commit okay now let's make encryption yeah i was thinking about encryption but [Music] for encryption i think we need a separate video because we have one more feature that a lot of people were asking about this is audio messages audio messages so yeah this is the third type of messages in our application and um here as well like we need to do a couple of things like it's not that straightforward first of all we need to record the audio when we need to be able to play it locally before sending and after that we will send the audio i mean we will save out the messaging as free storage similarly to what we did with the images and then uh sending the message with a url to that audio and on the other side of the device we will be able to play the the audio with audio player similar to this will you hide light box light box light box light box light box what's light box light box light box this i don't know okay so shall we get started let's do it oh let's drink some water don't forget to stay hydrated [Music] and let's start so for audio for audio messages we are gonna use expo av this is a library that handles both audio and video it handles both recording audio and playing audio so we are going to use it um for yeah for for for both recording the vowel the message and then playing it so let's start by installing this library expo ava and expo install expo av sang is asking do all the history text get loaded at once or do they get paginated they are paginated i think at somewhere at 100 or something like that so they load the the last x messages so if you want to implement pagination you would have to query the next set of messages okay lightbox is a kind of pop-up model when you click on the image oh you mean like for [Music] like zooming in and stuff like that it didn't plan that and didn't plan that but let me check i didn't know about react native react native light box yeah it reminds me of lightbox here uh okay yeah it makes it full screen you are able to zoom in and so on interesting is it hard to implement navigator setup we'll check like if advan will have time we might do it because it doesn't look that difficult but when was it updated last two years ago interesting i think it works no uh seems to to be working i don't know we'll see we'll see what else is there okay so we installed expo av we installed expo av uh what do we need there let's close everything to give a break to our pc okay where is it example video playback api no we need an example for see audio documentation recording example no i am okay should be somewhere here playing sound okay but we need the recording sound yeah so as we see there is a function start recording and stop recording in the start recording it will also request some permission for the microphone so let's grab this permission and access it i mean require request that permission when the component mounts just to simplify our code there so in components where is it message input component let's open it the same place where we are asking for media and stuff like that let's do it for this one okay we also need to import audio from expo av request permissions audio audi whoa yeah uh and let's grab vest start recording and stop recording functions in our application okay image picker let's close everything regarding image picker and then add here code for the audio start recording okay requesting permission now let's delete these two lines for reconsol log and request permission um set audio modes yeah this is for for ios and here is where [Music] the recording is starting start recording const recording audio recording create a sync with a high quality okay also we need to keep the recording in state so let's define that state variable right now let's close everything our component is getting out of the hand like it it's a lot of things here at the end we will try to refactor it because it has already oh my god 350 lines of code it's a lot it's a lot and the bigger component is the harder it is to maintain and upgrade so we need a state recording set recording use state and the value of the state is going to be null or something and that something is argument of type recording yeah it's a i think it's a recording type that can be imported from here does it have it has no no audio dot recording yep are you using a thing storage not in this project okay so start recording recording started okay and stop recording before doing anything here in the stop recording i don't know why they are not checking if recording is not null because it might be in some cases i don't know so if recording is null stop here i can do this stop here set recording to null await recording stop unload sync uri recording get uri and here is the uri all right so we have two functions stop recording and start recording uh based on very example so you know what i can do where is our microphone outline here so if i open here our microphone outline is recycling here so let's put it inside a pressable so so far in from pressable we were using the event listening on press this is like the click event however here we want to hold our finger on sorry sorry for that we we want to hold our finger on them on this icon and while we're holding we need to record when we release the finger we need to stop recording so there is this event on press in and it will be fired when we start pressing and when we start pressing we need to start recording and when we on press out when we stop pressing we need to stop recording stop recording stop recording and also based on the if we are recording or not we can change the icon itself to see if something is happening so we can say if recording then it's gonna be just microphone not my and otherwise microphone outline we can also change the color i don't know so if record recording it's going to be a red otherwise it's going to be that grey save so let's try uh press it turned red and i i'm holding right now with a click and if i release it it stops and if we look in the console ignore all the errors start recording recording started stopping recording and it should also show us the url of recording right where is it stopping recording recording stop should do this but it doesn't weird if i do it again okay recording stop and stored at file this one good good do you know if he takes on paid project at all unfortunately at the moment i'm not available for paid projects [Applause] i have too many projects on my hand and too many pro ideas for this channel so my focus is full time on this one all right so we have our recording of this file let's let's what let's say let's see how to play it let's see the example of playing it so sound create a sink and then the sound itself okay okay so let's from that url let's create a sound using let's load the sound to be able to play it yeah it's like sound then we [Music] we load it when we stop recording and then we will be able to do play a sync based on some events there so let's stop recording sound await audio sound instead of require because this is a local file we can send here a uri and yeah this uri all right uri if uri is null we can stop execution here and then we will set the sound in state to be able to later on play it so let's do const sound set sound equal use state audio dot sound or null or null and initially is going to be null okay we have a sounding state now the same way as we are doing here with this image oh my god it became so much this image here but yeah after the image or even before the image no after the image let's scroll a bit it's here before this row we will we will display some kind of a player to be able to listen back to the message and if you like it to send it i don't know if that's required or we should just right away send it what should we do should we do similar to our photo like first you see it here and then you send it should we send it right away now i think it's better to first of all check if you like it although i feel that the application are simplifying this without this extra step okay so if sound exists um then we're gonna display here a view with some what sandy image container something like this as well style and inside here i'm gonna have a play button um from expo icons play button play think from yeah let's take it from fever as well fever play let's record something and it's here yeah perfect that's good that's good send image container doesn't it have some padding oh no okay i'm gonna declare some separate stairs for it uh send audio container what do we need there we will need margin vertical we will need some padding um let's do some with border as well putting 10 is too much oh it's good and what else and probably that's it space between yeah if we will add some stuff there we can do the space between a stretch basically everything let's close the image here so we are focusing on the sound right now uh play okay let's let's put it in this play button in a pressable okay and on press when we press play pause sound because it will handle both playing and pausing so const play pause sound we can do here sound dot play a sync we can check if sound is null we will return and we don't need the question mark if we have this check let's have a look uh one two three one two three um i think the microphone here will not work i'll have to test it on my device but what will work is displaying another icon if we are playing the sound another variable as paused yeah set post use state and this is going to be true because initially it's supposed so true um if the sound is paused we are going to play it and we are gonna set both pause to true to false false otherwise we are gonna stop very sound and set it to true sound pause but we also need to wait here wait wait and let's do it here set pause and it should be a sync okay so if it's post we will play it otherwise setting it to true and true okay and here the icon name will also be different depending on paused should be play and if it's not paused it should be pause so let's have a look one two three one two three if i play its viking is changed if i pause it's back it's back so this one i don't like this yes okay okay like this what else does the sound have audio sound loaded key i'm wondering if it has how to get the length of a sound or is it the status let's check the documentation sound await sound greatest thing set is enabled set audio mode audio sound on playback stat on playback status update we will need this on playbooks playback status update if we will want to show a similar progress bar of how much of a sound we we have heard but before that let's let me try to run the application on the device and see if we are able to lo to record the sounds so one two three one two three sound test something is happening or not no i think i need to refresh it i think you have to ask for permission to access the microphone yeah that's what we did in um our first use effect here audio request permission this is for microphone permission vadim who why are not using opacity for buttons the attachable opacity i use the pressable just because it's more flexible for example it has this on pressing on press out let me check the audio message here one two three one two three sound test and let's play it the thing is i you cannot see what's happening on my screen but the audio is recorded perfectly but when i play it it's not from the speaker it comes from the yeah from the earpiece one two three one two three sound test yeah everything is fine but it comes from here so i was debugging it and is searching for an uh solution for that and actually the the bug is weird because it's happening because of them where is it it's because of this allows recording in ios because it's set to true the thing is that it should be set to true to be able to record it on ios but because uh because of this it will the sound will come from the earpiece so to fix that we will set allow recording ios to true here and when we stop recording where do we stop recording when we stop recording here we will set the allow recording ios to false and this is supposed to help and the sound should come from the speaker waiting for the application to load here alex alex alex are you home all right so let's try to record another audio one two three sound test sound test and if i play it one two three perfect it works it works um what there are it works like but still there are a lot of things missing for example we play this audio it plays until the end and then it remains like in a playing state it doesn't stop so you you should manually stop it so let's let's try to take it step by step and implement different features here so one of them is this progress bar that will display uh how much of a sound it played this will help us to see here on the display like if it actually plays or not because on emulator we are missing the actual microphone feature so we don't know if anything is happening when i play play or pause but that progress bar will help us understand the progress bar will be quite similar to where is it in the image that loading thing let's try to do it from here so in our sound we have the below pressable we can add this one but this one will be will display the line no i'm going to do it a bit differently you know i want to render a lot a gray line that is always going to be on the screen so let's do that and then like a little dot that will move so yeah let's start with that style let's do styles dot uh audio progress background and then yeah and i need two double co brackets so let's define the styles for this one are the background so it should have a height of somewhere i don't know five pixels um flex one or a line self stretch background color light gray okay um and some border radius to make it round everything round looks better five is good or maybe three yeah i think three is better and we should put them in the same line with that thing with that send audio container send audio container flex direction we are missing flex direction from send audio container to put them in the same row and this is going to be flex 1 instead of stretch yes and here we need to align items center to vertically center the line yeah this is better and i can add some margin ten not two yeah all right okay then then we will have uh a what inside this one we will have a simple view style styles dot out dio progress let's say foreground so that's gonna be a dot of i don't know five over five or ten height 10 border radius 10 um background color this blue where do we have it [Music] save and let's do let's position it absolute not to mess with anything around it so position absolute and top i'm gonna move it beat like minus five i'm not sure i remember the top minus value on top or any minus value might not work on all devices but it depends i will we'll test it on the android and we'll see if it works because on ios i see that it works okay what else and now with our left can i do left fifty percent yes left fifty percent we'll put it at the middle and left one hundred percent we'll put it at the end so with this left we can um yeah update how much of the audio we have played so let's go ahead and create a variable cost audio progress set audio progress it's gonna be use state zero so with this audio progress we are gonna go audio progress foreground and let's add here one more style that will contain the left parameter and it's going to be audio progress multiplied by 100 because in state we're gonna call zero to one here we need the percentage and then we will add this percentage sign one two three one two three one two three okay it's here so uh now back in our documentation for audio there is this function on playback status update um this function where is it on playbook status update a function taking a single parameter playback status this value defaults to null if no parameter is passed so the av document for details on the functionality provided by on okay on playback status update let's check this reference that we are giving okay playback object sound on playback sets a function to be called regular with av playback status over c below for the details of vcv let's see details of vcv this library is quite like complicated to be honest like it it has a lot of things on playback set status let's find the av playback status to see what values it has this is the structure return from all playback api calls so is loaded error otherwise is loaded okay progress update interval millisecond the minimum interval no duration the duration of the media in milliseconds this only present if a media has a duration position the current position of a playback so by position and duration we can understand we can understand if uh yeah by these two we can understand the progress position and milliseconds okay so when we play that sound play a sing here we can send what oh my god back to create no it's here in create a sink first one is source second one is initial status and then is this on playback status update and then is on play back status update let's try to define this function above equal i don't know data let's do console log data to see if we have something data not like this but an empty object object looking here if i play it stop it nothing happens let's try to um drax is asking sir please try to add everything which function on signal i have a question for you did you implement everything that we have so far like from the first video till here i'm really really curious so downloading javascript come on why it's all slow do i have it here maybe reload we're gonna wait [Music] [Music] let's go why so slow all right so that supposedly showed hello i watched your videos thank you very much so going back here let's try to record an audio hello hello recording started stopping uh object is loaded false object did just finish false duration in milliseconds okay perfect we have a lot of things here let's play it and what's happening uh it's position based on position and and and and duration we should yeah we should get progress so um as we are saying in the documentation where is it the playback status will either have is loaded to false and the error or is loaded to true and everything else so let's where is it so how is it called playback status let's keep it status so if status dot uh is loaded but let's let's give it um av audio dot av status no where is it coming from av playback status i need i need to define av playback status so now if i do dot is they can recommend it so if it's not loaded just yeah stay stay here don't go further okay at that point it is a dictionary with following key pairs if the playback object is not loaded it will contain the following key value pairs okay otherwise it will contain everything from here so we can say set progress to the status position in milliseconds status dot position milliseconds divided by status duration milliseconds duration milliseconds and this possibly undefined uh let's do it like this it's either this or divided by one we shouldn't divide by zero by the way or one so if i play right now nothing is happening uh porque no not set progress set audio progress if i play right now again nothing is happening um does it has something to do with the application not updated reload set audio status if is not loaded hello hello hello yes it's going there perfect so it's not very smooth because vaude is very short and this on playback status fires not that often i don't know maybe progress update interval the minimum interval in milliseconds between the calls of okay play is playing look there is a is playing boolean because right now uh how we are we are manually ourself where is it updating the set pause like if it's playing or not but it doesn't make sense because it gets out of sync it gets out of sync and for example at this moment audio has finished but our variable is not updated so in this case i'm not gonna update them manually here when we press a button but i'm gonna do that based on the playback status so set post status dot i don't think it has something like pause but it has is playing so basically it's the opposite of his playing save and now [Music] one two three if i play and then it stops and automatically it updates because we are doing that based on the callbacks that the library is giving us and and i think when it's stopped when it stops we need to unload it or not play sound play a sync okay there is a lot of things here play play uh sync play from position zero can we do that here play from position zero so if i do it one more time it's gonna start from the beginning if i do it one more time pause yeah i mean it can be uh even improved more but we are good with that we can also i don't know save them [Music] uh const audio audio duration and set audio duration you state i know zero and let's do it here in the playback status set audio duration with a status dot duration milliseconds and with that in mind or zero and with that in mind we can display it on the somewhere here after that i know in a text how would you how would you do ration no duration save one two three four okay but uh get duration formatted i don't know because now it renders them in milliseconds but we want to do it like this uh so basically const let's start with minutes minutes equal uh duration how would your duration uh divide it by how much one minute is 60 seconds and 60 seconds is a thousand milliseconds i don't know maybe seconds is our duration uh audio duration the seconds is wait a second no this is okay some math involved the minutes is very remainder of what from this oh my god my brain is tired to explain it so if this is yeah a thousand very no not the remainder actually not the remainder it's the whole values then seconds seconds audio duration the remainder from the minutes basically we take out the minutes and then everything we divide by 60 and then merely and we don't need milliseconds but not by 60 but 1000 will it work i don't think so so let's return the minutes and seconds get duration okay one two three four five six okay but we need some floors and i think we're good and here math dot floor and here math dot floor will it work meth that floor okay zero four okay okay uh and for the seconds i can do two fixed to fix two no two two two to two to precision two no no [Music] okay um i will do it with some magic so if seconds is less than 10 then we add zero in front otherwise we don't add anything so zero zero four one two three four five six seven come on should be more come on zero dot eleven perfect okay now we display also the minutes the seconds and if i play it we see it playing okay so everything locally with the sound is finished we installed the xyv record audio play audio now let's send the audio because we still have to do that the same thing as we did with the image we need to do to do to take it and okay ah we do so invest send image here let's copy this [Music] in our i'm getting lost with all these functions it's too much send ah we do so if if what it's interesting how to upload it very image but i think they where is it is it here where is it av expo ava okay so um in case of the image we were working with what with the image uri get image blob okay let's transform this function from get image blob to just get blob we'll see get get blob and we will receive a uri of type string and we will work with vatia right here i'm wondering if for the audio is going to be the same get blob so here get blob image this is in the send image function let's go to our send audio function and do we a url of audio in state you're right great sound no we just save a sound right let's try to do to save it in state as well so many state variables sound uri and set sound uri and it's gonna be string string or null going back here uh if no let's set it first of all stop recording you're right we have it here uh let's set sound uri to this uri okay now in send audio if sound uri or audio uri is null we should return and then we should get blob uh sound uri then storage put the same here we can do it i don't know is mp3 or we can take it based on the sound you arrive i don't know progress callback progress callback when is your lunch break uh until we finish everything with audio there is no lunch break send message let's uh comment this out to check if we actually upload correctly the the sound the audio in s3 so let's call the send audio function in our own press where is it this one on press so if image send image if audio i would your u array sound you alright sound you alright but not only if but elsie we will send send audio okay let's see let's see if something works one two three one two three and okay let's go back and here for our we need the send icon if it's message image or sound uri sound uri save so let's press send let's have a look here i don't know nothing is happening let's have a look in our s3 bucket if we have any sound there we have an mp3 and it's 314 bytes um let me try to do it from my device and then we'll check then we'll check we'll download the sound and we'll check if we can hear anything there and then we can be sure that we saved it correctly beast mode yes beast mode let's go okay intense intense i would say so yeah my application has been loaded and i'm gonna record an audio one two three sound test hello hello can you hear me and let's send it let's check here the second one not with three three four but the other one so not with three three four but this one okay i see that the size is good i really think that it's gonna work mp3 come on play play will you hmm let's try vlc vlc never says no vlc wants to access music okay so no it's bad it's not the sound why maybe because of that ah tata [Music] [Music] maybe it's not with the same with blob as we did with with the image hmm or is it because of um one two three sound test hello hello now that's coming from my device but it should be here as well easy because of a file extension can it be because this one is key av if you're recording so let's try to refresh one more time and see if it works so let's try one two three second try second try hello hello send uh did it work this is two four the other one was three four yeah this one three megabytes [Music] now this is png uh where is it i think i didn't oh key a fee 500 kilobytes i don't know let's try to open with with what now i want to open it with vlc yes yes it works just by saving it as key a fee it works i i don't think that you can hear it but [Music] but it works so instead of hard coding that here the extension we can get it from the sound uri so the const extension is gonna be sound your right dot i think it's split by we're gonna split by the dot uh and we are gonna so let's do it like this const uri parts this is going to be an array then extension is going to be uri parts at uri parts come on you're right parts dot length minus one basically the last part is the our extension so if i do it like this then um it should automatically be key few or something like that so if i do it like here hello hello one two three one two three how are you can you hear me send if i go back i should have two kv here i don't even know yeah it's this one uploaded uh three minutes ago and this one uploaded a couple of seconds ago yeah perfect so someone from sevilla is calling me and if it's someone from you guys um please don't especially one when i'm in a live stream and also when i'm not in live stream it's not very professional to call me or yeah i can be with my family where i can sleep and i can receive calls so all right so with that being said we save correctly the value message here now we need to just send the send the message here as not image but how your sound how did we call it amplify admin ui image uri no where is it data and through audio how we do okay and in very set fields we should do a lot of things there reset fields reset fields first of all set out with your uri no set sound you alright what they call it sound not audio sound you alright to null and and also set sound to node so after sending this [Music] and appears there that's good but now we should do the same thing in the message like we send the message but our message component should know how to play it whoo that's interesting um let's think how to we can reuse the same player from here we will create a new folder called audio player let's add the audio player.tsx here react native functional component and let's add the index.tsx and export default from audio player uh so our audio player oh we should take probably everything from here and put it in in there probably something like this okay pressable let's import everything that we will need import oh we're gonna have to work so back in our message input yeah i don't see yeah let's start right away by deleting everything from here because so it's going to be if sound then display the audio player but no you know what not sound if sound you arrive audio player and send where the sound you arrive because we will know the uri okay send it there now let's have a look here what functions are not used get duration for example it's not used here that means that it's going to be used in audio player get duration then whatever function play pause sound okay we can take it from here move it to audio player a lot of things will have to be refactored here i would progress audio duration post and sound we'll take from here audio player i'll do it here we'll put it in our audio player let's import you state from use effect use state what else what else what else the sound as well because the sound is the the deal of our audio player so let's import audio from expo av uh but here the issue will be that set sound we don't need to set sound to null okay where is it on playback status update this thing will also go from here it's the audio player's job all right then let's see what other errors do we have here set creating the sound creating a sound shouldn't happen here we should just set the sound uri in state and then creating creation of a sound should happen when the audio player is gonna receive a new sound uri sound uri so in a use effect whenever we receive a sound uri we will do this const load sound the load sound should be a sync and everything from here will be in the load sound and in our use effect we just call load sound so load sound if sound dot uri is null we will not do anything return otherwise we do create this and the uri will be sound uri on playback status update is this one and we set it in the state styles okay let's have a look in the message input here if we have no i don't see any other errors so let's grab the styles from here and bring them in our audio player and leave only what we need so we'll need send audio container audio progress yeah basically everything except these the last three ones send audio container audio progress background audio progress foreground that's it and from our message input we can delete them audio progress for ground no the progress background we don't need it send audio container and we don't need it because that's going to be the players container all right let's have a look if we still have the same functionality if we didn't break anything let's try one two three one two three can find variable styles a style sheet should be imported from react native save let's try one two three one two three we are here perfect and that means uh one more thing here when we load the audio player we load the sound but when we when this component is getting unmounted we need to unload the sound unload sound and we're gonna do it if sound then do sound dot remove or delete or unload a sync okay so if we send it it's there all right so that means that having this audio player we can reuse the same audio player that we saw here in our message component message tsx uh let's say uh if message dot audio and uh audio player sound your eye will be message dot audio no because message that audio is actually [Applause] is an s3 key so first of all we need to download it uh should we do it in audio player no i don't think it's good to do it in audio player sound uri we're gonna do it differently so use effect where is it message message what's going on so we need to uh the const download sound is equal async okay we will need a state const wait a second let's have a look at the s3 documentation amplify s free because audio can be played from a uri and it shouldn't be local so [Music] download files get a pre-signed url of a stored file you can specify some options storage get yeah this will return just a url so key returns assigned url okay it doesn't actually download but will const sound uri set sound uri use state null and it's gonna be of type string or null sound you alright so in the download sound we're gonna do cost uri equal await storage dot get message dot audio not length but get storage get and the storage should be imported from amplify storage.get okay and you know what all this logic can happen in our use effect so use effect when the component mounts or when we receive a message probably message so if message dot audio then we need to do storage dot get message dot audio audio then we will set sound uri set sound uri null and undefined probably right the object okay we will receive an object with that will have what what will return storage dot get returns an object with a body field of tableau oh if download is true what's going on here set sound uri object or string response and here i'm gonna say if response uh type of oh my god what's going on you know what the easiest at this point is to say any okay so sound uri let's try to give it here to [Music] sound your eye let's give it to the player will it work yes i think it did i think it actually did work i'm gonna do it like this instead of max with 75 percent uh i'm gonna say weave if uh to sound uri then it's gonna be 75 percent 75 percent otherwise it's going to be auto will it work is me no no no no no where is it like this auto you know what i don't see oh because it's the same background color let me now your player no background color white save yeah that's good also and let's see if it actually will will do it so let me go here or here and do hello hello can you hear me we have it send it's there and it's automatically updated and yeah we can hear you vadim we can hear you from the other side i don't think you can hear it but he's there yes yes we can oh my god and yes with that being said we have audio messages how beautiful how beautiful you know in in the case of all the messages we can skip this background to look better but that's not the point i think you can do that as well like the the part that we can send images audio record it send it play it stop it and so on like that's mind-blowing like i'm so happy with how this project turned out so let's do git add git commit minus some audio messages and we are how much timing we are almost four hours in it's okay it's good it's good perfect but we have everything how are you guys how is this part did they plan anything else no we are advanced questions guys i don't think i have power for a very tough question so take it easy i don't know maximum like what's the weather outside or something like that and i have something for for this type of jokes no why doesn't work oh yeah it doesn't work because it's yeah okay never mind are we using aws amplifier just joint yes we have been using aws amplify and this is uh i think the end of signal clone so you have everything ready on the channel you can start from um from the first video and let me show you here in the first video we started with implementing the ui displaying all them um all the users here there is one part that is disturbing me in the first video i told you that if i'm gonna have time we're gonna fix this timestamp here and we didn't do it so while we are talking here let's implement that because i'm not gonna be able to sleep well so in order to transform timestamps to from this form or from any form into human readable timestamps we're going to use moment js this is a library to work with dates so let's install moment with npm moment install npm install moment and then in the docs let's do something from now or something like this manipulate display format time to x time to now time from x a day ago yeah this is what we want like a day ago or five days ago so it's going to be a from b okay and also we need to parse moment all right so let's it is installed let's go in our components components what do we have there we have chatroom item and chatroom item somewhere here displays created at so instead of rendering this one let's do const um i don't know time or something like that it's gonna be moment moment this one dot from now or from just moment or it's vice versa it's however this moment from from now if we call moment like this it will uh get the current date so time let's try it save two hours ago seven hours ago 14 minutes ago two hours ago a few seconds ago perfect so if i go here to the gif which is seven hours ago and say how are you doing how are you pink i don't know and if i go back and if i refresh my application because they didn't implement their should be a few seconds ago jeff a few seconds ago the message is how are you ping perfect so now it looks better it doesn't have like that with stuff all right moment.js is deprecated why instead of moment just use datejust uh mommy.js is deprecated moment just is deprecated is it uh personal weird i don't see it being deprecated but maybe where is what this jazz yeah like the issue with moment just because it's it's quite a large library and contains a lot of uh yeah it's heavy but this one is two kilobytes and it has a lot of stars okay you don't know about that but thank you for [Music] and it has the same things this moment yeah thank you for letting me know about that okay so receive a message at the right top in the home right top considering using moment yes there may be better modern alternative for more details and recommendations please see project status in the docs okay okay okay we have a lot of information here okay we now generally consider moment to be a legacy project in maintenance mode it's not dead but it is indeed done all right thanks for that how is was your time in the netherlands uh i studied in the netherlands so i've been there for what two years and it was nice it was nice i wouldn't complain it was the first years when i started actually doing a lot of stuff on my own i opened my company there in netherlands i was working a lot i had time to party from time to time but yeah it was it was a very good experience okay whatever messages we have here i really want to entering app development can you suggest some good resources some good resources is all the videos on this channel that we have already built and if you finish a couple of projects from the channel and you are ready to take it to the next level uh join the waitlist for the course that i'm building which is going to be published in a couple of months so where we take it to the completely next level to build full stack mobile applications from zero to deploying them to market hi alex and come say hi to everyone will there be part four of his build do you want there to be part four of this build that's the question and what would you add here it's awesome that you made an app in three hours actually it's not in three hours we this is the third video so in total probably that's more than 10 hours but yeah like it's quite fast when you're using the tools that optimize the speed of your development because if i would have to do that uh without amplify oh man like that would be i know at least a week of work hola come say hi hello i'm almost done [Music] and we can start the weekend oh we can sing today it's friday did you use flat list for the home screen yes we did if i were to delete a chatroom from the back end how would i delete an item from the flat list you would subscribe to going back here you'd subscribe to chatroom updates we did something similar in the chatroom screen here we are subscribing for updates about one chatroom you can subscribe to multiple of them on the home screen and check if the operation type is delete then you'll just delete it from the local state and if you delete it from the local state it's not going it's going to disappear from the screen right away what are the prerequisites to learn react native javascript know the fundamentals of javascript and specifically try to learn es6 syntax because in react native we are using like a lot of things like this if you don't know es6 syntax then this looks like uh magic to you uh word destructuring props or like question mark dot or web stuff like this so these are basic simple javascript features that you have to learn and drag native and react just will become easier some people say that react.js is a prerequisite to start learning react native i wouldn't say so if you want to get into mobile development you can start from react native and that's actually how i started learning it and there is no issue at all like you're gonna learn the react stuff together with react native so yeah like it's the same however if you have experience with frag jazz it's going to be much more easier to get into react native but that's the same but that's true if you have experience with react native and you want to go into react jazz it's going to be as well easy because there are a lot of things similar which comes from react so that's the idea we want part four what would you like in the part four leave a comment down below and we'll see i watched uh vadim and learned everything about react native lol thank you i really appreciate that kinda late but came by to say good stuff thank you very much gotta head back to my hackathon what hackathon are you doing right now because we might do something on the channel as well maybe for part four create a group delete a group uh ban people some sort of admin just a few ideas i knew nothing about programming and just watched vadim and you managed to build this project yourself that's impressive like that's with the stuff that impresses me like i've been learning this for seven years and like for some people it takes i don't know a couple of months that's really great all right guys so i cannot promise the part four but i encourage you to let me know down below in the comments uh what would you like to see in the part 4 and if we cover a lot of ideas and interesting ideas that we have didn't cover on the channel then we can definitely do it but before that try to implement everything yourself try to do it yourself everything until this point so i came from gym and you're still streaming go drink some tea yeah i'm gonna head out and drink some tea and probably not only more function in part four yeah i can hear you more specific what functions would you expect all right guys so thank you very much for watching if you enjoyed this video if you find it valuable subscribe to the channel down below somewhere where where like the video send it to one of your friend who is learning mobile development right now and uh yeah see you next week on friday we are live every friday at 2 p.m gmt our usual time so see you then and take care stay hydrated and write clean code and before i leave check out [Music] i always i don't know how to do it this video this video subscribe to the channel somewhere here everything guys thank you i'm tired bye bye
Info
Channel: notJust․dev
Views: 137,391
Rating: undefined out of 5
Keywords: vadim savin, not just development, notjust.dev, react-native tutorial, react native ui design, react expo, react native live coding, live coding, react native auth, javascript, react tutorial, aws amplify, chat app, react native, react native tutorial, javascript tutorial, real time chat app, socket io, programming, react native chat app, signal clone, build a signal clone, signal clone react native, signal clone tutorial, signal private messenger, signal app, sonny sangha
Id: u7NXKu5hbbY
Channel Id: undefined
Length: 239min 45sec (14385 seconds)
Published: Fri Aug 27 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.