Create a Desktop App With JavaScript & Electron

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's going on guys so in this video we're going to be creating a desktop application using electron so electron is a tool that allows you to build cross-platform apps using HTML CSS and JavaScript and if you want to use a front-end framework you can do that as well so there's a lot of really popular applications that are actually built on electron including vs code atom Postman slack and the list goes on there's there's a ton of really popular software built on electron it's actually one of my favorite Technologies so I actually have a course on a udemy course on electron and a lot of this stuff has gone out of date so I'm in the process of updating that as well as some other courses and in that course there's a project called image shrink some of you may have have taken it and built that application you basically just you're able to shrink the file size of an image well some of the packages that I used in that project have gone out of date so I'm replacing it with an application called image resizer which allows you to to basically just edit the dimensions of an image so really simple functionality but I think it's a great project to get your feet wet with electron so this is actually going to be the project that's in the course I might add a couple things here and there when I when I add it to the course but it's essentially the same thing basically we can select an image actually before I do that let me show you I have this bird image on my desktop and if we open it with preview you can see it's pretty large so let's say we want to shrink that to a smaller size we can go ahead and select it and then we're going to see this form with the width and height let's say we want to change it to maybe five thousand not five thousand one thousand and let's do for the height we'll do 600 and down here it's going to show us the file name it's also going to show us the output folder where this is going to be put and it's going to create ate this automatically this image resizer folder in your home directory so if I click resize it's going to give us a message and it also opens up this output path which has the image in it okay and if I were to open this now just to check it out you can see that it's much smaller so now it's 1000 by what 600 height okay so again pretty simple application but I think it's going to give you a lot of the fundamental skills you need to know for electron as far as the main process the renderer process how to create menus and all that and then as far as prerequisites you just need to know JavaScript you don't have to know node.js and and all that as long as you have decent JavaScript skills you should be able to follow along and I would suggest following along maybe grab a coffee or a tea or something sit down and you know spend a little time learning and building this out with me alright so let's get into it foreign so before we get started just a couple things electronjs.org that's where you can find all the documentation which is pretty good so I'll probably reference it a few times and of course you can use it as a supplement or if I don't explain something well enough and you want to read more about it the documentation is pretty good so this is the final repository this is where you can find all the the final code I'll have the link in the description and then we also have the theme files here so we're not going to uh to type out HTML and CSS we can just grab the theme files from here we're going to have of course our main window which is index.html and then our about window and our CSS our images which I believe is just yeah it's just a logo and then the JavaScript here you don't really need it's just basically so you can hit the button select an image and then the form displays but we're going to do all that from scratch and when the time comes I'll go ahead and show you you know what to do here and what to grab now this repository this is the resize IMG package this is what we'll be using to actually do the resize so if you want to look more into that you can I'll put the link to that in the description and then as far as packaging up your app for different platforms you have a lot of different options electron packager is something you could use I believe that's what we used in the course you could use something like electron Forge which is pretty cool but you'd probably want to use this from the beginning by doing create electron app now I'm not going to use this I want to keep this as Bare Bones as possible without any extra packages so if you want to do this it's fine but I'll just be installing electron just directly with npm all right so let's get started I'm going to jump into vs code let me just open that up okay and then I just have this empty folder called image resizer electron and I'm going to open up my integrated terminal if you want to use your regular terminal or whatever that's fine and the first thing we want to do like with many node.js apps we want to just run npm init and this will initialize our package.json so we just want to go through these real quick package name that's good version description I'll just say app to resize image dimensions and then the entry point I'm going to call it main.js if you want to call it index that's fine but in electron we have something called the main process and this file is the entry point to that so I like to call it main.js all right and then author of course you know you can put your own name and then MIT license all right so now we have our package.json now one thing you usually want to add when you're using electron is a product name so let's say product name and this is what will show like when you're on a Mac and you have the pro the the app name in the menu unless you put this it's going to say electron even after you build out your your app so we're just going to name this let's say image resizer all right now we just want to install our dependencies so let's say npm and we're going to install electron and then the resize Dash IMG package and then I'm also going to install something called toastify so it's toastify Dash JS and that will allow us to have toasts or alerts so we can have nice looking error alerts or success messages or whatever all right so now that those are installed let's go ahead and create our main.js so like I said with with electron you have something called the main process and you can think of that as like your like kind of like your back end that's where we're going to do the actual resizing of the image if you were dealing with a database that's where you would deal with your database the renderer process is basically like your UI and and your front end JavaScript so you can kind of think of the main process as your back end and the renderer process as your front end so in main.js right now let's just do a console log we'll just do uh hello world all right and then in our package.json we need a way to run our app and we want to do that with electron so let's create a start script and let's get rid of this and then we just want to run electron and then dot so the home directory with and since I put main.js here it's going to run main.js so let's save that and then down here if we run npm start it's going to run electrons so essentially it's running our main.js file as a node.js process all right and you can see it's just it keeps running it did display hello world because we logged it but to stop this you just want to do command or control C all right so we know that we can now at least run our application so the first thing we want to do in this file is get our main window up and running okay obviously we need something to work with something to look at so let's go ahead and bring a couple things in from electron so we want to require this from electron and what we want to bring in is the app object and also the browser window object so whenever we create a new window we instantiate a new browser window and electron uses chromium under the hood so let's create a new function here and I'm going to call this create main window because that's what this is going to do and you might see this often called just create window but you can have multiple windows in fact we'll have an about one later so I like to call it create main window and then in here we want to have our variable let's say const Main window and set that to a new browser window so we're instantiating this browser window object pass in some options here we can add a title we'll just say the name of the app image resizer and then let's add a width for the window I'm just going to do 500. and then for the height let's do 600 and then outside of that main window variable still within the the function we're going to say main window Dot and then we can we can either load a URL you can even load like Twitter or something in a window but we're going to load a file and the file we want to load is going to be part of our renderer all right so we need to create a new folder and you can call this whatever you want it's basically like your front end I used to call it app but now I call it renderer because that's what it is you have your main process which is you know kind of like our back end and then our renderer process which has our HTML files styling all that so I'm going to create an index.html just add a boiler plate and then let's just say image resizer and then for now we'll just say hello hello world close that up and then in here we want to load that file and I'm just going to bring in the path module to help so let's say require half and obviously you can include any node modules any npm modules into this main process you can't within the render by default you have to use something called a preload file which we'll get to later but in load file let's say path.join and basically we just want the first of all the directory we're in so we can say double underscore dur name and then comma and then from there we want to go into dot slash renderer slash index.html that's the file we want to load into this main window now to call this we need to come down here and there's a couple ways we can do this we could do app.on and we could listen for uh ready you just say obviously can't type today so app.on ready and then we could have a function and we can then load the window or we can say app dot when ready and that actually returns a promise so we can do dot then and this is what you'll mostly see in the documentation so we'll add a function in here and then that's where we want to call create main window so when the app is ready it's going to create the main window run this function and load this file from the renderer so let's save it let's try it out npm it was npm start and there we go so we have a desktop window here with hello world because that's what's in our render in our HTML and as far as the menu goes on Windows your menu obviously is part of your window um on a Mac you can't you guys can't see my menu it's up at the top of the screen and you're going to have just some default values or items like file edit view you have like cut and paste and all that obviously we don't need that stuff so I'll show you how to get rid of that later and how to add menu items in a little bit so the process is running if I if I X out of this then it shuts it down now there are some things that you want to add as like boilerplate code that you're going to add to all your your applications so if we look at docs introduction and we come down here it's basically what we've already done create a window Etc but down here you'll see this app.on so basically we're listening for an event and this window all closed so basically when all the windows are closed all of our application windows we want to check to see if we're not on a Mac so this process platform will show you what you're on and Darwin is what you'll get if it's a Mac so if we're not on a Mac then we want it to quit out of the or terminate the the process and the reason for that is a Mac Works a little differently if I X if I X Out of chrome my icon stays there and it stays open if I'm on Windows and I X then it terminates it so we just want to make sure that we replicate the standard for each operating system and it is kind of a pain in the ass to do stuff like this but in return you get one code base that's completely cross-platform for Windows Mac and Linux which is fantastic so um there are some little you know things like this so I'm just going to grab this little piece of code and let's go back into our main.js and what I like to do since I check for if it's a Mac in a few different places we'll create a variable here called ismac and we want to test the process Dot platform and process platform will be Darwin on a Mac it'll be win32 on Windows and it'll be I believe just Linux for Linux so we want to check to see if this is equal to Darwin okay so basically if you're on a Mac this is going to be whoops this is going to be true if not then it's going to be false and then down here underneath the when ready let's paste that code in and instead of checking if process dot platform is not equal to Darwin then we'll just say if not is Mac then we want to quit all right so yeah that should do it and then the other thing that I want to grab from here is this right here so basically inside the when ready when the app is activated if there's no windows so if the windows length is zero then we want to just make sure we create our main window this says create window but I called the function create main window so I'm going to keep that in mind and I'm going to just copy this and then come up here and that's going to go in the when ready paste that in and I'm just going to make sure I change this to create main window okay so let's just make sure that that still works I'm going to run npm start and my application opens good now one thing you'll notice is when you close out of it this is still running so you do have to stop that as well and I'll show you something we can do so we don't have to keep stopping and starting in a little bit but the next thing I want to do is when we run our actually let's run it again in PM start so we have access to the dev tools we're using this uses chromium under the hood so I can do a command option I and open up the dev tools and just ignore that warning we'll address that in a few minutes but we can toggle the dev tools on Windows it might be F12 but what I want to do is if we're in development mode I want to show the dev tools when this opens so we don't have to keep toggling them so let's do that I'm going to close this out and then let's uh let's add another variable up here and we'll call this is Dev and then we'll say process dot EnV Dot and then we want to check our node environment and if that is not equal to development then this is going to be true okay if it is equal to development then this will be false and then what we can do is go right let's go right above the load file and let's see let's put a comment here and just say open Dev tools if in Dev environment so we'll go ahead and run a check here we'll say if is Dev then we can take our main window and then there's this web contents object with an open Dev tools method on it so we just want to run that if we're in Dev mode now if I go ahead and I run npm start it opens with the dev tools now the issue here is the width of this I want to be able to you know see my application so another thing that I'll usually do is let me just get rid of that another thing I'll do is the width here we can put a ternary and we can say if is dev then let's make this 1000 else will make it 500. that way if we come back down and we run the app again we can see the whole application and of course you can make 1000 whatever you want you can change the width but at least now I can see both the dev tools and the app all right so next thing let's address this keep having to you know every time we make a change we have to restart this and there's there's a few ways to solve this you can use node mon of course I know a lot of you are familiar with that there's also a tool called electron mon that we don't even have to install locally so we can just say npx electron Mon and then dot which will run the main process the main.js file all right now if I were to change something like let's say change the height to 800 and save it just restarts automatically which is nice so we don't have to keep restarting it ourselves so I'm going to use that for the rest of the tutorial if you don't want to use it that's absolutely fine so what I want to do now is add our theme our UI so if you go to the GitHub repo you can go ahead and you can either clone it or download the zip file and you'll have this theme files folder as well as the assets and the assets just has a set of icons so when you if you use like electron packager or something like that you need to have specific icons for a specific platforms and I have those here for you so you don't have to create those all right so we can just bring assets over to the root and then let's just copy folder and then let's see we're going to go to our theme files and basically all this stuff is going to go in the renderer so we can grab all of this and we can just replace the index HTML that's in there so we'll bring all that in and replace okay so basically if we let's just restart our application and we should see yeah we should see the UI here now the JS the script JS I'm actually going to clear this out because we're going to do this from scratch so let's just clear that out for now and if we look at the index HTML basically where we're importing a Google font Poppins we have our style sheet we have our script JS which is our renderer in fact let's rename this you don't have to but I'm going to rename this to render rjs because this represents our renderer process and then in here we'll just change this to renderer all right and then as far as the UI I did use Tailwind style CSS as a custom Tailwind style sheet we have just our logo we have this input with the ID of image that's the main box so that's you know this right here and then we have our form which has a class of hidden and basically in our JavaScript once we load an image we change the display none which is what this hidden class does to display block and then we have our width and height inputs at the bottom we have two paragraphs one is to show the file name so we'll put that in this ID of file name and then we'll also show the output path so we have an ID of output path right now it's just hard coded so we can actually get rid of that and I put that in a comment right here so we can get rid of that as well and save that okay now let's address this over here it says there's an insecure content secure security policy to fix that we can simply add a meta tag there's a link there if you want to follow it and read more about it but easy fix for us we can just do a meta tag and here we're going to do HTTP a quiv and set that to content Dash security Dash policy and then we're going to set the content attribute to script Dash Source because it's we're just saying we want to be able to you know include Source scripts and then also self so self is going to go in a set of single quotes and just doing that should fix the issue all right and then we'll just want to add that to the about HTML as well so I'm going to copy that and in the about we'll just add that here as well and yeah the about page we don't need this this include right here the script I don't know why I kept that there but we can get rid of that the above's very simple just has like the version and stuff like that just so I can show you how to create a second window if you want one all right so next thing we're gonna do is before we start to work on the JavaScript the render JavaScript to select the image and all that because right now if I try to select an image it doesn't do anything but before we get to that I want to show you how to customize the electron menu so again on Windows your menu is going to show like right here on Mac it's going to be at the top of the screen and right now you just see some default options that we don't need we don't need edit copy and stuff like that so what we need to do is create a menu template so we'll go right under the when ready here and let's say menu template and we're going to create a variable called menu set that to an array it's going to have an object in it and what I'm going to do here is create a file menu our file menu item and then that's going to have a sub menu so items underneath it and that's also an array of objects and we want a label here and I'm going to have a label of quit so I want an option to quit out of the application and then here we want to have a click Handler and this is going to be a function so make sure that you add a function here and then we want to call app.quit don't just put app.quit and not the function because what will happen is this will execute right away and your application will just quit all right and app.quit we use that down here as well whenever you want to just exit your your application you can run that and then you can also add an accelerator which is basically like a shortcut and on Windows you can do control let's say plus W on Mac you would do CMD but you can also do CMD or Ctrl plus W okay now that on its own isn't going to do anything we need to implement the menu template let's go up here let's just add a comment just to say app is ready just so we know what's going on here this function create the main window and we're going to go inside the when ready right under where we run run create main window and let's say implement menu so we're going to create a variable called main menu and we need to bring in menu from electron which has a bunch of methods on it to to obviously work with the menu so we can say menu Dot and then we want to build from template pass in our menu template and then here we can say menu dot set application menu and then pass in our main menu now if you save that you should see up top and it's going to be different if you're on a Mac you're going to see file you hit click or hover that and then you have quit on Mac you're going to see the name of the application and in development mode it might just say electron when you package your app up it should say your app name and that's where this comes in this product name that we added early on all right now um and that's kind of how it works with Mac is your first item no matter what it is is always going to be that that app name so yeah and if you want to try it out let's uh let's choose quit and it's going to exit out now if you're using electron mon this is still running down here so you have to just exit out of that and you can also try command or control W and that should quit as well all right so next thing I want to show you is menu roles so file actually has a there's a specific roles like for file for edit Etc so instead of doing this we can actually yeah we can actually take this out and just specify roll and then file menu I think is yeah it's all no it's uh camel case menu that should do it now if we look at that you'll see up top the same thing except it doesn't say quit it says close window so this is basically a shortcut we're using a roll to do the same thing we just did now I do want to have an about window I want to show you how to create a second window and also how to add like a cust another custom menu item now it's different on Macs as you as you as I said you'll have the app name on a Mac and on Windows we will have like file or whatever so we have to basically add two different items for each platform so I'm going to go right above these still in this array but right above this object and I'm going to use the spread operator and then in here say is Mac and we're going to make this a ternary so if it's a Mac then we'll do something we'll have an array else we'll have an empty array in this array we want to have an object and actually this needs a comma after it so in here we're going to have an object and let's give it a label and we can get the app name like this okay because again on a Mac your first menu item is going to be that app name and then we'll do a sub menu which will be an array and I just want to have an about option so let's say label about I'm not going to add the click Handler yet but let's just do that so if you're on a Mac what you should see now is your app name or it might just say electron if you click on that you'll see an about link and then next to that you'll have your now you have your file because that pushed this to you know after the app name so if you're on Windows what I want to have is a help option after file with the about option okay so what we'll do is under here we'll use the spread again and we'll say if not is Mac then we'll have our array else will have an empty array and then in here we want to have an object and let's say label we'll say help and then Sub menu is an array and in here we'll have an object and label is going to be about okay so now if we save that and you run it on Windows you should now see a help a top level item called help you click our hover on that and then you see the about now we want that about to open up a new window so what we can do is up here under create main window we're going to say let's say create vote window and we'll say function create about window and we can kind of copy we'll just grab this actually we'll grab all of this and paste it in and then you want to make sure you change this to about window and for the title we'll just say about image Sizer and the width I'm going to just do 300 because it's really small it just shows you some info so width and height are going to be 300 we don't want the dev tools so get rid of that and then make sure you change this to about window and then we're going to load in the about HTML okay and then down here where we have our menu template and we have our label of about let's go under it excuse me and we'll say click and then we want that to call create about window okay and then we'll do the same thing here so click is going to be create about window and don't put don't put your parentheses because then again I will fire off automatically so let's save that excuse me and then I'm going to go to electron about or whatever app name about and it's going to open up this little window which has just an icon and some information okay so that's how you can have multiple windows now we can start on the the meat and potatoes of this application which is selecting an image putting in some information sending it to the main process using something called IPC renderer and then you know resize the image so so let's go into render.js renderer and from here we want to bring a bunch of stuff in from the UI so I'm just going to paste that in because it's just Mindless typing so everything has an ID we have our image form and if you want to open up the index.html just to check it out so our image form we are bringing in the image input which is right here input ID IMG so we're bringing that in we're bringing in the output path and the file name which are at the bottom so these are spans file name output path and then we have of course the height input and the width input all right so we'll bring that stuff in let's add an event listener onto the image input so we'll say IMG add event listener and we're going to listen for a change event so this is where we load the image so we'll call this function load image and I like to put my event listeners at the bottom and of course you can you know format this how you want so let's say function load image and pass in our event parameter so we have to get the image obviously and when you upload a file it gets put into an array called files even if it's just one single file so let's say cons file and we could either do image IMG because that's the ID that we brought in or we can just do e dot Target because we have this function on an event listener that's on image or IMG so there we can get our files array we want the first item first and only item which is the image okay and then we're going to want to check to make sure it's an image so I think what we can do is come down here and create another function let's say check or let's say make sure uh file is image and we'll call this let's say function and we'll call this is file image whoops function okay and that's going to take in a file and then I'm going to create an array of accepted file types so let's say cons accepted image types and let's do an array and the first one is going to be we can have gifs so we'll say image slash gif let's do image slash PNG and image slash jpeg so those are the accepted types and we just we just want to return a true if it's one of these or false if it's not one of those and we can do that by saying return file and accepted image types and we want to just check to make sure that that it matches so we'll say includes so includes and then we want to pass in from the file that's passed in as an argument we want to check the type we can do that all right so now up here we should be able to say if if not is file image so if it's not one of those accepted types then we're going to want to alert an error but for for now we're just going to do a console log we'll say please select an image okay and this is just a select image this isn't to like submit the form or anything like that and then we'll just return all right so down here let's just console log just to test this out let's console log success okay so we'll come over to our application let's go ahead and try to grab an image so we get success let's grab something different let's see I have um a zip file here and that that also worked see what did I do here if is not file image we have our accepted image types return file accepted image types includes file type hmm oh I didn't pass in I didn't pass in the file yeah and that's we probably need that so let's try that again I'm going to do an image success I'm going to do a zip file and we get to please select an image and we don't get success because it returns all right so we get that done now we also want to show the form which is easy we brought in the form so we can just say style Dot dot display and it's set to Hidden or none by default so we'll set it to block so if we come back and we select the bird image now it shows the form now I also want to show the file name and that's pretty easy we can get that just from uh from the image file name from file.name so let's come down here and let's grab or we already grab the file name but let's take it and let's say in our text and we'll set that to the file dot name okay so that should work if we yep so bird jpeg now I'd also like to show the original width and height of the image so that's not available like on this file it's not something that's just available so there's a few ways to do this we're going to use the image Constructor and the URL object so let's do it right under this check right here yeah we'll say get original dimensions so for this I'm going to create a new variable called image and set it to a new image Constructor and then we can take that image and set source and then use this URL object and this has a create object URL method and we're going to pass in our file then we'll say that image dot on load equals a function that will fire off and then that's where we want to take the width input the value because it is an input so we need to set the value to this dot width and then we're going to do the same thing for height so let's say over here this is going to be height input height input and that should do it so let's save let's try it out grab this bird and there we go so we get the original width and height now to get the output path basically I want to get the the user's home directory and then from there there'll be an image image resizer folder that's ultimately where the the the edited image is going to go now to get that we need to use the OS node.js module because there's a method called home home directory but in the renderer we can't simply do like const OS equals require OS if I do that in the render are just like this it's going to say require is not defined I can't just you know use common JS module syntax in the renderer by default like this so what we need to do is use something called a preloader or a preload script and I'll just go to the documentation here and let's search for preload and you can look this over if you want but I just want to read you this part because it kind of explains it so electron's main process which is our main.js file is a node.js environment that has full operating system access on top of electron modules you can also use node built-in modules such as the OS module that I just showed you as well as anything you install with npm so just it's just node.js right on the other hand the renderer process which is you can think of as like our UI or our front end it runs web pages and does not run node.js by default for security reasons so to bridge electrons different process types together we use something called a preload and then down here they give us an example so what we need to do is use this context Bridge from electron and then we can expose some certain things certain functions in the main world or in the render I think Expose and render probably be better better name but here they're just basically creating uh this versions and then they are including the node Chrome and electron versions using process.virgins.node because you can't use this in the renderer so what it's doing is exposing this to the renderer by using this context Bridge so what we can do just to get started is we'll just grab this and let's go to and of course course you do have to let let your application know that you're using that preload and you do that in your window so let's just copy that for now and then we'll go into our root and create a file called preload.js and then I'll just paste that in all right so remember process.versions dot node we can use this here like we can bring in node.js modules and stuff here and then we're passing it into the into the render I should say exposing it to the renderer but again we do have to let our window know that we're doing that so let's go up to create main window um or we want to go to our whatever our window excuse me window object here and then we want to add web preferences and we can set the yeah preload and we want to set that to our preload file so let's do path.join and current directory and then it's just preload dot Js now since we're using node modules I I found that I had to add a couple other things here such as context isolation set that to true and also node integration set that to true as well so now if I save that we should have access to in our renderer we should have access to versions dot node.chrome.electron right and just to show you I'll try to do this in the renderer use this process here so I'll just do console log process.versions dot node and that doesn't work right process is not defined but we should be able to do versions Dot and then node which I'm sorry is a function and there we go so we get our node version all right now obviously we don't care about these versions that was just an example what I want to bring in here is two things right now the OS module and the path module so let's say const OS remember we couldn't do this in the render but we can do it here and then pass what we want into the renderer and then let's also do path set that to require path and let's replace versions here with OS and then the only thing from OS that I want is the home dur method because I want to get the home directory so I'm going to specify here home dur and I could call this anything actually I could call this and this anything but what I want to set this to is a function that Returns what I want that to be which is going to be os.home dur okay and then for path let's take this same thing paste that in let's change this to path and then what I want from the path is going to be the join method so I'll call this join as well now that's going to take an arguments so what we can do is pass in spread operator with args and we want this to be set to path dot join okay because that's what I want to use and pass in our args here as well now we should have access to os.homeda and path.join in our renderer so down here where we set the file name let's now do the output path so I'll put path and now we can set that we're going to use path.join and inside there we want to say OS dot home der and then in the home directory we'll have a folder called image resizer and obviously you could call this whatever you want actually no this is wrong we want uh output path Dot in our text we're not setting the the element itself so now let's come over to our application let's select an image and now we have the file name as well as the output path which is whatever your home directory is slash image resizer okay so now should we do next let's handle before we move to using IPC renderer and and sending to the main process we'll resize the image let's handle the uh the alerts so we install the package called toastify.js so if you don't have that in your package.json just go ahead and install that with npm now we can't use npm modules directly in renderer just like we can't use core node.js modules but what we can do is go to our preload and we can bring it in here so let's say const toastify set that to require and we want to require toastify Dash Js and then I'm going to copy one of these okay and then I'm going to call this say toastify and then we'll have a method called toast and what we want that to be actually that's going to also take in a bunch of options and then what we want that to call is going to be toastify Dot actually actually it's it's toastify which is the the function that takes in options and then we do dot show toast so normally we would do this like in our if we were using this in main.js but we're just setting this to a method called toast now so let's save that or I should say toastify dot toast whatever you put here it's going to be this Dot and then whatever is here and that takes in options yeah so that looks good now let's go to our renderer and go to where we want to actually use this which is going to be right here however instead of like instead of doing toastify Dot toast here with with a bunch of options I'm going to create two new functions one is going to be to alert an error okay so we'll say pass in the message and then this is where I want to use toastify so we'll say toastify dot toast and then we'll pass in our options here which is going to be an object so the text is going to be set to the message that's sent in the duration because it does go away on its own so the duration will do 5000 milliseconds so five seconds close I'm going to set to false because I don't want to have a close button and then we can also set the style so for the background since this is an error let's set it to red let's set the color so the text color will set to White actually these need to be strings so color white and then let's do text align we'll do Center okay and then the alert success is basically the same thing but just a different color and if you wanted to create one function and pass in success or error that's fine it doesn't really matter but let's do alert success and just change the background to Green so now we can come up here and instead of a console log we'll do an alert error I think that's the only place we need it right now so let's try it out we'll save and come back and let's try to load something that's not an image and there we go please select an image and that should go away on its own in five seconds so now what we're going to do is communicate because obviously we need to send some data to the main.js file so that we can do the the resize and we're going to do that with something called IPC renderer but before we do that let's just create an event listener for the form submission so we'll say form dot add event listener we want to listen for a submit and initially I called this resize image but the actual resize doesn't go on here we're sending an event with some data to the main process to do the resize so I'll call this Send image and then let's put this um we'll put this right below load image say Send image data to main process or just to Main and function Send image now since this is submit we just want to make sure we do prevent default and then let's see we're going to make sure that there's an image there so let's say if not IMG Dot files and that's going to be an array we want the first and only so if not then let's do an alert error and say please upload an image and then return okay I also want to make sure that the width and height inputs are filled in so let's say if if actually you know what let's oh instead of putting in with input height input there let's create a variable of width and say with input with input dot value all right and then we'll do the same thing with the height so height input and height and then we'll check that so let's say if width is equal to nothing or height is equal to nothing then we're going to alert an error and let's say please fill in a height and width and then we'll return all right and we can try that real quick so if I were to choose an image and then leave one of these out I get an error all right so now let's see in addition to the width and height those are two things we need to send to the main process we're also going to want an image path and with electron we actually have some some extra properties that we can access so we can say image dot files zero and then we can access the path so we can do dot path and those are the three things we want to send now like I said to send to Main or centimain using IPC oops oops IPC renderer and that's included with electron however we can't directly use it in here just like everything else so we have to go to our preload and in addition to context Bridge let's bring in IPC renderer and we have to expose that so let's copy one of these and we'll call this IPC renderer and there's two methods that we actually want access to and that's going to be send and on so send and on okay now send is going to take in a channel and the data that we're sending and then what we want that to call is IPC renderer dot send and then pass in the channel and the data and then for on that's going to take in Channel and funk because we pass in a function and we want that to do ipcreender Dot on and then pass in Channel and then after Channel we're going to want a function that takes in event and any other args so that'll be a function and then we'll call func with those args so I think that's correct so now in our render we should be able to use ipcreender dot send and Dot on and actually send the data all right so let's go back to our render and let's do IPC renderer we're going to use dot send here because that's what we're doing we're going to send basically send an event and we can call this whatever we want so let's call it image colon resize uh yeah I guess yeah we'll call it that and then our options our data that we want to pass in are going to be the image path the width and the height okay so now I'll save that and let's go to our main.js now the way that we catch that is using the IPC main okay so we have IPC render and then in here we use IPC Main and then we're going to come down to wherever you know wherever we want to catch this let's just go under the menu template right here and let's say respond to IPC renderer I guess resize so we can just say IPC Main and we want to listen for that event so we'll do dot on and the event is called image colon resize and you can call that whatever you want and then that takes in a function and that's going to have an event and options okay now options should be the data that we send so let's just do a console log of options and when we log this uh what's this ID if you see right there oh you know what I think in the render it autoimp yeah it auto imported this we don't want that because we're not bringing it in here we're exposing it through the preload all right now when we log the options that are getting sent so it's sending right here and this data is going to be the option so it should log down here in our main process so let's try it out say 500 600 resize and down here you can see the image path the width and the height so we know that we're communicating from the render to the pro to the main process okay now there's one more option I want to add on to this and that's the destination where do we want this to go which is going to be the home directory and then a folder called image resizer so I'm going to take that options object and just add onto it a dust and set that to path dot join and then we want os.home dur and then from there image resizer and I don't think I brought OS in no I didn't so we just got to make sure we bring that in to our main we're also going to be using the fs the file system module so we might as well bring that in now Okay so we're adding the destination to the options now what we'll do is call a new function called resize image okay and then we'll come down here let's say resize the image function resize image and that's going to take in our options our four options the image path height width and destination now I'm just going to destructure those so let's say image path um what order should this be in image Pat we'll just do yeah with height dust and then I'm going to have a try catch block here if there's an error we'll just go ahead and log it and this is where we're going to use that resize IMG tool that we installed that package that we installed so to do that we're going to say const actually this has to be an asynchronous function because the resize IMG function is returns a promise so we have to wait on that so let's say const New Path and we want to await on resize IMG which we need to bring in whoops no that should be lowercase so yeah we need to actually bring that in so let's go up top const resize IMG equals choir resize Dash IMG okay so let's go back down here so we're awaiting on this asynchronous function this resize image and this is going to take in we're going to use the FS module so fs and then we're going to use read file sync and this is what's in the documentation if you want to take a look at the resize IMG docs basically we're doing this right here okay so um we want read file sync and then we pass in here the image paths which comes in as uh as an argument and then we want to also pass in an object with the width now the width needs to be a number and it comes in as a string so what we'll do is just add a plus sign to it and that will convert it to a number and then also same thing with uh with the height okay so that will give us our new path our image path then we want to get the file name or create the file name and you could do what you want here I'm just going to keep it as this the same file name so for instance bird jpeg once it's resized it's going to stay bird jpeg if there's already a bird jpeg in the destination directory it's going to overwrite it if you want to call this something else you can but to keep the same name I'm just going to use path.base name and pass in the image uh IMG path and we'll just say this will create file name all right so the next thing we want to create destination folder if it doesn't exist all right so we can do that by first just running a check will say if not FS Dot and then exist sync and pass in the destination so if it doesn't exist then we can do FS dot make durasync and pass in dest okay so that will handle that oops then after we do that we want to write the file to the destination folder right file to the destination so for that we're going to do FS Dot right file sync and let's pass in here path.join and in here we want to say dest and then file name and then we just want to add in here the New Path okay so we're writing that file then we want to send a success message back to the renderer because so that we can you know have some kind of alert but I'll do that in a second the last thing we want to do after that is open the destination folder so that they can see the image so we can do that using shell which is part of electron so right here let's bring in Shell and then let's add that here shell Dot and there's a method called open path we want to open is the Dust okay now to send a success message to the Run renderer we can do main window and remember that web contents object there's actually a send method on that and we don't we don't need to send data we just need to send an event letting you know letting it know it's that everything went okay so we'll say image done now in the renderer we need to then catch that image done and we do that with IPC renderer on remember in our preload we we have send which we already used and then we have on so we're going to put the on hmm I guess yeah I guess we'll just put that right I guess we'll put that here yeah so um or let's say catch the image done event so IPC renderer dot on and it's going to be on image done and then we have a function that we want to run and then it's I mean all we need to do here is do an alert success you don't have to do this but it's good to somehow let the users know visually that it was successful even though that it does it is going to open the folder which you know but it's good to have a message so we'll say image resize to and let's add we can get the width input dot value times the height input dot value and that should do it let's save let's try it out IPC render has it did it again so for some reason it Auto Imports IPC renderer whenever I use it so I'll just get rid of that and let's select the bird image I'm going to resize it to 1 000 by 600 main window is not defined okay so I must have some some stupid thing I did here um oh okay so main window right now is I meant to do this earlier but right now main window is function scoped right if we go up here it's in the create main window function so in the global scope it has no idea what we're talking about so what we can do is initialize it let's say let main window and then we'll get rid of the const here that way it's globally scoped but if we do this we want to make sure that we that this gets deleted after and we don't have you know memory leaks so so let's go into the when ready and let's see we're gonna go Implement menu right under where we implement the menu and let's say remove main window from memory on close so do that with main window dot on and when that's closed so on closed then um we're just going to set main window we're going to set main window to null okay so now we should have access to mainwindow.send in the global scope so let's try it again change that to 1000 600 not 10 000. and just to show you what the image you know the size of the image now before I do this you can see it's pretty big it's 3 000 something with but now I'm going to go ahead and resize we get our message see image resize and then this folder opens we have our bird image and let's open that and there we go so now it's 1000 by 600. okay so again not the most advanced application in the world but this should have given you some good knowledge on electron and the the main process the renderer process the preload script IPC renderer IPC main how to create menus how to create different windows so you can start building your own electron apps all right guys so I'm an idiot I just realized that I have this is Dev set to not equal to development now the reason this has been true for me is because my node e and V is not set at all right now so it's not set to development or production but this should be set not equal to production okay now I just want to test this out right now I'm still in development but let's go ahead and say process dot EnV dot node underscore EnV and set that to production explicitly like that so now you can see the dev tools are not open also the width is what 500 now because it's in production so this is what it will look like once you package it and you know you set it to production okay so I'll have to go back and put a um an annotation in there so that's going to be it I mean to package this up you could use electron packager I'm not going to go through that in this video there's there's a 100 different ways you could package this but then you have to test it on each platform so I'll leave that up to you guys I just wanted you to get familiar with all the different parts of electron but that's it hopefully you guys enjoyed this again the repository will be in the description and thanks for watching
Info
Channel: Traversy Media
Views: 171,729
Rating: undefined out of 5
Keywords: electron, electronjs, electron.js, javascript, javascript desktop app
Id: ML743nrkMHw
Channel Id: undefined
Length: 71min 47sec (4307 seconds)
Published: Mon Oct 03 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.