Looking at files.android SDK, let's convert this API to upload a local file and implement this callback method. Let's collapse our constructor and implement a new method for this. We'll call this upload local and we'll have it accept a file path to a local file. Let's drop in this line from the readme.
This URI to local file is going to accept an android URI. We'll use the android.net package utilities to actually get this URI to the local file. We can use android.net.uri, and we'll use from file. We can see it accepts a java.io file type so we'll just construct one java.io file. It takes in the path to the file directory, so this we can pass in our file path.
For our second argument this context will come from app.android.context. If we look back at the usage example we can see that the third argument is this file picker call back structure. We can reference this like we did above for file picker as file picker call back and this will again come from the io.filepicker package. Here we'll just construct one.
This constructor is going to take an object containing keys to these various callbacks, so we can take on file upload success and set it to a callback. We'll do the same for the other callbacks here. This is going to be error.
If we look we can see this is actually typed as a Throwable. We can actually use that type. If we go to Android's API documentation we can search for Throwable and we'll see that it is part of the Java.lang package. We can use that directly, Java.lang.throwable, and just set this as a callback. Then we have one more. Then we'll get the last one.
This passes back the URI and a progress here. We'll say URI and progress. Also, you can type these as well. This is using our android.net.uri class and progress is just a number. For each of these we'll just console log them out for good measure now. We'll just log the progress on this one.
With this implemented we can try uploading a local file now. Before we do that let's run a build of our plugin. Let's make sure we can get the latest typings updated. You may notice a typescript error, it's because we need to get a little more specific with our script now.
Since we already have typescript definitions generated for Android and iOS libraries here, let's just make sure that we only build for iOS and Android suffixes here. We can see that succeeds. Let's now take the android definition that was just generated, since we created a new API.
Let's just update our index since we are maintaining an index typings file independently. Now, let's try uploading a local file. Let's open the app component constructor. What we want to do is get a reference to a local file. I happen to have one in this project already, so we'll just use this one.
First we want to import * as fs or any alias you'd like. This is going to be the file system module from native script. We'll use this to get a reference to that local file using fs.known folders, current app, get file.
This is going to grab a file from the current app directory and we'll just pass the name of it. It is insegghead.ping. Now, we'll upload that local file using the new API, upload local, and we'll pass in the file.path.
When our app launches this time it should instantiate this component and immediately upload this local file. However, we've realized something. We had a progress method that would actually let us know what the progress on the uploading was, but we have no way to actually get that here. Let's look at a way we could do that.
Let's go back to our plugin implementation and see what we can do. Native script provides an observable class but it is not like RS, JS, observables. In fact it may be renamed in the future to avoid such confusion.
For now we can use this observable class to our advantage to shuttle events into and out of this class. We can import observable from the data observable package. Let's just extend this observable class, and ensure we call super on the super class.
This gives us the ability to send out notifications to listeners. On our file upload progress we can actually use this.notify and we can pass some properties here. One is the event name and we'll just call this upload progress.
The second we can pass is object and this is just a reference back to the object that's sending the notification. In this case it's our file stack class. Then we can pass this data key. This can be an object or anything that you want to pass along. In this case we'll just pass the progress.
If we look back at the readme on this progress argument we can see it is typed as a float. Let's just make sure that this is converted to, say, a percentage. Let's just floor this value while multiplying by 100. We'll make a note.
Now, let's grab the name of this event and back on our component constructor we can wire to this event now, and it's upload progress where we can grab the event. Let's bind it to a view binding that will call progress and we can set this equal to the event.data property.
Since these observable events are not passed through angular zone let's make sure we also inject injie zone, set it up in the constructor to be dependency injected. Now, we can call injie zone and run to make sure that this does update our view binding.
In our view let's setup a label to bind to that progress property, and for good measure we'll just add a class here and ensure the color is white. Lastly, we'll add a percent sign just to be clear. This time we should see the app launch and we should immediately see a percentage indicator telling us the progress on that file upload.
Now, the app launches and we can see the progress get updated up to a 100 percent, and we can see that we actually have a file in the cloud that was uploaded now. That's the local file that we uploaded from the app.