| 12 | const LoadingContext = createContext({}) |
| 13 | |
| 14 | export const useSetLoading = () => { |
| 15 | const loadingId = useRef(uuidv4()) |
| 16 | const loading = useRef(false) |
| 17 | const { dispatch } = useContext(LoadingContext) |
| 18 | const [metadataIds, setMetadataIds] = useState(new Set()) |
| 19 | const [chunkIds, setChunkIds] = useState(new Set()) |
| 20 | |
| 21 | useEffect(() => { |
| 22 | return () => { |
| 23 | const loaders = [{ id: loadingId.current, key: 'loading' }] |
| 24 | metadataIds.forEach((id) => loaders.push({ id, key: 'metadata' })) |
| 25 | chunkIds.forEach((id) => loaders.push({ id, key: 'chunk' })) |
| 26 | dispatch({ loaders, type: 'clear' }) |
| 27 | } |
| 28 | }, []) |
| 29 | |
| 30 | useEffect(() => { |
| 31 | if (loading.current && metadataIds.size === 0 && chunkIds.size === 0) { |
| 32 | dispatch({ |
| 33 | loaders: [{ id: loadingId.current, key: 'loading' }], |
| 34 | type: 'clear', |
| 35 | }) |
| 36 | loading.current = false |
| 37 | } |
| 38 | }, [metadataIds.size, chunkIds.size, loading.current]) |
| 39 | |
| 40 | const setLoading = useCallback((key = 'chunk') => { |
| 41 | if (!['chunk', 'metadata'].includes(key)) { |
| 42 | throw new Error( |
| 43 | `Unexpected loading key: ${key}. Expected one of: 'chunk', 'metadata'.` |
| 44 | ) |
| 45 | } |
| 46 | |
| 47 | const id = uuidv4() |
| 48 | const setter = key === 'metadata' ? setMetadataIds : setChunkIds |
| 49 | setter((prev) => { |
| 50 | prev.add(id) |
| 51 | return prev |
| 52 | }) |
| 53 | |
| 54 | const loaders = [{ id, key }] |
| 55 | |
| 56 | if (!loading.current) { |
| 57 | loaders.push({ id: loadingId.current, key: 'loading' }) |
| 58 | loading.current = true |
| 59 | } |
| 60 | dispatch({ loaders, type: 'set' }) |
| 61 | return id |
| 62 | }, []) |
| 63 | |
| 64 | const clearLoading = useCallback((id, { forceClear } = {}) => { |
| 65 | if (id) { |
| 66 | setMetadataIds((prevMetadata) => { |
| 67 | prevMetadata.delete(id) |
| 68 | return prevMetadata |
| 69 | }) |
| 70 | setChunkIds((prevChunk) => { |
| 71 | prevChunk.delete(id) |