Quasar & Vue 3: Dialogs, Animations & Touch Events (Real World App #6)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this series i'm documenting my journey creating a real world app budget 2 from scratch using quasar 2 view 3 and the composition api an app that will ultimately be deployed to the ios android mac and windows app stores and in this episode i'll be talking about custom dialogues custom buttons handling touch events and much more make sure you subscribe and click the bell so you don't miss any of the videos in this series and you can find the link to the whole playlist in the description so i've just taken a week off work and now i don't know what the flip is going on with this app i find that when i'm working on a project every day i understand everything that's going on in the project well then i take one week off take a look at the code and it's as if i've never even worked on it before and i'd be interested to know if you have this problem or if it's just me so let me know in the comments but i'll do my best to explain what i did last so i finished all the front-end for this ask a question section within the settings section where we can display a list of questions on this email danny link we can also allow the user to search for something and display these dummy questions and when we click on a question we can see the answer to that question and i've done all of the front-end for this account section including this pop-up which looks different on mobile and desktop and i've created individual components for all the different kinds of buttons in the app including these big chunky buttons these standard buttons and these little link buttons as well and i've also added a dummy subscribe process when the user clicks this button so we show this little loader and then we allow the user to create a new account at which point they're logged in and now able to use live data sync across their devices but obviously this is all just dummy for now i'm still just focusing on front end for the moment and i've also made a start on the front end for the budgets page so i've added this nothing here component for when there are no budgets and this is a reusable component which i'm also using on the start page here and also on this entries pane here i've created this custom dialog for adding a new budget where we can enter a name and select a currency symbol click on create and we see our new budget added here and we see the nothing here thing disappear and i've also finished styling a budget item and if we click on that it will load in the entries pane here and i've also added some basic touch handling to these budget items so we can click and drag this to the left or we can drag it back to where it was because eventually i'm going to show some options under here to give the user a shortcut to delete print and export a budget so i'll try to explain how this ask a question section works and this section was originally called help but i realized it was pretty dumb to have a section called help within a section called help so i renamed it to ask a question which i think is more fitting to the page so i'll just jump to my settings store file which is generating all of these settings sections and fields so i'll jump to source store settings store settings dot js so here's the help section and this ask a question object here is generating this item here and we have a click handler here which is fired when we click on this and this is setting a state property called show pane ask question in another store module to true so i'll just jump to help and store help.js so that's going to set this state property to true and if i jump to my settings component settings dot view i have this ask a question component at the bottom here and if i open that up we have a v if directive here which is going to display this pane when this property is set to true and you can see this pane is wrapped in a transition component with the slide in right and slide outright animations which is allowing this pane to animate in and animate out so in the pane header and in the buttons left slot i'm spitting out this header button this one here which allows us to go back to the settings page by simply setting that state property show pane ask a question back to false which will then slide this component back out of view and i've actually created a new global component for these header buttons because i realized i was starting to have a lot of these panes pane headers and pane buttons and i was duplicating the same props color properties and icons all over the place and i realized that if i needed to change the way these header buttons look i would have to change them in countless places so i've created a new component here pane header button which is a global component and that's here and i'm using props such as the back prop or the icon prop to create a header button like this which is a back button with a chevron or to create just an icon style button like this one that we see on the budgets page and that's an important thing to keep in mind when you're working on big projects it's a good idea to keep asking yourself how can i break this down a little bit further how can i reduce duplication reduce the room for error and reduce headaches in the future for myself and other developers so then back to this ask a question component in the pain body i have this div with a class of restrain 660 which is just giving all of the content on this page a maximum width mainly for desktop so if i stretch this out a bit you can see we're restraining the width of all of this content because it didn't look too clever when it was stretched out all the way across this div on larger displays so then i have a cue list component and i have this settings section header component for displaying this title and icon which is the same component i'm using throughout the settings section to add all of these icon header thingies and if you remember in video four i talked about how i created individual components for all the different types of fields that we can find throughout the settings section and i'm using one of those here so this label here and this input that's just a field input component and this is bound to a property in the help store module so this object here and that's where it's getting this label from and the placeholder and the icon etc and the value of this input is bound to this value property here and so if there's something in this value you can see i'm using it in this v if here then we display this template which will list out all of these questions which are in this search results array here so if i type something in we can see those questions appear and obviously later on when the user types something in here i'll actually search through all of the available questions and display all of the questions that contain keywords that they've searched for but for now this is just displaying these dummy questions and i'll just jump back to the ask a question component so then below this cue list i have another cue list for displaying these common questions so then i have another one of these setting section header components for the title and icon and then again i'm just spitting out a bunch of these field item components to display all of these questions which are coming from this questions array and then right at the bottom i'm spitting out this email danny link which is just another field item component which i've put in its own component because i'm displaying this in a few different places and i've put this here so that if the user can't find the answer to their question they can send me an email and in budget one i have this email danny link right on the main settings page and this resulted in receiving a lot of emails so in budget 2 i'm burying this away a little bit to hopefully reduce the number of emails i receive my goal with this ask a question section is to enable users to find answers to questions on their own most of the time and only email me if they really need to anyway back to ask a question.view if the user clicks on one of these questions one of these field items whether it's a question down here or one of these questions then we have a click handler which is setting this state property show answer to true so this property here and if i jump back to ask a question dot view i'm including the answer component here and if i open that up this is just another pane component with a transition and if that show answer state property is true then we slide in this answer pane to display the answer and if we jump to the pane body again i'm using this restrain class to make sure that this isn't too wide on desktop and for now the content on this answer page is just hard-coded and it's mostly just lorem ipsum but eventually it will load in the answer to the specific question that they clicked on and i may actually manage this ask a questions section and all of the different questions and answers outside of the app somewhere so maybe i'll create a separate quasar app with a firebase backend for managing all of this stuff so that i can easily add a new question or edit a question without having to completely republish the app and get through the review process and all that nastiness every time i simply want to add or edit a question although i haven't figured out how i'm going to do all that yet right now i'm still mainly focused on just getting all of the front end working before i get to all that nitty gritty [Music] so i'll explain what's going on with this new account section and again we have a new store module for managing this so i'll jump to source store account store account.js and we have three properties here and this logged in property determines whether the user is logged in or not because if they're not logged in then they see this login page or if they are logged in just set this to true then they see this your account page which tells them their account email address and what plan they're currently on so i'll just set that back to false and then we have this show fudge it plus pop-up property which determines whether the budget plus pop-up is shown and we can see that here and this subscribe property is for determining whether the user is subscribed or not if they're not subscribed then they see this kind of promo within this pop-up trying to encourage them to purchase the subscription but if they are subscribed then they see this create an account form within the pop-up instead so i'll just set these back to false so i'll jump to the main view component for this account section which is in components account and account.view so we have a computed property here which is determining whether the user is logged in or not using that state property and if they're not logged in then we display this account login component so i'll jump to that and again we have another restrain class here which is restricting the width of all this to 400 because it didn't look good at all on desktop when all of this was stretched right the way across here so then we have this account header component which is spitting out this budget icon graphic and this title and i've made this into a reusable component because all of the account pages have this at the top so all we need to do to set the title is just pass in this label prop and i'll just jump to this component account header and we can also pass in a sub label prop as well if we want to add a second line to this title so i'll jump back to account login.view so next we have these two inputs for the email and password and again i've created a shared component for this input this account input dot view because we have quite a few of these inputs with the same style throughout this account section and this is basically just a queue input with the outline style with the background color set to the backdrop color because all the different color themes have a backdrop color and in the default orange theme that's this beige color the same color that we see in the background on lots of our pages like this and if i jump back to account login.view these two inputs are bound to this login form reactive object and you can see i've hard coded in some credentials just so i don't have to keep typing them in and then we have a computed property which is going to check whether the form is valid and right now this will return true if there's anything at all in either of these fields so even just a single character and so if there's something in both of these fields then this login button will be enabled and of course later on i'll add some proper validation here to check for a valid email address and check for an appropriate password so then we have this forgot password button which is here and i've created a global component for this button because we have quite a few of these throughout the app so that's this button link component and this is not a cue button component but it's just a span with the text color set to the current primary color from the current theme and i'm just using some css to add hover effects for desktop and then we have this login button and that's here and again i've set up a global component for all of these default style buttons throughout the app so that if i want to change the way all of the buttons look in the app then i can just do that in one component so if i just jump to that button component so buttons button.view so let's say i want all the buttons in the app to be capitalized i can just do that with one change here by just removing that prop and now all of the buttons in the app are capitalized and i'll just put that back how it was and i'll jump back to account login.view and then we just have a paragraph which is spitting out this text here and this greater than iphone 5 class is a custom class that i've set up for hiding certain elements on really old devices such as the iphone 5. so if i switch to iphone 5 here we can see that paragraph disappear because on the iphone 5 it was pushing this button down off the bottom of the screen and this button is really important because this is the one which triggers the pop-up which encourages the user to subscribe to a budget plus account so then finally we have this learn about fudgit plus button which is here which i'm changing into the outline style by just passing along the outline prop uh when we click this we're going to set the show budget plus popup state property this one here to true thus showing the budget plus popup and i'm not including this budget plus pop-up within the account section i'm actually including it in the main layout file down here the reason being is that there are going to be lots of places within the app where we can actually trigger this pop-up so for example there will be certain features which are just for plus users such as the calculator function and for free users the calculator buttons will be grayed out and if they click or tap on one of those buttons i can show them this pop-up and tell them about the calculator feature on all the other features and hopefully encourage them to purchase the plus subscription so i'll jump to this budget plus pop-up component which is here so this is using the q dialog component not the q dialog plugin but the component and i'm setting the transition show prop to slide up and the transition hide prop to slide down so that we get this nice slide up and slide down animation when it appears and disappears and as you can see on mobile this pop-up is a full screen dialogue whereas if we look at it on desktop then we just have this little dialog which only takes up the space of the content inside it and i've done this by conditionally setting the maximized prop on the queue dialog to either true or false so if the user's device width is less than the medium break point then we set the maximize prop to true otherwise if they're on a desktop device then we set the maximize prop to false thus giving us one of these smaller pop-ups which only takes up the space of the content inside it and i'm also using the screen plug-in to position the contents of this pop up in the absolute center by adding this absolute center class only on mobile and the reason being is that on larger devices such as the iphone 6 7 8 plus or the ipad in portrait it looks pretty weird having all of this content right at the top up here with a big gap at the bottom so that's why i'm centering this content only on mobile and i have another restrain class here to restrain the width to 400 pixels and then i'm outputting one of two components so if the user is already subscribed then we output the register component where they can create a new account and if they're not subscribed then we spit out this budget plus pop-up sale component which is encouraging the user to purchase the plus subscription so i'll jump to budget plus pop-up sale so first we have the same account header component that we saw before which is spitting out this image and the header there and then i have a cue list component which is spitting out all of these benefits and adding this check icon which you can see here and these benefits are coming from this benefits array in our setup function and i did need to use a bit of css to style this list by reducing line height and stuff like that because this list was a bit too long and it was pushing everything else too far down and then we have these two chunky button components which i've created a global component for called button multi-line and these buttons have a bunch of different props so we can set the text which is this text at the top we can add a description which is this small text we can add a badge if we want to like this blue badge you see here and we can set the background color and the text color as well and if we click one of these we're just setting this subscription type which is a ref to either annual or monthly and then based on the current value of that subscription type ref we're spitting out different background colors and text colors so that we can activate the chunky button that they've just clicked on and then we have a bunch of button link components these little orange ones you see here which is the same component we used for this forgot password button link there and these are contained in this button link list component which allows us to group these button links together and add these nice little bullets between them and i'm just using a bit of css to add these bullets so i'm basically using the before pseudo element on each of these button links setting the content to a bullet symbol setting the color adding a bit of margin and i'm only adding this to all of the button links besides the first child by using this not selector and then finally we have this try free and subscribe button at the bottom here and if the user clicks that it will fire this subscribe method which is down here and in this method i'm just using the quasar loading plugin to show a little loading spinner with a message and i'm using this box class property to set the background and the text color on that spinner and then i just have a two second set timeout and once that finishes we hide the loading spinner and then we set this state property subscribed this one i showed you before to true thus replacing the content in this dialog with the register component where the user can create an account so i'll just click on that button so we see this spinner and we now see you're subscribed now create a fudgit plus account and there's nothing too fancy going on here just a couple of inputs and a button um when the user clicks on the register button we set this logged in property in our state to true and we also hide this popup by setting show budget plus popup back to false and now whenever they visit the account page they see this your account page instead which shows the email address they're logged in with and the current plan that they're on now of course this is all just dummy behavior at the moment but in the finished app the user will purchase the plus subscription and we'll wait for that to all go through then we'll show them the register page and when they enter an email and password we'll create a real account on firebase and move all of their local budget data up to firebase so that they then have live data sync across all their devices and a bunch of other features as well [Music] so i've made a bit of a start on this budgets page so i'll jump to source components budgets and budgets dot view so if there are some budgets in this budgets array which is in the store file store budgets store budgets dot js so if there are some budgets in this array then we display this budgets list component which lists out all of the budgets but if that array is empty then we display this nothing here component which is this no budgets yet component and i've made this into a reusable component because i'm also using this on the start page when there are no start entries and also on the entries pane when there are no entries so this is a really simple component so just open that up so this is just a div with a class of absolute center to put it in the center text center to center the icon and the text then i just have a cue icon for the icon and a div for the text and i'm setting the text color on both of these to the light color because all of the themes in our app have colors for dark medium and light gray text and to use this component we just need to pass in the icon name and the label and we're good to go and in the pane footer we have this add budget button which again is using my global button component and if the user clicks this we set this show add budget dialog property in our store to true so this property here and if that's true then we display this dialogue add budget component which you can see here and i'll jump to that component dialog add button and i've set up a reusable component for these dialogues called app dialogue because we're going to have a bunch of these dialogues throughout the app with the same colors props and same kind of buttons at the bottom etc so i'll jump to that reusable component app dialog so that's in here and this is just another q dialog component and i'm using the screen plugin to conditionally add the full width prop only on mobile so this dialog fills the available width on the screen on mobile whereas on desktop it will just take up the width of the content inside it and then we just have a cue card component with the flat prop to make it flat and i have the class set to bg backdrop to give it the current themes backdrop color which is this beige color in the default theme and then within that we have a q form component and a cue card section for displaying this label at the top this add budget bit but only if a label prop has been provided then we have another cue card section with a slot where we can inject any fields that we want to display on this dialog and then we have a cue card actions component with a named slot called buttons where we can inject any buttons that we want at the bottom so i'll jump back to dialog add budget dot view so you can see we're injecting these inputs into the default slot here and injecting this create button into the button slot here and again i've created some reusable components for a dialog input and a dialog select component because we're going to have tons of these dialogues and all of these imports and selects and check boxes etc are all going to look the same and these two fields are bound to this add budget form reactive object so the name field is bound to this name property and the currency symbol is bound to this currency symbol property and so if we enter a name for the budget this create button becomes enabled and when the form is submitted this on submit method is fired which will then trigger this add budget action in our store and pass along this add budget form reactive object so i'll just jump to the store file so it's going to pass the data from this form to this add budget action and then just using object dot assign to create a copy of that reactive object so that we can get rid of all the view reactivity stuff from the object and then i'm just adding an id property to the budget and setting that to a unique id which i'm generating with the uid utility from quasar and then we're just simply pushing that new budget object to this budgets array in our state and at this point if i jump to budgets dot view this nothing here component will disappear and we'll display this budgets list component instead so i'll just click this create button and we can see that budgets list being displayed now instead of the nothing here component so i'll just jump to the budgets list component and there's not that much going on here we're basically just grabbing that array of budgets from the store and displaying each budget item one by one using a v4 loop and using this budgets list item component so i'll jump to that component so i have some touch stuff going on with this component which i'll explain in a little bit but this budget item is basically just a cue card component and then within that we have a cue card section with the horizontal prop so that we can add cue card sections to this card horizontally instead of stacked vertically and then inside that we have another cue card section which is this bit from the budget name up to this chevron over on the right and we have a class of call on this to make a column and then inside that we just have a queue item which is all of this bit from here to here and we have a cue item section for the budget name a cue item section for this amount where we're also adding the side prop to push it over to the right there we have another cue item section for this chevron icon as well then we have a cue separator component with the vertical prop to create this vertical line then we have another cue card section for holding this menu button here um this is just a cue button component with a cue icon inside it and i did need to add a little bit of css to give this final cue card section with the menu button a fixed width of 50 pixels so i'll just jump to budgets.scss so i'm just using the flex property on that cue card section to set the base width to 50 pixels wide and to stop it growing or shrinking by setting the grow property to zero and the shrink property to zero as well and if i jump back to budgets list item so this q item here which is all of this bit from the budget name up to the chevron when the user clicks this we have a click handler which is setting this show entries property in the entries store module to true which will then display the entries pane like this which i've explained in a previous video so eventually clicking on this menu button here will pop up this edit budget dialog where we can change the name of the budget change the currency symbol and also delete a budget print export move and duplicate however in budget one we can actually swipe left on a budget to reveal some options here such as delete rename export and i wanted to do the same thing in fudge it too to give the user a shortcut to accessing actions such as delete export duplicate so they don't have to open up that dialog every time they want to perform one of these actions so eventually i'll add those options as little icons underneath here but for now i've got the basic touch handling working so i'll try and explain how this is working so in budget one i used hammer js to add all of these kinds of touch interactions but quasar has built-in touch events that we can make use of which so far seem much easier to use so included with quasar we have touch events such as this v touch pan event which i'm using on this cue card and this event will be fired every time the user clicks and drags or touches and drags on this component and this mouse modifier just makes sure that it works with the mouse as well as with touch and this prevent modifier just stops the actual app being dragged or scrolled when we drag on this item so this v touch pan event will be fired every time we touch or click and drag on this element and every time it will fire this move item method which is down here but before i explain this move item method i'll just explain these variables here so this item offset here is a ref variable set to zero by default and i'm using this on the cue card in the style attribute to move the element from its default position using the transform translate property and you can see i'm spitting that out there so if we wanted to move this card 10 pixels to the left then we could just set the value of this item offset to minus 10 and we can see it moved 10 pixels to the left and this transition duration variable is another ref set to zero by default which is setting the duration of the css transition for this cue card again in the style attribute here so this is set to zero by default so by default there will be no transition no animation as this card moves around and i'll explain why we need to change this duration in a little bit so back to those variables this offset min variable determines the maximum that we can drag this cue card over to the left and this is set to -100 so we can't drag this cue card any further than minus 100 pixels and i'm just going to spit out this item offset variable on the page so you can see that changing save that so you can see that's set to zero by default and as we drag it we can see it change but we can't drag it any further than minus a hundred and this offset max variable determines the furthest we can drag it to the right and this is set to zero because i don't want this to be dragged over to the right at all so back to this move item method this is going to be fired every time the user touches or clicks and drags this item and it will return the event object which contains this delta dot x property which tells us how many pixels they clicked and dragged by so we can then add that value to our item offset ref value which again is being spit out in this style attribute here in this translatex property so this will then move the card by the same amount that the user clicked and dragged by but it will only do this if the item offset value is greater than or equal to our offset min value minus 100 and less than or equal to our offset max value which is zero and then when the user lets go of this either this touch end event will be triggered or this mouse up event will be triggered if they're using a mouse which will fire this handle touch end method which is here and in this method we first check if the card has been dragged too far so if the item offset value is less than our offset min value minus 100 then we set the item offset value to our offset min value so i can actually drag this slightly further than minus 100 but as soon as i let go it will push it back to -100 and if the item offset value is greater than our offset max value so greater than zero then again we do the same thing so i can drag this slightly further than zero but as soon as i let go it will snap it back to zero now if the cue card is somewhere in between the two limits when the user lets go then this will be handled here so if the item offset value is closer to the offset min value which we can figure out by just doing item offset value greater than offset min and less than offset min divided by two then we'll move it to the offset min position or if it's closer to the offset max position zero then we just move it to the offset max position so if i drag this and just go slightly above minus 50 it will slide over to minus 100 but if i go slightly below minus 50 then it will nudge over to zero but before we actually snap it back to zero or snap it back to -100 we're firing this set and reset transition duration method which is here and this is just going to set our transition duration ref this guy here to not point three temporarily and this is bound to this transition property in our style property here so this will give it a transition an animation of 0.3 seconds temporarily then we have a set timeout of 0.3 seconds and after that's finished it will set the transition duration value back to zero and this is what gives us this nice animation when we let go which nicely slides it back into the finish position and the reason we can't just have the transition duration set to 0.3 all the time is because it doesn't look good when we're clicking and dragging this card uh just to demonstrate that i'll just hard code 0.3 seconds into this style attribute here and save that and if i click and drag it now we get this really weird kind of stuttery transition because the transition duration is set to 0.3 seconds so that's why we need it set to zero most of the time except when we let go when we need this nice little animation [Music] so what i'm going to do next is carry on working on this budgets page and this will keep me busy for quite a while because there's still a lot to do here so i need to add those options which will appear underneath here and also i need to add the ability to drag and drop items so that we can tap and hold on an item and reorder the items and if we look at the design there's a few other things i need to do like adding this all budgets balance adding these tool tips i need to do the front end for adding a folder to our list of budgets i need to do this edit budget dialogue with all of these options i need to do this more advanced version of the add budget dialog which has these extra options which will appear in this dialog if the user has multiple budgets and if they have start items and i need to add this draw for budgets options which could be quite tricky because by default draws will appear fixed to the right hand side and on desktop i probably don't want this draw to be like that probably want it to appear within this pane here so that could be a bit tricky and i need to do the front end for when we're viewing a folder and another draw for folder options and finally i need to do the front end for multiple selection so the user can select a bunch of different budgets and folders and either delete them export them or move them let me know in the comments if you would do any of this stuff differently or if you have any questions uh check out the full playlist in the description uh please hover over my face and click subscribe so you don't miss any of the videos in this series uh thanks for watching and i'll see you in the next one
Info
Channel: Make Apps with Danny
Views: 2,758
Rating: undefined out of 5
Keywords: *Tags (430 Characters):* android, app design, app development, app development process, app ideas, app success, building an app, cordova, create a real world app, create an app, creating an app, css, electron, firebase, firebase cloud firestore, how to create a successful app, how to launch an app, how to start an app business, html, ios, mac, make money with apps, quasar, quasar framework, quasar framework tutorial, real app, real world app, successful app launch, vue, vue.js, vuejs
Id: Jow_g3OQqYM
Channel Id: undefined
Length: 38min 3sec (2283 seconds)
Published: Wed May 19 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.