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