frontend: steadier upload button

Massimo Melina committed Feb 17, 2023 at 14:32 UTC 89bc123399e634cbabc3cdfaec4de479f8e0fa5b
4 files changed +18 -9
frontend/src/menu.ts
+9 -2
@@ -39,6 +39,13 @@ export function MenuPanel() {
39
40 // passing files as string in the url should allow 1-2000 items before hitting the url limit of 64KB. Shouldn't be a problem, right?
41 const list = useMemo(() => Object.keys(selected).map(s => s.endsWith('/') ? s.slice(0,-1) : s).join('*'), [selected])
42 +
43 + // avoid useless dom changes while we are still waiting for necessary data
44 + const [changingButton, setChangingButton] = useState('')
45 + useEffect(() => {
46 + if (can_upload !== undefined)
47 + setChangingButton(showFilter && can_delete ? 'delete' : (can_upload || qs.length > 0) ? 'upload' : '')
48 + }, [showFilter, can_delete, can_upload, qs.length])
49 return h('div', { id: 'menu-panel' },
50 h('div', { id: 'menu-bar' },
51 h(LoginButton),
@@ -51,12 +58,12 @@ export function MenuPanel() {
58 state.showFilter = !showFilter
59 }
60 }),
54 - h(MenuButton, showFilter && can_delete ? {
61 + h(MenuButton, changingButton === 'delete' ? {
62 icon: 'trash',
63 label: "Delete",
64 className: 'show-sliding',
65 onClick: () => deleteFiles(Object.keys(selected), pathname)
59 - } : (can_upload || qs.length > 0) ? {
66 + } : changingButton === 'upload' ? {
67 icon: 'upload',
68 label: "Upload",
69 className: 'show-sliding ' + (uploading ? 'ani-working' : ''),
frontend/src/state.ts
+4 -4
@@ -28,11 +28,11 @@ export const state = proxy<{
28 serverConfig?: any,
29 loginRequired?: boolean, // force user to login before proceeding
30 messageOnly?: string, // no gui, just show this message
31 - can_upload: boolean
32 - can_delete: boolean
31 + can_upload?: boolean
32 + can_delete?: boolean
33 }>({
34 - can_delete: false,
35 - can_upload: false,
34 + can_delete: undefined,
35 + can_upload: undefined,
36 iconsClass: '',
37 username: '',
38 list: [],
frontend/src/upload.ts
+1 -1
@@ -320,7 +320,7 @@ function abortCurrentUpload() {
320 req?.abort()
321 }
322
323 -export function acceptDropFiles(cb: false | ((files:File[]) => void)) {
323 +export function acceptDropFiles(cb: false | undefined | ((files:File[]) => void)) {
324 return {
325 onDragOver(ev: DragEvent) {
326 ev.preventDefault()
frontend/src/useFetchList.ts
+4 -2
@@ -42,8 +42,8 @@ export default function useFetchList() {
42 state.selected = {}
43 state.loading = true
44 state.error = undefined
45 - state.can_upload = false
46 - state.can_delete = false
45 + state.can_upload = undefined
46 + state.can_delete = undefined
47 // buffering entries is necessary against burst of events that will hang the browser
48 const buffer: DirList = []
49 const flush = () => {
@@ -70,6 +70,8 @@ export default function useFetchList() {
70 data.forEach(async (entry: any) => {
71 if (entry.props)
72 return Object.assign(state, _.pick(entry.props, ['can_upload', 'can_delete']))
73 + state.can_upload ??= false
74 + state.can_delete ??= false
75 if (entry.add)
76 return buffer.push(entry.add)
77 const { error } = entry