
No Comments Yet
Be the first to share your thoughts and start the conversation.
If you're having trouble with the expo initial configuration with Expo v51, run this command:
npx create-expo-app@latest ./ --template blank
Be the first to share your thoughts and start the conversation.
How did you manage to remove the blur property and reach here?
Upgrading gives you access to quizzes so you can test your knowledge, track progress, and improve your skills.
By logging in, you'll unlock full access to this and other free tutorials on JSM Pro.
Why? Logging in lets us personalize your learning experience, track your progress, and keep you in the loop with new workshops, coding tips, and platform updates.
You'll also be the first to know about upcoming launches, events, and exclusive discounts.
No spam—just helpful content to level up your skills.
If that sounds fair, go ahead and log in to continue →
Enter your name and email to get instant access
In this video lesson, we focus on implementing the homepage for a React Native app using various components and features. The speaker takes us through setting up the layout using a FlatList, implementing search functionality, handling video data rendering, and utilizing context for user information. The lesson highlights core concepts in React Native and best practices for building scalable applications.
00:00:00Â And now we are on our home component within the tabs.
00:00:05Â And now I think you can barely see it at the top left, but it says home right there, which means that we are ready to start working on the home screen.
00:00:13Â And that should look something like this.
00:00:16Â We have welcome back JS Mastery so we know we're properly logged in and we're going to pull our username from that global context we created.
00:00:25Â Then we're going to reuse our input for the search.
00:00:29Â We're going to show some trending videos and we'll have another display for all of the videos that people upload.
00:00:36Â So, once again, amazing job for coming this far into the video, learning how to create React Native apps, learning how to do file-based routing within
00:00:47Â React Native, learning how to use Tailwind, or should I say Nativewind, within our app, importing all of the assets, crafting three beautiful screens with
00:00:58Â React Native components and implementing AppRide for our user management, databases, and storage.
00:01:05Â More on that later.
00:01:06Â So let's get to the good stuff and let's implement our homepage.
00:01:10Â To get started working on the homepage, we can wrap everything in a safe area view, similar to what we have done so far.
00:01:18Â And this safe area view will come from React Native safe area context.
00:01:24Â Right within it, for the first time, we'll use a component known as a flat list, coming directly from React Native.
00:01:33Â It is a self-closing component to which you can pass a lot of props, and it is used to render a list of elements.
00:01:42Â We mentioned it in the crash course at the beginning, but now we're going to put it to use.
00:01:47Â There are a couple of things that a flat list needs, such as data, which is the most important part.
00:01:53Â And this is an array or array-like list of items to render.
00:01:58Â So we definitely need to provide some kind of an array.
00:02:02Â Then we need a key extractor.
00:02:04Â So this will be a way for us to get the key out of that item.
00:02:09Â So for example, if you have an array of objects where the ID is a number like this, you would create a callback function where you get each individual
00:02:19Â item and then you get the item.id out of it.
00:02:22Â In our case later on, once we fetch data from AppRite, it's going to be $id.
00:02:27Â So let's leave it like that.
00:02:30Â And then most importantly, you need a render item, which looks like this.
00:02:34Â And this explains React Native how we want to render each item in the list.
00:02:39Â So we can open it up as a callback function.
00:02:43Â That's going to look something like this.
00:02:45Â And we can have an immediate return.
00:02:47Â So just parentheses right here.
00:02:50Â Right within here, we can destructure the data from each item.
00:02:54Â And then for each one, we can return something like, let's do a text for now, and the text can render the item itself.
00:03:03Â Or in this case, it can be item.id.
00:03:06Â So let's save it and see what do we have.
00:03:08Â You can see one on top left.
00:03:10Â We can make it a bit bigger by giving it a class name equal to text-3xl.
00:03:17Â And you can see number one.
00:03:18Â Now, if we add multiple objects within this array, I can duplicate this and add maybe two more.
00:03:26Â We can give them IDs of two and three.
00:03:30Â You can see that it basically creates a list where it shows different text elements.
00:03:34Â Soon enough, we'll fill this data with the real video data coming from AppRide.
00:03:40Â For now, let me show you another property belonging to the FlatList.
00:03:44Â It is the ListHeaderComponent, which also is a callback function with an immediate return, where we can return a view.
00:03:54Â This view will have a class name equal to marginY of 6, padding x of 4 and space y of 6 between the elements.
00:04:05Â Right within it, we want to have another view and this view will have a class name equal to justify between, items start,
00:04:18Â flex row, and margin bottom of six.
00:04:22Â And within it, we can have one more last view.
00:04:25Â And within it, we can have a text element that will say, welcome back.
00:04:31Â And right below, we can create another text element where we can, for now, hard code JS Mastery.
00:04:38Â Later on, we can use the real username here.
00:04:40Â And you can see this appear at the top as the header to our flat list.
00:04:44Â Let's style these text elements.
00:04:46Â Let's do the first one first by giving it a class name.
00:04:51Â equal to font-p-medium, text-sm, and text-gray-100.
00:05:00Â The second one will have a class name equal to text-to-excel, font-p-semi-bold, and text-white.
00:05:09Â Of course, it's hard to see it right now because our background is white.
00:05:13Â But let's immediately make it black so it's easier for our eyes by giving the safe area view a class name equal to bgPrimary.
00:05:23Â There we go.
00:05:23Â That's better.
00:05:24Â And we can also give our text items a text of white so it's easier to see them.
00:05:29Â There we go.
00:05:30Â This is our flat list.
00:05:32Â You can see how customizable this flat list is.
00:05:35Â And I didn't even show you half of the things that it offers.
00:05:38Â We can immediately pass the data in.
00:05:41Â We can choose how the data will be rendered.
00:05:44Â And then we can also form the header component for that list.
00:05:48Â There's more stuff coming soon.
00:05:49Â Let's also render an image right below this view by adding another view.
00:05:55Â that will have a class name equal to margin top of 1.5. And within it, we can render a self-closing image, which of course we have to import coming from
00:06:07Â React Native.
00:06:08Â And we need to import images at the top by saying import.
00:06:13Â images coming from dot dot slash dot dot slash constants and images.
00:06:21Â Or no, I think it's just coming from constants since we have the index that exports them.
00:06:25Â We can now give it a source equal to images dot logo small.
00:06:31Â It's not that small right now.
00:06:33Â So let's give it a class name equal to w nine and H dash 10 and give it a resize mode equal to contain.
00:06:44Â There we go.
00:06:45Â That's better.
00:06:46Â Now we have a proper header.
00:06:48Â We want to go two views down and we want to implement our search input component.
00:06:54Â This will be similar to our other text inputs that we used within our sign in and sign up, but just a tiny bit different.
00:07:02Â So let's create a new component within the components folder called search input dot JSX.
00:07:12Â And we can start by entirely copying the entire form field and then making some modifications to it.
00:07:18Â First, let's actually show it within the home by rendering the search input like this.
00:07:26Â And of course we have to change the actual name, search input.
00:07:32Â And also we have to export it as such.
00:07:36Â So now if we go back, it's going to give us the auto import, which is good.
00:07:42Â And now we can see it barely at the top.
00:07:44Â So let's go into it and let's make some slight modifications.
00:07:48Â In this case, we don't need this outer view with the text.
00:07:51Â The only thing we need is one view and the input within it.
00:07:56Â So we can delete this outer view.
00:07:59Â At the end of the classes for the view, we can give it some space like space dash X dash four.
00:08:06Â and I think the rest can be the same.
00:08:08Â We can also give additional class names to our text input.
00:08:13Â We'll give it a class name of text base, margin top of 0.5, text-white, flex-1, and font-p regular.
00:08:24Â Now here's where things change.
00:08:25Â Instead of having this title, we will render another touchable opacity, which we have to import from React Native.
00:08:34Â So let's get it right here.
00:08:36Â Touchable opacity.
00:08:38Â It has already been imported.
00:08:40Â Within it, we can render an image.
00:08:44Â that will have a source equal to icons.search.
00:08:50Â Let's see if we have imported icons at the top.
00:08:53Â We have, let's also give it a class name equal to w-5, h-5, and you know it, resize mode of contain.
00:09:04Â There we go.
00:09:04Â Now we can see the search icon.
00:09:06Â For now, we can leave it as it is.
00:09:08Â And later on, once we implement the search logic, we can add additional stuff to this search input.
00:09:13Â For now, let's go below it and let's continue with our homepage.
00:09:18Â Below the search input, we'll create another view.
00:09:21Â And this will be for our latest videos section.
00:09:25Â So let's give it a class name equal to w-full.
00:09:29Â flex-1, padding top of 5, and padding bottom of 8. Within it, we can render a text element, that will say latest videos,
00:09:43Â and we can give it a class name equal to text-gray-100, text-lg, font-p-regular, and margin-bottom of 3. And if memory serves you right,
00:09:58Â the next section we have to implement is a horizontal list of videos.
00:10:02Â And also let's add a placeholder to this input.
00:10:05Â So we can quickly jump into the input.
00:10:07Â So we can replace the placeholder with something like search for a video topic.
00:10:15Â And there we go.
00:10:15Â You can see it right here.
00:10:17Â Now going back to home, how are we going to implement that horizontal video list?
00:10:24Â Well, right below our text, we can create a new component.
00:10:28Â So let's create it in the components folder and let's call it trending.jsx.
00:10:36Â We can run rnfe and we can import this component right here, trending.
00:10:43Â And of course we have to import it at the top as well.
00:10:46Â That's going to be trending coming from components, trending.
00:10:51Â To this trending, we can pass a posts property that will be equal to some kind of an array where we can also have a couple of different things.
00:11:00Â Let's do just IDs now to keep it simple.
00:11:03Â For example, ID one.
00:11:05Â Let's also do another object with an ID of two and then another one with an ID of three.
00:11:13Â And we can say question mark, question mark, meaning if it doesn't exist, then make it an empty array just so it doesn't break.
00:11:20Â Now we can dive into the trending and we can map over those elements in another flat list.
00:11:27Â So we know we're getting the posts right here as a prop, and the only thing we'll render will be another flat list.
00:11:35Â We already learned how to work with that, right?
00:11:38Â We have to pass in data, which will be equal to posts.
00:11:41Â We need to give it a key extractor, which will be equal to a function where we get the item.
00:11:48Â And then we take over the item.$id as that's how the items will look like coming from AppRite.
00:11:55Â And we have to give it a render item, meaning how each one of these items will look like once we destructure it and map over it.
00:12:04Â For now, I'm going to copy what I have right here at the top.
00:12:07Â It will be just a single text element, since we don't have a lot of data to show right now.
00:12:13Â And there we go.
00:12:14Â You can see that we have another flat list right here.
00:12:17Â But the most important thing for this flat list will be transitioning it to a horizontal view.
00:12:24Â simply by giving it a horizontal prop, you can now see latest videos.
00:12:29Â One, two, three.
00:12:30Â That is great.
00:12:31Â So now we have a horizontal list and we have a vertical list right here.
00:12:36Â And that's actually the primary reason why I wrapped everything in one flat list.
00:12:42Â instead of wrapping everything in a scroll view, as we typically should do.
00:12:47Â That's because scroll views don't support both horizontal and vertical scroll at the same time.
00:12:53Â And in this case, since we have a flat list with vertical scrolling, this one right here, and another flat list within that flat list that supports trending
00:13:02Â or horizontal scrolling, this is the way that we needed to do it.
00:13:05Â There's a special error in React Native.
00:13:08Â If you wrapped everything in a scroll view and had two different flat list types, like horizontal and vertical, you would get a special error saying that
00:13:15Â you cannot do that.
00:13:17Â So with that in mind, let's go below this trending and below the list header content as well.
00:13:23Â And let's use another special flat list property called list empty component.
00:13:32Â It allows us to create a function inside of which we can specify what will happen if our list is empty.
00:13:39Â So we can say something like text and then say empty.
00:13:44Â Now this doesn't show right now, but if we modify this data to be simply a completely empty array, I'm going to comment this out and remove it and make
00:13:55Â it empty.
00:13:58Â Now, you cannot see anything, but if we give this text a class name with a text of white, you can see it says empty.
00:14:09Â But come on, let's make this look a bit better.
00:14:12Â Let's create a new component that we will call empty state.jsx.
00:14:20Â We can run rnfe.js.
00:14:23Â And we can import this empty state and show it as the only thing right here.
00:14:28Â Empty state coming from components.
00:14:32Â We can pass it a title of no videos found.
00:14:37Â And we can also pass it a subtitle of no videos created yet.
00:14:44Â Or we can say something better like be the first one to upload a video.
00:14:52Â Now we can navigate over to this empty state, implement a view with a class name of justify center, items-center and padding X of four.
00:15:05Â Within it, we can render an image coming from react native, of course.
00:15:13Â And we also have to import images.
00:15:17Â coming from dot dot slash constants.
00:15:21Â And we can render the image with a source of images dot empty with a class name equal to W of 270 pixels and H of 215 pixels with a resize mode equal to contain.
00:15:40Â And there we go.
00:15:40Â Now we can see that we cannot find anything.
00:15:43Â Let's also add a text element to make it a bit clearer.
00:15:46Â And as a matter of fact, we can copy these two text elements we had in the homepage right here.
00:15:53Â Text and text.
00:15:56Â We can paste them here and we can invent them properly.
00:16:00Â The first one will be a small text with pmedium, gray 100, and it will render the title.
00:16:07Â Of course, that title will be coming from props and subtitle too.
00:16:12Â The second one will be TextXL with a TextCenter property, font-p-semi-bold, text-white, and margin top of 2 to divide a bit from the top,
00:16:24Â and it will render the subtitle.
00:16:28Â No videos found, be the first one to upload a video.
00:16:32Â I think it might make more sense to modify the subtitle to be the title and title to be the subtitle.
00:16:39Â That way we can see no videos found, be the first one to upload a video.
00:16:43Â And we can even change them around.
00:16:46Â There we go.
00:16:47Â This makes more sense.
00:16:49Â Finally, we can render a custom button, which is now super simple as we have already created that component before.
00:16:57Â We can import it at the top by saying import custom button from .slash custom button.
00:17:05Â And of course we need to pass some props to it.
00:17:07Â Props like title of back to explore, or even better, since we say be the first one to upload a video, we can say create video.
00:17:18Â We can give it a handle press equal to a callback function where we call the router, which we have to import at the top by saying import router from expo router.
00:17:34Â And then we can call a .push method on it and we can push to forward slash create.
00:17:40Â We can also give it container styles equal to w-full and margin y of five.
00:17:47Â There we go, that's looking great.
00:17:50Â Also, it seems like it's not taking the full height of the screen.
00:17:54Â So I can go back here to safe area view and maybe add a border of 2 and border of red 500, just so I can see how it wraps it.
00:18:06Â Yeah, you can see it's missing a bit of height right here.
00:18:10Â If I add h-full, it should make it full height.
00:18:14Â There we go.
00:18:15Â That's better.
00:18:16Â And we can remove the borders as now we know how things look like.
00:18:19Â And that's another pro tip.
00:18:20Â If you're struggling with positioning, adding borders is always helpful.
00:18:24Â With that in mind, our empty state is now done, which is great.
00:18:28Â We can kind of move it around, scroll it up and down.
00:18:31Â But for now, I'm going to bring back my array of three fake items.
00:18:36Â That's going to look something like this.
00:18:38Â That way, we don't see that empty state.
00:18:41Â And the last pretty cool thing about the flat list is that you can also give it a refresh control inside of which we can render a refresh control component
00:18:53Â coming from React Native.
00:18:55Â And we need to create some special props that we can pass to it.
00:18:58Â I'm going to explain what this does very soon.
00:19:01Â I'll create a use state field.
00:19:04Â that's going to be called refreshing and setRefreshing at the start set to false.
00:19:11Â And I'll also create a function called onRefresh, which will be equal to an async arrow function.
00:19:19Â There, we can simply set the refreshing to true and later on, we'll be able to recall our posts or videos so we can see if any new videos appeared.
00:19:34Â Once that is done, we can set the refreshing back to false.
00:19:39Â So why are we doing this?
00:19:41Â Well, we can now pass it to the refresh control function.
00:19:45Â We can say refreshing is equal to refreshing and onRefresh is equal to onRefresh.
00:19:54Â And if we save it and if we import useState at the top coming from React, you can now scroll up and later on, once we have real videos to fetch,
00:20:06Â Once we implement this recall videos function, it will actually try to refetch and show you new videos.
00:20:13Â You might be used to this on platforms like Instagram, Facebook, even TikTok.
00:20:18Â If you scroll up and release it, it will start loading new data.
00:20:23Â And I will teach you how to do that very soon.
00:20:25Â As soon as we start fetching real data within our application.
00:20:30Â And now that our homepage is basically done, I think it's the perfect time to do that.
00:20:36Â So let's create some data and let's fetch it from within our application.
00:20:41Â Very soon, we'll implement our own screen to upload our own videos directly through the platform.
00:20:48Â But for now, I just want to ensure that we can see some videos on the homepage.
00:20:53Â And the quickest way to do that is to create a few documents directly through AppRide's dashboard.
00:20:58Â So let's go to databases, enter our single database, go to the videos collection and click create document.
00:21:06Â In the readme down below, you'll find a section where you can also find the data for a few of these videos that we will add.
00:21:14Â So let's copy it one by one.
00:21:16Â First, I will add a video with the title of How AI Shapes Coding Future with a URL of this thumbnail and enter a video URL as well.
00:21:27Â And finally, I will enter a prompt that I used to generate this video.
00:21:32Â That is the whole idea of the application.
00:21:34Â To share different prompts and videos that you have generated somewhere else using AI.
00:21:39Â Or you can also share your own videos.
00:21:41Â You'll also see that this video is actually mine.
00:21:44Â I recorded it, but it doesn't matter.
00:21:46Â The most important thing is that we can upload it and see it within our application.
00:21:51Â And finally, choose a creator.
00:21:53Â Since you only have one user now, it's going to be you.
00:21:56Â Does this make sense?
00:21:58Â Find the Read Me down below, copy the data, and let's create a couple of videos.
00:22:02Â Of course, if you want to, you can upload your own videos and thumbnails, but just for the app to look good, I have prepared some for you.
00:22:10Â So let's click Next, and let's click Create.
00:22:13Â And our first document containing our video has been uploaded.
00:22:17Â Let's do at least two more.
00:22:19Â The second one I will do is get inspired to code with some kind of a thumbnail, prompt, and a video URL.
00:22:28Â And I'm going to add myself as the creator.
00:22:31Â And the last one will be a Dalmatian, which is a dog breed with a thumbnail, video URL, and a prompt, and I'm going to choose myself as the creator as well.
00:22:43Â And let's click create.
00:22:45Â There we go.
00:22:46Â I think three videos are enough for us to start showing some data within our application.
00:22:51Â So let's go back to the code.
00:22:53Â Let's close all of the currently open files and let's navigate over to AppWrite.
00:22:58Â Here we have to create and export a new function that will fetch all posts by saying export const getAllPosts which is equal to an async function with
00:23:11Â a try and catch block where in the catch we throw a new error with an error and in the try and in the try we can say const posts is equal to await databases.listDocuments.
00:23:28Â And to it, we need to pass the database ID, which is under config.databaseID.
00:23:36Â And we also have to provide the config.videoCollectionID.
00:23:42Â and I don't want to every time say config.
00:23:44Â and then config.
00:23:45Â as well.
00:23:46Â What we can do is simply destructure all of these values from the config object.
00:23:52Â So I'm going to copy them all, say const, destructure them like this, and of course you have to provide commas at the end of each one,
00:24:01Â and then say equal to config.
00:24:04Â This will allow us to expose them outside of the object.
00:24:08Â So now I don't have to say config.
00:24:11Â rather, I can just refer to them like this.
00:24:14Â Finally, we can return posts.documents.
00:24:18Â This is great.
00:24:19Â We have a function that fetches all posts.
00:24:22Â So how do we actually use this within our application?
00:24:26Â Well, let's go back to home, And let's give it a shot.
00:24:29Â I'm going to write it right here at the top of the file.
00:24:32Â First, we need to create a new useState, which we'll call data.
00:24:38Â SetData at the start equal to an empty array.
00:24:41Â And we also need another useState for the loading.
00:24:45Â So isLoading, setIsLoading, and it's going to be set to true.
00:24:52Â Then we need to create a use effect within which we'll fetch that data as soon as the component loads or the screen in this case.
00:25:00Â So we can say use effect like this with a dependency array that's empty, meaning only fetch it at the start.
00:25:08Â And don't forget to import use effect from React.
00:25:12Â Within here, we can create a function const fetchData is equal to an async function like this.
00:25:20Â And then we can immediately call it right below fetchData.
00:25:25Â The reason we need to do this is because you cannot use async code directly within a use effect.
00:25:31Â This would be illegal and wouldn't work.
00:25:33Â You have to create a new function inside of which you call asynchronous code.
00:25:39Â Here, we can set isLoading to true because we have started fetching the data, and we can open up a try, catch, and finally block.
00:25:49Â Whether we succeed or fail, we want to set isLoading to false because we're done fetching.
00:25:56Â In the catch, we can call the alert coming from react-native.alert error, and we can render the error.message.
00:26:06Â And in the try, we can say const response is equal to await.
00:26:12Â How did we call our function?
00:26:13Â Get all posts coming from lib upright.
00:26:18Â And then once we get the response, we simply set the data to be equal to response.
00:26:24Â And just like that, we have data about our videos.
00:26:28Â So what do you say that we console log it?
00:26:31Â Right here below, I'm going to say console log data.
00:26:35Â We are here.
00:26:36Â I'm going to open up the terminal.
00:26:38Â And would you look at that?
00:26:39Â The data that we have added with an app right is right here.
00:26:43Â We can see it by how AI shapes coding future, the video URL, and everything else.
00:26:48Â That means that we can now start modifying our JSX to actually show some thumbnails and videos instead of showing simple text elements.
00:26:57Â But before we do that, I want to give you another pro tip.
00:27:01Â We can further optimize this code and make it more reusable by converting all of this into a custom hook.
00:27:10Â If you think about it, we'll have to fetch data in a lot of different pages, in the profile, in the search, and in many more cases.
00:27:17Â And the only thing that will change is the actual function of which posts or which users or what data are we getting.
00:27:26Â So with that in mind, we can copy this entire Consologue data and the use effect and these two states and remove them from the home to clean it up a bit.
00:27:38Â What we're going to do instead is create a new file within lib called useAppWrite.js.
00:27:48Â This will be a custom hook.
00:27:51Â So as with every custom hook, it has to be a function that starts with the word use.
00:27:57Â In this case, I chose the name useAppRight.
00:28:01Â And as a parameter, we're going to get a function that tries to fetch something.
00:28:05Â So I'm going to call it fn.
00:28:07Â And within here, I'm going to paste everything we had before.
00:28:12Â It's loading, states, use effects, alerts.
00:28:15Â And of course, we have to import use state from React.
00:28:19Â We have to import use effect from React.
00:28:22Â And instead of console logging the data, we will simply return it.
00:28:26Â For now, we can say return data within an object like so.
00:28:31Â And then we can say export default use app right.
00:28:36Â Now, where will this get all posts come from?
00:28:39Â Well, we will pass it as a function through props.
00:28:43Â So instead of calling get all posts, let's call fn like this.
00:28:48Â Now, going back to home.
00:28:51Â Instead of all the code that you've seen before that was here, we can do one single thing.
00:28:56Â And that is const, get the data and rename it to posts, which is equal to useAppWriteCustomHook.
00:29:07Â to which we pass this function of getAllPosts, which we created not that long ago.
00:29:13Â It's basically just this one.
00:29:15Â So before we had about 20, 30 lines right here, and now we have moved that logic here.
00:29:20Â We're passing the getter function, and we can try to console log the posts one more time to see if we truly get them.
00:29:28Â We have renamed it to posts.
00:29:30Â So I open up the terminal and you can see there's a lot of code.
00:29:33Â So that must mean that it has actually done it for the second time.
00:29:37Â There we go.
00:29:38Â So the logic works the same, but we have extracted it to make it more reusable.
00:29:43Â We can also make it more powerful by creating this function called refetch const.
00:29:50Â Refetch is equal to a callback function that simply calls the fetch data one more time, which is the same exact function which we have created for fetching
00:30:02Â the data for the first time.
00:30:04Â But if we want to use it here, we have to bring it out of the use effect.
00:30:09Â So we're calling it once at the start and we're calling it whenever the refetch function gets called.
00:30:16Â And do you know when that will be?
00:30:18Â Well, it will be on refresh once we pull our device up.
00:30:23Â So with that in mind, let's return the data that is loading as well as the refetch and back in home, alongside just getting the posts,
00:30:35Â we can also get refetch and we can recall videos whenever we scroll up or swipe up.
00:30:42Â So we can say await refetch.
00:30:46Â There we go.
00:30:48Â I hope this makes sense.
00:30:49Â I know it's a bit more advanced creating custom reusable hooks, but I hope it will make even more sense once we use this custom hook for the second time.
00:30:58Â So you can see how much code we have actually saved ourselves from writing.
00:31:01Â With that in mind, instead of just doing a console log in the terminal, which doesn't mean too much, let's try to actually show some data within our flat list.
00:31:10Â And then instead of rendering the ID, we should be able to render something like title.
00:31:16Â And there we go.
00:31:17Â How AI shapes coding future, get inspired to code, and the Dalmatians journey through Italy.
00:31:23Â That's great.
00:31:24Â But we can do better than that.
00:31:26Â We can also show the thumbnails we have uploaded.
00:31:29Â So instead of simply showing a piece of text, let's create a new component called VideoCard.jsx where we can run rnfe and we can import it right here as
00:31:45Â a render item, video card.
00:31:50Â Make sure to import it at the top, right below empty state, video card coming from components, video card.
00:31:57Â To it, we can pass the entire post or we can call it a video equal to item.
00:32:04Â So now we have access to all of this data within a video card and we can destructure it video right here.
00:32:11Â We can also automatically destructure the properties within the video, such as the title, thumbnail, video, and creator.
00:32:21Â And outside of the creator, we can pull the username and the avatar.
00:32:26Â Pretty cool stuff, right?
00:32:28Â Now we can use anything we need.
00:32:30Â So just to verify this is working, let's give some class names to this view, like a class name equal to flex-col, so they show one below another,
00:32:41Â items-center, padding X of four and margin bottom of 14. And let's try to render a text with a class name of text-to-excel,
00:32:54Â text-white, and let's make it render the title.
00:32:59Â There we go.
00:33:00Â Everything is working exactly as we thought it would.
00:33:04Â Now, let's put the text to the side for now, and let's create more structure for our cards by creating another view with a class name equal to flex-row
00:33:16Â gab-3 and items-start.
00:33:21Â Within it, another view that will have a class name equal to justify-center, items-center, flex-row, and a flex of 1. And within it,
00:33:36Â last view, trust me, a view with a class name equal to w of 46 pixels, H of 46 pixels, rounded dash LG, border, border dash secondary.
00:33:55Â We can start seeing things now.
00:33:57Â Justify center, items dash center, and a padding of 0.5. Within it, we can render an image coming from React Native.
00:34:09Â with a source equal to URI is the avatar.
00:34:14Â Class name is W-Fool, H-Fool, and rounded-lg.
00:34:21Â And the resize mode is equal to cover.
00:34:25Â And now we can see J as in JS Mastery.
00:34:28Â This was created automatically for us by AppWrite.
00:34:31Â Let's go one view down below the image, and let's create another view, this time for the title of our video.
00:34:38Â With a class name equal to justify-center, flex-1, margin left of 3, and gap y of 1. Within it, we can render a text property.
00:34:56Â that will simply render the title.
00:34:58Â We can also give it a class name equal to text-white so we can see it, font-p-semi-bold and text-sm.
00:35:09Â And now we can remove this second title as we have the real one above.
00:35:13Â There we go.
00:35:14Â We can also give a special property to this text, which is a number of lines, one, which stops the text from going further if it's longer.
00:35:23Â Below the text of title, we can render another text.
00:35:27Â In this one, we'll render the creator, or in our case, the username.
00:35:32Â We can give it a class name of text-xs, text-grey100, and font-pregular.
00:35:42Â And we can also make it fit in one line.
00:35:45Â Number of lines is one.
00:35:47Â There we go.
00:35:48Â That's good.
00:35:49Â We can go below this text and one, two views down and we can create another view.
00:35:55Â This one will have a class name equal to padding top of two.
00:36:00Â And we can render an image that will have a source equal to icons coming from constants.menu.
00:36:09Â Make sure to import these icons.
00:36:12Â Class name equal to W of five and H of five and a resize mode equal to contain.
00:36:21Â There we go.
00:36:22Â Just so we can do some additional actions.
00:36:25Â Moving two more views down, right here, we can finally show the video.
00:36:31Â And this will be interesting.
00:36:33Â First, we don't want every single video to play right off the bat.
00:36:38Â So we want to create a new state to ensure whether the video is playing or not.
00:36:44Â So let's create a new use state snippet called play and set play at the start set to false.
00:36:51Â We need to import the use state.
00:36:53Â And for now, let's see what happens if the video is not playing.
00:36:58Â So we can open up a new dynamic block of code where we check play.
00:37:04Â And if it's playing, we can show for now a text saying playing.
00:37:09Â Else we will show something else.
00:37:12Â We will show a touchable opacity.
00:37:17Â which is basically like a button that will play it.
00:37:20Â But instead of it being a button, we will actually show the thumbnail.
00:37:24Â So once you click on it, you can start playing.
00:37:27Â Let's not forget to import touchable opacity from React Native.
00:37:31Â And within it, let's render an image that will have the source equal to URI of thumbnail.
00:37:40Â We're going to also have a class name equal to W-Fool, H-Fool, rounded-excel and margin top of 3, with a resize mode equal to cover.
00:37:54Â And immediately, you can see that it takes more screen, but we cannot really see anything happening right here.
00:38:01Â So let's apply some additional class names to this touchable opacity, such as a class name equal to w-full.
00:38:09Â And there we go.
00:38:10Â We can already see the thumbnail.
00:38:12Â h-60 for the height.
00:38:15Â rounded-excel, margin top of three, relative, justify center, and items center.
00:38:25Â And now we can actually move through three of these thumbnails and our app is starting to look better and better.
00:38:32Â Below that image, we'll show another image.
00:38:35Â And this one will have a source equal to icons.play.
00:38:41Â You can see this play icon.
00:38:42Â So for the images, if the source is a URL, you have to do it like this, say URI and then point to the URL.
00:38:50Â But if it's a local image, you can just do source and then point to the path to that image.
00:38:55Â Let's also give it a class name equal to W12, H12, and absolute.
00:39:02Â And a resize mode equal to contain.
00:39:07Â There we go.
00:39:07Â So now it seems like we can click to play it.
00:39:10Â To our touchable opacity, we can also give the active opacity of 0.7. So once we kind of hover over it or click it, we can see what's happening.
00:39:20Â And on press.
00:39:22Â we can call the callback function and set play to be equal to true.
00:39:27Â For now, that will just turn it into a text, and let's also give it a class name so we can see it, of text white.
00:39:35Â So if we click play on it, you can see that now it says playing, and we can repeat the process for every single one of these three videos.
00:39:44Â That is phenomenal.
00:39:46Â Let's also go back a bit.
00:39:47Â Now it always says playing because it's stuck.
00:39:50Â But if you open up the terminal and press the letter R, it should reload it, automatically log us in, and we can see our thumbnails once again.
00:40:00Â This is great.
00:40:02Â We can also fix this warning at the bottom regarding keys.
00:40:05Â But for now, before we get these videos actually playing, what do you say that we implement this latest videos section?
00:40:13Â That's this section right here.
00:40:15Â It's going to show us not the latest videos, but the trending videos.
00:40:20Â and it's going to show them in a bit of a different format.
00:40:23Â It's going to be a horizontal list where you can swipe left and right to see different videos in a portrait mode.
00:40:31Â So let's implement that and then we'll figure out how to get those videos to play.