Build a Music Player app with React Native, Expo, Typescript and Zustand

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey there my name is jonatha in this video we're going to build this nice and clean Apple stylish music player application using react native Expo typescript and Zoo stand our music player will feature four main tab screens the initial tab will be the song screen which will display all of our library tracks within our library from here we're going to be able to scroll through our our list of trucks and select the truck we want to [Music] play after having selected A TRU a floating player will pop up just above the tab navigation if we tap on our floating player the player screen is going to show up from here we're going to be able to implement most of the important features of a music player such as play the TRU po the truck seek to a specific time in the truck using the slider progress bar skip to the next or previous song in the queue adjust the player volume toggling the truck player repeat mode between off repeat and repeat q and finally the possibility of marking the current song is one of our favorite songs the other screen tab are going to be the favorite screen which is going to display our favorite choices tracks the artist screen will show up all of the artists found in our library and for each of them we're going to have a specific detailed screen showing all the tracks related to their artist and finally we're going to have a playlist screen from this screen we going to be able to search or select a custom playlist every playlist will have a detailed screen where we're going to be able to reproduce the tracks are pertaining to that playlist for each of those screen we're going to have a native search functionality for searching for a specific song and also we will have a play and Shuffle button to start playing the listed songs as they were in a c we're going to build this application mainly targeting iOS devices but you should know that react native is meant for generating code that runs also on Android devices so if you want you could try to run this application also on Android device before we get started I want to highlight the fact that this project will be perfect for learning some of the core functionalities from react native and Expo in fact we're going to cover many important topics such as managing Dynamic list of data using react native flat list set up the app navigation using Expo router managing the application State using a modern State manager like zand and also we're going to see how to reproduce audio from a native application using a dedicated Library called react native track player so without further Ado let's get started all right then so the first thing that we're going to do is to create a new Expo project by running the command yarn create Expo DT this will ask us what kind of template we want to use and since that we are going to use typescript we're going to select blank typescript our h name will be music player and now let's wait for our application installing all the necessary packages great our project is ready so let's see the inside it so let's see the inside music player and let's clear the console and we should be good go so uh now I'm going to open up this folder inside vs code also so inside so inside project YouTube music player let's open it up great and this is our initial Expo project so for those who are not familiar with expo Expo basically is a framework for building native application without using the beay react native environment so Expo provide many cool features for example the export router which is a way to set up our enough navigation using uh a file system based router and without installing any thirdparty uh Library such as react navigation for example and also it provides for example the Expo SDK or Expo toolkit which is a suite of uh libraries useful for accessing native functionality such as the camera the system storage uh the media and so on so the first thing that we are going to do now is to quickly set up our project environment the first thing that we are going to do is inside the vs code folder uh we're going to create a file called settings. Json and here we are going to paste this configuration right here so basically here we are setting uh some utility uh options such as formatting on Save setting the default formatter and also organize the Imports and enabling the word wrapping down in the description you will find also the GitHub repo in case you need the complete source code of this project great so let's close this and now let's set up our typescript configuration uh which right now it's quite empty so here we are going to paste this configuration uh right here so basically what I did here is setting up some typescript option in order to uh work in a react native environment for example you can see that the jsx is set to react native uh library that we want are the Dom and yes next uh I enable the skip Li check uh resolve the Json module uh set up a base URL uh and also I set up to the part alysis for example when we are going to inut import by typing this at followed by something else we are going to reference the source folder actually this folder uh is not uh present right now so we are going to quickly create it great so now every time we are going to import using this um uh expression basically we are going to reference this folder right here uh and also when we are going to type at assets we are going to reference the assets folder the assets folder is where we are going to host all of our static files for example here you can see that we have um the splash image the icon image fa icon and adap the icon Etc these are really used by uh Expo for setting up for example the splash screen or the icon that is going to be displayed on our device great and finally we have also other options such as as the file to include the file to exclude Etc uh as always you will find this file on my giab repository so let's go on okay great uh Next Step will be setting up a pretor which is a code formatter which will format our code every time we e save so for doing that we're going to run yarn add DD right here uh great um so uh prer works with two uh files the first one is the prer RC and we have also the prer uh ignore so let me copy the content of prep RC we are going to use this configuration and also for the prer ignore we going to ignore some file for example the file inside the not mod modules the iOS or Android build folder the assets folder and the Expo folder uh great okay at this point what we can do is to run pretor uh a first time and for doing that we're going to run MPX pretor D write dot this basically will um pass all of our files and will run pretor uh on all of them so for example here you can see that these are all the files that are have been um pared and formatted by pror uh great okay next up will be installing um one of the most important uh Library provided by Expo which is Expo router so export router is a way for setting up um our hup navigation uh using a file system based router so for doing that we're going to copy the comments directly from the Expo guides so so we are going to uh basically install some package basically we are going to run uh an expo install and we are going to install Expo router react native safe area context react native screens Expo linking also Expo constant and finally Expo status bar so let's run this command and let's wait to um all the packages being installed so expor outter basically will work with a folder called app that we leave under our source folder so you can see that here we already have a nap. TSX file and what we can do is to move this file under this app folder let's move it here and actually we are going to rename it toore layout. TSX so layout. TSX basically is um way for telling export outer that the current file is um uh is going to be applied to uh all of the screens that are under the same folder so all the screens that will leave under the app folder will have the same layout in this case uh we don't really have um a real layout here but we actually have uh just a component with a view that display uh a text okay great so before running our application uh we will need to do some other step for example uh let's close this stop and let's move under the package.json so here what we are going to do is updating our main entry file and we are going to say export router forward slash entry this is a way to set up our expor out to work correctly uh then we need to close this package.json and open up our app. Json this app. Json is basically a way to set up our uh application native uh configuration for example uh we know that our application is going to use a sort of dark mode so uh we can update the user interface style to be uh dark for example and here you can see how um you we can set also other property for example the icon will be retrieved from under the assets folder and will uh get the icon do uh PNG we can set also for example a background color here for our splash screen to be dark and the same will be on Android even though we are actually not a Target Android device for this project so here what we are going to do now is to define a property called scheme which is important to have the Expo application working correctly and our screen will be music player great uh also uh remember that we have also a bubble. conf.js which is uh a file for configuring uh Babel but uh the current configuration should work fine so yeah uh double check your project that is uh actually like that otherwise it might not work as expected great okay under the up the Json we also need to add uh to new property which are the experiment uh experiment Rems property so under here we are going to activate the typed routes and set it to true and also we are going to activate the TS config parts to true so basically this will um enhance our um Dev experience because with type routes we will get type inference for all the routes that we leave under the app folder and instead with the TS config PS basically uh we can basically use the ptalis that we uh defined inside the TS config.js so these two right here uh great great job at this point we can try to launch our application and see if it's uh work as expected so what I'm going to do now is to bring up our iOS simulator and going to increase it a bit so you can um so you can uh see it correctly I'm going also to resize my window in order to um have the right uh amount of space so we will put our simulator on the right hand side of our screen and you can see that I'm using an iPhone 14 with iOS 17 and this will be our Target device so great great job so to launch our application um we will need to First clear up the console um if we want to run our application we uh generally with the Expo we have two option the first one will be using Expo go or the second one is to create a development build to launch our application but since we are going to need to um use some native life libraries we cannot use Expo go for this project so we are going to need to make uh a native build for in this case iOS and then run one of these development build also using Expo so there is a specific guide to how to create uh a development build using Expo and what I'm showing I'm showing here right now is the a guide written by Expo that explain how to uh create a development build so since we are targeting uh iOS basically you can see that we have some requirements for example we need a Mac uh to build project with native code for iOS and also we we need uh some uh dependency installed in our system for example uh we need a stable version of node.js and also we need to um install Watchman we need excode to uh be installed in our system and also um install cocoa pods um I will leave you the link to this uh guide down in the description but for now since I have already all the requirements basically once we have all of that uh we can just run npx Expo run iOS and from that um Expo will take over will create a build of the iOS uh application and we'll create basically a running version of our uh application inside the simulator great so from here what we are going to do is to run npx Expo run iOS great so now now it ask us what we would like your iOS bundle identifier to be so we can use com. music. player this is just a mock identifier you are free to choose the one that fits your needs obviously and now we're going to wait that Expo will create our iOS build folder actually you can see that you start creating our uh Native iOS build in fact it just create our iOS folder just right here and also you can open this project with excode and just running with ex code but obviously since we have Expo we're going to just use this Expo launcher for this project so let's wait for the build to finish and also let's say um this process um could take uh a little bit of time because it needs to compile all of our file transforming into native files and then finally we are going to see our application popping up here and from there we are going to be able to launch our application great so our application has been built and you can see on the right hand side that we have a new iOS application name music player if you're going to tap over this icon you can see that our app is working fine and is actually showing open up appsx to start working on your app actually this come from the under Source folder the layout. TSX that we were seeing uh before or actually this text right here we're going to set up our uh application style soon but before doing that we need to complete some other configuration for this project so so let's close this tab and one of the most important um library that we need to install it is the Expo Dev client so let's run npx Expo install Expo dd- client so Expo Dev client is very useful for running basically a Dev menu that is going to pop up uh over our application when we press command D so once the the Expo Dev client is installed we can relaunch our application by running npx expor run iOS great great so our application has been uh recreated and has been basically rebuilt and you can see that now this menu pops over and this is basically the Expo Dev client library that we just haded and you can see that uh we can open it at any time with this Command right here but generally on Mac OS if I press uh command D it should be pop over and this is actually our Dev menu uh it's super important because from here we can toggle many important functionalities for example we can reload the app we can toggle the performance monitor we can also toggle the element inspector in case we want to debug our UI and many more option so let's close this tab and yeah let's go let's go ahead with our app configuration great our final missing utility library that we are going to install it is es link so let's run yarn add- D yes link then yes l- plugin D react and also yes l- plugin d react-hooks uh what we are stalling yes link is to avoid possible errors while using react for example avoiding infite rendering or avoiding using custom HS like use effect or use layout effect without inuring into subt problem so once those packages are installed what we are going to do is to create to new file which are going to be yes link rc. Json and I'm going to paste the configuration of yes link uh as always you will find this file um on my guab repo and also finally the es link ignore to ignore uh some file that we don't want to be uh Link at basically so let's space all the files that we don't want to be uh linked and finally uh what we need is to go into inside the package.json and create a new scripts under the scripts property so let's go here and let's define a script called um link and this script is going to run es link on the current folder uh great job so uh what we can do is to test it out so let's run yarn link okay it seems that we are missing a plugin so let's immediately inst install it so let's run y add- the typescript yes link yes link plugin and let's way to be installed let's clear the console and let's try to run it again our link okay uh seems that we are missing some other property I think we need to add also another Library called typescript ESL parser so let's run it and let's write another time hoping for more luck and yeah it it it's working fine we only have one warning that say that the version not specifying in yeslin plug-in react settings but for now we can just ignore this warning uh great so let's close these tabs so let's minimize our terminal let's close this package Json now it's time to start working on our application so before starting let's take a quick look at the preview of our application layout so here you can see that we have different things uh going on in our application so the first thing that you might notice is that we have a bottom tab navigation this bottom tab have four different tabs the favorite tabs the playlist tab the songs Tab and the artist tab we're going to start to implement these four tabs and each of them will be obviously a separate screen so let's start by setting up our inup navigation and also Define some initial styles so the first thing that we are going to do inside the source folder we are going to create a new folder called constants inside this folder then we are going to create a new file called Tokens The Tokens file will store some constant token related to our application style like colors font sides and Screen ping so let's start with Define our color palette so export const colors and this will be equal to actually let me just uh paste it so this is some common colors that we're going to use throughout our application we have this primary color which is a soft red we have the background which is basically uh black we have text color set to White uh text muted which is a basically a soft gray we have colors for our icon and also two different color called maximum Trac in color and minimum Trac in colors that are going to be used by our slider progress bar like the volume bar or the track progress bar great then let's define also some font size this case we're going to Define uh extra small set to 12 uh small set to 16 uh base will be set to 20 and also large set to 24 pixel then we are going to also have this screen padding that to horizontal and we are going to have 24 so we're going to be use the screen padding to set some horizontal p adding in all of our screen great Next Step we're going to also to create a new folder called Styles inside these Styles we're going to create a new file called index.ts great inside this file we are going to define a default some default styles that are going to use the stylesheet API from react native so stylesheet do create and actually we need to import this stylesheet from react native so import style shet from react native and actually this is with a capitalize s here and also here great so the default style will be uh a container default style which will have a flex set one and a background color set to colors do background and these colors you can see that we are importing it from the constant token file that we are just previously defined and you can see how our puses are working just fine great so as default style we're going to also have a default style for our text where the font sides will be font sides dot base and also the color will be colors. text uh we're going to also have some utils Styles uh that we are going to Define it uh later but for now let's just declare this constant since we're going to reuse it later great actually we need to export both of these uh constant styles in order to be imported from a different file from our application so now let's focus on creating our app navigation with the bottom tab navigation that we have seen before so let's close this tab and let's open the app layout file so inside here we can actually remove everything and we are actually going to have um nap file which is going to be the uh the component entry point of our uh application and this will be a classic react component and at the same file we are also going to Define the root navigation and this will also be a react component it's super important to also export um the up entry point as the default export otherwise export OU will not work as expected so the app uh component will be the perfect place for initialize important part of our application such as our truck player or defining some important provider one of the most important provider that we're going to need is the safe area provider so let's define it and inside the safe area provider we are going to also basically return the root navigation that we are going to we're going to Define soon uh which is this component right here H at the same level we're going to also use the status bar and the status bar will come from Expo status bar um the status bar for the status bar we're going to define a prop uh style and we're going to set to Auto so the status bar basically now the application is not working as expected because we have some error but the St basically is the uh top bar that we are seeing right here so basically by setting aoto we are telling uh the application that since our application is using a dark mode style the main color for the text displayed must be white otherwise the contrast will not be visible great so at this point we can start Define our rout navigation so um our Rook navigation will actually not be uh as you might expect directly our tab navigation but will be a stock navigation coming from export outer so let's define this stock and inside this stock we will have uh a stock do screen which will basically redirect inside the group tabs the group tabs basically are going to be defined right now so let's go inside the app folder and let's define a group called tabs so the tabs group basically is delimited by opening and closing parentheses and it's used by expor outer for grouping common screens that share common layout or common domains for example in this case we are referencing it as a screen and we're going to place here inside here hold our bottom tab navigation screen in order to be used later so here we're going to also Define an option called header uh shown uh set to fults otherwise this will have some wrapping issue and also what we are going to do now uh is to define a root layout for our top screens so let's go here here and let's define our root layout. TSX so inside the tabs layout. TSX we're going to Define const called tabs navigation and this will be a react component as always we need to export uh these components as the default one so export default tabs navigation so the tabs navigation basically will use the tabs from EXP router and inside here basically we are going to have four different screen the first will be tabs do screen with name faites then we're going to have another tabs do screen we name playlist uh another one which will be with name of actually here we're going to use a group folder since this will be basically our index or the initial tabs that we want the user to be displayed when he opens the application and finally we are going to have also the four tab which is going to be the artist stab uh great obviously we need to return this and you can see that the application is not working because we are we are not yet defined uh these four tabs so in order to work let's start by creating our necessary folder so for the songs folder we're going to use a grouping folder this is because as I said before this will be our main Tab screen that is going to be displayed so we can we need to wrap it inside a group folder in order to tell export router to treat it as the index screen so inside here what we can do is basically creating two files first will be the layout. ESX and also the indexx inside the layout. SX we are going to export we're going to define the SS screen layout this will be our component and here what we are going to return is a view coming from react native this view will have a style that will come from from our default styles do container great and inside this view basically we are going to have a stock and inside this stock we are going to have a stock screen which is going to reference our index file or this one right right here also we can specify some option and say that the header Title Here is going to be SS great and as always we need to export default SS screen layout so you might be wondering why we need to WRA like use an inner stock uh inside of view so this outer view basically is like is acting like a background a background that will be that will use the default St container which will set the background color property set to the black color property so this way we're going to have a dark background and instead we're going to use an inner St screen in order to leverage some functionality and feature that stock screen provides like animation like um other search functionality and also many other things that will be more clear when we're going to showcase the application so the next step will be going inside the index. ESX of Our Song screen so here we are going to Define Our Song screen component and for now what we are going to return is a view with let's import this from react native and the style will be default styles. container great and as always we need to export the default um T screen and actually uh we can also display a text inside and we can import the text from react native and here we are going to say song screen great actually you can see that something is popping off on the right side but is not actually work as we expect um the text will be also have a style and this style will be the default style. text you can see that how uh this text is now uh correctly showing up inside our uh hinder screen and also you can see um how we have an initial um first tab uh here we have the text and here we have the title so something is we are coming from our desired results so now what we need to do is to do the exact same thing for the other four tabs so let's close all of these tabs and now um uh let's increase the Explorer um size and inside the tabs group folder we are going to create also the other three tabs so we say that we going to have the favorites we are going to have the artists and we are going to have also the playlist also you might have noticed that compared to the sunscreen you're not using a grouping folder this is because the artist favorite and playlist must be treated as different screen let's go inside our favorites folder and as we did before let's create layout dosx and also index. DSX uh actually what we can do is to copy this two file from the SS uh group folder uh we can delete this and just paste it inside the favorites obviously we need to update the name for example we know that this is the favorite so let's go here and let's rename to favorites screen and also I'm going to rename the text displayed and we're going to do the exact same thing also for the layout this is going to become the favorites screen layout the title will become favorites great let's see okay you can see that now favorites is um displayed correctly and actually it's actually working if I if I tap over the favorites you can see that we changed the screen correctly and also you can see that here uh the title are also updated correctly so okay let's do the exact same thing also for the artist and playlist so let's go inside the playlist let's paste this stuff and let's rename this to playlist playlist playlist screens and this will be the playlist screen awesome and also here we're going to rename this as the playlist screen layout address title will be playlist as the title let's see if it's working yeah it's working and okay finally we missed the artist so let's go inside the artist so artists screen layout this will be artist artists H great and this will be the artist screen let's update this artist screen great um yeah it's working just fine so now if you go inside the artist you can see that uh is properly uh working fine but as you might have noticed the Styles is not looking fine you can see that this um the bottom navigation and also the Eder navigation is being rendered with a light mode style and obviously we are going to do it soon so let's close all of our uh tabs and now let's collapse all the folders and let's go back to our tabs layout okay great so inside here we're going to Define some option um in order to have our bottom tab navigation and header navigation looking fine so inside the tabs let's define the screen option property and inside here we're going to specify multiple propert first off we're going to Define tab bar active in color and this will be equals to Colors dot we need to import our colors from the tokens and this will be uh colors. primary and you can see that they become uh just red great then we're going to define the topb bar label style this will have the font font sides set to font sides do extra small and also a font weight set to 500 great you can see that how the font Sid has increase noticeably then we're going to also to set the header shown set to false you can see that the top header with which was innerly set by the stock screen that we set for each of those four tab is now not showing so how do we achieve the Bottom bar navigation dark blue red background so if you recall from our preview you might remember or you might notice that the background of this botom bar navigation is slightly blur is dark and it also has some kind of Border radius right here so in order to achieve this this cool effect we need a library called um a component called blur view that will come from a library called Expo blur so let's open up our terminal and let's run npx Expo install Expo blur great now let's go back to our screen option and here let's define a property called tab tabar background so here we are going to specify actually a component without the cly braces actually and this component will be the blur View okay we can see that we have some errors but I think that's because we have to restart our application from the beginning so let's define our blur View and then we are going to fix this error so let's set up an intensity for this blue or 95 and let's also Define a style this style will be first off we're going to use the Styles sheet do absolute fill object and we are going to import the Styles sheet from react native import style sheet from react native great so then we need overflow set to Hidden this will comes in EN to achieve the Border radius then we set the Border top left radius to 20 and also order top right radius also set to 20 great we're going to also to define a tab bar style and this tar style will have a position set to Absolute it will have a border top left radius set to 20 same for the Border top right radius set also to 20 then a border top with set to zero and find finally ping top set to eight great so our tabs uh our tab navigation should be set up now to to recover from this error what we're going to do is to is going to uh kill that process and let's try to rerun our application so npx npx expor run iOS let's close this application and let's wait for export rebuild our application from scratch great our application has been restarted automatically and you can see how the tab bar now looks very nice with this uh blur background that I don't know if it's super visible by the video but it should be blurred and we actually achieved our dark Bottom bar navigation so what we are missing right now is an icon for each of these top and also a nicely formatted tab name so for doing that let's minimize the terminal and let's scroll down to our top screen so what we are going to do now is to Define some option for each of those top screen so let's start with the favorite top screen so here we're going to specify the title to faves then we are going to have a top bar bar icon and this will be basically a reat component the icon that we're going to use will come from Expo icons so in this case we are going to import for example font awesome from uh react actually not react but expo at Expo Vector icons so let's scroll it down and and let's use Font or font awesome icon and yeah for for this icon we are going to use the he icon the sides will be 20 and the color actually will be received from the prop of this component basically this props is passed from our top screen provider down to our icon uh great as you can see that our now the favorite uh tab is nicely formatted and we're going to do the same thing for the other remaining tab so let's go here let's paste this stuff now we are editing the playlist so let's name this playlists and actually for the playlist we're going to use material Community icons so let's go here let's import material Community icons let's go back here and let's define playlist will be playlist play uh with a size of 28 great let's hit save and you can see how it looks fine great so let's do the exact same thing for the song screen here we're going to set the title to songs and we're going to use the ionicons icon so let's go here let's import ionicons and here we're going to use the musical note Shar with a size of 24 actually the the right name is musical notes sharp yeah and you can see how it looks very very nice great let's do the exact same thing for the artist Hub uh rename this as artist and for this one we are going to use the font awesome 6 so let's go here and Import in phont awesome 6 and the name will be users line with the sides of 20 and there we go our artist tab now is looking fine great now it's time to start working on our header so let's take back our preview and you can see that the other has basically some custom styling you can see that this left aligned is actually using a pretty big font sides it has a search functionality and also it has these two buttons but um the play and Shuffle button is actually related to another part of our component so we are going to see later how to implement those this is a very common native layout sty style uh that is actually not so difficult to achieve thanks to the export router uh navigation so let's see how we can implement this header what we're going to do is inside the constant folder we are going to create a new file called layout. TS inside here we are going to Define a constant variable called stock screen with search bar and this will be of type native stock navigation options and this type will come from react navigation native stock so so let's copy this and let's paste it here great actually we are missing an S and also here great now we should have the type inference for all the property so here we are going to specify basically all the option that we need to display our header so the first option will be the adder large title set it to true then we're going to have the header large style and this will be an object with a background color set to colors. background let's import this from the tokens and this actually will be background then we're going to have header large title going to be header large titled style and this is going to be color set to colors. text this is going to update basically the text color of our header then we're going to have the header tint color set to colors. text finally we're going to have the header transparent set to true we're going to have the header blur effect set to prominent and finally we're going to have the header Shadow visible step to for great let's now use this constant navigation style inside our for main different top screen so let's go under the Hub folder and let's start with the song screen so let's open up the layout and along with the header title now we are going to spread all the option of the St the stock screen with search bar that we have just defined and obviously we need to import this from the constant layout so let's see saved let's move on to the song screen and you can see that is actually looking very fine we are actually missing the search bar functionality but we're going to add it later on so let's do the exact same thing for the other four tabs so let's go under the artist and paste it this one and import it let's check it great let's go under the favorites paste it import it then save it and it's looking fine and finally the playlist so let's go here let's paste this import it save it and it's looking actually super fine great great job okay now we should be ready to start implementing our first screen which will be the song screen so let's take a look at our preview of Our Song screen so basically here we're going to have a list of multiple tracks and for each of this uh list item which will represent a song basically we will display the title the uh artist we're going to display the artwork uh image uh and also every item will also have a sort of option uh menu that I'm going to show you what is going to do so let me go here and let me open the TRU option and you can see that basically this option will permit us to uh adding or removing the truck from the favorites or adding the truck to a playlist uh great so I think that we can start by closing uh most of these uh tabs and now what we are going to do is to create a new folder called components which will hold most of our re components so what we are going to do now is to create a component that is going to display a list of a list of songs that it might be scroll through so this component will be called tracks list. TSX so let's export this tracks list component which will be a react component and basically here what we are going to do is ret uh we're going to use the flat list component that will come from react native so basic basically flat list is a very high performance list component that is used to display a list of data which will might contains multiple items so performance are very important here so this component takes an input to required properties the data which will represent the list of item inside our component and also a function called uh render item which will basically be the uh function to render uh each of these item as you might be wondering you might ask yourself how we're going to retrieve the songs playlist that we're going to display inside this application so for that we are going to create inside the assets folder a new folder called data and inside this data we are going to paste this Library do Json file so let's take a look at this library. Json so this file will represent our library so we are not going to actually use a third party API we are not using a file system for this application because is a bit out of scope of this project but uh we're going to use this sort of uh mocked Library uh this Library will contains different items each of these items will have these properties for example the URL of the songs that is going to be hosted on this uh platform called audio. Juke host and also we're going to display some metadata information about the songs like the title uh the artist the artwork image uh the rating which will be used for to know which truck has been favorite by the user and also every truck might be um assigned into one or multiple playlist in fact you can see that uh you can see here that the playlist is an array of playlist that that songs are pertain to for example you can see that these songs uh title anxieties um is already present in the chill playlist instrumental playlist and rep playlist so the important uh takeaway is that these libraries will be the source of our data that we are going to display inside our application uh great we can go back here to our track list component and for now what we can do is to uh import this Library what we are going to do for now is import the library from we can say assets slash data SL Library so we can pass this Library uh down to the data prop of the flat list so once we are here we need to render our track list item so for doing that we're going to extract another component called track list item. TSX so let's export this component so track list item and let's define a react component and so this component basically will be WRA by a touchable highlight since it's will be basically uh a button that once pressed we start uh Our Song so we're going to have also a parent view and we need to import this view from react native and so let let me just get back our uh preview so you can see that a track list item is this single item that we see uh right here so we need to display the title The Artist and the artwork uh image uh in this way so let's make it work so we have this parent and we need actually to figure out how to display an image so we might be tempted to use the image uh that comes from react native but I see that uh for this project was not the um our best option actually we are going to use most anounced um image component called Fast uh image that will come from a third party Library so let's open up our terminal and let's open up actually a new terminal and let's let's run MPX Expo install uh react-native D fast image great also while this package is installing we're going to also to import some default images let's see what we need to import if we open up the assets under the data we're going to paste this two new image and the image are the unno art ar.png and the unknown track.png these two image will be used when we encounter an artist or a track that does not have artwork image defined so at the same time what we can do is going inside the inside the constant folder we can create a new file called images. yes and here what we can do is to import the image that we just have imported inside the assets folder so for example import unknown artist image from SL asset slash unknown actually you can see that we do not get type safety support for images in order to to have that we have to actually Define we actually have to define a file called index . D.S that will enhance our typescript runtime environment to take in consideration for example images uh to do that we can go here create a new folder called types and inside here we can create the index. T.S and we can just paste these two modules inside this will uh permit typescript to create all the uh file extension that will have PNG or jpeg as files that can be imported inside our code base so from within our file so now if we go back here inside our images. yes you can see that we can import the image so here we are importing the unknown artist and actually we are going to do the same thing for the oops for the um for the truck so unknown truck and this will become unknown truck uh image uh great at this point what we can do is uh Define two export the first one will be a no Tru image URI which will basically will resolve the outset source of the unknown Track image and will return the URI actually for doing that we need to import image from uh react native and we actually going to do the exact same thing for the unkown artist image URI so in this way when we notice that um an artist does not have an image or a truck does not have an artwork we can just fall back to these two images great great job so now let's go back to our track list item and here we can just use our fast image uh component so let's import fast image from react native fast image okay actually it seems to have some problem oh yeah because this one is not um membered export but is a default export so yeah that way should work so as I was saying the first image will take two props the first one is the source prop and is the source of our image in this case we need to specify what is the source of the TRU that we are rendering actually here we do not have a truck uh so what we can do is to take uh an input the TRU we want to render so let's go here and let's define a type called track list item props and this will take an input the track a track for now as a title which is a string and also an image that will be an optional string and that's because not every track will have an image defined so let's hit save and let's extract this prop from the track list item props and here what we can do is say that the source will take an URI property and this will be the track do uh image or in case it's not defined we're going to use the unknown trck image URI as fullback image uh great also we can specify the priority of this image and we can just set fast image. priority. normal great uh also uh this will not be the real type of our truck since when we are going to install the react native truck player we will see that we are going to have a specific type that will match the type that we have seen inside the Library Json file uh great but for now this is also for showcase the result okay great so let's define also another property called uh style and here basically what we are going to say is to paste all the Styles name track artwork uh image actually we need to Define this uh style so let's go here let's type rnss and let's import uh Styles sheet from react native and let's paste the style for the trackwork image so basically we are setting the WID and he to be 50 and a the radius of eight uh great so another option that we might be set um is to set a dynamic uh opacity based on based on the if the current item is the active truck or not so for now let's suppose that um this truck uh is not the active playing truck so let's set it to false but in the other case what we're going to do is set the a dynamic opacity and if it is the active Tru we're going to set 0.6 otherwise we are going to set uh one uh great also what we can do it's defining uh the track title and the artist so so here we're going to have another view and this view will have a style of with that to 100% and inside this View basically here we are going to display the track title and artist even though uh we not have an artist so the track title plus artist so uh let's take the Artist as input so let's set artist uh here and also as optional because it's possible that a truck does not have an artist set so inside here we are going to have have a text and this text will come from react native so let's go here let's define the text uh great and the text will be track. title okay obviously we need to specify some props for example the number of lines will be one in order to not drop into multiple line the title and also we're going to have a style this style will have a pretty default styles that we're going to name track title uh track title text and also we're going to specify the color to be if is it is an active track we're going to set the colors dot uh import the colors colors. primary or otherwise it will be uh colors. text great so we need to Define this Tru title. text let's go inside our uh local Styles and let's paste this Tru title texttile here let's import the default style. text and let's import also the tokens so basically the track title text will be we have a font side small a font weight of uh 600 and a max weight of 90% uh great and also if it is the active draft we're are going to color the title text has red great also what we are going to do is to uh render also the artist of that truck so if the TRU artist is defined we're going to add that text so let's go here and let's add a new text which will display the track. artist great as always the number of lines this will be one and the style will be uh Styles draw. track artist uh text and we need to Define uh this style as well let me just paste it here uh basically it has the color text is a soft grade font s side set 14 and a margin top of four uh great uh finally we want this like the title text and the fast image be wrapped inside a parent WID container so let's copy all this content let's paste it here okay great so let's try to uh take a look at the result so let's go back to our track list component and here what we can do is to extract the property item and rename it as the truck and here what we're going to do is to use the track uh list item and obviously we need to pass the track and track will have the title which will be equal to track. title also we'll have an artist set to track. artist and finally an image that will be track do uh artwork actually these two are not needed we can just do uh we can just use the uh spread operator like that and we should be good to go now what we are going to do is to render this track list so let's go ahead inside our app folder let's open up the songs um index uh the songs index file and inside here instead of rendering all of these uh this TXS we're going to use scroll View and inside this scroll view we're going to have the track uh list awesome now you might be wondering why we should need to um wrap the track list which is a flat list inside a scroll view this will come in ending to have basically uh the navigation that will display here acting correctly when we scroll through the list of songs and it's like a sort ofp work around but it's the only way I found to make it work uh nicely so actually here we need to pass some props to this tracks list so inside this component we're going to define the props for the track list called track tracks list props and basically it will inate all the props of a flat list but we are not making them required so we're going to use it partial then flat list uh props and we need to also pass the generic which for now is unknown now let's get the flat list uh props here and let's type the track list props here so now what we can do is to spread all of these props just right here okay we're getting some error but uh soon we are going to to to fix those great so here it's important to set the scroll enable to FSE otherwise we will get some runtime uh error and it say that react children expect to receive a single react children element inside the touchable highlight so I think that the problems is inside the track list item because the the children of a touchable highlight must be unique so what we're going to do is to add another wrapper View and take all of this content and paste it here and then actually we are going to uh Define a style for this uh parent dropper and this style will be styles. Rock item uh container so let's go here and let's space the style for the track item container which will say flux Direction row column Gap 14 align items Center and ping rank to 20 so we are getting some error and this comes from the fast image view so since we are basically uh installed a native Library sometimes it we need to rebuild our uh Native builds from scratch in order to to make it work so so in order to do that we first stop our application and then we run npx Expo pre-build uh- P iOS since we are targeting iOS D- clean so this will basically uh clean our currently native directories and then we are going to rebuilding uh those with npx Expo run iOS so let's wait to the process to complete great at this point we can run npx Expo run iOS and let's wait for the build to complete and then it should work as we expect okay so our application has been rebuilt from scratch so we can run it again so let's stop on music player and you can see we just achieved uh pretty good results for me even though we have some trouble with spacing but but you can see that the images are displayed right the title of the each tracks is displayed correctly and also we can actually scroll uh through the list of tracks and you can see also that we got a very uh nice effect when we scroll uh through and this is thanks to the stack screen animation provided by react navigation that export outer use under the hood great so what we can do right now is adjusting those spacing issue that we have and specifying like a separator and adding some uh margin between each item for doing that we are going to go back to our track list uh component and here uh just above the track list definition we're going to uh Define a component called item divider which is an inline component which is basically a view with a style and this style will be the utils styles. item separator which we're going to Define soon set the margin vertical to to 9 and also the margin left to 60 uh great so let's define this U style so let's go inside our constant and let's go actually let's go inside our Styles index.ts and here uh remember that we have this H Styles so here we're going to Define item separator and this will be equal to this style right here so we specify a border color to be a soft gray we specify border WID to be Airline width from stylesheet and an opacity of uh 0.3 uh great so now we need to import this U style and then uh inside the flat list component we are going to specify a prop called items separat uh separator component and this will be our item divider great let's H save and you can see that now our elements are nicely spaced and we are actually having a very soft divider right here that uh I don't know if it's super visible but on a real device uh should look very nice and maybe on your screen will look uh actually more clear rather uh on the on the video but the most important thing uh is that is working what we are going to do now is going back to so actually and right now we are inside the track list uh let's go back to our songs uh index file and in here remember that we were using a scroll view that were wrapping our uh track list so here what we're going to do is Define a style for our scroll view for example we're going to set the content inser adjust insert adjustment um Behavior set to automatic and then we're going to also set a style this style will be have a podding horizontal set to screen poding do horizontal and that's it so you can see that now we we have our components we have our main screen be uh being applied some horizontal padding to actually looks more uh clear great great job also if we try to scroll you can see that we have also this n scroll bar uh effect which is very nice to see uh great great job so the next step now will be adding the search bar functionality just below the songs title so for doing that react navigation actually provide um an option called Adder search bar that can be applied to the stock screen option in fact if we go under here um we should be able to add header search bar option and this will permit us to uh apply our search functionalities but the problems of declaring this option here is that we will not have uh room to manage our search text uh input so what we are going to do is to define a new folder called Hooks and we are going to have an hook specific for managing the search functionality use navigation search. TSX so let's export use navigation search and this hook will first Define some default search option which will type search bar props and will come from react native screens and here we are going to Define find the tint color set to colors do primary and also let's set the height when hide when crawling set to false let's add a comma great so inside this hook we're going to have a state and this state is going to hold the search text that we just typed in so let's set this set search Set uh set action and here we're going to use the US state to come from react it's importing and the default will be an empty search great then we're going to declare a variable called navigation and we're going to use the used navigation from export router this will permit us to add those property in particular the adder search option that we were seeing before uh on top of the current screen that is declaring this hook great so let's go ahead and let's type an N called use layout effect inside this use layout effect we are going to execute a callback function let's define the dependency array to be empty so by using the navigation now we can access the set options and this inside this set option we are going to Define the other search bar options and in here we're going to pass the default search option then we are going to actually okay for now we can just declare this inside the dependency array we have to declare the navigation uh also we want this use navigation search be uh we want to have some control over this use navigation search uh especially on the props that we are setting in here so what we are going to do is Define some input props that we're going to take uh as input so here we're going to define a search bar options uh that will be optional and will be of type search bar props so here we're going to extract the search bar option once we EX ract it from here we're going to spread it out just right here uh great uh and finally we need to Define uh an Handler called unchange text so basically onchain text is a call back function that will update our search when we are going to type something in our uh search bar so what we are going to do now is to define a new Handler function called handle on change text this will be of type search bar props uh of type of the property on change text and here we going to Define this callback function so here we can extract the native event and inside the native event we can also extract the text property great so here we're going to set the search to be equals to the the text that has been input by the user great and finally inside the unchange text we are going to pass the endle unchange text uh also we need to defines this handle unchange text um actually we need to define the search bar option over here okay great so the final thing that we are left to do is to return the current uh search that will come from the this use state that we defined over here great now we can start using this useful uh use navigation search hook inside our song screen so let's open up the up folder tabs songs uh index let's close the Explorer and over here we are going to set const search equals to use navigation search and this will be equal to the search bar option we're going to pass the search bar option and we are going to pass a placeholder to be find in SS uh great if we hit save you can see that the search bar option is displayed on top of our screen and also if we scroll back to the top we can see that we have the title and the search bar and as soon as we scroll down you can see that how the search bar remains attached on on top of our header component and that is awesome also if we tap on the search bar we are able to search whatever we want we also have a button for clearing the text we have for example a cancel button and so on so our search functionality is almost ready okay another thing that I would like to update is to adding a little bit of spacing over uh this part because is to attach to the search bar option so for doing that let's go back inside the tracks list and over here we are going to define the content container uh style to be equal to having a padding top of 10 and a pading bottom of 128 let's save it and you can see that we have now a little more uh room to break and also if we scroll the entire list of songs you can see that we have some space left here and this will be super important to display our floating player just above the tab navigation also you might have notice that the last item in this list does not have any uh divider and we can just add it by defining uh list hoter component to be equal to the item divider so now even if it's not super visible also the last item has the uh item divider display on the bottom great also what we can do is to actually implement the navig the search functionality for this screen so let's go back so let's close all of these tabs and let's go back inside our songs index file so here what we need to do is to basically filtering the songs based on the current search functionality so for doing that we are first going going to import the library from the assets SL data/ library and from here we're going to define a new variable called filtered SS and we're going to use the use memo hook in order to uh just not wasting because filtering could be pretty expensive operation so we're going to wrap it with use memo in order to avoid calculating the filter songs on every rerender so great uh what we're going to do here is that if we don't have a search we're just uh going to return the library otherwise what we are going to do is to filter our library songs so in this way we're going to do library. filter and here uh we're going to specify a filter predicate in order to filter these songs so for doing that uh let's create a specific file for managing all of our filters so inside the uh the source folder let's define a new folder called helpers that will hold some of the utility function that we are going to use throughout this project so inside here we're going to create a file called filter dots that will hold some of the filters that we are going to use throughout this project so here I'm going to paste the track type title filter so basically for now let's put Hy here so basically the track title filter what uh what it does is taking the track uh the track title uh transform it to lower case and compare it uh with the current title that has been uh searched obviously by transforming it to lower case great so we can go here we can pass the title filter and pass it the search that is currently active on the song screen so here we need also to define a dependency array with the search and the library great also library is not needed actually uh but now you might have noticed that we have our filtered songs but we are not passing these songs to the track list so we can go here and actually Define a list of our tracks over here for now I'm going to use Hy but soon we're going to use a specific type for the tracks so now inside the tracks list we can extract the tracks and pass this inside the data great as you can see something uh seems to have broken and and that's because inside our songs index we need to pass the prop tracks to be equals to the filtered songs actually to be more compliant I'm going to rename this to fi theed uh tracks great so now everything seems to work and let's trite out our search functionality for example let's see what happen if I search for the title memories you can see that is actually working for example let's see all the tracks that start with the letter a and you can see that we get all of the trucks that I think that contains the letter A for example if we want this truck here Atlanta let's see hot and you can see that is working just fine great all right then I think that we are ready now for introduce one of the most important libraries to have this application work as a music player application we are going to install a package called react native track player so react native track player is a fully fledged Audio models created for music apps and if we take a look at the get started um actually in the intro we can see that this Library features many cool features that that are super important for a music player application for example uh it feels native so it follows the same design Principle as real music apps do it's multiplatform we have media control support uh we are we are able to fetch uh songs from local or from Network we have support for bitr streaming support it's built on top of react Hooks and actually I just tried it out and it's very well done so shout out to the creator of react native truck player and we're going to take a look at the installation so the installation is not super uh straightforward especially on on iOS it seems that we might need to set up some uh files with the ex code uh for example here we we need to enable Swift modules but actually when I was building this application I didn't uh need this step right here but yeah in case you have some troubles I suggest you to to follow the installation guide from uh the beginning so actually uh react native track player support uh Expo so it should not so difficult to integrate in our project great so let's dismiss this tab and let's open up a terminal let's create a new terminal actually and let's run npx Expo install uh react native trck layer okay at this point another important things to do will be go inside the app. uh Json and here under the iOS property we are going to define the info p list and just right here we are going to set up UI background uh modes and we're going to set uh actually this is expect an array and we're going to set audio this is a requirement to have the react native track player work as expected especially with background uh modes uh great okay so now let's try to relaunch our application from scratch and see if everything is working fine so let's run npx expor run iOS let's try to Let's close the current application and yeah it seems that we are getting some error and that's because I think that we need to restall our native directory so let's run npx Expo pre-build uh D- clean Let's uh proceed and now we are going to install all the dependencies again from scratch because uh we installed a native Library so we need to rebuild everything from scratch okay the pru process is done then we can run npx Expo run iOS great now the application has compiled and it's working fine so now we have the react native track player uh installed correctly and the first thing that I'm going to do is closing this tuab go back inside the track list and here we can start using the type truck that will come directly from reactnative truck player great so now we can also specify truck here and here you can see that they're getting some some error I think that we can just remove this and pass the current track and let's see what the problem is yeah because is that is because uh over here we have to just update our type to using the truck from react truck player uh great so everything should work as expected now uh even though uh we are getting some trouble with the with the images seems to every image uh seems to be loaded from to not load correctly the image and that's because here inside the first image we cannot uh we do not have the track. image property but we have the track. artwork property and you can see that now is getting back working as expected great let's also try to run a PSC which will compile all of our typescript files and we are not getting any error so we should be good to go great now let's close all of these stops and I'm going to create um inside the O folder new hook called use setup track layer. TSX so inside this hook basically we're going to set up our react native truck player so let's export our use setup TR player and basically what we're going to do inside this ook is running a new effect that will run only on Mount and that will set up our Tru player for working as we expect so before doing that I'm going to define a function holder here called the top ler which will be an sync function and over inside this function uh we're going to run some common to set up the player for example the first thing that we're going to execute is Tru player that will come from react native Tru player the setup player and here we can pass some option and one option that I would like to pass is the max cach sides set to in this case 10 megabytes uh This Way some song will be uh cached and we will get a slightly more better user experience avoiding some possible buffering between uh multiple songs since uh we have to remember that the songs are fetched from an external API so we might be encounter some uh buffering since we have to download the songs but with this property we will be able to introduce a caching system to avoid that buffering uh great so another thing that we're going to do is to set the initial volume of the truck player so let's go here and let's set set volume and and I'm going to set uh so this value must be I think between 0 and one so I don't want to uh like the playback overlap with my voice so I will set a very uh low volume for now which will be 0.0.3 which is not too loud and then we're going to also to set up the track player repeat mode state and we are going to set this repeat mode to Q so this part uh will also be more clear later when we are going to set up the button for um changing this repeat mode uh great so let's go back inside our setup um setup track player and let's define a news effect inside this use effect we're going to execute a function and what we need to do here is um is going to run the function set up player that we Define over here so we're going to set up the player and then we're going to do something else when it finish since is an a sync function so when the setup player is finished actually we need to basically adding a new variable called is initialized which will be equal to use ra set to false and this will be super important to avoid re-executing this use effect uh in case our application uh reloads again so here we will go over here and say his initialize current set it to true and also we want to take an uh an input call back function called onload and so load will basically be just a plain function and we are going to execute it uh here actually this will be an optional uh function so we will go over here and we're going to execute the load if it is defined uh great uh in case in case of possible errors we are going to take the error and we are going to say that is is initialized do current will be set to false so we will try to in case we we can try to uh reexecute this use use effect again and over here we're going to also to console log the error Also let's drop this parenthesis great and over here we're going to pass this on load function uh great okay so this was it for our us setup track player so we're going to use this us setup track player inside our application entry point which is actually the root layout. TSX uh file so if you remember from before this was like the main uh root component that gets executed by uh Expo or react native in this case so over here we are going to execute you setup track player so here now we need to pass the function on load what we want to execute on when the Ro player is finished loading basically most of the user experience behavior is to show the splash screen when the application is loading internal assets such as uh images or fonts or even setting up internal uh system like in this case the react native truck player so what we are going to do is to use the is to First import The Flash screen from export router and we're going to say out of the up entry point prevent outo a sync so this will basically show the splash screen until we are uh going to call another function called I a sync so over here we going to we're going to declare a function called endle track player loaded and this will be a new SCB back function we need a new SC back function over here because we don't want to trigger the use effect inside the use truck player over and over again so let's go here and let's say that when the truck player has finished loading we are going to execute Splash screen. hide a sync so that means that when the truck players finish loading we're going to hide the splash screen and we're going to show the song screen great and now over here we can pass this function great okay let's try to refresh our application yeah it's still working great now we're going to Define also another uh useful uh hook that will will come in end for debugging our truck player state so let's go under the hooks folder and let's create a new hook called use log Rock player State great hook over here we are going to import some uh types and um function from in this case from react native Rock player and we're going to import the event and also the use Tru player events so basically inside this zook we are going to log on the console the current state of the track player so the events that we want to log are going to going to be on a list of event the first one will be event. playback State and you're going to listen for the event. payback eror and also event do um playback active cck change it uh great so now let's define our hook so use log trck player State and let's define the body so inside here we're going to use the use Tru player uh events we're going to pass the events that we want to listen for and also an a sync function that will be basically this will be the call back function that will that is going to be executed every time a new events that we are listening for gets triggered so over here we're going to say that if the event. type is equal to event. back error we are going to log console.log actually we're going to use the console. wor and we're going to say an error occurred while playing actually we're going to say an error occurred uh semicolon C column and then the event then we're going to say if event. type is going to be event. playback state we going to log cons log playback State column and we're going to render the event do state great and finally we're going to also have another if statement where we're going to say that when the active track change it we're going to console log the index of the active Tru change it great so now uh if we go back here uh let's try to refresh and actually is not anything is logged because the truck player uh I think is not doing anything yet so yeah let's just uh move on or actually we have to add this um hook inside the app entry point so use log TR player State and let's execute it uh great so let's refresh let's open up our log and let's try to uh actually let's save this and let's refresh and yeah actually I think that uh this must come after the um this up function otherwise it will not work so let's refresh okay seems to work fine even though sometimes we're going to say see this error the player has already been initialized via set up player and this is something that could happen when you refresh your application with the fast refresh but is something that you should really not worry about unless you are obviously uh trying to ship in production this application great okay at this point let's close these tabs and let's go back to our track list item and if you recall from before uh we were basically uh we marked the this is active Tru was mocked by us uh to uh to set the value false actually react native truck player uh export a an Nook called use active track active track which we can call and we can access the URL of that uh active Tru and we can compare to the current uh truck item actually with the URL of the current truck item so if the two uh the active truck and the currently rendered uh truel matches that means that the truck it is in an active State and remember that this active truck was used uh by us inside the style of the uh image that we're displaying and actually over here great so um since we are inside the track list item uh we can also have the three uh dots that gets displayed over here and that will represent the option or the option men the shortcuts menu to add a library to a playlist or uh removing or adding to the favorite songs so let's go here and and what we are going to do is to is to basically had um an icon that will come from in typo and this en typo will come from uh react uh from Expo Vector icons so over here we're going to set the name of the icon as dots PR horizontal we're going to set the sides to 18 and the color will be colors. icon great let's save and I think that we need to refresh but it's actually not shown um yeah I think that we need to the reason for that is that we need to wrap everything inside the parent view and take this stuff this uh just inside this parent view okay you can see that now they get displayed but we want them to be displayed you know horizontally so we can just go here and attaching this style so the flex set to One Flex Direction set to row justify content space between and align item Center and you can see that now the three option menu gets rendered correctly in a later stage of this video we are going to implement the UI menu for the uh shortcuts great now we want to add a proper Handler that needs to be executed every time we click on a in one of these songs so right now we are not doing anything because the touchable highlight uh does not specify the onpress heaven Handler so what we are going to do inside the truck list item props is Define an a callback function called on track s and this function will take an input the TRU and we'll just return void that way we can extract this on TR select and basically execute it over here so we can go here and just run actually I'm going to rename this on track select to handle track select right and over here we're going to say handle truck select and passing the current Tru uh great now what we need to do is going back to our trucks list and over here we need to specify our Handler so here on truck select we're going to take the actually we are going to go here and let's call this uh callback function handle Rock select this will take and input the TRU and for now we're going to log the current uh Tru like that so we can pass this handle track select to the prop on track select uh great so you can see now that when I click on the um track item we get the touchable animation but if we open up the uh the terminal you you can see that the truck gets console logged in the console great great job okay before we get forward and start playing uh songs from our library I'm going to also adding um a new component called floating player so the floating player basically is this component right here and it's basically um like a minimized version of the track player that gets render just above the tab navigation and the goal of this component will be displaying the currently active truck and when it will gets pressed it will open up the real truck player screen so let's try to implement this component okay so let's go ahead and let's close this tub and inside our component let's define our floating playerx so let's export our floating player and this component will use different HS so the first hook that is going to use is the use active truck to get access to the currently played truck so active truck will be retrieve from use active truck um here we are going to immediately had a if statement where we're going to say that if we do not have any active truck played in right now we just return uh null that means that we should not display the floating player great so now let's implement the renderer function so basically the floating player will be a touchable opacity component and inside here we are going to have a fragment because the touchable opacity accepts only a single child and inside here we are going to have the fast image component that we uh used before and we're going specify the source property and we're going to pass the URI as the yeah I'm going to Define another utility variable called display track uh to be the active truck uh this will come in handy later because if we do not have any active truck we might render the last active truck uh that was uh rendered uh before the current one this will become useful to avoid some flickering issue that the floating player component might end up if we rely only on the hook huse active truck but we are going to implement it just before the renderer function so let's go here and let's say display track. artwork and if we don't have any image we're going to display unnown Track image great uh then we are going to also Define style and the Styles will come from Rock artwork image so we need to Define these Styles over here so let's import the style shet from react native and over here let's get this track artwork image so let's go here and paste it the track artwork just here so this will be basically the uh small thumbnail of the image that is currently being played okay let's copy this out and let's use this Styles here instead of styles great great so this was for um this was done for our first image then we're going to have a view let's import the view from react native and inside this view we're going to have a text this text is going to display the display track. title great let's import the text from react native text and that should be it I think that we need also a style which will be styles. track title so let's go here and let's add the track title style let's import the default style so the track titles basically inas all the property from the default styles. text we set the font size to font weight to 600 p in left to 10 uh great so let's go ahead and now let's add also apparent style to this view which will be styles. track type container and this will be super important to avoid the track title overlaps the other two uh components of the floating player which are going to be the play and the uh skip to the next one bottom so let's go ahead so let's go inside the Styles and let's s this track title container that will set the flex the flex to one overflow hidden and a margin left to 10 uh great uh finally we're going to have also another view uh that is going to render to component the play play uh or pose button or the skip to next button great actually we're going to uh we're going to need to implement these two component but I can say that they are going to take a property called call icon sides that will be 24 for the playpost button and an icon sides of 22 for the skip to next uh to the next button also we're going to also to add a styles to this parent view and this will be styles do track controls container and this track controls container we're going to Define it here so basically they will have a flex Direction row a line item Center and some gaps marging and some ping uh great so next step will be implementing these two component called play pause button and skip to next button so we're going to implement this component inside a single file called layer controls. TSX great inside this file we are going to first Define a type called player controls props and we are going to take an optional style that will come from The View style great also we're going to define a second type called player button props uh which also going to take a style which will be the view Styles and also the icon s which will be a number great so now what we're going to do is to First Implement our or um play or POS button and this will basically take all the player button player button props so from here we're going to extract the style and the icon sides so this component needs to know if the the truck player is playing a song or is currently posed so for doing that react native track player export a very useful hook called use is playing and this will tell us if the current truck player is playing a song or actually even if it's buffering during playing but we will need only the playing State here so here we're going to return view from react native and inside here we are going to have touchable opacity and inside the touchable opacity we're going to have a font awesome icon so let's import this font awesome from um Expo Vector icons and this icon will be conditionally rendered and we're going to say that if it's playing very we going to render the post button otherwise we're going to render the play button besides actually here we need font awesome okay the sides will be the icon sides and also the color will be colors. text great uh also we're going to add some sty to this touchable opacity for example we're going to set an active opacity of 0.8 85 and actually we are going to set an oppress function and if a track is current play we are going to execute the track player do uh POS function otherwise we are going to execute the track player. playay function and these are both uh function that comes directly from the truck player and as you might have understand this will posst the current truck and this will play or resume the current track great finally we're going to also add a style to this parent uh container so we're going to set a KN set to the icon sides and also we are going to pass the parent style great so that was it for our play post button so if you go back here we should be able to implement import this component actually I like to use the the P alysis to have inner code and yeah so let's try uh let's go ahead and let's implement the skape to next button so let's go just uh below the play poost button definition and let's define the skip to next button so this will be also use the player button props and this will basically extract the style actually not the style but the icon sides and we're going to set a default to 30 over here we are going to return um touchable opacity component and inside this touchable opacity component we are going to use an icon and we're going to render an icon which will come from font aome 6 so let's go here and let's extract font aome 6 this icon will be named as forward we have a sides of Icon sides and we'll also have a color of colors. text ah great also we need to Define some property for the touchable opacity for example the active opacity will be 0.7 and on press we are going to execute something in this case uh what we are going to execute will be Rock player do skip to next uh actually we need to wrap this in inside the function and execute it like that so you can see how powerful it is the truck player Library it offers this super simple API to just uh control our Tru player great since we are here we can also implement the skipe to the previous button and which is basically similar to the skipe to the next button so I will just copied it here so uh we are just taking the icon sides uh we are just as we did for the skip to next button Define attachable opacity Define the off font aome six with uh the icon name set to backward actually here what we can do is to paste this here and just create an in line function as we did for the skip to next button uh great okay then now we can go back to the floating player and we can just import this one great so we should not have any other error so now what we want to do is to display this floating player uh somehow over this tops uh but actually the problem is that since we are not able to start a song anything will uh be um displayed so what we can do here is adding a mocking Tru that we are going to remove it uh later so we know that this must be a track so we can go here and say the title is this is just a song and and we are not going to Define anything else just a track with a simple title okay now you might be wondering how we are going to display the this floating player what we know is that the floating player must persist between our tabs navigation so we we don't want the floating player be remounted every time we change screen so in order to do that what we can do is go inside our app folder inside the TBS group folder open up the layout and as you might remember here with Define all the screen inside the tabs navigation so what we can do now is wrapping everything inside a fragment so let's take just all of this content and paste it inside this fragment and just um below the navigation we're going to Define our floating player great uh we can also add some style uh which should we are not taking so let's go here and let's add this props view props that will come from uh react native so now we should be able to get this style prop and over here we are going to define the position set to Absolute uh left set to 8 right set to 8 and bottom uh will actually be will be 78 just to like distate from the current bottom TP uh Bottom bar navigation great let's hit save and let's see what is going to happen so it seems that nothing is being displayed let's try to refresh and still nothing is displayed so let's try to figure out why okay the problem is that if we go back inside our floating player we are saying that if the active truck is uh basically null we are not going to render anything but we actually have to check the the currently display truck so um so this way we're going to check the display truck so now if we hit save we should have something so you can see that we get the results we have something but it's not correct we can see that we have the like the image displayed but the container is appearing as sort of white so let's go back to the floating player and actually we are missing some styling over the touchable opacity which is the container that is wrapping our floating player so here we are going to set the active opacity to 0.9 and we are also going to set a style which is going to be um styles dot container and also and also the parent style great so let's go here and let's define our container style so the container Style we'll have a flex Direction set to row Al line item set to Center and we're going to have a background color set to like a very soft gray variant we will have some padding set to eight a border radius set to 12 and finally aing vertical set to 10 okay let's see and it's working just fine you can see how our mocked song is displayed correctly and here we have the play or post button and here we have the skip to next button so great great job so at this point we are able to just start playing Our Song from our Library so in order to do that we need to instruct the react native track player to play the songs that we top over this list uh over here so how we are going to do that we are going to move inside the track list component and over here if you remember from before we had this call back function called handle track select so basically here what we are going to do is to make this application on a sync function and over here we're going to have a track player dot load. track so basically what this function will do will basically load the current truck as the the only truck that the player must be play so what we is going to happen that every time we click on a we press on a song we're going to play that song but we are not be able to skip to the next or previous songs because we still don't have a way to managing a queue of song but just for testing let's try this out so let's go over here and let's try to play a song for example let's select this one okay you can see that anything is happening because it seems like truck is stopped but if we press the play button it should work as expected and it's working I don't know if it's hearable so in this case I'm going to do I'm going to go inside the US setup truck player and I'm going to set this to 0.5 so it should be um hearable that way so let's just go here select this song and select play awesome how truck player is working just fine actually if we want to avoid that issue we can just go here and had an await track player. playay so that way we will first load the truck and then play it immediately so let's try it again let's try this time with another song for example this one and it's working just fine great great job I think that I want you to notice is that if we try to switch between different songs The Floating player might be a little bit flickering let's see what I mean by that so let's select different songs and basically okay now it's not super is not super visible but it can happen that if we are fast enough to change truck this floating player might flicker there is a little trick to to avoid that and it is uh by caching the last active truck so what I'm going to do now is going back to our floating player and over here we are going to Define last active rck and this will come from your last active rck so obviously we need to implement this hook so let's go implement it so let's go here inside the books folder and let's create this book use last active track. SX so let's define our export function use last active track and here what we are going to do is to take the currently active truck so use active truck which will come from react native truck player and also we are going to make use of an use state to keep track of the the last active truck so set last active truck and here we're going to use an use State we type truck and let's import is from react native track player so everything we need to do here is adding an new effect like that and basically we are going to save the last active truck to be the active truck so and this will run basically every time the active truck change so what will happen is that every time the active truck change the last active truck will be updating uh accordingly but you might be wondering wait so what is the the real uh utility of last active truck if it is the same of active truck well the trick will come here because we are going to say if not active truck we're going to return so what this means that uh every time the truck change if we transition in a state where the active truck is undefined we still have the active Drive set to the previously active truck and this is super very important because sometimes while transitioning between screen or sometime trucks the active truck can become undefined and with this type guard we are going to be able to always have a valid truck inside it a great so at this point we just have to return this last active Tru save it and make use this us last active truck over here so at this point we can just remove this and say that the display truck will be the the active truck and if the active truck is not defined we are going to display the last active truck great uh at this point I think that we can remove also this and you can see that typescript infared correctly this type to be truck or undefined and you might be wondering why it is undefined if we have the last active truck well the reason is that when we first load the application we don't have any active truck or last active truck because the application has just started so if we try to reload the application actually there is some things off I think that we need to refresh and restart you can see that nothing displayed because you know the application just started we do not have any kind of state set yet so yeah this will be super useful to increase our user experience and avoid flickering between transitioning between different songs or screen another thing that I would like to H is if we go back to our TRS uh list you can see that if we search for a song that doesn't exist nothing gets displayed so in that case what we are going to do is to add a list empty component which will render a component when the list of tracks is empty so here we're going to use a view from react native and inside this view we're going to display a text that will say no SS found and we need to import this text from react native so over here and also here we can use the SL components great and yeah so we are going to set the style that is going to be will come from util Styles empty component uh text actually we need to Define this util Styles and basically will be just this one we're going to use the default style text uh set the color to text muted uh set the text alignment to Center and a margin top to 20 so now can just do empty content text and you can see that the no found is getting displayed uh actually we can just do uh better and if we go back to our track list along with this no F we can also add an image that we're going to import from Fast image and we're going to display uh the unknown Tru image U so over here we also I have to Define these Styles inside the U Styles and just paste this style over here which is called empty content image that will have WID of 200 he of 200 align align self Center and a margin top of 40 so let's save and you can see that we have now this nice looking uh list empty component display when we search for a song that doesn't exist great okay great at this point what I'm going to do is going back to the US setup player and just lower this value down otherwise the sounds will be too loud and can overlap my voice so let's try this out okay is still hearable but should not overlap my voice okay at this point you can see that when we have an active truck like for example uh this one we get some hint that that is the active track so for example the title becomes uh red the image becomes slightly more uh darker but if you played around with uh most of the music player application they also show some kind of animated uh loaders and what we're going to do now is implementing that animation so let's close these tabs and let's head into the component track list item so if you remember here we were checking if the current truck is the active truck and so from here for adding the animation that we were uh talking before we're going to add a third party Library called react native loader kit so react native loader kit is just a library for adding loader animation so let's take a look at the preview on GitHub so as you can see we will be able to access most of this animation and for example we are going to use uh this one or this one to uh animate our truck artwork image when a truck is loading great okay so let's dismiss this window and let's go here and let's clear the console and let's run npx Expo install react native loader kit great so let's stop our our application and let's try run it again great our application has just relaunched correctly and it seems to work fine so at this point we can just start adding our anim so inside our track list item we're going to have some new features so let's scroll down under the let's go where we Define our first image and here we're going to have some conditional rendering so we're going to say that if this is the active truck and if the current truck is playing actually for retrieving this state we are going to need another uh hook that we used before and it is USIS playing for react native truck player so let's go here and let's extract playing great so if it is the active truck and is playing we are going to render loader an icon from loader kit so let's import our loader kit from react n loader kit great let's go back here and let's set name to line scale party great and also set the color to colors do icon if the truck is not playing we are going to actually display another icon but this time it will come from ionicons so let's import I ions from Vector icons so here ionicons great so we're going to use name the icon play we're going to set the sides to 24 and we're going to set the color to colors do icon awesome um at the same time you can see that we actually have a result but it's not super correct I think that we need to WRA all of this inside a parenthesis so okay now it looks fine and we need also to add a specific style which is going to be named styles. track play icon indicator and this style will be applied also for this icon right here so let's go here inside the style and let's define our track playing icon indicator and we are going to set these values right here we're going to set the position to Absolute the top set to 10 left set to 16 withd to 16 and also night set to 16 and that should be it uh this way the icon will be placed relatively to this uh image and basically will be centered over like displayed on top of the image so let's take a look at the result okay you can see that actually we don't have the result but this is actually because we this conditional rendering is displayed only when we have an active truck so for example let's go here and let's try to select this song okay you can can see that we have our cool animation playing actually I think it's a little bit higher so let's stop this song and yeah definitely there is something that is off because now we should have a play button but it seems like it is cut off so let's try to figure out why okay I think that we need to increase the Top Value to 18 but still it's not correct so the issue that we are encountering right now is because we are actually using the same style for both of the um icons so for the play indicator and the post indicator actually we want different style so let's go and implement the different style so let's go back here this is the track plane indicator which will have a top set to 18 and we're going to have also another property another style which will be the track pose indicator which will still be absolutely positioned but we'll have a top of 14 and a left of 14 so let's go here and and let's set the cck post indicator to the ionicon ccon great great job you can see that now is displayed correctly now you can see that every time I play the s song the animation is displayed correctly and when it gets stopped it also display the play icon uh great great job so the next thing that I want to implement is a very cool feature of our music player and it is the moving title animation so what do I mean by that so what is the moving title animation so if you playing around with with the Apple music app or Spotify you might have noticed that track titles that has a very long title gets animated by being translated from the right to the left uh back and forth so let's take a look at an example let's go inside the floating player and let's say that instead of displaying the current track title I'm going to display a very long name for example a very long string like that and you can see that this is not actually the behavior that we want so what we want here is like a text that is single line and that will move as I was saying before uh back and forth in order to display the entire title text so for achieving uh this feature we're going to extract a new component that is going to be named moving text so let's define our component moving uh text so since this component is an animated component we are going to need um library for endling animation and the best library for endling animation in react native is called react native reanimated so let's go here and let's install react native reanimated so react native reanimated great while this package is installing let's let's start by Define the props of our uh moving text so let's call it moving text props and this will take and input the text that need to be displayed and with will be a string and then we are going to need an animation threshold that will be clear it will be clear soon so let's see what is happening seems that our application uh keeps refreshing it so let's uh refresh one last time okay uh it seems that something have broke so okay let's try to uh rerun it from scratch so npx xor run iOS and let's uh close it so while it's restarting let's complete our moving text Pro so here we're going to get an animation threshold and also uh style prop that will come from style props and the style props will come from uh react native reanimated so from here going get style uh props awesome so let's see actually our application is recompiling from scratch because we still reanimated and I think that must be recompiled from completely from scratch so yeah let's wait to be reloaded okay and it's working just fine awesome so here we are going to take an input this moving text props and from here we're going to extract text animation threshold and the style uh great so let's start by defining our component we're going to use the animated from reactnative rean animated. text and inside here we are going to display our text great obviously the number of lines that we want to display will be just a single line we don't want the title of our track to wrap in multiple lines and here uh we're going to also Define some styling so we're going to pass the parent style an animated style and also a conditional animation that we're going to pass it later actually so let's define our animated style so basically the animation of this uh component will happen in the will consist of translating our component on the x axis so we going to define a property called translate X and this will be equal to use shed value and initial value will be zero great then we are going to hold so Define a variable called should animate and here we are going to check the length of the current text and if it is greater or equal than the animation threshold then we should apply the animation otherwise we just display the text as it is this is logic because uh if the text is super short we don't need it to animate it back and forth to display the complete title of the TRU so it makes sense to have this should animate great so we also going to have another variable called text width and it's going to be equal to text length time three great we're going to also to Define an animated style uh which is going to be equal to use animated uh style and we're going to pass a function function over here where we're going to return a transform property which will be equal to translate x equal to translate X do value actually I just make a typo should have an object here like that so perfect at this point we have to also add a new effect to make this animation happening so let's add this use effect and let's add the dependency array empty for now and here what we're going to do is if not should animate we're going to just return otherwise we are going to update our translate x. value and this will going to be equal to some different animation option that will be applied one of each other for example we want this animation to have for example a delay so we're going to use with Delay from react native reanimated and the delay will be 1 second so inside the wi delay we are going to also pass another kind of animation and this other animation will be with repeat so with repeat means that our animation should animate back and forth forever so we are going to just pass null here and we are going to pass uh the second value will be the number of repetition if we set minus one it means that the animation goes forever and then the third property is to if we want to reverse the animation so if we go from left to right the the order animation will go from right to left so we're going to set this to True awesome so inside the first parameter we actually we have to specify a third animation which is the WID timing and here we are going to pass minus text uh WID to and this is to tell uh this animation from going from left to right initially and the second option will be the duration of this animation will be actually 5 Second which are 5,000 milliseconds and finally an eing function set to uh eing do linear uh great let's hit save and that should be uh correct now so let's check that eing is actually yeah eing should come from react native reanimated and not from react native so here ising okay make sure that all the Imports comes from from react native reanimated and not react native otherwise something could broke over time uh great so here you can see that uh we must Define some dependencies to have this use effects works correctly so here we have to define the translate X the text the animation threshold and should animate and DET text with uh great so our animation should be uh actually is not ready because we have to Define also a cleanup function that must be executed when the moving text gets unmounted in this case we are going to execute the cancel animation and passing the translate X to stop the animation and also the translate x dot value set to zero to reset the animation when it gets unmounted awesome that should be hit and I think that uh we are almost ready I think that we need also another property here where we're going to say that if we should animate we are going also to apply a weight of 999 and this is for basically uh preventing the ellipses uh from uh appearing so basically uh if we don't do not set this weed basically our text will be like cuted with some ellipses at the tail of the text but to prevent that we set a very long weight that should prevent those ellipses from appearing also we are going to set a padding left set to 16 and this is for basically uh avoid the initial characters being barely uh visible because this anim when when start animating could basically uh tend to cut the initial uh characters of our text but by adding some padding left we should avoid uh this issue okay I think that our component is ready to be used so let's go inside the floating player and instead of using this text style we are going to use the moving text also here let's copy and paste it it here great I think that we need to pass also the uh text S text we are going to pass this one just to test it out obviously we are going to uh we are not going to have any children because the text will be passed as a prop and finally we need an animation threshold set to 25 characters great so let's try this moving test component now now I'm going to uh select these songs for example and you can see that our animation is looking absolutely fine now let's try to pass the real title so we are going to say here display a track. tile or in case it's not Define we're going to pass the empty string okay it seems okay you can see that now is not animating because the title is short enough to not triggering the animation but let's say for example that I want to place this song and you can see how we are getting this Smo animation uh back and forth that will permits us to display uh the entire uh the entire title of the tracks awesome okay also I just noticed that our play icon is not the one that I was really looking for so let's open up the player controls and you can see that here as the icon being rendered you're are using uh font awesome instead of font awesome six so let's go here and set font awesome 6 great as you can see now it's way more uh smoo awesome great so now it's time to implement one of the most important screen for our application and this screen is the player screen so the player screen is actually a little bit is not super straightforward since it has many um inner components many subtle effects then that needs to be implemented so let's try to break it down so we have multiple things going on in the screen for example we have the title of the truck the artist name a button for uh checking for uh for toggling the trucks as favorite or unfavorite also a progress bar uh that permits us to uh it will act as a slider and we like and we are going to be able to seek to a specific time of the truck as long as the current progress and the total remaining duration uh we have three main button one for uh playing or posing the truck uh skipping to the uh next uh Tru or to the previous one we have a slider for controlling the truck uh player volume and finally we're going to have a button for toggling the state of truck player repeat mode and also the main uh the largest components would be the track artwork uh image uh also you can see that the background has some kind of fancy effect because it looks like a linear gradient and also it will compute at run time the background color uh by extracting the the primary and The prominent colors from the current artwork image so we have a lot work to do to implement this screen so let's get started okay we are going to implement this component not as a like as a separate component but directly as a screen so what they mean by that is that uh we're going to implement this displayer screen and directly under the app uh folder so let's go here and let's type player. TSX and this component basically will uh act as a uh stock screen which will have a card animation transitioning uh effect so let's start implemented this uh player screen so let's define player screen uh to be a react component and as always let's export let's export has the default export uh great so we going to have um parent view and this parent view will have uh a style uh actually let's import this view from react native and this will have a style uh called styles. overlay container so let's define our Styles here let's import um the style from react native and this overlay container basically will have these Styles so we're going to import the default Styles uh so it's basically a default style container and but at the same time we are we are applying some horizontal ping and we're setting a background color of basically a black background color with an oppositive of 0.5 great so here we can just use these Styles and Define it just right uh here great so the second component will be uh this Miss player symbol actually symbol like that and let's going to implement this component in line here now this Miss player symbol equal to a new react component and this will basically use the use Save area insets and we'll extract the Top Value and from here we are going to return a view uh display with this style uh Position will be absolute uh the top will be um the top from the safe for inser Plus 8 and also left will be zero uh right will be zero Flex direction will be set to row and finally justify content will be set to Center and inside here we'll have the symbol uh itself so uh this actually can be um self- enclosing tag we'll have the accessible uh properties set to uh false because this is not actually a container it's just um like um just acting as a symbol so the style for this symbol will be a weight of uh 50 8 of 8 uh border radius set to8 then a background color actually let me scroll down background color set to sh this will be white so FFF and an opacity of 0.7 uh great so this was that was it for our displ dismiss player symbol uh actually we want to just try playing around this uh player screen so how are we going to do that so we are going to open the uh root layout file and over here after the top screen we are going to have a new stock. screen and this will have name layer to just look up for this file right here and we're going to set also some options we're going to set the presentation set to uh card we're going to set thejust enabled set to True thejust Direction set to vertical and also animation duration set to uh 400 and also header shown set to BS awesome uh now we want um to provide a way to show up up this screen right here and we are going to do this by using uh the router from Expo router and um more precisely we are going to open this screen when we are going to tap over the floating player so what we are going to do is to open up the floating player and here we are going to access the router so con router equals use uh router from Expo router and basically uh this uh inside this touchable opacity we're going to specify an on press function and this will be handle press and this handle press will be defined here and basically what we need to do um is just use the router dot uh navigate and and over here we're going to say slash player uh great so at this point if we try to press on the floating player it should open up our floating player and is actually working you can see that we get this night smooth uh animation coming from bottom to towards the top let's see again yep is working just fine and here here it is our dismiss player uh symbol great awesome so let's go back to our uh player uh screen so uh let's add also uh other components obviously we need to get access to the currently uh active track so let's define active truck to be used active truck from react native Bayer and from here we are going to say that if the the current truck if we don't not have an active truck we are going to return an activity uh indicator because it is possible that that truck is uh loading so uh it might not be just defined yet so uh let's define a activity indicator and this will have the colors to set to colors. Icon and this VI this parent VI will have style equal to will be equal to default styles. container and we're going to also set um justify content Center to have our activity indicator set to um on the center of the screen uh great so this was in case the active tra is not defined but in case it's defined I think that we want to display something so we uh after the dismiss player symbol so after below the dismiss player symbol we are going to have a new parent view this parent view will have a style uh to be equal to flex set one uh margin top margin top set to top plus uh 17 uh this stop will come from the US sa Fara insets so here we're going to start top and also we're going to use also bottom uh so margin top was uh tops plus 70 and also we're going to have a margin bottom set to bottom great so that was it for our parent uh container uh now we're going to have another view uh this uh view will contain our track artwork image so here we're going to have our fast image component and as always we're going to have the source prop the URI will be let me scroll down um it's going to be the active track. artwork image or otherwise is going to be unknown uh Track image URI great going to set also a priority and that will be fast image do priority actually prior prority and here we can set High because it will be the only image uh display on the screen uh great uh I think that we can also set the reside mode set to cover and also we're going to have a style set to styles. artwork uh image and also over here uh we're going to have also a style which will be uh Styles uh artwork image container great let's define these two Styles so let's go here and uh let's define first the artwork image uh container that I'm going to paste here basically we are setting some Shadows over here and then setting Flex direction to row justify content Center and the height of the image container set to 45% of the screen so basically uh oops so basically until here great and also we're going to need uh the artwork uh image style itself that is going to be placed here so uh basically are setting WID and I to be 100% because obviously we are relative to this parent container recites mode set to cover and a b radius B radius set to 12 uh great so you can see that um our image uh is being uh our unknown truck uh is being displayed correctly and you can see also that we have some uh Shadow over here that helps emphasize the the TRU image over the background awesome great so let's go ahead and let's add some new content okay so now we're going to have another view to wrap our uh track information so this P view we have a style of Lex one actually we need to WRA it inside an object like that okay great uh we will also have another view uh this view will have a uh margin top set to Auto great and then we unfortunately this component is a little bit tricky uh it will have many view nested uh in order to achieve the result that we are aiming for but the result will be awesome I can assure you so let's go here and set the style to have the height to 60 great so uh let's see uh okay so basically this one will be the track title row and we're going to set a fixed height uh so inside here uh okay actually let me remove this comment because might be um misleading we're going to have another view and inside this view we're going to set the flex Direction uh set to row then we're going to have justify content set to uh space uh between then we are going to also have align items uh set to Center great okay so what will be the content of this interview so here you're going to have the truck going to have the track title so we're going to use the moving text here actually not like that and we're going to pass the text to be uh to be actually the truck oops mistake track. TI the active track. title or an empty string uh the animation threshold will be set to 30 and then we also have a style to be Styles dot uh track title track title text uh that way and also we're going to WRA this stuff with the parent view so let's move this here and let's move also this over here and this parent view uh will be we have also style which will be equal to styles. artwork sorry uh styles. track title container uh great but we need to Define uh these two Styles so uh let's go ahead and let's define let's define these two missing Styles uh so the track title container basically will have Flex one and overflow hidden while the track title text will have the default styles. text with a font size of 22 and font weights at to 700 okay so we get some result awesome uh great let's go ahead and uh let's have the basically the favorite uh button icon and here we're going to use the font awesome um icon and we're going to use actually a dynamic icon where we're going to say that if is favorite uh we're going to display um we're going to display an art otherwise we are going to display an art- oh uh great so actually we don't have this favorite so for now I'm going to say that is favorite is false uh later we are going to Implement like we're going to uh retrieve a way to understand if the current rack has been favored by the user or not awesome so we're going to set also a side set to 20 and we're going to have a color uh set if is favorite is going to be uh colors do primary otherwise will be colors do uh icon great and also we're going to set the style to be margin horizontal set to 14 and then we are going to have also anpress function uh which is going to be named toggle favorite that for now I'm going to Define here toggle favorite favorite and will be basically an empty function for now uh great uh okay you can see that our icon is over here and our button icon and you can see that it wraps nicely with the title uh without uh overlapping one each other awesome okay uh Next Step will be heading after the button I think that outside this VI we going to have the track artist plus the actually uh the album but I don't think that we don't have any album so only the track artist uh so uh what we are going to do here is going to say uh if Tru do active track. artist is defined we're going to have a text component from react native this TX will be the active Tru dot I think it's artist yeah and the number of lines will be one and we're going to have also style which is going to be styles. Tru Artist Artist text and also a margin top set to 60 H to six sorry um great uh okay let's define this track artist uh text uh let's go inside our Styles and then let's define the track artist text like here let's import the tokens so we are using the default style text font side space opacity 0.8 and Max we set to 90% And you can see um the uh artist displayed over here awesome okay okay at this point we are going to have two new components which is going to be the player progress bar like that with the style of uh margin top set to 32 and then we're going to have the player controls which are going to have a style with a margin top set to uh 40 and after this view we are going to have a player player volume bar like that and this will also have a style of margin top actually margin margin set to Auto and also margin bottom set to 30 uh great and finally we are going to have under the player volume bar we're going to have a view and inside this view we're going to have the player repeat toggle uh control with a sides of 30 and a style of uh margin bottom set to uh six okay uh finally this wrapper container we have uh your tails actually not like that UTS oops UTS styes dot centered uh red row uh let's add the center red row uh actually yeah let's define the center draw here let me go here and do the center row it style and yeah I think that we are good to go so obviously it crashed because we have not defined all of this component so let's go ahead and Define this component okay so let's move inside the player controls and so what we have to do now is defining we basically have to create this sort of slider progress bar over here and also here but in order to implement a slider component we are going to import uh some third party libraries that will make our life easier so let's close this image and let's open up the terminal okay let's close this uh application let's clear it out okay so the first package that we need to install is npx X for install is react native uh just Handler so the react native Gest Lander is a library for managing gesture in react native then we are going to have to install uh react native awesome uh slider will be like that I hope the react native awesome slider uh provides very cool slider we're going to use to implement our progress bar and volume bar then we're going to need also react native image colors uh this Library will be useful for creating the background effect that we have seen in our truck player screen and finally to have that um linear gradient effect we are going we are going to install uh Expo linear gradient actually I think I misspelled yeah Expo linear gradient component awesome and there is actually a last Library called yes pattern and it is for uh handling pattern matching in a very modern way so let's go here uh let's run yarn add pattern great after having installed all of that Library we are going to uh run a prebuild um of the iOS native directory okay the pre-build this finished I not sure if we have to run a clean pre-build I'm going to try to uh run the application and if something's not working we're going to run a clean prebuild so let's go here and let's run npx Expo run iOS okay great it seems that it worked uh our application seems to work just fine without any error so uh what we're going to do now is open up our uh layout. TSX our root layout actually and what we what we need to do is to after the safe area provider adding the gure Handler uh root View and we need to wrap both the root navigation and the status bar also we are going to set the style to uh Flex one otherwise it will not uh work okay great so now we can just go back and implementing this component over here so we say that we were having this component inside the player controls so so let's go here and let's define player uh controls and let's take the style here we're going to take the player controls props and here we're going to return a view uh this view will also another view inside and here we're going to use the skip to previous button then we're going to have the P post button and then we're going to have the skipe to um next button uh great let's save and then let's go here and let's define a style which is going to be equal to styles. container and also the style that we pass from the parent uh prop so here we have to paste this awesome and over here we're going to have a style which is going to be equals to styles styles that's not work I don't know why and so let's define this container and row let's go here and let's type react native uh Styles sheet and we need to import him from react native Styles great so let's go here and pasting these two uh style so the container will just have the WID set to 100 and the styles. row will have the flex Direction Flex Direction row justify content space evenly and Aline item set to uh centered uh awesome and that was it for our player control uh if we go back to our player now we can import this and actually uh now we need to implement the player progress bar the playing volume bar and the player repeat toggle so let's start with the player progress bar okay so let's go here inside the component and let's create a new file called ler progress bar. TSX here we're going to Define our react component here progress bar uh okay not like that we going to do sign here we're going to take view props okay so okay so here we're going to return a parent view and this parent view will take uh this style from this parent style we need to import this view over here and now we can use the slider component that comes from react native awesome slider so let's simp import it and here we need to uh Define multiple props so the first props will be the progress props so the progress will actually uh came from book called use uh progress and this use progress will basically pull for truck progress for the given interval and this interval will be 2 um 250 millisecond so basically it will pull the current truck progress in order to uh see how much it does uh progress so from this hook we can extract the duration so the duration of the pro of the truck and also the current uh progress that uh over here is called position okay at this point since uh this slider component use react native reanimated under the hood we have to specify some value some uh variables using the react native reanimated use shared value so uh here we're going to say his sliding is going to be equal to use shared value and it's going to be false uh this will tell this component if the user is uh sliding along the the progress bar or not then we have the progress and this will be used shed value and initially will be zero then we have the mean value which will be use shared value and this will be also zero and also a max value and this will be also uh zero this will come in Endy soon when we are going to tweak the option of this slider uh component another important variable that we need to declare is the track elapsed uh time and this will be equal to format uh seconds to minute of the current position and con uh track remaining time of format seconds to minute of duration minus current position so these two variable basically are the variable that we see right here this is the track elaps set time and this is the truck remaining time so when the truck will progress over time this will diminish and this will increase very similar to a music truck player uh Works normally uh great so uh we need to Define this format sec to Minot function and and they're going to uh create under the alers folder a file called miscellanous UHS and inside this uh file we are going to paste this uh format seconds to minute uh I'm not going to stop explain how this function worked it basically takes an input the number of seconds and it formats in minutes like we see in the previous screenshot that we have seen before so as always you have the access to my G up repository so go there and check it out great so now we should uh we can import this uh function so import uh from um helpers miscellanous and from here we should have format seconds to uh minute so actually we can go here and replace these two great okay great so uh actually here we have also um condition where we say if sliding do value is false uh we're going to update progress. value to be equal to if the duration is greater than zero we're going to do position divide div by duration otherwise we're going to set zero so basically this is a simple way to calculate how much the truck has progress over time and it is done by dividing the current position by the duration but um yeah we're going to calculate only if we are not sliding otherwise we might encounter some uh weird error so inside the slider we can now Define the progress like that and also many other option for example the minimum value will be the mean and the maximum value will be the max so the mean will be zero and actually the max will be one and not zero okay great then what do we have actually we have a team property here we're going to specify the maximum trting color and this will come from color let's import these colors from Maximum reacting colors and also a minimum trating colors that will be equals to Colors minimum tracting colors uh Define the comma uh great also we have a container Styles which will be equal to detail styles do uh container uh which actually we don't have defined so let's go here sorry actually this is slider and let's go here and let's define the slider to have an eight of seven and aort the radi of radius of 16 uh great let's close this and actually uh let's save this and let's go ahead and also let's set the T WID set to zero also render bubble set to null so um basically we are iding the render bubble what do we get get also uh we're going to have also one sliding start this will be equal to um is sliding do value is going to be true so when we start sliding we are going to set this is sliding value to true and then we're going to have uh also actually let me just paste this just above the team just below the team then we're going to have on uh value change and here we're going to specify in a sync function with the value and here we're going to do a wait back layer um dot s to Value times duration great so basically every time we slide and we stop to a specific uh position uh we're going to use the SE operation provided by the track player awesome we're going to also have this fun this call back function or this Heaven Handler called onsl sliding complete so onslide in complete actually is it will be a sync function that will uh receive a value and inside the body what we are going to do is doing this if not is sliding do value just turn and so that means that if the user is not sliding uh we should not update the the current uh position uh then uh if it's sliding we're going to set is sliding set value to false because we are actually have finished sliding and also let's call the track player oops track player dot uh C to Value time duration so basically when we finish sliding we basically seek to the where we uh end up sliding awesome I think that that is the majority of what we need actually we need also to add another view to basically show the TRU elaps at time and the truck remaining time so here we going to have a text where we render the track elaps time this text will come from react native API so here great and the style will be equal to uh styles do time time text actually we have to define the style so let me go here let me add style shet and let me add the time text here we need to import some styling on side so the time text is basically we applying some default style text uh color font sides and Etc and also we're going to have another style called uh time row where we set the flex Direction row justify content space between and the light item set to Baseline uh great so this will become uh Styles and also here we're going to set the style to be equal to styles. time row uh great and finally we will have another text uh where we are going to basically display this so we're going to display the track remaining time uh prefix by a dash and also here we're going to set this styles to be time text all right so that was a huge component to build but we should be fine and yeah the next component I think that will be one similar component and it will be called player uh volume bar. SX so let's export on player volume bar this will be basically equal to okay so this component as we did before we take some VI props from react native and it will have as we did before uh some we use the use shared value from reanimated it will have a mean and max value it will have a progress and also this progress. value will be equal to okay actually let's do this before so what is will return we return a view with a style let's import is from uh react native let's define the style to be equal to uh style and we are also going to have another view where we're going to have a style where we set the fle direction set to row the Align items set to Center okay and here we are going to have an icons from ionicons uh so just to uh make it it more clear what we are building right now so before we have built this component here and now we are building this compon this volume bar right here which has a slider and then it has this icon and this icon so yeah let's do it let's import ionicons uh great let's import the colors great so this is the volume low and this the left hand side icon uh then we have basically this exact same slider as we Implement inside the player progress bar so I'm going to paste it just here and I'm import I'm going to import the uh the slider here we import the U style okay so basically uh we did the exact same things uh the only thing that changed that when the value of the slider change we're going to execute the update volume that we are going to implement soon great so actually after the slider we're going to have also another icon which will be the volume height icon and yeah I think that that's it uh we need just to implement this update uh volume so for doing that we are going to go here and we're going to use H stack player volume and from here we're going to extract the volume and also the update volume function uh great okay now uh let's implement this hook so let's go inside the hooks let's create used Tru layer volume. TSX and let's implement this hook so use track layer volume okay so inside here we're going to have a state which is going to be volume and then set volume this will be on use state which is going to be a number or undefined and initially will be undefined and then we're going to define a function called get volume this will use a use call back function and uh over here what we need to do is called const current volume is equal to await uh track player Dot uh get volume uh and then we're going to set the volume to be the current volume also since this use um a weight we need to uh specify the same keyword uh so where we are going to execute this get volume we are going to execute this get volume inside un use effect so let's go here let's divide the dependency array to depend from get volume and here we're going to to execute this get volume function so basically what happen is that when the component mount it will execute um like extract the execute the truct player get volume and set the value inside this state obviously we need to return the volume and also the function update volume that I'm going to Define just over here so let's define update volume and this will be a new scroll back so what we need to do here is check that actually the new volume will be a number and if the new volume is less than zero or the new volume is greater than one we're going to return because the volume must be between zero and one otherwise we just set the volume like that and also call the track player do set volume to the new volume volume great so this will be an a sync function okay so uh it seems that uh reactor called back as a missing dependency uh volume H yeah because this is an error this should be new volume great so we can just use this uh use Tru player volume over here so import it and now on value change we are going to execute this update volume and actually we are uh missing something uh we need to update this progress value uh with the current volume so we're going to do this progress not value is going to be volume but if it's not defined it will be zero great great job I think that that should be hit now if we go back inside our player screen we should be called uh we should be able to import this and also the player progress bar as well actually uh inside the player progress bar I think that okay it looks okay so the last component that we are missing is the player uh repeat toggle that we're going to implement inside our component so let's go here and let's say player repeat toggle. yesx so let's export a new react component player repeatle like this yeah so uh this component basically uh let's see what we are implementing right now so we are implementing uh this component over here this one and this can be in three possible State uh off State or repeat the current track or repeat the current Q so we have basically three different state so let's define this uh like the repeat order by defining uh variable called repeat order which will be an array and over here we are going to uh use the repeat mode do off for the first state then repeat mode do track for the second state and then the repeat mode do Q for the third state uh great yeah actually here we can say this will be uh constant uh so we can get a type inference from uh typescript great awesome so let's try to implement this component so basically here we just have to display an icon that is going to be uh dynamically rendered based on the current uh repeat State basically here we are going to have sort of State called uh repeat mode and we can set it for example to repeat mode. off for now but we are going to extract anook soon for managing this state so now we are going to extract an icon to manage to like decide what icon should be rendered based on this state so here we're going to do a pattern matching using match from TS pattern so here we're going to match the repeat mode and we're going to return basically an icon and this icon will be from will be of type icon name this icon name will come actually from uh let's define the type here will come from the component props of the material Community icons that we need to import so let's go here and let's import material Community icons from Expo Vector icons so basically the icon name is the prop name of the props of this component right here and we can also extract the icon props of the same component uh great so basically in the icon we need to return this icon name so what we're going to do is that we're going to do the pattern matching so if we get for example repeat mode. off uh we are going to return return uh repeat the icon repeat off instead if we are going to have the state repeat mode do uh track we are going to have the icon repeat once and finally and finally we are going to have a third state uh which will be this one if the repeat mode is C we're going to uh display the repeat icon and also we're going to have also a fullback icon which we are going to Define like that like order one we are going to uh return repeat off uh great so now that we have the icon we need to render it so let's return material uh Community icons uh we're going to pass the name of the icon that we choose and we are going to also pass aness function where we are going to execute the toggle repeat mode that we're going to Define soon and a color which is going to be colors do uh icon uh great also we are going to pass order props that we are going to extract from here so let's spread use the spread operators and here we're going to say icon props great so the component is um almost done we need a way to manage actually this state and for doing that we are going to extract a an N called use Tru player uh repeat mode so here you're going to say use Tru player repeat mode uh let's implement it so let's go inside our Hooks and let's Implement use Tru player repeat mode. SX let's go here let's define it use track player uh repeat mode and this is going to be so basically we are going to have a a state called repeat mode and also set repeat mode here let's use a new state and this will be of type repeat uh mode uh great then we are going to have a new effect where basically we are going to run track player. get repeat mode and when it's done we are going to set the repeat mode so yeah basically this is for initializing this Val Val when the hooks runs for the first time basically also we are going to return the repeat mode and also we going to export a function called change repeat mode and this will be a use callback function uh like that and here actually we are going to use a sync with our repeat mode to be equal to repeat mode type and here we're going to say await rock player. set repeat mode and it's going to be repeat mode uh great also we going set repeat mode to repeat mode to update our state so basically the pattern that we are seeing that every time we want to change something we need to update both the state but also the track player State because it's like that we have the internal state of our application and then another state that is internally managed by the truck player so we need to be sure to keep them in sync in order to have our application working as expected okay so let's go here and let's export this change repeat mode and that should be it for this component we can go back to our player repeat toggle import this and actually here we can extract the repeat mode and also the change repeat mode yeah I think that something is off here otherwise yeah I think we need to specify a function here that will say repeat uh of uh great uh we're missing only function toggle repeat mode that I'm going to Define over here toggle repeat mode and this will be a function uh where we're going to say if the current repeat mode is not defined we're just going to return otherwise we're going to take the current index by saying repeat order do index of repeat mode so basically we say uh inside these three possible state where am I right now for example zero it means we are in off State one it means we are in position uh we are in track mode and two it means that we are in Q mode so once we have the index we can compute the next index uh the next index that is going to be basically the current index + one and we're going to use the modu operator repeat order do length that means this module operator so basically what we do here is that is say that if I'm track I'm going to this stay that is q but if I'm Q if I uh if I do plus one I will go out of boundary and with this module operator actually we will go back to the off State so that way it should work as expected next we have to call our change repeat mode function by passing repeat order and passing the index that will be the next index uh great so we pass the toggle repeat mode here and now we are able to import this function over here and our player should will be uh ready I guess so yeah let's uh let's try let's try to run uh a song let's try to play a song like this one let's open it up and you can see that this working just fine we have all the necess necessary components that uh we need so you can see that the play post button uh is working also let's try our volume so I'm going to play my song and then then I'm going to increase and decrease the volume and it's working just fine now let's try the player progress bar so let's play it and it's working just fine you can also see that how the uh elap set time and the duration time are updated uh while the truck keep progressing awesome and I think the last button that we want to test is the repeat mode you can see that now we are in Q mode but if I press it we go into off mode so the next track in the queue will not be played and actually uh this icon that we see right here it means that uh the current track will be looped over and over again actually we cannot test it this feature yet and also we cannot test skip to next or skip to previous because we do not yet introduce the concept of uh cues and we're going to make it soon as soon as we introduce our internal State manager and after that we are going to have a mechanism to have a queue of song play one after the other also the favorite button is also not working because we do not yet implemented a way to favorite our songs but the most important thing is to know that our truck player is now working as expected so we can also select different song and you can see that is working just fine also here it's working just fine the last thing that we are missing is a super cool effect and it is linear gradient background that is based on the current images so let's try to implement it okay great so let's work on this truck player background effect for doing that we are we're going to extract ANUK called use use player background. TSX uh great so here let's export this use player background and basically this component like we take an input an image URL which must be a string inside here we're going to have a state which we're going to store image colors and also set image colors and let's use this use state to be of type iOS image colors that will come from react native image colors that one of the dependency that we installed before but actually this can also be null because we need to make a fetch call to retrieve these colors from the uh image that we want to that we're going to display so over here we're going to run a use effect and here we are going to then use the get colors that will come that get colors function that will come from the react native image colors uh this function will take the image URL and then some option for example the fullback uh color that in this case uh will be I will say colors do background then we are going to enable the caching and also the key will be the image URL great so since this is on a sync function we're going to use the prise API so we are going to use the den and here we are going to receive some colors and this colors are going to be uh set inside the set image colors and passing these colors as iOS image colors so here we are inference uh like we are uh inferring that the type is uh strictly the iOS image colors because we are targeting iOS devices but in case you are building for Android devices or you know cross device cross devices you cannot make this sort of inference so I encourage you to take a look at this Library Rea native image colors because it actually handles all the possible uh cases inside here we need to add inside the dependency array the image URL and then return this image colors great so now we can just uh we can start using this used player background so let's go back inside the player screen and let's use this hook so let's go here import the hook and extract the uh image C colors but obviously we need to pass the active track. artwork uh in case the image will not be defined we're going to use the unknown Track image URI uh great okay so at this point we need to create this uh linear gradient effect that will start from top and will end uh to the bottom so what we are going to do is to wrap all of this content ins inside the linear uh graded from Expo linear gradient Library so let's take all of this content and let's put it inside and here we're going to set the style set to flex one and then we are going to set the colors so these colors are going to be if image colors is defined it's going to be an array containing the image colors. background and so this is the starting color so from the uh top and it's going to go uh towards another colors which is going to be image colors. primary uh great if image colors is not defined we're going to return single elements array with the colors dot background great now if we hit save it should work as we expect let's try and it's working just fine let's try with also other possible songs for example let's try desert bro open it up and you can see that we have actually um a different effect but it's still based on this image uh let's try for example as you fade away and you can see how awesome his background effect and just with a few lines of cone and mostly thankful those react native image colors so our player screen is now almost ready we are missing all the skip buttons functionalities and the favorite button functionality but we are going we're going to implement it soon when we're going to have a way to manage our queue of songs so now let's move on with other features so the next thing where we are going to work on is the favorite screen so let's take a look of a preview of this uh new screen so the favorite screen basically will be exactly the same as the as the song screen we will have the same header the same buttons and also a list of song where we can scroll through along with our uh floating player visible in case we have a currently truck selected the only thing that we that is going to change inside the screen is the list of song that we are going to display obviously inside the fav screen we are going to display only the tracks that has been favored by our user so let's dismiss this preview and let's take a quick look at our library. Json if you remember we had a property called rating which can either be zero or one where one means that the user has favorite this song whereas for all the trucks that does not have this rating property or have the rating property set to zero that will mean that truck is not being favored by our user so let's go back and let's start implementing this track so first thing I'm going to close all of these stabs and if you remember inside the app folder we have tabs and we have the favorites folder and this favorites folder actually uh right now is displaying this text right here so favorite screen so let's actually close this player screen and let's open the favorite okay so what we can do is basically remove this text here and basically replicate the exact same layout we used inside the song screen so if you remember we had basically a scroll view uh from react native and inside the scroll view we add the tracks list so the tracks list takes in input a list of tracks and for now we are going to import the same Library folder but after this having implemented the screen we are going to start implementing um shared our state manager so we're not going to use directly our library from the mock Json file so here is just to make a demonstration of what we need to uh display so let's go here let's go inside the assets uh let's go inside the data and library. Json and here we're going to pass this Library also uh let's remember that we need to pass the scroll enabled set to fults and also yeah that should be it actually we need to apply a style here and say that the pting horizontal will be the screen pting do horizontal and also we need to apply another important property called content inser adjustment Behavior set to automatic in order to have our search functionality work as expected okay so right now I think that I just stopped my uh application so let's run it again and let's see our uh result actually in this way we are going to display all the library all the trucks inside our library but actually we want only to display the trucks that has been favored by our user so in order to do that uh we basically going to filtering our songs so let's define our favorite uh songs or actually favorite tracks to be let's use an a use memo here in order to uh optimize this code and here what we're going to do is to basically say that we're going to basically return library and then filter and here we are going to apply basically we are going to have a truck and this truck we are going to take only the truck that has the value set to one so now our favorite trucks should be what we expect so we can pass the favorites tracks here and actually uh we can also add H the search fun functionality so let's go here and let's use the use navigation search hook and in here we need to pass an object where we say where we specify the search bar option and inside we specify the placeholder which will be find in songs great and then we can also go here and extend our our filtering function so beside taking all the tracks that have the rating set to one we want also apply the track title filter by passing our search okay actually let's do it uh then okay so I think that now if we go to the favorite screen you can see that the page is looking uh the screen is looking fine because we have only the tracks that currently has the rating set to one and this is actually what we are searching for also the we have the search functionality we had the title so it's working fine currently we are not actually applying the search Behavior but we are going to do it uh soon the most important thing is to know that now the two screen work properly and another thing that I want you to notice is that if I for example play this song I'm going to stop it now and I'm going to change screen you can see how the floating player remains here without remounting and also if I play if I play the songs it keeps playing so you can see how placing the player inside a shared layout makes uh possible keep this component being mounted between our Ina navigation awesome so at this point before starting implementing our search functionality I think it's time for introducing a state manager for our music player application right now we are actually using our library as our States but actually we want something more precise and that can let us to handle our state exactly how we want in order to do that we're going to install a state manager called zand so zand is basically one of the easiest way to implement a state manager in react application using just plain hooks so let me just increase this window and you can see how simple it is uh to stand basically we are going to define the type of our store and basically what we're going to do is creating our store and then just extracting some sort of hooks for example here we are extracting an hook called ustore and in that way we are basically just playing around with react hooks that we can just hook up in our react components and from there access uh accessing in uh our state obviously uh this library is optimized for avoiding too many rendering Etc so it's and and also it's super simple to use and that is the reason why I decided to use uh zand it's simple it's very efficient and so I think it's the right pick for our Music application so let's dismiss this tab and let's install to stand so let's go here and let's open up a new terminal so from here we're going to run yarn add to stand so once installed we're going to go inside our Explorer and create create a new folder called store and inside this folder we're going to store our different stores for managing different domains for example the first thing that we're going to manage it will be the library so let's go here and let's create a file called library. TSX great so inside this file we are going to first Define our interface for our library store so let's define an interface called Library State and this will have a list of tracks that will be of type track with playlist so you might be wondering uh where we're going to get this track with playlist well actually we are going to Define inside the inside the helpers folder we're going to define a file called types. TS and in here we're going to just Define our type that we defined before so export type track with playlist and this will be equal to a track from react native track player and a property called playlist which will be optional and will contain a list of strings so if you're wondering why we're going to have this property playlist is basically because inside our library. Json remember that we have this property called playlist which is an array of strings and the strings contains the name of the playlist where that trucks app pertain to so that is the reason why we are basically extending our initial truck type with this new property called playlist actually we're going to have also two other type and and those will be a playlist so a playlist basically will be we have a name name which will be a string then we're going to have a list of tracks so track as an array and then an artwork preview which will be a string then you're going to have another type called artist so an artist will have a name will be a string and then we'll have a list of tracks oops this is truck so these are all the types that we're going to need in our uh music player application so let's go back to our library. SX so here now we can import our Rockit playlist and actually we can extend this Library State further so here we're going to also add two uh action that will be toggle track favorite and this will be a function that will take an input a track and will basically return void so here we can actually import this track from react native truck player and here we are going to have a second action that will be out to playlist this will be a function that takes a Tru and also a playlist name and we'll return void so we are going to implement this function later on on uh on this tutorial when we are going to implement the favorites and the playlist management but for now let's focus on how we're going to retrieve this list of tracks so here we going to define a n called use Library store and in here we're going to use create the create function from toand passing the type that we just Define so Library State we're going to call this function and then we're going to pass ini iiz function in here so this will be this will accept basically a sort of callback function where we are going to have access to the set function and inside this object that we're going to return we're going to initialize our use Library store so here in here we have to Define these three properties so the first property is the tracks property and this basically will be our library so so Library will be just be imported uh from our uh assets /data uh library. Json uh great uh then we are going to have uh toggle track actually I think that we need to drop this object inside the parenthesis otherwise uh we might get some error so let's see so here we should have toggle track favorite and for now we're going to just Implement an empty function and also here for add to playlist we're going to have an empty function uh great so our use Library store is now ready so now we what we can do is extracting two useful hooks that are going to compute like two utility hooks that are going to compute the values that we need starting from this used Library store for example we're going to have we're going to have a first hook called use tracks and these hooks what is going to do is using the use Library store access in the state and return state. tracks so basically every time we're going to use this use tracks this will return a list of track with playlist exactly this one awesome so let's go ahead and let's Implement also another hook called use favorites so this hook basically will be a little bit more complex compared to the use structs and here first we're going to extract the favorites trucks by doing use Library store uh accessing the state and in here we're going to do state. TRS do filter oops filter we're going to take a track and we are going to to do trate track. rating is equal to one this is basically the same logic that we did the exact same logic we did inside the favorite screen for computing our favorite strs awesome so we need also actually to we can also implement this uh toggle Rock favorite and we're going to do use Library store and we're going to accessing the state and accessing the state. toggle truck favorite so basically we are extracting this property right here from use Library store and we are saving saving it in this variable okay this hook what is going to do is returning the favorites and also the toggle FR favorite awesome uh later on in this tutorial we're going to also have all other hooks for example for managing the playlist for managing artist and so on but for this part we are good to go so now let's go back to our favorite screen and instead of computing the favores truck in this way what we are going to do is doing use favorites from our store and from here we're going to ACC in the favorites and then we are going to uh we're going to filter these tracks by applying the truck title filter and passing the current search awesome so now what we can do is first uh remove this use memo and extracting the our favorite TRS by doing use favorites do favorites at the same time we can also filter our favorites TRS by doing use memo and then passing this function right here so here we are going to do if not search we're going to return the favorite strs otherwise we're going to do return favorites tracks. filter and we're going to pass Here track title filter and passing the current search also here we have to specify the dependency array which will include the search and also the favorite structs awesome at this point we can take this new filtered favorit tracks and pass it down to our tracks list awesome let's save let's refresh our application let's go inside our favorites and you can see that the result is exactly the same actually now we can also be able to filter our songs for example let's run right outside and you can see that is working fine create we can start using also our new state manager inside the song screen so let's go ahead inside our up folder open up the SS folder index and in here what we are going to do is to extract our tracks here by doing use tracks and in this way we can remove our library from here here we can just return the tracks and also here can re uh replace the library with the trucks and here pass the trucks so let's save let's refresh and you can see that everything is working as expected so we still have access to our library of songs and also the search should work as we expect great so now it's time to introduce a very important concept inside our music player application so so far as you might remember we don't have a way to skip to the previous or next song inside our library of songs so for example if I go here and start playing this song The skip to next next or even the skip to preview will not work as we expect and this is because we never introduced the concept of a q to understand what is a q i just prepare a diagram that I'm going to show you so let me increase this and let me just Center it a bit right that should be uh visible I hope so so what is a q a q BAS basically is a list of song that gets played one after each other so for example if we are playing the TRU two the next song in the queue will be track three and after that that will be the track four and when we reach the end of the queue generally we start from the beginning so the most important thing to know about the queue is that every queue so every this kind of list of song have a specific ID because not every que are the same so to identify a q we need an ID why the concept of a que is important to understand in our application so let's move on to another diagram uh so so far we know that each of our screen so the song screen favorites playlist and artist uh each of them has like an internal cue so a list of song that we want to be played so basically every screen has basically an internal Quee and each of them have a particular ID for example the song screen will have is uh Q of songs with ID songs the samees for the favorit structs which has a q with a favorites so why it is important to to differentiate this queue for each screen well that is important because the track player internally has an internal queue manager so basically what we want to do is that every time we change we change screen we need to update the track player que so let's make an example let's suppose that we are uh actually playing a truck uh the TRU number two from the song screen and we go inside the favorite screen so when we go here and for example we decide to play the TRU number three basically the que uh the truck player now must know that the current Q active will be this one and not this one so not this one basically this is an a very important things to know because otherwise if we are not managing our queue in this way we might cause a very bad exp uh user experience because the user expect that every time he change uh a screen and start playing a song from that screen the the queue internally changed where that songs belongs to so this is a very uh subtle concept to know and it's very important to understand correctly also we must remember that this queue that we see right here so every queue Associated uh for each of of the screen that we have in our music player application will actually be uh ma managed by our justan state manager but instead the truck player will have his internal state which will be different from the zustan state manager so it's important to keep the truck player state in sync with the our m music player state which is managed by zand okay then so I hope that this is clear now and actually now we are going to start implementing the Q management so let's go ahead and let's start implementing our Q manager okay great so to handle our queue management we are going to have a a new piece of State inside our store so let's go here and let's create a new file called called q. TSX so what will be the type of this Q store so we're going to have anactive q ID which will be a string or null in case we don't have any Q active right now and also a function for updating the current active Q so set set active Q ID which is going to take an ID which is going to be a string and will return Point uh great so now let's export this hook called use QQ store here we're going to create a new Zan store passing the Q store and then passing the initializer function so inside here we're going to first set the active qad to be null because when we start the application we don't have any Q initially set and then let's set the set active Q ID which is going to take an ID and here we're going to use set actually we need to extract the set function from here and this set function will update the current state by passing the active QD to be thatd passed as input uh great finally we're going to have a u hook called useq and this will be just a function that will do useq store and we'll return the current state so from this use Q uh we are going to be able to extract the active Q ID and and to set the active Q ID awesome now let's start using this new state that we just introduced so let's close these tabs and now let's open uh the component uh tracks list so inside the track list the first thing that we're going to do is extending the tracks list props so now we're going to take an input an ID which will be a string this ID will basically uh identify the Q that is associated to the list of songs uh that is rendered by this tracks list awesome once we have this ID we can extract it from here okay so inside the track the tracks list component we're going to have we're going to use the hook use q that we just defined and from here we are going to extract uh the active Q ID and also the function function set active Q ID awesome uh we're going to need also another variable called Q offset which will basically uh be a number and it won't be a part of State since we uh we are not cuse a rerender when this Q offset change so we can store it inside a new ref and the initial value of this Q offset will be zero this Q offset will be important for managing uh for saving the currently uh index of the truck being uh played and will be super important for inside our uh endal Tru select function so what is going to happen now so right now when we basically select a song from our list of que basically uh what we do is loading the selected truck and then which just play but it is not enough we have to every time we play uh we start playing a song we have to set the correct active queue in order to have the skip to next and Skip to previous button functionalities so the first thing that we're going to do is to remove this code so what we are going to do now when we're going to select a song so the first thing that we're going to do is to identify the truck in index of the selected song so let's just go here and and let's just rename the uh this Tru param name to select the TRU just to be more clear awesome then what we are going to do is to extract the track index the track index basically will be equals to tracks. find index we're going to take the uh the currently uh compared track and if the tracks are the same so basically they have the same URL to the selected truck. URL then we find the track index that we are searching for so the track index will basically uh represent the index of the selected track inside our list of uh songs great so in case the track index is equal to minus1 it means that the TR was not found so we're going to just return and not doing anything awesome now there is an important part we need to understand if we are basically coming from a different Quee from the active one so basically we can have two use cases there is the first case uh in case we are not changing the queue so for example right now we are playing the anxiety anxiety song and I select another songs for example changing this scenario is basically the scenario uh in which we are selecting a song from the same queue but there is a second scenario where we are playing a song from for example from a different screen and then I go for example in another screen the the favorite for example and I select a song in here so here what happen is that we are changing queue and changing Q means that we have to update our internal queue so the uh what we are going to do now is to understand first if we are changing Q so let's define this function called is changing q and basically it is a simple comparison of the ID of the Q Associated to this uh track this component so we are changing Q if the current ID does not match the active Q ID uh the active QED let's remember that we take from the zustand store Al aome um actually here I made a mistake is is changing Q okay so what we need to do if we are changing Q so basically we have two ske the case in case we are changing q and the case we are not changing Q let's try to tackle first the is changing que so in case we are changing que basically we have to reconstruct the truck player que and how we are going to do that uh we're going first to to uh split the list of songs into part for example let's say that I select this song right here changing so what we are going to do is to extract first the part the all the songs before changing and then also the songs after the song changing so this one so how we're going to do that so we're going to first Define the before track and here basically we're going to do tracks do slice and we're going we're going to uh start from zero up to the current track index and then we're going to have also the after tracks that are going to be the tracks do slice. Tru index + one great so now that we have splitted our list of song in two part what we are going to do is this first we are going to take the track player and call the reset function so the reset function as you can see reset the player stopping the current track and clear the current queue what we need to do now is to select this song that we select as the first one in the queue so we're going to do await track player. add uh selected Tru uh and then after the selected Tru we want to play all the after tracks so all the songs that comes after the selected tracks in this case hotlanta and outside the box so we are going to do await Tru player. add after tracks awesome and then also we want a sort of uh circular um like a sort of circular navigation of our CU so once the selected truck has been played and when the after tracks has been played we want to go back to the beginning so we want to also play these songs right here so here we are going to do track player do OD before tracks awesome and after that so here basically we uh let's say we construct the new q and after having constructed we can just play the current song so let's go here and say await Rock player. playay so play basically will play the first song in the queue in this case the selected truck awesome there is also another important part here to do and it is updating the current Q offset so here the Q offset will be Q offset current will be equal to the track uh index and also uh let's not forget to update the current the currently active queue so set active Q ID will be equal to the current ID awesome okay so this one was the first scenario in case we are we were changing the queue so basically we were playing a song inside a screen and we select another song from a different screen so uh inside a different queue but there is also the other scenario in which we are playing uh we want to start playing a song which is basically in the same cue of where we are so this is a little bit more tricky because basically we need to select the right index of the song that we want to play so here we don't have to reconstruct the queue from scratch because the current active queue is the one that we want to play but we need to uh pick the right index of the the song that we want want to play so basically here we are going to have a variable called next song or actually next track index and this will be basically the currently track index so the track index of the song that we want to uh play so here what we're going to do is take the track index and subtracting to the currently Q offset do current and so in case the difference between this expression is less than zero what we are going to do is doing tracks. length plus Tru index minus Q offset do current great otherwise what we're going to do is to do track index minus Q offset do current so this is a little bit tricky to understand but I encourage you to take time to stop and try to to play with this code to understand why we are making these checks this is the only way I I found for having you know Q working as we expect and as always you will find repo on my GitHub you will find the link down in the description so yeah I encourage you to take a moment to understand how this code works so when we have the next track index that we want to play what we are going to do is to just do track player do skip to the next track index and then do track player. playay so you might have noticed that here we use the skip function and we are using the skip function because we are already inside a valid queue so we don't need to reconstruct the queue from scratch so okay that's that should be hit for our queue management this I think one of the hardest logic inside the this music player logic and yeah as as I said before take your time to understand how this code works and be sure to at least have a glance on how this logic is handling this part this feature which are the Q management okay after that I think that we can try to see if our queue is working as we expect so uh what I'm going to do now is to try to select a song and then skip to the next or the previous songs so let's try I'm going to select these songs and now uh I expect that if I uh press the skip to next button the cattle songs should be start to play so let's try it and that's it you can see now the player is in post state but you can see that every time I press skip to next it is updated correctly so also another important feature is that if I select this song for example it gets um selected correctly and you can see that our skip to next keeps working as we expect also if we reach the end of the queue and I press skip to next you can see how the que start become like start from the beginning and this is because uh we have the repeat mode set to Q awesome another important thing that I want to show you is that also the skip to previous button works so obviously uh both skip to next and Skip to previous work inside the track player so let's trite okay okay so anxiety that is correct so I expect to Memories start playing and you can see how this is working just fine okay also the other scenario that we add is that basically we we are playing a song from these screen songs so from the que Associated to the song screen and we change screen and we start playing a song from different queue but you can see that is not working why it's not working actually now it gets selected the right song why it's not working why when we select this new the song from a different screen uh does not get updated correctly that is because if we go here and let's run a typescript check you can see that we have some error and the error is that the tracks list now accepting input uh needs an input an ID and is the ID of the queue which this track list internally manage so basically here we need to pass a unique ID for the queue managed by the track list so for generating this ID we're going to have a specific uh function so let's go inside the helpers inside the Misan file let's just paste this function so this function is called generating song list ID but actually I will prefer to name it generate track list ID and this will take a track list uh name let's pass it here and basically what it does it takes an input a track list name and also an optional search functionality and from here it compute this string ID so the string ID basically is the track list name and if we have uh also a search Associated to that track list it appends this suffix right here which will include the search so let's start using this generate tracks list ID so uh let's go here and let's call generate track list ID and here we're going to pass we're going to pass as the track list name we're going to pass favorites and also the search uh variable in case we have a search going on also uh we need to do the exact same thing for our uh song screen so this one oh actually I just made a mistake because this was the song screen so here I'm going to rename this to songs and then I'm going inside the favorite and okay this is now is the favorite screen I'm going to specify the ID and here I'm going to say generate track list ID I'm going to pass the favorites and then I'm going to pass this search uh great so now it should everything should be correct let's run a typescript Check okay and now let's try again this particular case so we can see that the skip to next is working just fine also if I skip manually by selecting another song is working also the previous uh button is working now what I'm going to do is for example selecting this song then going inside another screen and selecting a truck from a different screen so here and you can see that is working so now this the truck gets selected correctly even though it's part of another queue and also the internal queue is updated correctly so now you can see that the queue is managed as we expect great we reach one of the most important feature of our application that was uh managing uh the internal queue of the truck player great great work okay then so the next thing that we're going to implement is going to be our play and Shuffle button so these two buttons right here so we waited until now because for implementing these two buttons we need uh all the logic for managing cues and basically what these two buttons will do is uh the play button will just uh start playing the current queue from the beginning while the shuffle button will take the current queue Shuffle it and then just playing the queue so let's just uh start implementing this button and so let's just close uh all of these stops and inside the components we are going to create a new component called Q controls. ESX so let's go here and let's export this Q controls react component so this component will have also some kind of props which we are going to call Q controls props and it's going to be equal to this type here so we're going to take an input a list of track and also uh we're going to take uh some view props awesome so now let's go here and let's extract these props so Q control props let's take all the tracks and also we need the style and the other view props great so now let's return a view component in here uh let's import this view from react native so this parent view basically will have two child view one for basically the play button and another one for the the shuffle button uh great so let's go here and let's set the style for this component for this view to one and let's do the exact same thing for the other view uh great inside here we're going to have a touchable opacity that will represent our button we're going to set an active opacity of 0.8 and we're going to apply not here a style and this style will be from Styles um do button uh actually we need to implement this style so let's go here and let's implement this style shet let's import these two Styles so we're going to have basically a button style and also a button text style so here we have to import the colors so the button basically we have some ping uh this background colors uh border radius uh some inner layout with flex Direction row justify content Center Etc and also the button text will have will inate all the default styles of text we set the color of the text to primary to have the red text colored and also font weight 600 font size 18 and text align Center uh great so uh we can actually do uh copy this exact same style and apply it here so touchable opacity and plus it here uh great so here actually we're going to have Al on press where we are going to handle play here while he near oness we're going to handle Shuffle actually we are going to handle the shuffle play oh great uh so inside the uh play button we are going to use an ionicons let's import ionicons from Expo Vector icons so so here we're going to use name will be play also sides will be 22 and the color will be colors do primary great and also in here we're going to have a text uh which is going to say play and let's import this text from react native so let's go here text play and the style will be uh styles. button text actually great so basically we're going to have the exact same thing for our uh Shuffle button so we're going to use uh an ionicons with the shuffle sharp icon SES at to 24 color and text set to shuffle uh awesome at this point what we are U missing uh is to implement this endle play and this endle shffle play but before doing that actually we need to apply a parent style to this parent view container and here we're going to set the flex Direction set to row and also a column Gap set to 16 and also we're going to merge it with the parent with the prop style uh awesome can also pass on The View props spread all the view props in here and now we should be able to start implementing our first Handler which will be handle play so handle play will be an sync function that what is going to do is to First away that truck player is going to set the Q to the current tracks that we pass in input and then is going to start playing uh that queue by running track player. playay and that's it for the endle play then we're going to have also the endle shuffle play and this also will be an a sync function and here what we need to compute first is the shuffle tracks so we're going to go here make a copy of the current tracks and then sort it using a random uh sorter so for a random sorter we're going to do m. random minus 0.5 this way basically we are generating a number which can be uh negative or positive with the exact same probability so let's go ahead and let's go here and say track player uh do set q and set the shuffle tracks and then do it the exact same thing so uh track player. playay uh great so that should be it for our uh two uh two button component and now we should be ready to start using this Q controls component inside our tracks list so we want these two buttons to be displayed like just under the search bar so here so in order to do that we are going to have this component in the in the header of our track list so we can go here and say list header component is going to be equals to few controls and here we are going to pass the tracks to be tracks and also we're going to set a style to have a padding bottom set to 20 great so if with save you can see that we reach what we were searching for and actually let's try and let's see if it does it work so now if I play I expect that this queue will start from the beginning so let's right and that's it so now if I press skip to next I'm expecting that it goes to the memory songs and it's working just fine instead if I press the shuffle button I expect in this to generate a random shuffle of these songs in a obviously random order so let's make it a try so let's uh let's press Shuffle okay and you can see that the truck selected is the cattle and now when I'm going to press next I'm expecting that a random song inside the same que gets selected so let's try it okay you can see that this truck has been selected as the next one let's see what the next one will be okay the second one let's make another try and this one was the next one generated so the two button is working just fine the the only thing that I want to add also is a way to manually control the visibility of this two button using a prop so what I'm going to do here is going inside the track list prop adding a property called i q controls which will be an optional prop and which will be a Boolean so let's extract this IQ controls and let's use it here so let's say that if uh we do not want to hide the Q controls we are going to display these Q controls otherwise we're going to set undefined so basically every time we're going to set this value to True from apparent component the Q controls will not be displayed otherwise they will be displayed correctly so we are going to going to set the uh default value to be false so by default we want always to display the IQ controls but in case we're going to pass it through these one are are not going to be displayed so if I go here and I set through you can see that now the Q controls are not visible but as we we were saying before we're going to set it false by default uh great so also if I we go back to the favorites yeah we get also the the control because uh in this component we are using the tracks list component as well great great job great now it's time to start implementing another screen of our application and that will be the artist screen so before starting let's take a look at a preview of The Artist screen so basically this screen will uh be composed of two screen actually the first one will will be a list of all the artist that we find inside our library and basically will be a scrollable list of all of our artists okay you can see that the item the artist item is very simple we are going to display actually a default uh unknown artist image because uh I did not bring any image for the artist inside this project and also the artist name when we are going to press on a particular artist we are going to open a new screen and that will be the artist detail so the artist detail screen basically will feature the main image related to the artist which will actually be this unknown artist image we are going to display the artist name we're going and then we're going to have our list of songs or list of tracks related to that artist and from there we're going to have a track list that we are is going to be managed as a queue so if we go here and for example we're going to press play we're going to play all the tracks related to that artist all right then so let's go ahead and let's close this tab and inside the app folder let's open up the tabs group and you can see that we already have the artist folder actually here we're going to make some new update so let's start by implementing our index file because right now is actually an empty screen so as we did for the other screen songs and favorites we're going to have a scroll View and inside we are going to have this time we are not going to use the tracks list because we are not displaying a list of tracks but we want to display a list of artist so here we're going to have a custom uh flat list that is going to come from uh the flat list component of react native so inside here we have to uh extract first our artist so here I'm expecting to have something like artist and then do like having an called use artist that will return us the all the uh artist found in our library so let's go implement this OS artist so let's open up the our hook uh folder actually not the hook folder but the store and open up library so in here under the use favorite we're going to define a new hook called use artists so this will be a function and in here basically what we're going to do is to use the Ed Library store we are going to extract the state and from this State we need to basically find all the artists that we find in the library. Json let's see what I mean by that if we open up our library. Json you can see that every tracks has an artist property so what we are going to do is to look over all of these tracks and save it and save inside an array uh the artist that we found inside the property artist but in case we found a duplicate artist we do not add that artist to our list of artists since we don't want duplicate artist obviously so let's try to implement this particular Logic for doing that we are going to use actually state. tr. rce so we're going to use the reduce function so the reduce function basically takes an accumulator and basically the current item that we are uh checking which is our truck so from here what we are going to do is this one the first thing is understand if the current artist that we are uh evaluating exist or not so let's Define a variable called existing artist and here uh we're going to use the accumulator and then do uh accumulator do find okay actually you can see that we are getting some typescript error I guess that we need to go here and say that we need to pass a second variable uh which will be the initial accumulator which will be empty and Mark it as a list of artist like that so now the accumulator should work as expect so here inste accumulator do fine we going to retrieve the artist and we're going to say we need to do an artist comparison and basically the uh the check will be based on the track. artist uh name so uh here we're saying that if the artist name is equal to the track. artist that we are evaluating then that artist already exist so here we're going to say if the artist already exist what we need to do so we need to push that truck to the uh list of trucks related to that artist otherwise in case it is a new a new artist we're going to push uh inside the accumulator and we are going to do B basically we are creating a new uh artist so we're going to say track. artist and if we don't have a name we are going to rename it un known and the list of trucks will be just the current truck so here we're missing a comma and yeah that should be it and finally we need to return the accumulator okay so uh that should be uh hit for our us artist now uh we can see that if we over actually there is a slightly uh problem uh actually we don't need this Carly braces but we need to just return this function and now you can see that use artist return a list of artist awesome so we can go back here and just uh import this new hook so now we have a list of artist okay so from here as always we want also some kind of search fun functionality so I'm going to define the search uh by using the use navigation search and I'm going to pass here the search bar um options and this is going to be equal to a placeholder oh actually I make a mistake here this should be an equal and here we should have uh actually let me rewrite this from the beginning so use navigation search and here we're going to set the search bar option and specify the place holder here that will display find in artists uh great so now we want also you can see that the search is displaying correctly uh what we want to do is also filtering our artist by the current search so so let's go here and let's define a use memo let's define the Callback function and in here we're going to do basically if not search we're going to return just the uh artist list but if we have a search going on we're going to return artists. filter do artist name filter by passing the search actually we need to implement this artist name filter and basically we're going to implement inside the helpers uh filter and basically here I'm going to pass this function uh basically the artist name filter takes uh a name and basically it compare the artist name lower case with the current search lower case so let's save it and let's use this artist name filter over here and yeah actually here we need the artist and also the search awesome now we can pass the data over here and passing the filtered artist awesome great so we actually need to do some other thing for example the scroll enable will be set to fults and we're going to also set the content container style this will be this will have a padding top of 10 and also a padding bottom of 120 awesome also the scroll view will have some style and this will have the padding horizontal I'll set to screen ping. horizontal and also uh we'll have a property called content actually will be content inser adjustment Behavior set to automatic uh great so let's go back to our flat list and we are going to also set the item separator component actually we need to Define it so let's go here and let's set con item separator uh component this will be basically a react component uh where we are going to return a view and this view will have this style right here we're going to use the utils uh styles do item uh actually we don't need to Define like that we can do just like here util style do item separator and then merge it with another style which will have a margin left of uh 50 and a margin vertical of 12 uh great so we can just go here and say item separator component uh awesome in the same way we're going to go here and say list footer component is going to be the item separator component to have the the separator also for the last item of our list and we're going to also have a list empty component in case we search for an artist that does not exist so inside here we're going to have a view and inside this view we're going to have a text which is going to say no artist uh found uh we need to import the text from react native so text great yeah also we are going to display a fast image and over here we're going to say Source it's going to be equal to U okay so here we are going to default we're going to use the no artist image URI but you should know that if you want to implement the image for artist over here you can add the image artist or otherwise fall back to the unknown artist image URI great so let's set also a priority which is going to be fast image. priority uh. normal uh great uh we need also style and this style will be uh utils styles that empty content image uh great okay at this point we miss the most important part of this component which will be the render item so how we are going to render the current artist so let's go here and let's define a new react component over here we're going to extract the item which will be an artist so let's let's rename as the artist okay so uh let's go here and basically we are going to return a link so everything will be wrapped inside a link from Expo router and the HRA for this link is going to be inside artist slash and then we're going to pass uh the name of the artist so artist. name uh that way so this is because uh when we're going to press artist item we're going to redirect to the artista detail screen so later we're going to go here and and we're going to implement a name. TSX and this will be the screen that is going to display the detail uh of an artist that we selected awesome but we're going to do it later so let's go ahead and let's add some new stuff so here we need also to add the S child prop otherwise we're going to have some problem rendering in the content inside the link and over here we're going to have a touchable highlight uh great so this St CH light will have an active opacity of 0.8 and also we're going to have uh parent view this for view we have a style set to styles do artist name uh actually will be artist item container and this will be a styles we're going to Define it later and then we're going to have another view which will drop a fast image and this first image will have basically these two props let me just paste it over here so basically here we are rendering the Anno artist image uh URI setting the priority to normal and also setting the style to artist image so let's go ahead and let's add these two Styles so let's scroll down and let's Define our Styles sheet need to import this from react native uh where is it react native should be here so let's say Styles sheet awesome and over here I'm going also to uh paste some Styles so let's go here and let's paste those Styles so we have a style for the artist item container we have a style for the artist image and also a style for the artist name text uh nothing too crazy so let's go ahead inside our first image and now under this view uh let's add another view and inside this order view we're going to display basically the name of the artist so let's set the style actually here we're going to have the text and we're going to say artist. name also and obviously the number of lines will be one because we want and we don't want any wrapping Behavior the style will be styles. artist name uh text awesome and also we're going to have I think it should be okay actually no because we need to go here and I guess that we need to set the width to be 100% and now it should work as we expected uh great so now our list of artist is displayed correctly awesome and let's try to search for for example an artist I don't know maybe uh telecasted okay it's working for example NX yeah yeah it's working fine uh awesome okay the next thing that we're going to implement right now is the artist detail screen so let's go here and let's define our artist detail screen and this will be a react component and since this will be a screen we need to remember to default export this AR this detail screen uh great so inside here what we're going to do is first extracting the name of the artist so let's rename let's rename it at the artist uh name and for extracting it we're going to use the use local uh search params from Expo router uh great also here we can just uh type the expected type to be inside our search for in this case we're going to have a name that is going to be a string uh awesome we can also have a check and say that if the we are not going to have well actually not here so let's go ahead and say let's get all the artists so let's go here and say use artists uh let's import it from the store library and now we need to search for the artist that we were uh looking for so let's go here and say You const artist is going to be artists. find let's say the current artist and compare it by name so artist. name is equal to artist name great so if we do not uh if we don't find that artist uh basically we are going to maybe console warning um artist uh artist name not found and also we're going to redirect the user us the redirect component from exporter return redirect and we're going to use HRA and over here we're going to say we're going to redirect the user to tabs. artist screen uh awesome okay over here we going to return a view and inside this view we are going to have a scroll view this parent view we have a style set to default styles. container let's import the view from react native and this scroll view we have the content inser adjustment Behavior set to automat and also this style will be we have a podding horizontal set to screen ping. horizontal awesome okay so this is the exact same pattern that we use for the other screen for showing a scrollable list of items but inside here we're going to have a custom component called artist tracks list and we're going to display all the tracks related to that artist so here we're going to pass artist to be the current artist and now let's start implementing this artist tracks list so we're going to implement it in a separate component so let's go here inside component and let's create our artist tracks list. SX let's create this new component so this component will take an input the artist so let's define artist here and we'll have a search functionality so search will be equal to use navigation search and we going to pass the search bar option to be equal to uh I when scrolling set to true and also the placeholder be set to find in songs a great then we want to basically get all the artist tracks but with a possible search applied on so let's define the variable filtered artists tracks this will be an use memo with a callback function and over here we're going to do we're going to return artist. tracks not filter and here we're going to say track title filter and passing the search uh great over here we're going to pass the artist. tracks and also the search so basically here we are filtering amongst the tracks uh related to that artist awesome so over here we are going to return our tracks uh list and we're going to pass all the necessary props starting from the ID so over here we're going to say generate track list ID we're going to pass the artist. name and we're going to pass the possible search awesome then we're going to have the scroll enabled set to uh false and also we're going to also hide the Q controls when we are going to we're going to also set the IQ controls to true because we are going to include the Q controls directly from inside our Adder so let's go here and say let list Adder component to be equal to uh styles. playlist Adder container actually I made a mistake actually inside the list component we are going to have a view and actually let's import this from react native and let's import okay here we don't we don't have to import anything actually so here we're going to have Al another view and this view will have a style to be equals to styles do artwork uh image container and over here we are going to have uh the basically the image of the uh artist even though uh we are going to use the unknown Track image uh U uh I'm going also to define the stylish the Styles and let's import style okay and let's import all the necessary Styles so let's go here and let's paste all the necessary Styles so basically what do we have imported here we have imported a style for the Ed container we have imported an artwork image a style for the artwork image container uh a style for the artist image and finally a style for the artist name text nothing too crazy so here I'm going to replace this with Styles and yeah we should be uh good to go after the image actually we are going to display a text just under this image and the text will display the artist. name uh let's import the text from react native let's set the number of lines to one let's set the style to be equal to styles do artist name text let's save and also we're going to have uh we're going to say that if the search. length is equal to uh zero so we are going to we are not going uh any search uh going on uh we are going to display our uh Q controls so let's go here and let's define our Q controls let's import it and ask the missing attribute and here we're going to pass the filtered artist tracks and also we're going to specify Style with padding top set to 24 uh great so I think that that should be it so so actually we are still missing some type let's see at missing attribute what we are missing and obviously we are missing the list of tracks so let's go here and let's pass the artist. tracks uh great so now we can go back to our name. TSX file and we can import just this new artist tracks list so now if we go back here and we select for example an artist we get redirected to this new screen but actually is something is off with the header so let's check it out so what we are missing right now is that we actually Define the file like the route but we do not actually declare it anywhere so we actually need to go inside our layout file in uh underneath the artist folder and and just declare this stock screen so let's go here and let's define stock. screen and let's set name to be uh the name which is equal to the corresponding file name and then let's define some option so inside this option we're going to set the adder title Adder title to be empty then we're going to have the adder we're going to set the other back visible set to true because we want to go back back to the artist list and we're going to have the other style and this is going to be have a background color of colors. background awesome and finally we are going to have the adder T color which is going to be uh colors. primary okay let's hit save and you can see that is working just fine awesome actually what I'm seeing right now now is that uh the poding here is not correct so let's check this out so let's go back inside our uh name. TSX file let's go inside the artist TRS list so over here we are missing the list header component style to be Styles dot artist uh header container so let's hit save and you can see that now now we have the nice padding that we are looking for awesome so yeah now we should be able also to play songs related for our uh artist for example I can select one song from netlix and you can see that the queue is managed correctly uh awesome we can also go back to the list of artist and obviously select other possible artists you know maybe track tribe uh or Patrick here uh Ryan mcaffrey uh you know uh whoever is your favorite artist so yeah I think that should be hit for our artist screen I think that the next step will be implementing our playlist screen okay next up in our menu will be implementing the playlist list screen so let's take a look at the preview of these screens so when we're going to click in the playlist tab is going to open this screen right here so we're going to display a list of playlist with is related preview image and when we uh press or select a playlist we're going to open a playlist detail screen that is going to show basically some information regarding the playlist along with all the tracks Associated to that playlist awesome so without further Ado let's start implementing these playlist screens so let's close all of these tabs and inside the app folder uh inside the playlist let's open up the index file so right now the playlist screen is empty and we can just remove this text so over here we're going to have the exact same pattern we use in the other uh screen so we are going to have a scroll view with the content inset adjustment Behavior set to automatic and we're going to have a style where we're going to set the padding horizontal set to screen padding set to horizontal inside here we're going to have a playlist actually playlists list and we're going to pass this scroll enabled that to fults uh also a list of playlist that we want to render actually this it's an S and also on playlist press here we're going to pass the handle playlist press so over here we're going to add some new hook so first we're going to add the search functionality by using use navigation search uh here we're going to pass this search bar option and pass the placeholder to be find in playlists then we're going to need to extract a list of playlists and here we're going to use the use playlists hook but actually we need to implement this H playlist so let's go inside our store actually store library and let's implement this hook so basically we are doing we are going to do the exact same thing uh we did for calculating the uh use artist look so if you remember from the library. Json every track has a list of playlist where the track is associated so what we're going to do is to Loop all over these tracks extract the playlist name and then just filter out the duplicate so let's go ahead let's go here and let's export con use playlists okay so here we're going to use use Library store and actually going to have a proper hook with Carly braces and we're going to first extract this playlist we're going to use the used Library store we going to extract the state and over here we are going to return state do fr. radius uh the the red will take an accumulator and current track and we are going to basically okay so over here we need to take the track do playlists and loop over this playlist uh here we're going to have the playlist name and so now we we need to check if the current playlist already have been pushed inside the playlist that we discovered so far so we're going to say X6 playlist it's going to be accumulator do find we're going to say playlist and here we're going to say playlist. name is going to be equal to playlist name actually we are getting some type inference problem I think that that is because as over here we need to pass the initial accumulator which will be of type playlist like that uh awesome so so now we're going to say if the playlist We already discovered this playlist what we're going to do is to take the existing playlist and we're going to take the tracks and we're going to push the current track otherwise if we discover just a new playlist we're going to push inside the accumulator so we're going to do accumulator do push and we're going to create this new playlist the name will be the playlist uh name uh then we're going to have the tracks which will be a single element array with the current track and then we're going to have the artwork uh preview which is going to be track. artwork and if we don't have the an art artwork defined we're going to use unknown Track image U uh also and finally we are going to return the accumulator as always okay that is not all okay actually think that I made a mistake because this part goes uh over here probably and now okay actually no this goes here and this also goes here yeah uh this was the error that I that I made uh before actually this code Maybe could be refactory a little bit well so this one are the playlist so you can see that here we're going to have a list of playlist and now uh we had also to define basically we want to return this playlist but at the same time we want also to extract the add to playlist action that we are going to extract from the used Library store so let's take the state and let's take state. to playlist and here we are going to return this on to playlist as well great so you can see that now our is playlist will return the playlist which is a list of playlist and an add to playlist function uh awesome so let's go back here ins inside our playlist screen uh file let's import this use playlist and let's go ahead with implementation now since we have search functionality I'm going to do the exact same pattern with it many other times so filtered playlists uh is going to be in a use memo and I have a function here a dependencies array over here and we're going to do return playlists do filter and here we're going to use playlist name uh filter and passing the search functionality actually uh we need to implement this uh function so let's go inside our uh helpers filters and let's paste this implementation actually not this one but uh this one so let's go here and let's implement the playlist name filter where basically we take an input a search and a playlist and basically we uh transform both the search and the current playlist this name to lowercase and then compare them to see if it includes that search uh awesome so let's save uh let's import this playlist name filter and now here uh we should have playist of playlist and also the search and also here we're going to pass the filtered playlist okay so we are going to also to Define uh the function const handle playlist uh press and this will take a playlist in input a playlist and is going to use the uh basically when we press on a playlist We are going to redirect uh we're going to use the router to redirect the user to the playlist detail screen so for doing that we're going to go here and use the user router from export router and over here we're going to do router. push and we're going to say slash tabs actually slash playlist and over here we're going to pass the playlist name so we're going to say playlist. name awesome uh great so we're going to pass this Ender playlist here actually here we made a mistake so now we should go here inside the playlist folder and adding the file for the screen for the playlist details screen so name. TSX and let's remember to add this also to the layout uh not this layout but the layout from the playlist folder so let's go here and let's add a new stock screen stock. screen uh let's set the name to be uh name between uh square brackets let's define also some options for example the adder title will be empty uh the adder back Adder back visible why I do not get Adder back I don't know what's going on okay Adder back visible true Adder style will be La a background color colors do background and then also the uh Adder pint color will be colors primary right uh that should be it we are still getting some error on the playlist screen uh let's see why yeah because now we have to implement the playlist list component so okay so let's go here under the components and let's create our playlist actually play playlist list. TSX so export const playlist list and this will be a new react component so okay here we're going to first Define the type of the props that this component will take an input so we're going to take an input a list of playlist so playlist oops I made that typo playlist col that and it will be an array and then we going to take on playlist and also we're going to have on playlist press which will take a playlist and we return return white awesome and at the same time we're going to take some prop from uh the flat list uh props by passing the playlist as the item being uh rendered great so now we can extract this prop over here playlist props here we're going to extract a list of playlist and playlist props that we're going to rename to handle playlist press and then all the flat list props okay great so okay it's always here over here we're going to have a search functionality so let's use use navigation uh search let's pass the search bar option and here we're going to say placeholder is going to be find in playlist then we're going to filter our playlist tracks so we're going to filter our playlist so con filtered playlist and we're going to use use memo and we're going to return playlist oops playlist. filter and here we're going to say playlist name filter byp passing the current search okay so use memo is not working because we need to pass a dependency array where we pass the list of playlist and the search awesome uh great so now we can Implement our render function so we're going to have a flat list uh let's import from react native we're going to pass the data will be our filtered playlist then we're going to as a Content container style which is going to be pading top 10 and a ping bottom of 128 as always uh then we're going to have an item separator component uh which will be item divider and also the list footer component which will also be the item divider okay so the item divider is the same that we did for many other uh screens so I'm going to paste it here is this view this is going to use this util style item separator and we're going to uh specify this uh margin over here uh awesome so let's go ahead and let's define also a list empty component and over here uh we are going to just display this content so basically we are going to display no playlist found with an image so let's import react native fast image let's import unnown Track image URI and let's import details uh Styles actually we need to import text from uh react native let's go here let's say text uh great uh so that was it for our list empty component over here we are going also to spread all of our blot list props and finally I guess that we need the most important fun uh props that will be render item so render item will basically be a component over here we're going to extract the item this item will be a playlist and we're going to render basically a new component called play list item actually playlist list item and we're going to pass the playlist that we want to render so playlist going to be this playlist and we're going to also pass the onpress function which will is going to be this function over here we're going to do handle uh playlist uh press by passing this playlist uh awesome so yeah at this point we miss this component playlist uh list item that we're going to implement it really quickly so let's go here and let's Implement playlist uh list item. SX let's go here and say export cons playlist uh list item uh this will be a new react component let me just paste the the props that we're going to take as input so basically this component will take a playlist as input and also detachable highlight props so let's go here and and let's ract this props so here let's say playlist list item props and uh here I'm going to extract the playlist and also all the uh order props fine so okay what we're going to render here we are going to render a touchable highlight so let's go here and this touchable highlight will have an active opacity of 0.8 and we're also going to pass all the props uh let's let's import this touchable highlight okay I just made a mistake this come from uh react native and not from react native Just Surrender so keep uh really um attention to that type of mistake on the import because uh are really subtle to the bug sometimes so let's go ahead and let's wrap uh let's add this View and this view uh basically will have this style and and let's define our react native stylesheet so let's go here Styles sheet and let me just paste uh this um styles let me remove this comment uh let me just quickly explain what style uh we had we have a style for the playlist item container we have a style for the playlist artwork image and a style for the playlist name uh text nothing too crazy let's go ahead so let's go Styles dot playlist item container so this will be the our item container we will have a view that will drop our first image our first image as always will have the exact same prop that we use multiple time so I'm going to just paste it here so this will be the basically the thumbnail of the the playlist list and then let's go ahead and under the image we are going to have this view with this style so we're going to use flex Direction set to row we're going to have a justify cont that set to space between then we're going to have a line item set to Center and finally a WID of 100% awesome so inside this view we going to render two things first a text which is going to display the playlist. name uh let's import text from react native uh great and this text will have a number of line set to one and also a style set to styles do playlist name text awesome and finally uh we're going to use an icon called and design uh which I'm going to import from Expo Vector icon and this will be have a name set to right the side set to 16 color set to colors do icon and style set to have an opacity of 0.5 and yeah that's should be it for our uh playlist list item so let's go back to our playlist list and let's import it actually here we can use at components okay let's hit save but still something is off because inside the index we need to import our playlist list uh let's go inside here and you can see uh that is actually uh looking fine so we have our playlist with its title uh it's thumbnail and also this icon over here that hints the user that if is going to press over is going to be redirected to the playlist detail uh screen uh so good now next step will be I think implementing the playlist uh detail screen uh let's just check it real quickly so we're going to implement this screen uh we're going to implement basically uh the image title of the uh playlist the two buttons and a list of the playlist songs uh great okay then let's start implementing our playlist detail uh screen so actually we already done some of the work because we already already have our name uh. SX file which is the uh playlist details screen and we already included the stock screen uh inside the layout. TSX so we're going to go here and let's define our playlist screen this will be a new react component and as always let export as default so playlist screen okay so here we have different things going on so for example we need to access the name of the playlist so let's rename this as playlist name and let's use the use local search par let's define the type the type will be name String if you are wondering this is going to be passed uh whenever we uh press on this item the expor outter we pass uh is going to pass this uh name search par param inside this screen awesome uh then we're going to use the use playlist book so let's go here and extract this playlist then we have to find for the playlist We want to render so let's go here and say playlist. find and here let's say playlist playlist. name is equal to the uh playlist name that we are searching for in case we are do not find the correct playlist We are going to console. war uh this uh string playlist uh playlist name uh was not found and in case we are going to uh redirect the user the playlist to the list of playlist uh screen over here we're going to say TOS do playlist and that should be it in case we found our playlist we are going to uh return uh basically a view let's import it from react native and this view will drra a scroll view inside and this scroll view will have a Content inser adjustment behavior that to automatic and also the style set to pading horizontal set to screen fing do horizontal and inside here we are going to render the play list tracks uh tracks list or the all the track all the list of tracks related to that playlist so over here we actually missing a style which is going to be the default styles do container uh great so here we're going to pass pass a playlist prop which is going to to be the current playlist and yeah I think that's it for this component uh now we're are going to implement this playlist tracks list so let's go here let's close the app folder and let's create a new file called playlist TRS list. TSX here let's export playlist TR uh list and here we are going to say okay and here basically we are going to return uh tracks uh list but obviously we have to Define all the necessary uh props so what we know we know that we have the a search functionality going on here so we are going to use the use navigation search here we're going to pause the search bar option and we're going to set up when scrolling to true and also we're going to set a placeholder set to find in playlist oops playlist uh great uh then we're going to filter out our playlist tracks and we're going to use use memo for that uh let's define the dependency array let's import this hook and here we're going to basically return playlist so here we're going to say oh actually I was missing something because here we need playlist as input so here I'm going to say playlist as the playlist type uh great so here we can say playlist. tracks. filter and we're going to use Tru title filter and passing the search uh the current search here we're going to pass the playlist. TRS and passing the search and this filter playlist tracks is going to be passed inside our tracks list and for our uh ID uh we're going to use the generate tracks list ID and we're going to pass playlist. name and also the search uh great so we have also to specify some other props for example scroll enabled is going to be false also we're going to hide the Q controls because we are going to hide it manually and also we're going to specify a list Adder component Styles which is going to be equal to styles do playlist Adder container so here what I'm going to do now will be importing style shet from react native then go here and specify some style and here I'm going to paste this uh pre computed style so let's import all the missing Imports on sides here so so here basically we are four Styles going on one for the playlist other container one for the artwork image container one for the artwork image itself and one for the playlist name uh text so let's go ahead yeah let's go ahead and after the list Adder component I'm going to pass the list Adder component itself which is going to be a view let's import this View and so over here we going to have first the another view for wrapping a fast oops or wrapping a fast image and this wrap image will have these two properties uh that I'm going to paste so the U will be the playlist and actually we are going to display the artwork preview of the playlist so basically uh what I'm referring to is uh uh this stuff over here this image over here okay so let's close it I don't know if it is going to work so if I'm going okay it's not working because we still have some problem maybe we can import it and save it and then go inside the playlist and try to open up okay right now we are only displaying the list of playlist the list of tracks Associated to that playlist so uh let's go ahead and so after the uh first image so after this we're going to render a text uh which is going to be imported from react native and they're going to display the playlist. name and here we're going to set the number of lines to one and the style set to styles. playlist name text okay you can see that we have something going on awesome and also we're going to say that if the search. length uh is equal to zero uh we're going to oops we're going to display basically the Q controls and we need to pass the obviously the playlist TRS as the que and also specifying a style which is going to be but it's going to have a padding top of 24 uh great uh something is still off off uh with the layout but we are going to uh fix it soon okay so I just figure out what the problem uh was is that inside the view that wraps the first image we need to have another style and the Styles is going to be styles. artwork image container and now it looks fine awesome you can see for example that we have this playlist called chill and these are all all the songs that I categorized as a Chill song and I put in in there so awesome actually we can just to play uh with it a bit so you can see that it works also skip into the songs uh you can see that uh we remain always in the same cue related to this playlist and also we can find S key inside the playlist for example I don't know maybe I want to search for anxiety and you can see that whenever I type A search the Q controls are eyed but the exact time and I'm going to clear the search they're going to pop up uh again so awesome uh we can also go back and just take a look at the other playlist that I created for uh uh for this music player application and yeah I think that we are almost there what we are missing right now are basically some uh Missing functionality if we go back to the song screen we are missing basically the shortcuts menu to add or remove a track to the favorite list or to add a specific song to uh a specific playlist also uh we want to have the toggling favorite functionality inside the player screen by just tapping on the her icon and also I want to just quickly uh give you a quick demo of the repeat uh mode so without further Ado let's move on with this other feature okay then so I think it's time for implementing this option right here here but first uh let's take a quick look at a preview of this uh menu so you can see that basically every time that we are going to press on this three dots icon a native UI menu is going to pop up and we are going to have two option displayed here we're going to have the first option that will be the possibility to add that song to uh a playlist and the second option will be add add in or removing that Tru from the favorites so to to implement this uh menu we are going to use um third party uh Library actually and that library is called react native menu so the library basically it provides this uh awesome actually I'm not able to uh Zoom more than that so basically we'll provide this uh Native UI menu and the fun thing is that it works also uh on Android and it provides also different type of menu for example here we have a sort of uh action sheet but we are going to use the default one which is uh this one so the installation you can see here we have to uh basically install install the library and then also rebuild our native direct uh directory in this case our iOS directory so so let's go ahead and so let's open up a terminal and let's run npx Expo install uh react native menu great I'm not so uh let's try to rerun uh so now let's rerun npx Expo uh pre-build DP iOS in order to clear the native directories and rebuild them and update the uh the eventual file that needs to be updated and then let's run npx Expo run iOS and let's see if it does it work while the application is rebuilding uh let's go ahead and let's Implement a new component called rck shortcuts uh menu do uh t X so this will basically will the component that will pop up when we are going to uh press on those three icons so track shortcuts menu going to be a new react component and so let's define the prop of this type of this component so it will be track uh meanwhile the application is restarted menu props and it seems to work and this will be props with children and we're going to specify and we're going to uh take the TRU in which we want to display uh the those option uh great so now let's go here and let's extract this props from Ro shortcut menu props let's go here extract the TRU and also extract the children great so so over here we're going to basically return this menu view is the component that comes from the react native menu and inside we're going to render the children awesome this menu view takes different uh props the first are the action that we need to display so in our case we're going to have two action the first uh so every action uh needs an ID a title and an image but also other props but encourage you to take a look at the libraries but for our case we need only these three props so let's start with uh the first uh ID for example will be add to uh playlist which basically identify the option that we uh select the title which will be add to playlist and then an image and here we can spe if Y images directly uh from uh the iOS or Android set of icons in this case since I know that uh we are in a iOS application I'm going to use the plus icon awesome uh we are going to also have a second option that is going to be dynamic or or like that second option could be add uh to favorite or remove from favorite so it will be a sort of dynamic option so to do that we're going to have to define the uh variable is favorite which is going to be equal to track rating is equal to one so our track is favorite if the track the rating is one and now on top of of our action uh we're going to put this ID so if it is the uh the track has been favored we are going to display uh actually we are going to use the ID remove from B uh otherwise we're going to use the add to favorites oops favorites also here it's favorites and the title also will be dynamic so if it's favorite uh we're going to display uh remove from favorites otherwise we're going to display add to favorites and also the image the image will be Cas it's favorite we're going to use star do fill other why we're going to use star uh awesome uh let's save it and also we are going to to specify uh non press action and basically this onpress action is going to be executed every time we press an option inside our menu so over here we are going to define a function uh an event handler function called endle press action uh which is going to take an ID which is going to be a string and it's going to be to execute uh something the most important thing here is to call this endle press action but we need to pass the ID so here the ID is going to be retrieved from the Native event and from the Native event we're going to take the event so the event is going to be the ID uh awesome so inside this endal press function we're going to uh do a pattern matching so we're going to use the match from TS pattern and we're going to match this ID so in case we the ID is on two favites what we're going to do is execute an a sync function and inside this a sync function basically we want to toggle the truck from being fa it or not so if you remember we had an hook called these favorites and from this hook we can extract the toggle Tru favorite function that we are going to implement it later and here basically what we're going to do is to toggle the TRU favorite and passing the current truck but we also need another logic in case basically if the truck is in the favorite Q uh we need to add it so we're going to do if so here to perform this kind of logic we're going to use the hook use Q which is going to return to us the active Q ID awesome so from here what we can say we can say that if the active Q ID uh which is can be potentially uh null starts with the string favorites uh we're going to do await track player oops Tru player dot uh let's import the TRU player from recogniz TRU player do add uh Tru so in this way basically we are adding this song to the queue if you're are running the if the the internal Quee that is running is the favorites one so for example let's say say that I go here and I'm running the I don't know maybe I go here and run this uh outa song so now my uh my qu is the one related to the favorite one so if I go here and add add uh and add this as you fade away to the favorite uh que this should be displayed inside the favorite screen but also to the current queue so in order to do that this is the actual logic that we need okay so uh we can go ahead with other P matching and say wait we want we are instead removing from aever uh we're going to execute another ASN function and in this function we're going to also we're going to also toggle truck from favorite and pass in the truck but at the same time we need to do the reverse logic of of what we did exactly here so we're going to do if active Q ID starts with favorites uh what we're going to do is taking the current Q so track player get q and we are going to identify the track to remove by doing q. find index Q track and we're going to do Q uh track. URL is equal to track. URL and then remove it by using track player. remove uh track to remove awesome so just to break up here what we are saying is that if the TRU is in the fav cuute we need to remove it so we need to remove it awesome uh okay so we have also a third case which is going to be the add to playlist and here what we're going to do uh actually if we want to add a song to a playlist basically we are going to uh show up a model that is going to uh show up from top to bottom and inside this model we are going to be able to select the playlist where uh we want uh the playlist to be added so uh since the model are can be handled by export rou uh what we can do here is first uh gaining access to the router using the use router H from export router and from here what we're going to do is to do router. push and then here we're going to specify a path name this path name will be uh models uh SL to playlist and we are going to pass uh some params and we're going to pass the URL of the basically the track URL so basically here we are passing the identifier of the track that we want to add to a playlist and the identifier is the URL so let's go here and say tr. URL also you can see that here we are getting some type script errors I don't know why it um types script is complaining I think it's because uh is unable to infer the correct type so I will leave this comment for now it should work and as a reminder here we are opening the at to playlist uh model so there is also a fullback case in case we are handling a case that is not meant to be in case we receive an event that is not supposed to be uh handled and here we're going to say unknown own uh menu action and here we're going to print the ID awesome so that should be it for our track shortcuts menu and actually what we can do is start uh using it by hooking it up uh to this icon right here so if you remember this item is name track uh should be track uh list item and uh if we scroll down this one is the basically the track option menu so what we're going to do is to wrap it with the track shortcuts menu uh like that so we don't need this and here we're going to pass the truck as the current Truck Yeah the truck should become from here here I think yeah and let's save and now if we press on the um the icons it shows up but uh actually the songs as also started that because when we click on this icon we want to stop the propagation of the event handler for triggering the you know the Handler of the item to start playing the song So for doing that uh we need to wrap this component with a util component called stop propagation and let's move this inside here and let's implement this like U components that I'm going to uh to create inside an util folder underneath the components folder so let's go here and create stop propagation ttsx so let's go so let's go here and say export const stop propagation here we're going to get children props will be props with children actually let's do like that here we're going to say props with children and here we're going to WRA everything with the view going to play the children inside import The View and over here we're going to have the prop on start R set responder and we're going to pass it through so this is to capture the event basically uh the event bubble event and then we're going to say on touch and uh we're going to take the event and we're going to say event. stop propagation and that should be enough for uh resolving our problem now let's go here and let's import this component let's save it uh here actually let me just import from add components also here uh head/ components okay uh just to have a clearer code base and now that should work as expected so let's go here and let's try to click on this icon you can see that it work without triggering the truck player without triggering the other event Enders now if I go here and I click over the track item you can see that um the tracks starts um as we expect but if we go here you know it works uh without triggering any other Handler and from here we're going to be able to add add the track to the favorites or add to the playlist so our next step will be implementing these two function great so we can start by implementing those two uh function and the place where we are going to implement this business logic will be inside the Library store so let's close this stabs and let's open the Library store great if you remember if we scroll all the way up uh we have these two function toggle track favorite and add to playlist and actually the current implementation is empty so we are going to implement this two function just right here let's start with the toggle Tru favorite so here what we're going to do is to take the track that we want to toggle and it that should be in front inferred as a truck uh let's see and basically what we're going to do is to update the current uh state so uh here we're going to uh extract the state and we are going to return the updated state so this new updated State basically what we're going to do okay so here we need to update our uh trucks that are stored inside the library to find the truck that we need to update and toggling the property rating uh between zero or one so what we're going to do is to update the tracks property so just right here we're going to do state. TRS do map this map will return us the current track that we are iterating to and inside here we're going to update um some conditional logic so first we need to check if the current Tru is the one that we want to update and we're going to do this by checking the URL so current track URL is equal to the track. URL then we're going to update the uh the rating for uh this current track basically here we just return the current track but we are going to update the rating and the rating will just be if the current track do rating um is equal to 1 it becomes zero otherwise it become one so this is basically a logic for applying the to link or that means uh adding or removing from the faites then if we instead we are evaluating the truck that is not the one that we want to update we just return the current uh track awesome actually I misplace the return so uh here we have to return the current truck just uh here uh great now it should be correct instead for the add to playlist we are doing something similar so in the to playlist we're basically going to have the track and the playlist uh name and here we're going to always we're going to apply the same logic by using the set function extracting the state and then returning the updated state in the updated State you're going to update the tracks to be state. TRS do map and we are currently we're going to extract the current truck and from here we are going to apply uh also some additional uh apply some conditional logic and we're going to say if the current track. URL is equal to the track. URL we are going to return return the current track but at the same time we're going to update the playlist property of this Tru and basically what we are going to do is to First spread all the current uh Tru playlist where this uh tracks belongs to by doing like that and in case uh does not appertain to any uh Tru playlist we're going to use an empty array and then we're going to have or we're going to append the playlist name otherwise we are just going to return the current track uh here we're missing a comma and we should be good to go so just to be more clear let's open up our library. Json so uh adding to a playlist basically means that uh for example if I want this Tru to uh pertain to a new uh playlist basically what we're going to do is to add the new playlist name uh just here uh so basically we are going to append the new playlist name at the end of this playlist array and instead for the toggle track favorite basically we are going to map all over these uh trucks find the truck that we want to update and update the rating property uh great so this was the two function that we were uh Missing and now we are able to apply uh this function where we need so uh let's go back so now let's just refresh our application and you can see that these are the currently uh favorite tracks that we have and let's try to see if the add to favorite work as we expect for example this desert blow this tracks desert bro let's try to add to the the favorites so I just I should have added to the favorites now if I open it again uh it say remove from from fites and now if we go here you can see that uh okay we are desert bro we are the desert bro so you can see that is actually right here awesome and we can do actually the same go here and remove from favorite and you can see that is actually remove uh you might remember that if we open up a song with our player screen uh like this for example we have this button right here to adding or removing a song from the favorite actually this button is not yet implemented so we are going to implement it now okay then so if we open up the player screen which is this one you might remember that the is favorite and the tole fav are currently mocked so what we are going to do now is to uh remove this mocked code and we are going to use an new hook called new stru layer favorite and from this hook we are going to extract his favorite and also toggle favorite so now we have to implement this H Tru player favorite so let's go here inside the hooks folder and let's create a new hook called use Tru player favorite. SX and here we're going to export this use truck layer favorite so this hook basically will first extract the currently active truck by using use active truck from react native truck player then is going also to extract all the favorites track and also the function toggle Tru favorite and we'll exract this information from the hook use favorites now uh the first thing that we are going to compute is understanding if this truck is fa or not so we are going to compute is favorite to be uh favorites. find and we're going to compare the track and we're going to say if track. URL is equal to active track uh do URL and we are going to say we are going to check if the rating is equal to one so basically in this uh code snippet we're basic basically finding for the for the active Tru inside the list of our favorite song and we are checking if the current track is favorite you might be wondering wait why we need to check from the you favorite trucks whether this uh the truck that we want is favorite or not couldn't we just do active track do rating is equal to one actually no because the problem is that this use active Tru uh comes directly comes directly from the TRU player internal uh State and as you might remember we do not want to use the TRU player internal state to make assumption we want always use our zustan state manager that we set up for uh making our assumption for example checking if the truck that we want to update is uh has been favored or Not by the user so this is the reason uh why we need to make this double check that might not be so intuitive uh great so here we're going to return this is favorite but we're going to also to return a function called toggle favorite and this function will be wrapped inside a use callback so like that and here we're going to do first we're going to retrieve the ID of the currently active track so we're going to do tr player. get active track index and then we're going to do if the ID of the current track is null we're going to return actually we are here is important to say not to use the triple equal but the uh equal equal because we in that way we are going to check also for undefined uh value and here we're going to do we're going to update the metadata for this truck uh inside the truck player internal state so what we're going to do we're going to do track player update metadata for track and inside here we're going to pass the ID of the fun of the track that we want to update and we're going to also to update rating so if the this Tru was uh was favorite now we're going to pass zero otherwise we're going to pass one awesome in the same way we're going to do if the active track is uh defined we're going to do toggle track favorite by passing this active track and as you might remember this toggle Tru favorite comes from the use favorites so basically inside this function uh uh we are basically we are uh updating both the track player internal uh State here so here we are updating uh track player internal State and the application uh internal date over here so here we are updating the app internal St inside the dependency array we're going to pass his favorite also toggle Tru favorite and also active Tru uh awesome now we're going to export this toggle favorite and our us TR player favorite hook should be ready to be used so let's go back to our player. SX and let's import this new hook great now this tole favorite should be used uh let's search for toggle favorite and should be used by our favorite button icon so what is going to happen is every time we are going to press this button the truck will be added or removed from the favorites so what I'm going to do I'm going to refresh the application I'm going to select a truck for example this one and here I'm going to set it as favorite so uh does not seem to work as expected and that because I think I didn't save this file so let me just refresh the file the application again let me just select this song let me open uh let's try to press this button and you can see that it seems to work so now we unite the song and now we fav it okay now the this track anxiety should be should have been favorites so if I go back to favorites you can see that has been haded here awesome let's try to go back here and remove it from the favorite you can see that has been removed from the favorite list awesome and so now we have a way for a favorite or unfavorite the truck also from our player screen awesome another thing that I would like to show you is the track player repeat mode button actually this button as you remember can be toggled between three different state of Q and truck right now it's set in Q mode that means that when the current Q is finished so when it uh reach this uh the last song the queue gets like repeated all over again so we'll restart from uh the beginning the other like state that we have are the off mode so basically the off mode means that means that when the que uh is going to be uh finished the uh the queue will not Loop over again so it will stop over there but actually there is a more like more uh common functionalities which is the third state which is Loop over the current song and this is super awesome because uh if we set this mod and we uh seek to the end of the truck you can see that the trucks will start over again let's check it out you can see has the truck has been restarted again a super cool feature that every music player should have great so now that we have a way to add or removing tracks from the favorites list we can also add the option to add these trucks to a playlist so for doing that we're going to need a new screen uh which is going to be a model screen that will pop that will show up when we press to add playlist uh right now anything happens because we don't have that screen yet but we are going to implement it now okay before starting let's take a look at a preview of this model so this will be our model that will show up when we are going to select the add to playlist basically will be a pop up that will animate from Top from bottom towards the top and from inside this model we're going to be able to display a list of screen where the selected thre could be obviously we are going to also display the playlist where that tracks does not belong it yet so for example here we are selecting A TRU that does not belong to any playlist so all the playlist are shown but in case we are for example selecting A TRU that is already present in all the playlist that we have this list will be actually empty because it will not be possible to read it to a playlist which already it belongs to so let's go ahead and let's start implementing this screen as we said before this will be a screen that will be implemented as a inside our app folder and if you remember we previously defined a link that was redirecting inside models and inside here we add add to playlist so let's define our add to playlist model and this will be basically we'll return a safe area view from react n Save for your context and actually I misspelled return here and inside we're going to show a list of playlist so playlist list we already have this component from before and here if remember correctly we need to pass a list of playlist and also on playlist press so let's Implement these two props so the playlist will come from the hook use playlist and from here we're going to extract all the playlist available and also add the add to playlist function then we're going to need also so the tracks so use tracks and also uh we want to know what track we should try to add to a specific playlist so over here we are going to Define our track URL which we are going to take from the user local search params and the type will be of track URL and here we're going to specify track of property URL great so now we should have basically uh typescript Support over here you can in fact you can see that track URL is a string uh awesome what else we need actually we need to find uh once we have the TRU URL we have all the trucks actually let's move this here like that uh we need to find the truck that we want to H so let's do truck is equal to TRS find to so here we're going to say current track and we're going to do the track. URL is equal to the current track. URL awesome uh that way we should be able to find the TRU that we need okay actually I made a mistake here because this one should be track URL and now it should work here we're going to say that if the TRU is not uh is null or R fine we're going to return return null or actually we are going to uh we're not going to render anything because the truck was not found so basically here truck was not found awesome and then we need also to uh retrieve the available playlist available playlists so the available playlist basically are the playlist in which the tracks can be added so we need to filter out all the playlist where the tracks already belongs so we're going to do playlist. filter and inside here we're going to do playlist and here we're going to do list. TRS do sum so sum it means that there is at least one match in here we're going to extract it current track and we're going to say if the actually not truck but we're going to say playlist track and we're going to say playist track. URL is equal to track. URL great and that should be it awesome this available playlist will is going to be added to the list of playlist that we want to render and now we need to Define on playlist press so let's let's define over here handle playlist press this will be an a sync function that will take a playlist type will be of type playlist let's import it and what it will do so here what we're going to do is to first run a to playlist of the current track and we're going to pass the playlist. name remember this to playlist comes from the use playlist hook uh and also what we're going to do is to do router. dismiss and this uh should close the model actually we need this router uh to access this router so we're going to do router equals to use router H awesome and now it works there is also another check where we're going to say that if the current Q is the playlist uh we are adding to uh we need to add the track at the end of the queue so basically here we're going to say that if the active que ID uh starts with and here we're going to say playlist. name we're going to do a wait track player Dot and we're going to add to the current Q so now we need to access this active Q ID and if you remember we can just use the hook use q and here extrac active Q ID and now it should work just fine finally we are going to add this event handler just here and I'll playlist press and it should work as we expect now what we're missing is to add this model uh to be presented as a model so what we're going to do is to open the root layout which is going to be this one scroll it down inside the root navigation and here just below the stock screen player we're going to add a new stock we're going to add a new stock do screen and inside here we're going to specify what is the file that we want to open so it's going to be model slash to playlist and we're going to specify also some option inside this option we're going to specify the presentation which is going to be a model then we're going to specify the adder style which is going to have a background color of colors. background and also we're going to specify an another title which is going to be add to playlist and also another title style which is going to have color of colors. primary actually course. text sorry and that should be it let's refresh our application and it seems that we have some kind of error is say that no route name models are to playlist exist in Access children so let's see what is going uh what is happening so should have added here add to playlist uh okay I guess that we are not the problem is that we are not exporting this compon component so let's go here and say export default uh to playlist model great and now it should work as expected okay let's write out so let's say that I want to add this song to a playlist I go here and click uh and press add to playlist and you can see that it seems to work but so we have the title and a search bar but there is something off with the content inside so let's go back to our add to playlist okay the problem that we are having is that we need some kind of uh style inside our safe area view so let's go here and let's add uh this styles. model container and also a padding top of header height so so let's first get this header height from uh here for example so con uh Adder height is equal to use header height and this will come I guess from react navigation elements okay so from here let's do this way okay so we are going to have some ping top equals to the header right and now we need to Define this Styles model container so let's go here and let's say reactnative Styles shet let's go inside the react native which I think I didn't import yet so let's go here let's define Styles shet from react native and let's define our model container to be equal to actually we're going to use the default styles do container and now let's import this and also let's specify a padding horizontal equal to screen pading do horizontal uh great now let's trite again and this working fine you can see that uh since this song uh guest never know it already belongs to the instrumental playlist and rap playlist when we are trying to adding to a new playlist only the chill playlist does show because it is the only one where we can add it so let's check if I uh if I select chill playlist you can see that model gets dismissed now if you uh if we go back to the playlist and open up the chill playlist uh you can see that uh it's working fine actually is not working fine because I see two uh duplicate uh two duplicate tracks so I think something uh is off okay I guess that I figured out what the problem was and I think that the problem is inside our com our model uh to playlist so if we scroll all the way up uh you might remember this function where we calculate the available playlist and basically here the filter function is not completely correct because we need to put a exclamation mark uh as a prefix of the entire predicate otherwise we are basically reversing the logic so instead of taking the playlist in which the truck does not belong we were taking the trucks in which the truck was already inside it so just adding this exclamation mark basically will reverse the logic so so let's try it again now I go here and say add to playlist and now you can see that only instrumental a rep so uh shows up so let's try to select rep go back to playlist open up rep and you can see that now we have the guess never know tracks and is only repeated only once because before was not present Also let's make also for example another another test for example let's say chill so chill has only this song and I think that for example as you fade away should not be inside chill so what we are going to do is to add to playlist Chi is correctly displayed we add it and then you can see that the as Fade Away song is appearing correctly and we can actually play it awesome and this was our last piece of functionality that our Hub will feature there's going to be one last Cherry I will say on top of our cake which will be enabling remote controls so let's see what remote controls are so when I'm talking about remote controls basically I mean the possibility of uh let me just minimize this a bit is basically the possibility of controls our songs from within the lock screen or even inside the control center so basically is this UI right right here uh that is going to display when you lock your screen on when you pull down your control center I'm just going to show up uh the control center uh version so so if you go here you can see that uh basically I just swipe down and the control center shows up and basically from here we should be able to have an a set of capabilities to control our background uh music actually uh achieving this feature is quite simple using react uh Tru native player but there is a big cavea so I uh according to the react native uh truck player documentation this functionality can be added only to uh specific devices and these devices are basically not iOS simulator so you can see in this part that as of as of iOS simulator version 11 Apple has removed support for Control Center and now playing info from the simulator we will not able to test lock screen controls on recent version of iOS simulators so the only option that we can have are either test it on real devices or download older version of iOS simulator so I unfortunately I wasn't able to retrieve a older version of iOS simulator since was quite uh complicated to do especially with the latest version of Mac OS so what I can show you is just a screen recording of my real devices and that is actually this uh video that I'm overlaying right now you can see that I'm able to play sorry uh just let me stop this and move it down you can see that I'm able to uh Play the song or stop the song using the lock screen uh controls I'm able to I'm able to skip the song to the next song or previous song and also I should be able to open up directly my application and you can see basically that uh when I unlock my uh device the music that the application that I was using was actually uh the application that we uh were building so I'm going to show you right now how to set up this capabilities inside our application but keep in mind that this functionality can only be tested on real devices or only on very old iOS simulator also uh keeping keep in mind that uh there is also another step to take in consideration let me minimize this and inside iOS to allow background audio playback on iOS we will need to activate the audio AirPlay and picture and picture background mode inside X code without activating the audio will only play When the app is in the foreground so I can just quickly show you how to add this capability using xcode so let's open up xcode now let's open an existing project and let's go under project YouTube music player and let's select the iOS folder okay from here let's select the music player let's go under sign in and capabilities and here actually is already active but I'm going to remove it also push notification so I will go here press on plus capability search for background modes and here we're going to activate this property right here which is audio AirPlay and picture in picture uh great once uh we have done it uh we should be able to add these capabilities to our our music player application so the first thing that we need to do is closing this tab and then open up the constants folder and here we're going to define the playback service.ts so we're going to import from within this file the truck player and also the event from react native Rock player and now we're going to export our playback service and we are going to do this will be an a sync function and inside this aing function we're going to do track player. add event listener and we're going to listen for the event uh Remote Play and we are going to do when the remote play is executed we're going to do track player. playay and the same for for the other events for example track player add event listener uh event. remote POS and here we are going to execute track player. pose then uh we're also going to add three other event listener which are going to be the remote stop where we are going to stop our T player remote next to skip to the next song and remote previous to skip SK to the previous song great then what we need to do is going back to our PP root layout uh scroll all the way up and just under the preved auto sync we are going to do track player do register playback service and here we're going to pass the initialized function where we are going to return back the playback Service uh great uh there is also another thing to set up and this this is inside the US setup track player so inside here you might remember that we were executing uh we have this hook but this Hook was actually running the setup player function that was this function right here so here we need to do another step which is Tru player. update options and from within this update option we are going to specify for example the rating type which is going to be rating type. heart uh this is actually something that we should have done previously but uh it's not too late and then we we're going to add the capabilities that we need in this case we're going to add actually this is an array we're going to have capability. playay uh then we're going to have capability. pose then capability do do skip to next also capability. skip to previous and also capability. stop obviously here you can add all the capabilities that you want and that will fit into your application feature and functionality so that should be it for setting up our uh remote controls features and that should be it actually for our application uh itself so let's TR just to refresh it and yeah I think that that should be it for the application it should work as uh as expected and we should have all the features that uh we need for this application okay guys I think that's it for this project I hope that you find this video useful but most importantly I hope that you learned something throughout this journey in case you need the complete source code of this project down in the description you will find the official GitHub repository along with the link to my Discord server in case you need help or just want to chat with me as always if you like the video please leave a thumbs up subscribe to the channel if you haven't and we will catch in the next video
Info
Channel: Code With Gionatha
Views: 44,293
Rating: undefined out of 5
Keywords: react, typescript, tutorial, webdevelopment, music-player, expo, zustand, react-native
Id: 9CElrkFwiBU
Channel Id: undefined
Length: 411min 56sec (24716 seconds)
Published: Sun Apr 07 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.