fix(upload): gezogenes Vorschaubild wurde erneut hochgeladen
Zieht man das angezeigte Bild ein Stueck zur Seite, legt Chrome es als
echte Datei in den Ziehvorgang. dataTransfer.types enthaelt dann
"Files" - nicht zu unterscheiden von einer Datei aus dem Dateimanager.
Die Ablageflaeche lud das eigene Bild daraufhin ein zweites Mal hoch.
Zwei Riegel: draggable={false} an allen Bildern, die kein eigenes
Ziehen brauchen (die Kachel bleibt ziehbar und verschiebt die Datei),
und useInternalDrag - was in dieser Seite losgezogen ist, wird nie als
Upload behandelt. dragstart feuert nur bei eigener Quelle.
Gemessen: vorher 1 Upload, nachher 0. Ein Zug von aussen laedt
unveraendert hoch.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e9e07f9bed
commit
b5a83e4057
11 files changed
+92
-3
No files matched your search
@@ -21,6 +21,7 @@ import MoveTo from '../components/MoveTo'
|
||||
import TagDialog from '../components/TagDialog'
|
||||
import OfficeEditor from '../components/OfficeEditor'
|
||||
import { useAppSettings } from '../hooks/useAppSettings'
|
||||
import { useInternalDrag } from '../hooks/useInternalDrag'
|
||||
import { DownloadIcon, ShareIcon, HistoryIcon, RenameIcon, MoveIcon, TrashIcon, FolderOpenIcon, StarIcon, CheckIcon, PeopleIcon, TagIcon, OfficeIcon, InfoIcon } from '../components/icons'
|
||||
|
||||
interface Props {
|
||||
@@ -135,6 +136,7 @@ export default function FileBrowser({
|
||||
const [ctxMenu, setCtxMenu] = useState<CtxMenu | null>(null)
|
||||
const [dialog, setDialog] = useState<Dialog | null>(null)
|
||||
const [dragging, setDragging] = useState(false)
|
||||
const isInternalDrag = useInternalDrag()
|
||||
const [dragOverFolder, setDragOverFolder] = useState<string | null>(null)
|
||||
const [viewMode, setViewMode] = useState<ViewMode>(() => loadPref('aether:view', 'grid'))
|
||||
const [sort, setSort] = useState<Sort>(() => loadPref('aether:sort', 'name-asc'))
|
||||
@@ -414,6 +416,10 @@ export default function FileBrowser({
|
||||
setDragging(false)
|
||||
const t = e.dataTransfer.types
|
||||
if (t.includes('aether-file-id') || t.includes('aether-folder-id')) return // internal move, not upload
|
||||
// Alles, was in dieser Seite losgezogen ist, ist kein Upload – auch ein
|
||||
// vom Browser begonnener Bild-Zug, der `Files` mitbringt, aber keine
|
||||
// unserer Kennungen. Siehe hooks/useInternalDrag.
|
||||
if (isInternalDrag()) return
|
||||
|
||||
// Capture FileSystemEntries synchronously – the DataTransferItemList is only
|
||||
// valid during the drop event itself.
|
||||
@@ -718,7 +724,8 @@ export default function FileBrowser({
|
||||
onDragOver={e => {
|
||||
e.preventDefault()
|
||||
const t = e.dataTransfer.types
|
||||
if (t.includes('Files') && !t.includes('aether-file-id') && !t.includes('aether-folder-id')) setDragging(true)
|
||||
if (t.includes('Files') && !t.includes('aether-file-id') && !t.includes('aether-folder-id')
|
||||
&& !isInternalDrag()) setDragging(true)
|
||||
}}
|
||||
onDragLeave={e => { if (!e.currentTarget.contains(e.relatedTarget as Node)) setDragging(false) }}
|
||||
onDrop={onDrop}
|
||||
|
||||
@@ -44,6 +44,7 @@ export default function LoginPage({ onLogin }: Props) {
|
||||
aus. */}
|
||||
{config.logo_url ? (
|
||||
<img
|
||||
draggable={false}
|
||||
src={config.logo_url}
|
||||
alt={config.cloud_name}
|
||||
className="mx-auto mb-4 object-contain"
|
||||
|
||||
@@ -150,7 +150,7 @@ export default function TagsPage({ tagId, correspondentId, onOpenFolder }: Props
|
||||
einer Liste reicht die kleine Fassung; die großen Cover
|
||||
gehören zu den Kacheln. */}
|
||||
{f.has_thumbnail ? (
|
||||
<img src={filesApi.thumbnail(f.id)} alt="" style={{
|
||||
<img src={filesApi.thumbnail(f.id)} alt="" draggable={false} style={{
|
||||
width: 22, height: 22, borderRadius: 4, objectFit: 'cover', flexShrink: 0,
|
||||
}} />
|
||||
) : (
|
||||
|
||||
@@ -106,6 +106,7 @@ export default function TrashPage({ onUserChanged }: Props) {
|
||||
}}>
|
||||
{file.has_thumbnail ? (
|
||||
<img
|
||||
draggable={false}
|
||||
src={filesApi.thumbnail(file.id)}
|
||||
alt=""
|
||||
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
||||
|
||||
Reference in new issue
Block a user