useDownloader hook
gorbypark opened this issue · 2 comments
Feature Request
Just thought I'd throw it out there that it would be cool to have a hook that could be consumed in any component. How I imagine it would work is that you'd create a new DownloadQueue()
and run .init()
at the top level of the app somewhere. Then in any component, you could do something like below:
import {useDownloader} from 'react-native-background-downloader-queue';
const MyComponent = () => {
const downloader = useDownloader();
const [downloadProgress, setDownloadProgress] = useState()
useEffect(() => {
const myDownloadId = downloader.addUrl('http://example.com/lala.mp3'); // Returns a unique id?
setDownloadProgress(downloader.progress(myDownloadId)); // should be able to call downloader.progress() and get entire queue, or download.progress(id) to get only specific progress for the id
}, [downloader])
return <View><Text>{downloadProgress}% downloaded</Text></View>
}
I didn't fully think through how the API would look, but something like the above. The main feature would be able to add and get the progress of all downloads or specific downloads from any component. I'm sure we'd want to be able to pause/cancel/resume and all the other niceties, too.
I think some hooks would be great -- certainly for the way that many people will likely want to use this library.
How should we handle the various options available at init? I wonder if it'd be easiest to provide a React.Context
around this, to encapsulate all the various inits. So it'd look something like this:
import {DownloadQueueContextProvider} from 'react-native-background-downloader-queue';
export default function App() {
return (
<DownloadQueueContextProvider
domain='someUserId'
urlToPath={url => new URL(url).pathname}
netInfoAddEventListener={NetInfo.addEventListener}
activeNetworkTypes={["wifi", "ethernet"]}
>
<MyComponent />
</DownloadQueueContextProvider>
);
}
function MyComponent() {
const myFavUrl = 'https://boo.com/8675309.mp3';
const downloader = useDownloader(); // This gets the DownloadQueue instance from the provider
const [percent, bytesWritten, total] = useDownloadProgress(myFavUrl);
const finished = useDownloadDone(myFavUrl);
// finished === true iff percent === 1.0 && bytesWritten === total
async function onPressPause() {
// You can call all DownloadQueue functions, as usual.
const statuses = await downloader.getQueueStatus();
downloader.pauseAll();
}
}
The idea would be to get all setup done via DownloadQueueContextProvider, which gives you a chance to set domain
and a few other init()
options. Notably, I'm proposing (for your feedback) that you can't pass handlers
directly via the context provider, but that there are instead hooks for all those handlers that each take a url.
Thoughts on this approach?