-
Notifications
You must be signed in to change notification settings - Fork 75
/
Copy pathuseFileStorage.js
150 lines (137 loc) · 4.41 KB
/
useFileStorage.js
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useRef, useEffect, useState } from 'react';
import federalist from '@util/federalistApi';
import { REFETCH_INTERVAL } from './utils';
const INITIAL_DATA = {
data: [],
currentPage: 1,
totalPages: 1,
totalItems: 0,
};
const TIMEOUT_DURATION = 5000;
export default function useFileStorage(
fileStorageId,
path = '/',
sortKey = 'updatedAt',
sortOrder = 'desc',
page = 1,
) {
const previousData = useRef();
const queryClient = useQueryClient();
const [deleteError, setDeleteError] = useState(null);
const [deleteSuccess, setDeleteSuccess] = useState(null);
const [createFolderError, setCreateFolderError] = useState(null);
const [createFolderSuccess, setCreateFolderSuccess] = useState(null);
const deleteTimeout = useRef(null);
const createFolderTimeout = useRef(null);
const handleSuccess = (setSuccess, setError, timeoutRef, message) => {
setError(null);
setSuccess(() => {
if (timeoutRef.current) clearTimeout(timeoutRef.current);
timeoutRef.current = setTimeout(() => setSuccess(null), TIMEOUT_DURATION);
return message;
});
queryClient.invalidateQueries({
queryKey: ['fileStorage', fileStorageId, path, sortKey, sortOrder, page],
});
};
const handleError = (setError, setSuccess, timeoutRef, errorMessage) => {
setSuccess(null);
setError(() => {
if (timeoutRef.current) clearTimeout(timeoutRef.current);
timeoutRef.current = setTimeout(() => setError(null), TIMEOUT_DURATION);
return errorMessage;
});
};
const { data, isLoading, isFetching, isPending, isPlaceholderData, isError, error } =
useQuery({
queryKey: ['fileStorage', fileStorageId, path, sortKey, sortOrder, page],
queryFn: () =>
federalist.fetchPublicFiles(fileStorageId, path, sortKey, sortOrder, page),
refetchInterval: REFETCH_INTERVAL,
refetchIntervalInBackground: false,
enabled: !!fileStorageId,
staleTime: 2000,
placeholderData: previousData.current || INITIAL_DATA,
});
useEffect(() => {
if (data !== undefined) {
previousData.current = data;
}
}, [data]);
useEffect(() => {
return () => {
if (deleteTimeout.current) clearTimeout(deleteTimeout.current);
if (createFolderTimeout.current) clearTimeout(createFolderTimeout.current);
};
}, []);
const deleteMutation = useMutation({
mutationFn: ({ item }) => federalist.deletePublicItem(fileStorageId, item.id),
onSuccess: () =>
handleSuccess(
setDeleteSuccess,
setDeleteError,
deleteTimeout,
'File deleted successfully.',
),
onError: (err) =>
handleError(
setDeleteError,
setDeleteSuccess,
deleteTimeout,
err?.message || 'Failed to delete file.',
),
});
const uploadMutation = useMutation({
mutationFn: ({ parent = '/', file }) =>
federalist.uploadPublicFile(fileStorageId, parent, file),
onSuccess: (file) => {
queryClient.invalidateQueries({
queryKey: ['fileStorage', fileStorageId, path, sortKey, sortOrder, page],
});
return file;
},
onError: (error) => error,
retry: false,
});
const createFolderMutation = useMutation({
mutationFn: ({ parent = '/', name }) =>
federalist.createPublicDirectory(fileStorageId, parent, name),
onSuccess: () =>
handleSuccess(
setCreateFolderSuccess,
setCreateFolderError,
createFolderTimeout,
'Folder created successfully.',
),
onError: (err, { name }) => {
const errorMessage = err?.message || 'Could not create folder.';
const formattedMessage = errorMessage.includes('already exists')
? `A folder named "${name}" already exists in this folder.`
: errorMessage;
handleError(
setCreateFolderError,
setCreateFolderSuccess,
createFolderTimeout,
formattedMessage,
);
},
});
return {
...data,
queryClient,
isLoading,
isFetching,
isPending,
isPlaceholderData,
isError,
defaultError: error,
deleteItem: (item) => deleteMutation.mutateAsync({ item }),
deleteError,
deleteSuccess,
uploadFile: (parent, file) => uploadMutation.mutateAsync({ parent, file }),
createFolder: (parent, name) => createFolderMutation.mutateAsync({ parent, name }),
createFolderError,
createFolderSuccess,
};
}