import fileDialog from 'file-dialog'; import { useCallback, useEffect, useReducer, useRef } from 'react'; export default function useFilePicker(value: any, onNotify: Function|any = null) { const [i, forceUpdate] = useReducer(x => x + 1, 0); const updateFnc = useCallback(function () { onNotify && onNotify(); forceUpdate(); }, [ onNotify, i ]); const chooseFile = useCallback(async function(accepts, transform) { const files = await fileDialog({ accept: accepts || '*/*' }); const file = files[0]; if(file) { let blob = file; if (transform) { blob = await transform(file); if (!blob) return; } value.upload(file.name, file.type, blob); forceUpdate(); } }, [ value, forceUpdate ]); const cancel = useCallback(function(e) { e && e.preventDefault(); if (value.$state === 2) { value.cancel(); } else if (value.$state === 3) { value.remove(); } forceUpdate(); }, [ value, forceUpdate ]); const ref = useRef(null); ref.current = updateFnc; useEffect(function() { const a = () => ref.current(); value.addListener(a); return function() { value.removeListener(a); }; }, [ value ]); return [ value, cancel, chooseFile ]; }