fix: (regression 0.47.0) admin/fs: blank list adding from disk #298

Massimo Melina committed Jul 21, 2023 at 10:50 UTC 08537a31ef6e8674ac7c6d933b9f91dd58da008a
3 files changed +37 -38
admin/src/FilePicker.ts
+2 -4
@@ -42,7 +42,7 @@ export default function FilePicker({ onSelect, multiple=true, files=true, folder
42 }
43 }).finally(() => setReady(true))
44 }, [from])
45 - const { list, error, loading } = useApiList<DirEntry>(ready && 'ls', { path: cwd, files, fileMask })
45 + const { list, error, connecting } = useApiList<DirEntry>(ready && 'ls', { path: cwd, files, fileMask })
46 useEffect(() => {
47 setSel([])
48 setFilter('')
@@ -58,8 +58,6 @@ export default function FilePicker({ onSelect, multiple=true, files=true, folder
58
59 const [listHeight, setListHeight] = useState(0)
60 const filteredList = useMemo(() => list.filter(it => filterMatch(it.n)), [list,filterMatch])
61 - if (loading)
62 - return spinner()
61 const root = isWindows.current ? '' : '/'
62 const pathDelimiter = isWindows.current ? '\\' : '/'
63 const cwdDelimiter = enforceFinal(pathDelimiter, cwd)
@@ -105,7 +103,7 @@ export default function FilePicker({ onSelect, multiple=true, files=true, folder
103 },
104 sx: { flex: 1, display: 'flex', flexDirection: 'column' }
105 },
108 - !list.length ? h(Center, { flex: 1, mt: '4em' }, "No elements in this folder")
106 + !list.length ? h(Center, { flex: 1, mt: '4em' }, connecting ? spinner() : "No elements in this folder")
107 : h(FixedSizeList, {
108 width: '100%', height: listHeight,
109 itemSize: 46, itemCount: filteredList.length, overscanCount: 5,
src/adminApis.ts
+1 -1
@@ -112,7 +112,7 @@ export const adminApis: ApiHandlers = {
112 return files
113 },
114
115 - async get_log({ file='log' }, ctx) {
115 + get_log({ file='log' }, ctx) {
116 return new SendListReadable({
117 bufferTime: 10,
118 async doAtStart(list) {
src/api.vfs.ts
+34 -33
@@ -14,7 +14,7 @@ import {
14 } from './vfs'
15 import _ from 'lodash'
16 import { stat } from 'fs/promises'
17 -import { ApiError, ApiHandlers } from './apiMiddleware'
17 +import { ApiError, ApiHandlers, SendListReadable } from './apiMiddleware'
18 import { dirname, extname, join, resolve } from 'path'
19 import { dirStream, isDirectory, isWindowsDrive, makeMatcher } from './misc'
20 import {
@@ -181,43 +181,44 @@ const apis: ApiHandlers = {
181 return { path }
182 },
183
184 - async *ls({ path, files=true, fileMask }, ctx) {
185 - if (!path && IS_WINDOWS) {
186 - try {
187 - for (const n of await getDrives())
188 - yield { add: { n, k: 'd' } }
189 - }
190 - catch(error) {
191 - console.debug(error)
192 - }
193 - return
194 - }
195 - try {
196 - const matching = makeMatcher(fileMask)
197 - path = isWindowsDrive(path) ? path + '\\' : resolve(path || '/')
198 - for await (const [name, isDir] of dirStream(path)) {
199 - if (ctx.req.aborted)
184 + ls({ path, files=true, fileMask }, ctx) {
185 + return new SendListReadable({
186 + async doAtStart(list) {
187 + if (!path && IS_WINDOWS) {
188 + try {
189 + for (const n of await getDrives())
190 + list.add({ n, k: 'd' })
191 + } catch (error) {
192 + console.debug(error)
193 + }
194 return
195 + }
196 try {
202 - if (!isDir)
203 - if (!files || fileMask && !matching(name))
204 - continue
205 - const stats = await stat(join(path, name))
206 - yield {
207 - add: {
208 - n: name,
209 - s: stats.size,
210 - c: stats.ctime,
211 - m: stats.mtime,
212 - k: isDir ? 'd' : undefined,
213 - }
197 + const matching = makeMatcher(fileMask)
198 + path = isWindowsDrive(path) ? path + '\\' : resolve(path || '/')
199 + for await (const [name, isDir] of dirStream(path)) {
200 + if (ctx.req.aborted)
201 + return
202 + if (!isDir)
203 + if (!files || fileMask && !matching(name))
204 + continue
205 + try {
206 + const stats = await stat(join(path, name))
207 + list.add({
208 + n: name,
209 + s: stats.size,
210 + c: stats.ctime,
211 + m: stats.mtime,
212 + k: isDir ? 'd' : undefined,
213 + })
214 + } catch {} // just ignore entries we can't stat
215 }
216 + list.close()
217 + } catch (e: any) {
218 + list.error(e.code || e.message || String(e), true)
219 }
216 - catch {} // just ignore entries we can't stat
220 }
218 - } catch (e: any) {
219 - yield { error: e.code || e.message || String(e) }
220 - }
221 + })
222 }
223
224 }