NativePHP - Desktop Apps with Laravel

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] what's up guys Andre here and today I'd like to take a look at Native PHP native PHP allows you to create native desktop applications using PHP and laravel and all of the tooling around the ecosystem you can think of it as a wrapper around electron but it also has support for bundling your app with Towery which is similar to electron but written in Rust and usually results in a much smaller application size native PHP is another project by Marcel potsiat and the Beyond code team and was just launched at lyricon us be sure to check out Marcel's talk at lyricon which I will link to in the description below so native PHP is still in early stages and marked as an alpha released as seen in the documentation here there are bugs but it's actively being worked on and new versions are being released quickly so we'll take a look at some of the Native php's features and eventually build out an example app which I have running here we are pulling from the Reddit API it's a subreddit that shows cute dog pictures and you can see we have thumbnails here we have the number of upvotes the number of comments and if you click into it will get a bigger image okay and we also have preferences here so we can change the theme to dark mode so again all of this is built with laravel and all of the tools you're familiar with but it's running in a native desktop application so let's go ahead and get started so I have a fresh laravel app here all I've done is layer value so first thing make sure you have yarn installed as native PHP makes use of yarn I actually didn't have it installed on my machine which resulted in some errors so you can see I have it installed here if you don't have installed the command I used to install it is core pack enable and that install the yarn for me next let's go ahead and install native PHP as a composer package so we can say composer require native PHP electron and let me just open this up in vs code okay and now we can install it using this command PHP Artisan native install let's go ahead and install the npm dependencies and we'll say no to the dev server because we'll run that manually so to do that we can say PHP Artisan native serve and this should bring up our electron app with the default welcome blade and you can see it here with the dev tools opened and here is our welcome blade so again we have the full power of laravel running in a native desktop application so let's take a look at a few files here we have a config within config native PHP and for now I'll just keep everything as default we have our native app service provider which sort of bootstraps our application so if I were to take a look here you can see we have our menu which is adding some default menu items here and we are opening the window with this size here and there are some other options here which I will get rid of just to keep it simple okay so if you make any changes in here then it will automatically reload the electron app so let's make our app smaller 400 by 400 save you can see that it automatically reloads now devtools opening is pretty annoying every time so we can close it here we can say show Dev tools false save that now it's off and one more thing you might want to add to the window is if you move this and save it by default it does not remember the position but if you wanted to remember then go ahead and add remember state remember State okay save that and you can see it's in the same spot now in terms of automatically reloading other files like our welcome blade you have to set up Veet to get that working so let me go to our welcome Blade Let Me Close the sidebar for now welcome blade let's go to documentation here documentation okay let's add some exclamation marks save and it scroll down because it formatted it documentation but you can see that it did not update here so again we have to set up Veet for this so for now let me just remove everything here let's make a default HTML page say native PHP and for now we'll just say div hello there okay save that again it doesn't update here and you would think you can reload here manually and you can but you have to set up the default application menu for that and I'll show you that later on so I'm hitting command R here and it's not reloading so again we have to set up beat for this same way you would in a typical level application so we can make use of the V directive within our head tag so wheat resources JS app.js and we also have to make sure that Veet is running in our terminal so I'm going to open up my terminal here let's stop this I'll make another tab here with a vertical split and this one will be responsible for running Veet so npm run Dev T not found npm install okay let's run feed now let's make sure our native serve is running as well and now you see our boilerplate app here let's make a change hello there with exclamation marks and it does update so again we have a full level application running within the context of a native desktop application so how about we just add another page here let's say div about in about page let's say about about save that let's go ahead and make that route so let's go to our routes file let me just get rid of this I'll make use of Route view here we're going to slash about and the blade view for that I'll make is called about so let's go to our welcome blade and let me just duplicate this duplicate about a blade and it's a we'll change this to home so we can navigate back because our native desktop application does not have a location bar so be sure to keep that in mind and make sure your navigation is in place for each page and let's say about page here okay let me save that let's hit about and it goes to that page as expected now what about opening another window within the context of a web app you don't really think about opening new windows but within a desktop app that's something common you might do so if you go back to the documentation we have a section for Windows here and it's the opening window and we're already opening the default one within our service provider and we can open another one within there and you can also do things like pass it a route so how about we open a new window with the about page we just created open by default so let me copy this let's go back to our code let's go back to our native app service provider let's paste that in and we have to give it an ID and by default I believe the ID is main if you don't pass it a param but in this case let's say window open about let's make it even bigger so you can see it open above our current window and we don't want devtools so let me put that there oh and we want to open the about Page by default so we can say route about and we have to make sure to give our route a name so right here we can say name about okay save that let's save this as well and now you can see we have two windows opened the default one and the new one we just created which opens the about route now what if we want to do this programmatically say when we click a button so let's go ahead and do that so let me close this let's cut this and how about we make another button or I guess a link in this case right here so let's go back to our welcome blade let's make another link here and we have to run arbitrary PHP code here so we can go to another route here it's a open window and let's do that for now open window let's save that let's go to our routes file we can duplicate this one this is going to open window and we can paste in our code to open that window let's make sure to import window should be the facade let's go ahead and save that okay let's open the window and that does work however if you take a look here you'll see that it navigated to slash open window which we don't want so there are a few ways we can solve this I think the best way would be to make use of Livewire I think Native PHP and Livewire share the same vision of making use of PHP wherever you can so they pair very nicely with each other but I want to keep it simple and not install Livewire at least for this video so we'll just make use of query strings here so let's go ahead and do that so we don't want to navigate to open Windows let me just cut this again let's get rid of this actually so we want to stay on the same page so in this case that's the home page but we'll make use of query strings here so let's go back to welcome blade for now instead of opening open window let's just make it a query string so let's say open window equals true okay save that and let me just make sure our window is showing the default window so we'll go here and save that okay so we're going to open window true but it's still the main page so we have to check for that gray string within our routes file so we can make use of the route Global helper so route sorry I meant request Global helper to check the query string so if the open window query string exists then we can run that code to open the window again this would be much easier using Livewire and wire click to run some arbitrary PHP code but this should work hopefully so let me save this let's open our window okay that worked but we are still on the same page here and there's also an option to always keep this window on top if you wanted to do that I believe the method is always on top save that let me close this and reopen it okay and now you can see it's always on top okay okay let's take a look at notifications so native notifications on the desktop on Mac OS it opens up in the top right corner so let's go to Notifications here and let's see how we can do this so pretty straightforward we have this notification facade that we can make use of it has a title a message and a show method so let's go ahead and make use of this so this actually didn't work for me in a previous version let's see if it works in this newer version so again we'll do the same thing we'll call it from the main route but we'll add a query string so let me duplicate this let's make the gray string variable named notification let's get rid of all of this and we'll paste in our notification code let me save that oops I didn't mean to save it and this is always on top that's pretty annoying let me get rid of that okay let me import notification it's the facade and we have to add this to our welcome blade okay let's duplicate this it's notification equals true qualification save why didn't this oh because I didn't save the routes file save the rods file okay or maybe I have to restart this okay let's try the notification here and yeah it still doesn't work but to make it work we just have to say notification new so right here okay let's say title and hopefully this works now so save notification and it's still not working okay so it's working now I just had a setting on my computer which I had to turn on so if you go to your notifications at least for a Mac I had to turn on the setting here which allowed notifications when the screen is being shared and also make sure you have it enabled for electron which is right here you can see it is enabled so now if I hit notification there's the notification right there cool okay now let's take a look at menus here so you saw in the default native app service provider there were some defaults there native app service provider we had some defaults here you can see we have the app menu so that's this right here sorry let's focus this so you can see it has the name of the application which is laravel by default you can change that in the app name in dot EnV let's actually do that here let's say native PHP app save that it should restart and it's showing the notification again because we're on that route I think we have to restart this okay so there is the new title you can see it here in the app menu what else do we have here we have a custom Sub menu it's named about and you can see it's just linking to the Beyond code page and Simon's website here you can see that right here again I have to focus this about Beyond code and Simon hemp and we also have a custom view menu which allows us to toggle full screen there's a separator and there's also a link to the laravel website so there are a few other native menus we can make use of so if we go back to the docs here let's go to application menu and you can see predefined menus here so we have the application menu edit view window so how about we just get rid of everything here for now and let's start from scratch so what do we have if we remove everything so open up native PHP and we just have this here actually I guess it does register all the default ones if you don't Define anything so again if we just want the native app menu we can say menu new app menu and then register let's uncomment this let's say register okay and we just have one we can add what else was there edit menu I believe actually before I do that the edit menu usually has copy and paste right now we cannot copy and paste using those global shortcuts so I'm trying to copy this trying to paste it here you'll see it doesn't work but once we add the edit menu which does have copy and paste that should work so edit menu okay save that reloads there's the edit menu there's copy paste and cut and everything else and now we should be able to copy this and paste it okay what else is there there's View and window again some defaults provided for us so we can say view menu and window menu and those should be added for us okay check out the menu there we go so again some defaults here and like I said at the beginning of the video we can now reload manually or Force reload with these common shortcuts we'll command r and command shift R so V doesn't reload you can do it manually once you have the view menu in place I don't think you can add to these menus or say for example you wanted to add a custom menu item within the view menu I don't think there is currently an option for that so you would have to register it manually so you would remove this and create your own view menu so again you can do that using what you see here so let's do that let's grab this let's put it next to the window menu let me just clean this up okay now we have this about menu after window and it has these two links we also have the option for a label what's the API for that custom sub menus yeah just label let's grab this let's put that after our links so label my label that should be fine okay there it is and I believe there's an option for something similar to a label but you can emit your own event so let's take a look at that we already saw links you can add a separator I think I showed that already but let's add one in between here okay there should be a separator now before my label there is and what's the other one I wanted to show you event-based menu items so again similar to labels but you can trigger your own event and I believe you can also add Global shortcuts here so let me grab that let's paste that in let me just close the sidebar for now and this should be the same as my label but it should trigger this my event so how about we create that let me use the Veet window here stop that let's say PHP artisan make event and my event okay so that was created back to our code let me just import this okay okay let me save this we should have that within our menu now oops we have to restart beat and now I should be able to reload here with command R and we can let's check out the menu here we have about trigger my event so now this should trigger my event but we have no listener on it yet so nothing happens but let's go ahead and make that work so let's go into our event service provider now usually you put it within this listen array and then Define a listener class but you can do it within the boot method as well and just provide a function so that's what we'll do here event listen we're listening for my event make sure to import that okay class and when that happens say function event we can do whatever we want in here so how about we open a new window like we did earlier so let me just grab that code from our routes web so we'll just grab this let's paste that in here let's import window okay let's make it smaller actually 200 let's get rid of this okay let's save that did I save my runs file or actually I don't need to do that let me just refresh this just in case and let's see if that works so if I go here about trigger my event and it does open that window you can also associate a shortcut with this menu item so again back to the docs here we have shortcuts somewhere down here or hotkeys they call it so for the last argument we can say the shortcut here and you can see the list of what you can use in here but for now this is fine let's put this within our native app service provider right here so for the last argument here is the hotkey as a string so in this case it's command shift d and that should bring up our new window so let me save that back here let's check it out it does show here on the right so command shift d let's try that out and it does open our window cool okay now let's take a look at the menu bar you can create menu bar applications with Native PHP as well and the way I think of it there are two types of desktop applications ones where you have a window opened and you work with your application in there for example apps like slack Discord WhatsApp or Spotify these apps are always open and you switch to them when you need it but there are also menu bar applications which are more lightweight and live in your menu bar so for example laravel herd where you have quick access to change your PHP settings or to my favorite menu bar applications are this weather app I have just shows the weather and also this calendar app which shows a simple calendar so again these apps live in your menu bar and provide quick access when you need it so I think I'll do another video on menu bar applications but let me show you it working here it's pretty straightforward let's go into our service provider let's say menu bar create so this will create an icon in our menu bar now you give it a window size let's say with say 300 height 300 and say show Doc icon let's make sure to import menu bar okay and just like our normal windows we can provide a route here as well any route name but I'll just stick to our home route so we should be able to see this within our menu bar so let me save this okay there's our normal app but if we look in our menu bar you can see we have this native PHP icon which you can customize as well and here is our normal app again you can do whatever you want in here and provide the user with functionality in a menu bar App instead of a window okay now let's take a look at databases data PHP allows you to use sqlite as a database for your application just keep in mind that we're in the context of an electron app so this database will only be local for this client so how about we create a button here which creates a user because there's already a default user model and how about we show all of them within here as well so let's go to our welcome blade let's add that so we'll add another div here and how about one more here and we'll say for else okay and we'll Loop over our users as user and we'll just display their name so Dave user name okay and if there's nothing let's just say div no users found okay so that should display no users found for now and of course we have an error because we have not passed in our users from our routes file so let's do that so for welcome let's just passing user all so users is user all okay let's make sure to import user save that no such table users so we might have to restart our app here so let's go ahead and do that okay it's still not working and you can see this error here it's a skipping database migration while in development that didn't happen when I was trying it earlier it just worked but there is this command here let's try running this PHP arson native migrate so we'll stop this let's try running that okay so that used sqlite and that should have migrated our tables let's try that one more time okay so now it did work we see no users found and now let's create a button to add a user or a random user so let's do that again right within our welcome blade let's do it above here div and this will be a form the action let's just say user it's a method equals post okay we have our csrf and we'll have a button here should be submit and say create user save that okay back to our routes file it's slash User it's a post request let's add that right here route call Post user we don't need the request here usually you do but I'm just gonna randomly create a user here let's say let me just move this up user Factory create that should create a random user using factories and we'll just return back or redirect back return back okay and how about we add a notification as well as a success message so we'll grab this we'll paste that in here save that let's say user created and I believe you have to have the message here and let's just say details about user here okay let's save that and hopefully everything works okay let's create our user and you can see it is adding and there is our notification cool so again just keep in mind this is a database that's local to this client specifically and not your entire application for that you would have another typical level application on the server which provides API endpoints for you to interact with or for any client to interact with whether it's a desktop app like we have here or for example a mobile app okay now let's take a look at how we can purchase settings so like I showed you earlier we want to have the option for a light or dark theme so you can use the database for this but if you take a look at the documentation it says if you're only storing small amounts of data then you should consider storing files instead so you can make use of laravel storage facade to read and write from say a Json file and I actually did that initially but I rewatched Marcel's talk and there is a settings facade that makes this much easier to do and under the hood it's just reading and writing to ajson file and that's not currently in the documentation so let's take a look at how we can do that first let's create a page that has our settings so let me just go to our or let me open the sidebar first let's go to our about blade and let's make a new page here let's duplicate this one let's say settings Dot blade.php and I'm not using layouts here you definitely should but this should be enough to get the point across and in the final code I'll make sure to refactor everything to make use of layouts so this will be your settings page say settings and we have to add this to our main layout as well or sorry our welcome blade our home page so this will be this let's move this down here let's say settings and settings save that okay you have to add that to our routes file so I'll add that down here I'm going to use a callback because we might need some added functionality here so I'll say settings actually I think we don't for the showing of the page so I'm just going to duplicate this and say settings we have a view called settings and we'll name it settings okay so let's save that let's make sure it goes to that page okay and let's go back to our settings and I'm just going to paste in a form here which has radio buttons for light and dark themes okay so I pasted in this form here again basic form that just has two options for light or dark theme it's posting to this endpoint here let me change that to settings so we have to create that route as well so let me save this let's go back to our routes file let's create that so let's say route call it's a post request to settings and it does take in the request so it's either going to be light or dark and the request variable is theme okay make sure to import request from here and you should do some validation in here but I'm going to skip that for this demo and we can make use of this settings facade so settings and we either have get or set again it's just setting or getting values from a Json file so we can say settings set we want to set a key theme to whatever's coming in so either light or dark so request theme okay and then we want to make sure to import that should be this one and we can return back to the home page so let's say return redirect back to the home page okay so let me save this I'm not going to submit the form at least for now let's go back to the home page and let's just Echo out settings get theme so by default it should be null because it hasn't been set yet so let's go back to welcome blade and right here let's just Echo out settings get or actually we can't do that from here we have to do it from here so wherever our welcome blade is let's say theme settings get theme actually for the second prime you can provide a default if it can't find anything so we'll do that instead say light so if this key does not exist in the Json then go ahead and just provide light save that in our welcome blade let's just Echo out that theme variable that we're passing through and again we haven't said this yet we haven't submitted the form but it's not going to find that key so it should show light here so let me save this and it's showing dark and that's because I think it's making use of the same file I used for the demo app so right now it is set to dark and I'm not exactly sure where this file lives on my computer but hopefully it should change when we go to the settings let's set it to light let's save that and you can see it light now so it does update correctly so we can make this more Dynamic and make sure the correct one is checked here so let's go back to our settings blade and we can use the checked directive you can see right here I am just hardcoding light as the default but we can use the check directive I'm just going to paste it in here and check it if the theme is either light or if it's null and actually I don't think we need is no because we'll pass in Knight if it's no and we can do the same for the other option for Dark theme so we can do that here and there should be dark and we have to pass in theme to this view as well so we actually can't use the route view we used earlier here so where is it right here we have to use a callback so let's get rid of this this is a get request this is settings you don't need this don't need this we just have to return the view and pass in a theme and you'll probably want this variable across all your views so you would use something like a view composer to do that but for now I'll just do it manually this should be settings and we should pass in the theme Here similar to what we did above so let me just grab that right here okay save that and now it's light but if I change it to dark save it's dark here if I go back here that should work it's not working because I did not save and you can see it moved to dark here so again dark dark light save light and it does work cool now we need a few lines of CSS to actually change it to a dark mode or a dark theme so again I didn't use layouts here so I'll just do it for the default welcome blade but I'll make sure to use layouts in the final code how about we add class equals dark on this and how about we add a style in here and we'll say body dark background let's give it a dark background say 222 and color white does that change it to dark mode and it should be on the home page save this home page and it does and how about we change the link color as well so let me just grab this body dark a and it's a color anything light to Blue okay okay so once we have this dark on the body it should be dark mode but if not it's just standard light mode so again we're already passing the theme variable right here so we can just make use of that within our class so let's get rid of this actually let's just leave it there and we'll use it here as well okay save that right now it's light mode but if I were to switch it dark save it does switch to dark mode and again this setting should persist even if I were to stop the app and run it again and you can see it's still dark mode here okay now we can start working on the example app I showed you at the beginning of this video where we pull from the Reddit API and show a bunch of posts so if you're not familiar with the Reddit API if you just go to any subreddit I'm here at rare poppers for cute dog picks if you just add dot Json to the end you'll get all of this information in Json format so let's grab this and how about we make a new route for this endpoint so we'll make a new menu item for Reddit so I'll put it right here let's say Reddit say Reddit okay save that back to our routes file and we'll do it down here so route call get request to slash Reddit okay and how about we return a view that's named index and we'll pass in some posts here so say posts is posts okay so we can make use of laravel's HTTP client here to grab the posts so let's do that so let's say response equals http just make sure to import that it is it knows which one it is it's a get request I believe I still have the endpoint in my clipboard okay and let's grab the posts here so post is response and we want it in Json format and it's within a key named data and within children again just look at the response here or if you want you can dump the posts but I've already done that and this video is getting quite long let's go ahead and create index so let me bring back the menu bar let's go to our about blade let's duplicate this again I'm not using layouts here but I will refactor to layouts so duplicate this say index top blade dot PHP and within here we can Loop over our post actually before we do that I am going to install Tailwind or at least just to see the end so I'll just paste that in here within the head and we should now have Tailwind let me just make sure here underline Tailwind okay let's go to Reddit here and it looks like it does work okay so again we just want an image here for the thumbnail and the title so say Flex items Center so the first flex item will be the thumbnail so I'll just put it directly in here let's say thumb and let's give it a class of rounded full let me hide the sidebar here and width of 20. and the second Flex item will be the title and I also had the upvotes and the number of comments in here so we'll put it within a container let's say margin left of two so a title goes here let's make a font semi-bold title here and this is where the number of comments and the upvotes go so this is flex as well it's a SpaceX for it's Ace band UPS or upvotes it's hard coded for now and same for comments comments four okay let's see how this looks okay that looks decent and now if I passed in the posts correctly we should be able to for each over this and I'll fill in the dynamic data so for now let's for each should be posts as post let's grab all of this let's move it up into there let's save that okay so it looks like it is pulling the posts correctly so we have to fill out the image so I'm just going to paste that in here so let's just post the thumbnail as an array the title is in here and actually it should be a link because it should link to the single post page so let me change this to an anchor tag it should go to slash posts slash ID and the ID is post data name again just take a look at all of the fields from the Json API and for the title it should be title post data title okay for the upvotes we have both data UPS and for the comments it should be num underscore comments and hopefully I did that correctly save and let me just say space y here class equals space y five or four but we are getting our posts from the Reddit API and the single bull should be the same I am just going to start pasting things in because this video is getting quite long so I'll just paste in the route for getting a single post okay so I pasted that in the end point is slightly different for a single post you can see it here we're grabbing the post info and I'm also displaying a notification just so you can see some native functionality working as well and we have to create this show endpoint so let me save that the show endpoint should be pretty straightforward let me bring back the sidebar let's duplicate our index show.blade.php so we can get rid of everything in here we don't need a for each we don't need a space y actually we can leave that in and I'll just paste in what I have here that's hide the sidebar again so again we're just showing our title and the actual image save that and this image might not always work because sometimes it might be a video or a gallery but it should work for most of them so if I did that correctly let's go ahead and try opening up one of these posts here and you can see we do have the larger image showing here so we can go back home again if I have layouts the Dark theme should persist and I'll make sure to do that in the final code one more post here it looks like it does work and you do see the notification come up as well cool so there you have it guys a look at using native PHP to build native desktop applications using laravel and its surrounding ecosystem again at the time of this recording is currently in Alpha but you can see it is functional and you can make working applications with it like I said earlier this project is being actively developed with new versions coming out very quickly so be sure to check it out and maybe you can be part of its development and growth in the future
Info
Channel: Andre Madarang
Views: 36,683
Rating: undefined out of 5
Keywords: nativephp, nativephp laravel, laravel, laravel nativephp, native php, php electron, laravel electron, electron laravel, nativephp electron, livewire nativephp, livewire v3, laravel desktop app, native desktop app electron, electron, desktop apps with laravel, desktop notification, laravel livewire, beyondcode, laracon us, electron js, tauri electron, tauri laravel
Id: TY21MRVNxSo
Channel Id: undefined
Length: 42min 39sec (2559 seconds)
Published: Sun Jul 30 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.