Skip to content

Commit 446f480

Browse files
committed
WiP: infinite scroll and more
1 parent 942a1eb commit 446f480

File tree

4 files changed

+148
-123
lines changed

4 files changed

+148
-123
lines changed

client/browser/FileSelectDialog.tsx

Lines changed: 120 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React, {
33
lazy,
44
memo,
55
Suspense,
6+
useCallback,
67
useEffect,
78
useImperativeHandle,
89
useMemo,
@@ -57,9 +58,9 @@ const ScrollSpy = (props) => {
5758
const {fetchFiles} = props;
5859
const {ref, inView} = useInView({
5960
triggerOnce: true,
60-
onChange: (loadMore) => {
61+
onChange: async (loadMore) => {
6162
if (loadMore && !inView) {
62-
fetchFiles();
63+
await fetchFiles();
6364
}
6465
},
6566
});
@@ -87,14 +88,14 @@ const FilesList = memo((props: any) => {
8788
<>{structure.files.map(file => (
8889
<li key={file.id} onClick={() => selectFile(file)}><Figure {...file} /></li>
8990
))}
90-
{structure.offset !== null && <ScrollSpy fetchFiles={fetchFiles} />}
91+
{structure.offset !== null && <ScrollSpy key={structure.offset} fetchFiles={fetchFiles} />}
9192
</>
9293
)}</ul>
9394
);
9495
});
9596

9697

