
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 lesson, we explore how to build a video upload form using React Native, implementing essential UI components and handling file uploads. The tutorial walks through creating a form where users can input video details, upload videos and thumbnails, and submit the data to an AppWrite database.
useState
to keep track of the video title, video file, thumbnail, and AI prompt.00:00:00Â So let's click on create right here at the bottom and let's navigate over to the create page and let's get started.
00:00:08Â Amazing job so far.
00:00:10Â First things first, we got to be safe.
00:00:13Â So let's start with the safe area view coming from React Native safe area context.
00:00:21Â Let's give it a class name equal to bgPrimary and h-full for full height.
00:00:28Â And let's turn this entire view into a scrollable view by wrapping it within a scroll view component coming from React Native with a class name equal to
00:00:40Â padding X of four and margin Y of six.
00:00:44Â Right within it, let's render our first piece of text on this screen.
00:00:49Â That will say something like upload video.
00:00:53Â And let's give it a class name equal to text-to-excel, text-white, font-p-semi-bold, and save it.
00:01:04Â There we go.
00:01:04Â That's our title.
00:01:06Â Right below it, we can render our first form field.
00:01:11Â And this form field is a component that we have created before.
00:01:14Â You can find it here.
00:01:16Â So let's just import it by saying import.
00:01:21Â form field coming from dot dot slash dot dot slash components form field.
00:01:29Â We have to pass a couple of things into that form field.
00:01:32Â So we're going to do that through props.
00:01:35Â We'll pass a title equal to video title, and we also have to give it a value.
00:01:41Â And to create that value, we can create a new use state field.
00:01:47Â That will be called form, set form, and at the start equal to an object.
00:01:52Â Let's correct the spelling here and let's give this object some default properties.
00:01:57Â Such as a title, that's an empty string at the start.
00:02:00Â A video, which will be null at the start.
00:02:03Â A thumbnail.
00:02:05Â which will also be null at the start and a prompt, which will also be an empty string at the start.
00:02:13Â Let's fix this title.
00:02:14Â There we go.
00:02:15Â We'll also have to know, are we currently uploading a video so we can show the loading?
00:02:20Â So let's immediately create a new use state snippet called uploading and set uploading at the start set to false.
00:02:29Â Great.
00:02:30Â Now let's go back.
00:02:32Â And let's give this form field a value equal to form.title.
00:02:40Â We can also give it a placeholder equal to give your video a catchy title.
00:02:48Â And we can also give it a handle change text equal to a callback function where we get the event.
00:02:56Â We set it to form.
00:02:58Â We spread it.
00:03:00Â the previous values of the form, and then we just modify the title to be equal to the event.
00:03:06Â Finally, we give it other styles equal to margin top of 10. And of course we have to import use state coming from react.
00:03:18Â Once we do that and navigate to create, we can see our nice looking input.
00:03:22Â Now let's create a view below that input.
00:03:25Â And that view will have a class name equal to margin top of seven, space Y of two to create some spacing.
00:03:35Â And within it, we can create a new text that will say something like upload video.
00:03:43Â And we can style it by giving it a class name equal to text-base, text-gray-100, and font-p-medium.
00:03:56Â There we go, upload video.
00:03:58Â And then we can create a touchable opacity right below that text.
00:04:03Â which will be our area to click on and upload a video.
00:04:07Â So touchable opacity coming from React Native.
00:04:10Â And here we want to see if we already have a form.video.
00:04:15Â If we do, we will display a video component coming from Expo AV audio video.
00:04:23Â So let's immediately import it at the top.
00:04:26Â by saying import video coming from Expo AV.
00:04:32Â And we also need to get that resize mode coming from Expo AV as well.
00:04:39Â We also need to close this ternary operator by creating the second part.
00:04:43Â If we don't have a video, we'll create a view that will allow us to upload the video.
00:04:50Â So that's going to be a view.
00:04:54Â And let's properly close this with a class name equal to WFool H40 padding X of 4, background of black 100, rounded dash 2XL.
00:05:12Â justify-center and items-center.
00:05:16Â It's kind of like a rectangle which we can click to upload a video.
00:05:21Â Within it, we can have another view with a class name equal to w-14, h-14, border, border-ed, border, secondary, 100, Justify Center and Items Center.
00:05:45Â And finally, right within it, we want to have an image which we need to import from React Native.
00:05:53Â So let's get it.
00:05:55Â get a source equal to icons, which we need to import from constants, dot upload, with a resize mode equal to contain, and a class name equal to w,
00:06:08Â 1 over 2, and h dash 1 over 2. There we go.
00:06:14Â This is an upload icon.
00:06:17Â And then once we click on that, once we upload the video, we can start showing it here.
00:06:22Â So we can immediately get the source of that video equal to URI is form.video.URI.
00:06:33Â We can give it a class name equal to w-full, h-64, and rounded-to-excel.
00:06:42Â We can use native controls.
00:06:45Â We can let the resize mode be equal to resize mode.
00:06:50Â dot cover like this, and we can say is looping.
00:06:54Â In case we're filling in some other fields and the video is done, we want it to start playing once again.
00:07:00Â With that in mind, we want to go below this touchable opacity and below the view as well, and create another view, this time for the upload of the video thumbnail.
00:07:11Â So let's create some space by giving it a class name equal to margin top of seven, and space dash y dash 2. And we can copy this same text element that
00:07:25Â before said upload video.
00:07:28Â And this time it will say something like, let's do thumbnail image.
00:07:35Â Make sure that this is the text with the text gray 100 font P medium and text base.
00:07:42Â And then right below it, we can basically copy this entire touchable opacity that we have created for the video, because we want to have the same thing
00:07:51Â for the image.
00:07:52Â So right below the text, we can paste the touchable opacity.
00:07:57Â And instead of checking for form.video, we're going to be checking for form.thumbnail.
00:08:02Â If we have the thumbnail, we won't be showing the video.
00:08:05Â Rather, we'll be showing the image that we have uploaded with a source equal to URI form.thumbnail.uri.
00:08:17Â with a resize mode equal to cover and a class name equal to w-full h-64 and rounded-to-excel.
00:08:30Â Okay, that's good.
00:08:32Â But if we don't have the image yet, we have to fix this second part.
00:08:36Â So for now, let's delete this inner view right here and let's just keep the outer view.
00:08:42Â Let's change the H to 16, and we can add the border right here.
00:08:46Â Border-2, border-black-200.
00:08:53Â Flex dash row and space dash X dash two.
00:08:57Â And within it, we have the upload image with a width of five and a height of five as well.
00:09:06Â Okay.
00:09:06Â So now we have different views for the video, a bit larger and a bit smaller for image.
00:09:12Â And we can have a text right below that image.
00:09:17Â That's going to say something like choose a file and we can give it a class name equal to text-sm, text-gray-100, and font-p-medium.
00:09:32Â There we go.
00:09:32Â That's much better.
00:09:34Â Finally, we can copy this form field that we created above, go all the way to the bottom, below the touchable opacity and below the view.
00:09:47Â And this one will be for our AI prompt that we used to generate this video, which we want to share with world.
00:09:54Â So we can say form.prompt and we can say under placeholder, something like.
00:10:01Â the prompt you used to create this video.
00:10:07Â And under set form, we're going to modify the prompt instead of the title.
00:10:12Â In other news or in other styles, margin top can be a bit smaller, like seven.
00:10:17Â And finally, below the form field, we can render a custom button.
00:10:22Â First, we have to import it right at the top.
00:10:25Â So let's duplicate this form field and import custom button from the custom button.
00:10:31Â Pass it a title of submit and publish.
00:10:37Â Let's also give it a handle press.
00:10:39Â So once we click on it, we want to submit it.
00:10:42Â So really quickly here, we can create a new function const submit is equal to an arrow function.
00:10:50Â That is good.
00:10:51Â And we can give it container styles of margin top of seven.
00:10:56Â That's going to push it a bit from the prompt input.
00:11:00Â And we can also give it the isLoading property, which will be uploading.
00:11:04Â So if we're uploading, that means that we're loading.
00:11:07Â Okay.
00:11:07Â This looks good.
00:11:09Â You can see it doesn't fit on my screen right here, even though it's a large screen.
00:11:13Â But since we use that scroll view right at the top, I can still scroll through everything and see what's happening, which is great.
00:11:21Â And this is it for the JSX part or the presentation part of our create video form.
00:11:28Â But of course, in this case, where the magic happens is with the video upload.
00:11:33Â So we first have to do the logic for uploading videos, then uploading thumbnails, and then uploading everything to our database.
00:11:44Â So first things first, we cannot work on the submit function until we have worked on the actual upload functions.
00:11:51Â So let's create a new function at the top, const open picker.
00:11:56Â That's going to be a picker for our video or image file, which will be an async function that selects the type of the file we're trying to pick.
00:12:07Â And we can open this picker once we click on this touchable opacity.
00:12:10Â So we can go right here.
00:12:13Â And say on press, we want to call a callback function where we open the picker.
00:12:20Â This time it's going to be a video picker and we can copy that on press and paste it to the second touchable opacity.
00:12:30Â And on the second one, we're going to say open picker image and make sure to properly close it as well.
00:12:39Â There we go.
00:12:41Â So now we can start working on the code within this open picker.
00:12:45Â So I can teach you how you can upload actual files from your phone to AppRite's storage buckets, and then getting URLs for those files so you can put them
00:12:56Â within your AppRite database and then see the video you have posted on your homepage.
00:13:02Â First things first, we can open up a modal that allows us to pick either an image for a thumbnail or a video.
00:13:10Â So let's say const result to extract the image or video we choose and say await document picker like this.
00:13:20Â And this document picker will come from expo-document-picker, which is another package we can install.
00:13:27Â So right here in the terminal, we can clear our second one and say npm install expo-document-picker and press Enter.
00:13:39Â Once we install it, right at the top, we can say import everything as documentPicker coming from expo documentPicker.
00:13:53Â Now to that documentPicker, we can use a method called getDocumentAsync to which we need to pass options object of type.
00:14:04Â And here we need to define the type that we want to get.
00:14:07Â Now in our case, the type will depend on which input we click on, video or thumbnail.
00:14:14Â So we'll say if select type is triple equal to image, then the types will be an array of image PNG, as well as image JPEG,
00:14:28Â and else the type will be a video mp4 as well as a video gif and now if you save it and if you click on upload video you can see that it will actually
00:14:42Â open up your recent videos we can also give it a shot with a thumbnail and here you can see some icons that I recently downloaded to customize my iPhone
00:14:51Â You can also go to browse and see all the different files on your phone.
00:14:55Â In this case, just sticking with Recents is fine.
00:14:58Â But now that we select a specific image, we want to do something within it.
00:15:03Â First, we have to make sure that our user hasn't canceled.
00:15:06Â So we can say if not result.canceled.
00:15:11Â In that case, we can set state to either thumbnail or video by saying if select type is triple equal to image.
00:15:21Â In that case, we can set form.
00:15:24Â We can spread the entire form and update the thumbnail to be result.
00:15:30Â dot assets zero, like this.
00:15:34Â And we can also duplicate that if right below and say, if select type is video, then we can update this video right here to results dot assets zero.
00:15:49Â Else, not else to these ifs, but to this outside if, if we have canceled the submission, then we can just set a timeout where we have a callback function
00:16:01Â and we can define the delay of like 100 milliseconds.
00:16:05Â And we can show an alert coming from react-native.alert document picked and json.stringify.
00:16:16Â the result.
00:16:17Â We don't want to replace anything so we can give it null and the space will be two.
00:16:22Â This should nicely show us which file we have selected.
00:16:25Â So let's give it a go.
00:16:27Â I'm gonna click upload video and I'm gonna select this real.
00:16:32Â And as you can see, it automatically got it here.
00:16:36Â We also got document picked, assets null, cancel to true.
00:16:40Â So this is only if you cancel out.
00:16:42Â But in this case, we actually have the asset here.
00:16:44Â The only problem is once I tried to play it, then it opens up this form once again.
00:16:51Â We'll work on that later on.
00:16:52Â For now, let's also select a thumbnail.
00:16:55Â I'm going to go with this nice thumbnail image right here.
00:16:58Â And now that we can select those files, the only thing we're doing in this open picker is we're setting them to the state.
00:17:05Â So now we have to actually create the submit function that will upload them to our database.
00:17:12Â So before we submit, we have to ensure we have all the data.
00:17:16Â So we can say if there is no form.prompt or if there is no form.title or if there is no form.thumbnail, Or if there is no form.video,
00:17:29Â if any of these is false or empty, then we want to return an alert.alert that says, please fill in all the fields.
00:17:40Â If we get past this if, then we can say set uploading to be true.
00:17:47Â And we can open up a try and catch block.
00:17:50Â It will also have a finally clause right here where we can reset our entire form.
00:17:56Â So we can say set form and we can basically reset it to the starting state by copying the empty values and pasting them here.
00:18:08Â And right below, we can also set uploading to false because we're done with uploading.
00:18:13Â So now if we have an error, we can simply alert.alert error with an error message right here.
00:18:22Â And how will we actually upload this file?
00:18:26Â Well, first let's do an alert.alert where we can say success.
00:18:31Â and post uploaded successfully.
00:18:35Â Then let's also navigate to the homepage by using the router functionality by importing router from expo-router.
00:18:46Â And then we can say something like router.push, pointing to home so we can see our newly uploaded post.
00:18:54Â And then the most important thing is right here, we have to make a call to AppRide to add this post to our database.
00:19:01Â So let's navigate over to AppRide.
00:19:04Â And let's create a new function, export const create video, and it will be equal to an async function that accepts the entire form data as the first param.
00:19:19Â We can open up a try and catch block and in the catch, simply throw a new error where we pass the error.
00:19:28Â And in the try, we can first upload our video and thumbnail.
00:19:33Â And then once we have their URLs, we can simply create a new document in our database.
00:19:37Â So let's do just that.
00:19:39Â I'm going to say const and I will destructure the thumbnail URL.
00:19:45Â and video URL, which will come from the call of await promise.all because we don't need to do one of these one after another.
00:19:55Â We can at the same time start uploading both files and we can do that using promise.all.
00:20:02Â Then we can pass an array of calls we want to do.
00:20:05Â And here we can call a new special function called upload file to which we can pass our form.thumbnail with the second prop of image,
00:20:18Â and we can duplicate that and pass the form.video with a second prop as video as well.
00:20:26Â And let's separate these by commas.
00:20:28Â There we go.
00:20:29Â Now, of course, this upload file is another function which we have to create.
00:20:33Â So let's create it just above.
00:20:37Â exportConstUploadFile is equal to an async function where we can get the file and the type of that file, and we can upload it to AppRite's storage buckets.
00:20:48Â First things first, we can check if a file even exists.
00:20:52Â So if there's no file, we simply exit out of the function.
00:20:56Â Then we want to get some data or information out of the file by saying const and we can extract a mime type and then spread out the rest of the properties
00:21:07Â coming from the file.
00:21:08Â We can do that like this.
00:21:11Â And then we want to reconstruct that file because that's how AppWrite accepts them.
00:21:16Â We can say const asset is equal to an object with a type equal to mime type, and we can spread the rest.
00:21:26Â There we go.
00:21:27Â So basically what we have done is we have taken everything out of the file and just renamed the mime type to type, as that will help AppWrite understand
00:21:36Â what file we're talking about.
00:21:37Â Then we can open up a new try and catch block.
00:21:41Â In the catch, we can throw a new error as we typically do.
00:21:44Â So we can copy this entire thing and paste it here.
00:21:48Â And in the try, we can say const uploaded file is equal to await.
00:21:56Â We call the storage for the first time right here.
00:21:59Â So we have to initialize a new storage bucket right at the top.
00:22:04Â So let's do it here.
00:22:06Â account avatars databases, but now we're also working with storage, which is new storage coming from AppRite, of course,
00:22:16Â at the top.
00:22:18Â So let's go ahead and import it.
00:22:21Â There we go.
00:22:22Â Let's go down.
00:22:24Â And then we can say something like storage.create file.
00:22:27Â And we have to pass a couple of things into it.
00:22:31Â First, we pass the storage ID.
00:22:35Â Then we have to pass the id.unique as we want to give it a unique ID to this file.
00:22:40Â And then we pass the actual asset into it.
00:22:43Â So that's going to look something like this.
00:22:46Â And then AppRite will give you a file URL.
00:22:49Â So we can do something like const file URL is equal to await get file preview to which we have to pass the uploaded file.
00:23:02Â And then the type as the second parameter.
00:23:08Â And we can return that file URL.
00:23:11Â And the only thing that's important here is that this get file preview is a bit different for our video and audio file.
00:23:19Â So let's turn that into a new function right here.
00:23:23Â export const get file preview, which is equal to an async function that accepts a file ID and type.
00:23:33Â We can declare a file URL at the top, let file URL and open up a try and catch block.
00:23:41Â In the catch, we can simply console log or throw a new error.
00:23:46Â And in the try, we can check if we're working with a type is triple equal to video or else if we're working with a type triple equal to image.
00:23:59Â And based off of that response, we're going to get the file URL a bit differently.
00:24:05Â So if it is a video, we can say file URL is equal to storage dot get file view.
00:24:13Â to which we pass the storage ID, as well as the file ID where we want to get it from.
00:24:20Â Now, to get the file URL off of an image, we can say file URL is equal to storage.getFilePreview, a bit different, not getFileView.
00:24:32Â And here we can pass the storage ID as well as the file ID.
00:24:36Â So that's the same, but now we can pass the width, which is going to be 2000, the height, which is going to be 2000 and the gravity,
00:24:45Â which is going to be top.
00:24:46Â And finally, quality, which will be 100. So we can basically pass a few more pieces of information to get the right preview and the right size.
00:24:56Â Finally, we can also do an else and throw a new error.
00:25:01Â of invalid file type in case we don't get video or image.
00:25:07Â And finally, if there is no file URL that we get back, we can throw an error one more time.
00:25:15Â And if everything succeeds, we can basically return this file URL.
00:25:21Â Great.
00:25:22Â So now we have the get file preview which is used in the upload file which is used within create video which then returns us the thumbnail URL and the
00:25:31Â video URL which we call both at the same time as we can upload both at the same times.
00:25:38Â They don't depend one on another so they can happen at the same time.
00:25:42Â So once we have those URLs, we can say const new post is equal to await databases.createDocument.
00:25:53Â Here, we need to pass the database ID within which we want to create that document and a video collection ID, which is the ID of the collection where that
00:26:03Â document belongs.
00:26:04Â And then the ID.unique, which will give it a unique ID.
00:26:09Â And the last thing we have to pass is an object of the actual data that we want to create.
00:26:15Â So it will be a title coming from form.title.
00:26:19Â Then we want to give it a thumbnail equal to thumbnail URL.
00:26:24Â After that, we can pass video as video URL.
00:26:28Â Prompt equal to form.prompt.
00:26:32Â And finally, creator.
00:26:35Â equal to form dot user ID.
00:26:39Â And with that, we have everything we need to create a new post.
00:26:42Â So finally, once it actually gets created and added to the database, let's just return it right here to our front end.
00:26:51Â Great.
00:26:52Â So now we have a function called create video, which uses upload file, which uses get file preview, which we can use within our create form.
00:27:03Â So right here, let's await.
00:27:06Â And for that, we have to turn our submit into an async function.
00:27:10Â And why are we awaiting?
00:27:12Â Well, we're awaiting create video, which we have to import, of course, from AppWrite.
00:27:18Â So let's do that.
00:27:20Â Going up, we can import, create video from dot dot slash dot dot slash lib AppWrite.
00:27:31Â Let's just command click it or control click it to see if we're pointing to it in the right way.
00:27:36Â We are, and we're creating the video and to it, we have to pass a couple of things.
00:27:42Â I'm going to spread the entire form and I'm going to also pass the user ID equal to user dot dollar sign ID.
00:27:50Â That way we have all the necessary information.
00:27:53Â to create a post.
00:27:54Â So let's give it a go.
00:27:56Â I will first upload a video.
00:27:59Â I'm going to go with this Instagram Reel.
00:28:02Â We can also give it a title of IG Reel.
00:28:07Â I'm going to post a thumbnail image.
00:28:09Â Let's go with this one right here and let's enter an AI prompt.
00:28:14Â I'm going to say something like testing and press enter.
00:28:19Â Let me spell it properly.
00:28:21Â Testing.
00:28:23Â There we go.
00:28:24Â And I'll press submit and publish.
00:28:28Â It gives us property user does not exist.
00:28:31Â That's okay.
00:28:32Â At least we got an error.
00:28:33Â In this case, we cannot get this user because we have never imported it.
00:28:37Â So right at the top, we know how to do that.
00:28:40Â We can simply say const.
00:28:43Â These structure the user, which is equal to the useGlobalContext, which is a custom context hook.
00:28:50Â So we can import it by saying import useGlobalContext coming from dot dot slash, dot dot slash.
00:28:59Â context forward slash global provider.
00:29:03Â Now we have access to the user and we can give it another go.
00:29:07Â Before we test it out, there's one more thing I want to fix.
00:29:10Â Right here, we have this else that sometimes throws this annoying alert and I think we can safely get rid of it.
00:29:19Â Nothing bad will happen.
00:29:21Â We just won't see the alert on the screen.
00:29:23Â So we can hide that.
00:29:24Â And another little tweak that we can do is within this touchable opacity, we cannot actually play the video or interact with the native controls because
00:29:37Â it's within the file upload button.
00:29:39Â So let's simply remove the use native controls and is looping.
00:29:43Â That way we'll know the video is there, but we won't be able to interact with it.
00:29:48Â So let's give it a shot.
00:29:50Â I'm going to name my video something like IG real.
00:29:56Â I'm going to upload the video right here.
00:29:59Â We can see that it is uploaded and now you can choose and you can add another one or you can just exit out of it.
00:30:06Â We can choose a thumbnail for that video.
00:30:08Â I'm going to go with this background and the AI prompt is let's say something like testing.
00:30:15Â I think that should be good.
00:30:18Â There we go.
00:30:19Â And let me click submit and publish.
00:30:23Â we got an AppRite exception, file extension not allowed.
00:30:28Â But why is it not allowed?
00:30:30Â That is one of the most basic file formats.
00:30:33Â So let's see where do we disallow people from updating that file extension.
00:30:37Â I think here on the file picker, first of all, we can also allow people to select image, and then we can do forward slash JPEG.
00:30:47Â And we can also go back to AppRite.
00:30:50Â And within here, we can go to storage, files, settings, scroll down, and we can add JPEG and press enter and click update.
00:31:03Â This should allow us to add this file extension.
00:31:05Â And you can also select others if you want to.
00:31:08Â Going back to the code, we can give our create one more chance.
00:31:12Â Let's go to create.
00:31:14Â Let's once again, type something like IG real.
00:31:19Â Let's upload a video.
00:31:21Â I'm going to go with this one and upload a thumbnail and select a prompt.
00:31:27Â Once again, I'm going to do test and press enter.
00:31:33Â This time we get the file you're trying to upload is above the limit allowed for your plan.
00:31:39Â Okay.
00:31:39Â So the limit is about 50 megabytes for the free plan.
00:31:42Â So let's try to find something a bit smaller.
00:31:45Â And while we're doing that, I just noticed one more thing as well.
00:31:49Â If I click here, you can see that it actually opens up my files as we're using a document picker.
00:31:56Â And I thought this might be a bit more fitting for videos, but still, videos, images, you want to get them from your gallery,
00:32:04Â right?
00:32:05Â So let's use something like Expo Image Picker instead of a document picker.
00:32:10Â The installation is simple, mpx expo install, expo image picker.
00:32:14Â So back in our terminal, mpx expo install, expo image picker.
00:32:22Â And the usage will be very similar to what we have with a document picker.
00:32:26Â We basically imported and we use it as we normally would, but the method is launch image library.
00:32:34Â And then here we can choose which types of media we want to get.
00:32:38Â So let's go ahead and copy their example.
00:32:42Â Go back here.
00:32:43Â And instead of using this, we can simply override what we have.
00:32:48Â And let's not forget to import image picker right at the top by saying import image picker from expo image picker.
00:32:59Â Let's see if we have to import anything else.
00:33:01Â No, I think that's basically it.
00:33:04Â And let's see media types, image picker dot media type options dot all.
00:33:10Â We don't want to go for all.
00:33:11Â We want to choose a specific type.
00:33:13Â So let's say media types.
00:33:15Â If select type is a string of image, then we'll do image picker media type options dot.
00:33:24Â I think it's photos or maybe images.
00:33:29Â Yeah, it's images.
00:33:29Â You can see only images.
00:33:33Â Else, we can do something like image.media.typeOptions.videos.
00:33:41Â No, I don't see it that it auto fills it.
00:33:43Â So we have to make sure that this indeed is the right property to choose.
00:33:48Â If select type is triple equal to image, then images.else.media.typeOptions.
00:33:55Â Let's see.
00:33:56Â I don't see that it auto fills anything.
00:33:58Â So let's go back to the docs.
00:34:00Â Or even better, we can command click right here and see what we can get.
00:34:05Â All, videos, images.
00:34:07Â Okay.
00:34:08Â It's as simple as that.
00:34:09Â For some reason, Visual Studio Code didn't auto fill it for me, but it's videos.
00:34:15Â We are not going to allow editing.
00:34:17Â I don't think it's needed.
00:34:18Â And we can leave the aspect ratio and quality as they are.
00:34:23Â And let's give it a shot.
00:34:25Â I'm going to click upload.
00:34:29Â And I got an error and now I can see why it wasn't auto-filling videos.
00:34:34Â I forgot to add the dot image picker instead of image at the start.
00:34:39Â So now it recognizes only videos.
00:34:42Â This is great.
00:34:43Â Let's save it.
00:34:45Â And let's give it one more shot.
00:34:47Â And you can choose any of your videos under 50 megabytes.
00:34:51Â You might want to do some compression online.
00:34:54Â I have selected one right here and I'm going to upload it.
00:34:58Â This video was AI generated and it looks like Japan.
00:35:02Â So I'm going to say Japan right here.
00:35:04Â And I'm going to also upload a thumbnail.
00:35:08Â There we go.
00:35:08Â I have uploaded a thumbnail and we can say something like Japan in spring.
00:35:16Â Let's say that is the AI prompt that we gave it.
00:35:20Â Finally, let's click submit and publish and hope for the best.
00:35:24Â This time we got another error.
00:35:26Â At least you can see it on my screen here.
00:35:28Â It says Kenneth Reed property of dollar sign ID of undefined.
00:35:32Â So let's search for dollar sign ID right here.
00:35:37Â And we have only one belonging to the user right here, and we are getting the user from our state.
00:35:44Â So I don't think it's this ID.
00:35:46Â This one should actually exist.
00:35:48Â But it also could be some of the IDs coming from AppRide.
00:35:53Â Here, if I expand create video, we can search for dollar sign ID.
00:35:58Â And you can see that it could be the new account, that ID.
00:36:02Â This is in create user.
00:36:03Â Rather, we want to look into create video.
00:36:07Â Here we have nowhere $id.
00:36:09Â What about an upload file?
00:36:12Â Here we have it.
00:36:13Â Uploaded file $.$id.
00:36:15Â And do we have an in-file preview?
00:36:19Â I don't think so.
00:36:20Â So I think it's pointing to this one right here.
00:36:25Â So as we know that this dollars and ID could be the problem, the problem is with uploading a file.
00:36:31Â And that could be because we switched from document picker to image picker.
00:36:35Â So this modification we're doing with the assets and the MIME type might not be needed.
00:36:41Â So just to be safe, let's do a console log where we can console log the file to see what we're getting back.
00:36:49Â And we can also console log the uploaded file to see how that looks like.
00:36:55Â And let me just say uploaded in a string right here, just so we can know what this is relating to.
00:37:01Â And in the above one, I'm just going to simply say file, just so we can easily find it in our terminal.
00:37:07Â I'm going to save it.
00:37:09Â And now we have to try to upload one more time.
00:37:12Â And I will speed this process up for you.
00:37:16Â There we go.
00:37:17Â We know that it won't work again, but at least we can see the logs.
00:37:20Â So let's click submit and publish.
00:37:23Â And it looks like the uploaded is undefined, but the file above actually has its asset ID, but let's see if it has the mine type.
00:37:33Â It does have the type and it also has the mime type, which is great.
00:37:38Â So in this case, I don't think we even need to transform it manually as both have their own mime types.
00:37:45Â So let me just reload our terminal and start it one more time.
00:37:50Â So what we have to do now is ensure that we pass the asset in the exact right format that AppRite accepts it in.
00:37:58Â And it's name, type, size, URI.
00:38:02Â So let's quickly copy this and let's start forming this asset from scratch.
00:38:08Â That way you'll even better understand why we were doing what we were doing right here.
00:38:13Â First of all, all of these are strings and size is a number like this.
00:38:19Â We have to add commas and we have to understand where we get all of those values from.
00:38:25Â But at least that is now noticeable.
00:38:27Â We know because we have console logged the actual file.
00:38:31Â So let's search for it thing by thing.
00:38:33Â First of all, we have file size, which is Size right here.
00:38:39Â So we can say size is file dot file size.
00:38:45Â One down, three more to go.
00:38:47Â URI, let's see if we have that here.
00:38:50Â We have it, there we go, URI.
00:38:53Â So we can say URI is file dot URI.
00:38:58Â Then we have the type.
00:39:00Â In this case, the type is the mime type.
00:39:03Â So let's say type is file dot mime type.
00:39:08Â And finally, we have the name.
00:39:10Â The name is the file name.
00:39:13Â So let's say file dot file name.
00:39:16Â Great.
00:39:17Â Now we're forming the asset in the format that AppRite should gladly accept it in.
00:39:22Â Let's remove those consoles and let me swipe back up from my settings to our app.
00:39:29Â Let's reload it one more time, just to be sure.
00:39:32Â And let's create.
00:39:34Â I'm going to speed up this process for you one more time.
00:39:39Â There we go.
00:39:41Â And I will press submit and publish.
00:39:45Â Post uploaded successfully.
00:39:48Â That is great.
00:39:50Â Now, if we swipe up to reload, right at the bottom, you'll see a new video that we just uploaded.
00:39:57Â And what do you say that we show it on top?
00:40:00Â So let's go to get all posts.
00:40:03Â And like we have done with get latest posts, simply copy this query.
00:40:08Â And add it right here below video collection ID and remove the limit.
00:40:12Â Since here we want to get all the posts.
00:40:14Â So we're essentially sorting it by a descending order.
00:40:17Â That way our new post will appear right on top.
00:40:21Â JS Mastery posted Japan.
00:40:24Â We can click on it and we can see the video that I just posted.
00:40:28Â If you want to, you can also turn your phone around and see it in full quality.
00:40:33Â Believe it or not, this video was created by AI.
00:40:37Â So with that in mind, everything is working perfectly.
00:40:40Â We can see all of our other videos as well and play through them.
00:40:45Â And after some time, this video gets back to a thumbnail in case you want to replay it one more time.
00:40:51Â So with that in mind, we have successfully created the create video form.
00:40:56Â We have had two different file uploads.
00:41:00Â or should I call them image uploads because we're picking directly from the gallery, both videos and images, we're creating those files,
00:41:08Â uploading them to a storage bucket, retrieving their URLs, and finally creating a new document within our AppWrite database.
00:41:17Â We also have our profile and you can see immediately that we get this new post in Japan coming directly to our profile.
00:41:25Â If you want to, you can also modify the order in descending within get user posts right here.
00:41:33Â That way it will also appear on top.
00:41:35Â Then you can add a comma.
00:41:37Â And this time without an array, simply saying query.org or descending within the same array right here, we're going to sort it.
00:41:44Â And if you go back to home or back to profile, you should be able to see Japan appear on top.
00:41:50Â So now we have successfully created our onboarding.
00:41:54Â login and register screens, as well as home page with two different types of posts, horizontal view, as well as a vertical view,
00:42:03Â a search page where we can search for different things, as well as a profile page and a create page.