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>
Auf 360px (Galaxy Z Flip 7 aufgeklappt) brauchten zwei Spalten
2x160 + 12 = 332px, verfuegbar waren nach 20px Innenrand aber nur
320px - also fiel das Raster auf eine Spalte zurueck.
Schmal jetzt 132px Mindestbreite, 10px Abstand, 12px Innenrand. Damit
stehen zwei Spalten ab 300px Fensterbreite, ohne dass breite Schirme
sich aendern (dort weiter 160px und 20px).
Raster und Innenrand stehen als Klassen in index.css: inline gesetzt
haette die Media-Query sie nicht erreicht - derselbe Fehler wie zuletzt
in der Kopfleiste.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Go-Backend (chi, pgx, golang-migrate) + React/TS-Frontend als PWA.
Enthalten: Auth inkl. OIDC, Dateien mit Versionen und Papierkorb,
Freigaben (Links + intern), WebDAV, Gruppenordner, Admin/Theming,
Volltextsuche mit OCR, eigener PDF-Betrachter und WOPI-Office
(Collabora/OnlyOffice).
Nicht im Repo: deploy/.env (Sitzungsschlüssel, DB- und Admin-Passwort)
sowie alle Daten- und Build-Verzeichnisse – siehe .gitignore.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>