Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | 2x 22x 22x 8x 8x 8x 8x 7x 7x 1x 1x 2x 7x 1x 7x 2x 2x 2x 2x 2x 2x 2x 2x 7x 1x 7x 1x 7x 22x | import { useState } from "react"; type Headers = { [key: string]: any; }; type RequestOptions = { method: string; url: string; headers?: Headers; body: Document | BodyInit | null | undefined; }; type BeforeRequestProps = { xhr: XMLHttpRequest; files: FileList; }; type BeforeRequest = ( props: BeforeRequestProps ) => Promise<RequestOptions | undefined> | RequestOptions | undefined; type UploadProps = { files: FileList; }; type UseUploadState<Response> = { loading: boolean; done: boolean; data?: Response; error?: ProgressEvent; xhr?: XMLHttpRequest; responseHeaders?: Headers; progress?: number; }; type UseUploadResults<Response> = [ (props: UploadProps) => void, UseUploadState<Response> ]; export const useUpload = <Response = any>( beforeRequest: BeforeRequest ): UseUploadResults<Response> => { let [state, setState] = useState<UseUploadState<Response>>({ loading: false, done: false, }); const upload = async ({ files }: UploadProps) => { setState({ loading: true, done: false }); const xhr = new XMLHttpRequest(); let options = await beforeRequest({ xhr, files }); // bail out if you return undefined from options if (!options) return setState({ loading: false, done: false }); xhr.open(options.method, options.url); /* Helper method for setting headers on an xhr request, one of the only extra features of this hook */ if (options.headers) { let headers = options.headers; Object.keys(options.headers).forEach((header) => xhr.setRequestHeader(header, headers[header]) ); } /* XHR Listeners */ xhr.upload.addEventListener("progress", (event) => { setState((state) => ({ ...state, progress: Math.round((event.loaded / event.total) * 100), })); }); xhr.addEventListener("load", () => { let data; try { data = JSON.parse(xhr.response); } catch (e) { data = xhr.response; } let responseHeaders = xhr .getAllResponseHeaders() .trim() .split(/[\r\n]+/) .map((line) => line.split(": ")) .reduce((acc: Headers, [header, value]) => { acc[header] = value; return acc; }, {}); setState({ data, loading: false, xhr, responseHeaders, done: true }); }); xhr.addEventListener("error", (error) => { setState({ error, xhr, loading: false, done: true }); }); xhr.addEventListener("abort", (error) => { setState({ error, xhr, loading: false, done: true }); }); /* send the request! */ xhr.send(options.body); }; return [upload, state]; }; |