97-
const FileSelectDialog = forwardRef((props: any, forwardedRef) => {
98+
const FileSelectDialog = forwardRef(function FileSelectDialog(props: any, forwardedRef) {
9899
const {realm, baseUrl, csrfToken} = props;
99100
const [structure, setStructure] = useState({
100101
root_folder: null,
@@ -108,74 +109,73 @@ const FileSelectDialog = forwardRef((props: any, forwardedRef) => {
108109
const ref = useRef(null);
109110
const uploaderRef = useRef(null);
110111
const [uploadedFile, setUploadedFile] = useState(null);
111-
const dialog = ref.current?.closest('dialog');
112+
const [currentFolderId, setCurrentFolderId] = useState(null);
113+
const [currentFolderElement, setCurrentFolderElement] = useState(null);
114+
115+
useImperativeHandle(forwardedRef, () => ({scrollToCurrentFolder, dismissAndClose}));
112116

113117
useEffect(() => {
114-
if (!uploadedFile) {
118+
if (structure.root_folder === null) {
115119
getStructure();
116120
}
117-
}, [uploadedFile]);
118-
119-
useImperativeHandle(forwardedRef, () => ({dismissAndClose}));
120-
121-
const setCurrentFolder = (folderId) => {
122-
setStructure(prevStructure => {
123-
const newStructure = Object.assign(structure, {
124-
...prevStructure,
125-
last_folder: folderId,
126-
files: [],
127-
offset: null,
128-
recursive: false,
129-
search_query: '',
130-
});
121+
}, [structure.root_folder]);
122+
123+
useEffect(() => {
124+
if (currentFolderId && uploadedFile === null) {
131125
fetchFiles();
132-
return newStructure;
133-
});
134-
};
126+
}
127+
}, [currentFolderId, uploadedFile]);
135128

136-
async function toggleRecursive(folderId: string) {
137-
setStructure(prevStructure => {
138-
const newStructure = Object.assign(structure, {
139-
...prevStructure,
140-
last_folder: folderId,
141-
files: [],
142-
offset: null,
143-
recursive: prevStructure.recursive ? false : true,
144-
search_query: '',
145-
});
129+
useEffect(() => {
130+
if (structure.root_folder) {
146131
fetchFiles();
147-
return newStructure;
132+
}
133+
}, [structure.recursive, structure.search_query]);
134+
135+
function setCurrentFolder(folderId){
136+
setCurrentFolderId(folderId);
137+
setStructure({
138+
...structure,
139+
last_folder: folderId,
140+
files: [],
141+
offset: null,
142+
recursive: false,
143+
search_query: '',
148144
});
149145
}
150146

151-
const setSearchQuery = (query) => {
152-
setStructure(prevStructure => {
153-
const newStructure = Object.assign(structure, {
154-
...prevStructure,
155-
files: [],
156-
offset: null,
157-
recursive: false,
158-
search_query: query,
159-
});
160-
fetchFiles();
161-
return newStructure;
147+
function toggleRecursive(folderId: string) {
148+
setStructure({
149+
...structure,
150+
last_folder: folderId,
151+
files: [],
152+
offset: null,
153+
recursive: structure.recursive ? false : true,
154+
search_query: '',
162155
});
163-
};
156+
}
164157

165-
const refreshFilesList = () => {
166-
setStructure(prevStructure => {
167-
const newStructure = Object.assign(structure, {
168-
root_folder: prevStructure.root_folder,
169-
files: [],
170-
last_folder: prevStructure.last_folder,
171-
offset: null,
172-
search_query: prevStructure.search_query,
173-
labels: prevStructure.labels,
174-
});
175-
fetchFiles();
176-
return newStructure;
158+
function setSearchQuery(query) {
159+
setStructure({
160+
...structure,
161+
files: [],
162+
offset: null,
163+
recursive: false,
164+
search_query: query,
177165
});
178-
};
166+
}
167+
168+
function refreshFilesList(){
169+
setStructure({
170+
...structure,
171+
root_folder: structure.root_folder,
172+
files: [],
173+
last_folder: structure.last_folder,
174+
offset: null,
175+
search_query: structure.search_query,
176+
labels: structure.labels,
177+
});
178+
}
179179

180180
async function getStructure() {
181181
const response = await fetch(`${baseUrl}structure/${realm}`);
@@ -186,7 +186,7 @@ const FileSelectDialog = forwardRef((props: any, forwardedRef) => {
186186
}
187187
}
188188

189-
async function fetchFiles() {
189+
const fetchFiles = useCallback(async () => {
190190
const fetchUrl = (() => {
191191
const params = new URLSearchParams();
192192
if (structure.recursive) {
@@ -199,7 +199,7 @@ const FileSelectDialog = forwardRef((props: any, forwardedRef) => {
199199
params.set('q', structure.search_query);
200200
return `${baseUrl}${structure.last_folder}/search?${params.toString()}`;
201201
}
202-
return `${baseUrl}${structure.last_folder}/list?${params.toString()}`;
202+
return `${baseUrl}${structure.last_folder}/list${params.size === 0 ? '' : `?${params.toString()}`}`;
203203
})();
204204
const response = await fetch(fetchUrl);
205205
if (response.ok) {
@@ -212,20 +212,26 @@ const FileSelectDialog = forwardRef((props: any, forwardedRef) => {
212212
} else {
213213
console.error(response);
214214
}
215-
}
215+
}, [structure.last_folder, structure.recursive, structure.search_query, structure.offset]);
216216

217-
function refreshStructure() {
218-
setStructure({...structure});
219-
}
217+
const refreshStructure = () => setStructure({...structure});
220218

221-
function handleUpload(folderId, uploadedFiles) {
219+
const handleUpload = (folderId, uploadedFiles) => {
220+
setCurrentFolderId(folderId);
222221
setUploadedFile(uploadedFiles[0]);
223-
}
222+
};
224223

225-
function selectFile(fileInfo) {
224+
const selectFile = useCallback(fileInfo => {
226225
props.selectFile(fileInfo);
227226
setUploadedFile(null);
227+
refreshFilesList();
228228
props.closeDialog();
229+
}, []);
230+
231+
function scrollToCurrentFolder() {
232+
if (currentFolderElement) {
233+
currentFolderElement.scrollIntoView({behavior: 'smooth', block: 'center'});
234+
}
229235
}
230236

231237
function dismissAndClose() {
@@ -245,53 +251,58 @@ const FileSelectDialog = forwardRef((props: any, forwardedRef) => {
245251
});
246252
}
247253
setUploadedFile(null);
254+
refreshFilesList();
248255
props.closeDialog();
249256
}
250257

258+
console.log('FileSelectDialog', structure);
259+
251260
return (<>
252261
<div className="wrapper" ref={ref}>
253262
{uploadedFile ?
254-
<BrowserEditor
255-
uploadedFile={uploadedFile}
256-
mainContent={ref.current}
257-
settings={{csrfToken, baseUrl, selectFile, dismissAndClose, labels: structure.labels}}
258-
/> : <>
259-
<MenuBar
260-
refreshFilesList={refreshFilesList}
261-
setSearchQuery={setSearchQuery}
262-
openUploader={() => uploaderRef.current.openUploader()}
263-
labels={structure.labels}
264-
/>
265-
<div className="browser-body">
266-
<nav className="folder-structure">
267-
<ul role="navigation">
268-
{structure.root_folder && <FolderStructure
269-
baseUrl={baseUrl}
270-
folder={structure.root_folder}
271-
lastFolderId={structure.last_folder}
272-
setCurrentFolder={setCurrentFolder}
273-
toggleRecursive={toggleRecursive}
274-
refreshStructure={refreshStructure}
275-
isListed={structure.recursive ? false : null}
276-
/>}
277-
</ul>
278-
</nav>
279-
<FileUploader
280-
folderId={structure.last_folder}
281-
handleUpload={handleUpload}
282-
ref={uploaderRef}
283-
settings={{csrf_token: csrfToken, base_url: baseUrl}}
284-
>{
285-
structure.files === null ?
286-
<div className="status">{gettext("Loading files…")}</div> :
287-
<FilesList
288-
structure={structure}
289-
fetchFiles={fetchFiles}
290-
selectFile={selectFile}
291-
/>
292-
}</FileUploader>
293-
</div>
294-
</>}
263+
<BrowserEditor
264+
uploadedFile={uploadedFile}
265+
mainContent={ref.current}
266+
settings={{csrfToken, baseUrl, selectFile, dismissAndClose, labels: structure.labels}}
267+
/> : <>
268+
<MenuBar
269+
refreshFilesList={refreshFilesList}
270+
setSearchQuery={setSearchQuery}
271+
openUploader={() => uploaderRef.current.openUploader()}
272+
labels={structure.labels}
273+
searchQuery={structure.search_query}
274+
/>
275+
<div className="browser-body">
276+
<nav className="folder-structure">
277+
<ul role="navigation">
278+
{structure.root_folder && <FolderStructure
279+
baseUrl={baseUrl}
280+
folder={structure.root_folder}
281+
lastFolderId={structure.last_folder}
282+
setCurrentFolder={setCurrentFolder}
283+
toggleRecursive={toggleRecursive}
284+
refreshStructure={refreshStructure}
285+
isListed={structure.recursive ? false : null}
286+
setCurrentFolderElement={setCurrentFolderElement}
287+
/>}
288+
</ul>
289+
</nav>
290+
<FileUploader
291+
folderId={structure.last_folder}
292+
handleUpload={handleUpload}
293+
ref={uploaderRef}
294+
settings={{csrf_token: csrfToken, base_url: baseUrl}}
295+
>{
296+
structure.files === null ?
297+
<div className="status">{gettext("Loading files…")}</div> :
298+
<FilesList
299+
structure={structure}
300+
fetchFiles={fetchFiles}
301+
selectFile={selectFile}
302+
/>
303+
}</FileUploader>
304+
</div>
305+
</>}
295306
</div>
296307
<div
297308
className="close-button"

client/browser/FinderFileSelect.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export default function FinderFileSelect(props) {
4545

4646
function openDialog() {
4747
dialogRef.current.showModal();
48+
selectRef.current.scrollToCurrentFolder();
4849
}
4950

5051
function removeFile() {
@@ -70,6 +71,8 @@ export default function FinderFileSelect(props) {
7071
return date.toLocaleString();
7172
}
7273

74+
console.log('FinderFileSelect', selectedFile);
75+
7376
return (<>
7477
<slot ref={slotRef} />
7578
<div className="finder-file-select">

0 commit comments

Comments
 (0)