fix: inconsistent drag&drop upload behavior when a dialog is displayed

Massimo Melina committed Oct 16, 2025 at 11:01 UTC f100e10f5b93cc1aef715a2eced148570ebe0f84
3 files changed +17 -13
frontend/src/App.ts
+16 -4
@@ -3,11 +3,14 @@
3 import { BrowserRouter, Route, Routes, useNavigate } from "react-router-dom"
4 import { createElement as h, Fragment } from 'react'
5 import { BrowseFiles } from "./BrowseFiles"
6 -import { Dialogs } from './dialog'
6 +import { alertDialog, Dialogs } from './dialog'
7 import useTheme from "./useTheme"
8 -import { useSnapState } from './state'
8 +import { state, useSnapState } from './state'
9 +import { acceptDropFiles } from './upload'
10 +import { enqueueUpload, getFilePath, uploadState } from './uploadQueue'
11 import i18n from './i18n'
10 -import { proxy, useSnapshot } from "valtio"
12 +const { t } = i18n
13 +import { proxy, ref, useSnapshot } from "valtio"
14 import { Spinner } from "./components"
15 import { enforceStarting, getHFS, getPrefixUrl, loadScript } from '@hfs/shared'
16 import { Toasts } from './toasts'
@@ -23,7 +26,16 @@ function App() {
26 if (!ready)
27 return h(Spinner, { style: { margin: 'auto' } })
28 installScript()
26 - return h('div', i18nWrapperProps(),
29 + return h('div', {
30 + ...i18nWrapperProps(),
31 + ...acceptDropFiles((files, to) => {
32 + if (uploadState.uploadDialogIsOpen) // in this case the upload is not started until confirmed
33 + uploadState.adding.push(...files.map(f => ({ file: ref(f), path: getFilePath(f), to })))
34 + else
35 + state.props?.can_upload ? enqueueUpload(files.map(file => ({ file, path: getFilePath(file) })), location.pathname + to)
36 + : alertDialog(t("Upload not available"), 'warning')
37 + })
38 + },
39 h(BrowserRouter, {},
40 h(NavigationExtractor, {},
41 h(Toasts),
frontend/src/BrowseFiles.ts
-4
@@ -42,10 +42,6 @@ export function BrowseFiles() {
42
43 const propsDropFiles = useMemo(() => ({
44 id: 'files-dropper',
45 - ...acceptDropFiles((files, to) =>
46 - props?.can_upload ? enqueueUpload(files.map(file => ({ file, path: getFilePath(file) })), location.pathname + to)
47 - : alertDialog(t("Upload not available"), 'warning')
48 - ),
45 }), [props])
46 if (!useAuthorized())
47 return h(CustomCode, { name: 'unauthorized' }, h('h1', { className: 'unauthorized' }, t`Unauthorized`) )
frontend/src/upload.ts
+1 -5
@@ -52,11 +52,7 @@ export function showUpload() {
52 const size = formatBytes(adding.reduce((a, x) => a + x.file.size, 0))
53 const isMobile = useIsMobile()
54
55 - return h(FlexV, {
56 - gap: '.5em',
57 - props: acceptDropFiles( (files, to) =>
58 - uploadState.adding.push(...files.map(f => ({ file: ref(f), path: getFilePath(f), to }))) )
59 - },
55 + return h(FlexV, { gap: '.5em' },
56 h(FlexV, { className: 'upload-toolbar' },
57 props && !props.can_upload ? t('no_upload_here', "No upload permission for the current folder")
58 : h(FlexV, {},