Uppy Uploader bricht bei Mehrfach-Dateien-Drop auf Composer ab

Hallo,
seit dem letzten Update (wir sind in einer verwalteten Umgebung) scheint unsere Upload-Funktionalität defekt zu sein, obwohl wir keine Zauberei betreiben.

Wir registrieren einfach einen neuen api.addComposerUploadHandler() innerhalb einer Theme-Komponente.
Dies funktionierte früher hervorragend mit mehreren Dateien, die in den Composer gezogen wurden. Jetzt werden Fehler in der Konsole ausgelöst, die sich auf Uppy zu beziehen scheinen (warum wir es nicht wollen).

Unser Code ist wirklich einfach, aber trotzdem scheint Uppy damit zu interferieren.

// Registriert benutzerdefinierten Upload-Handler für Videos.

api.addComposerUploadHandler(["mp4", "mov", "mkv", "avi", "m4v"], (file, editor) => {
console.log("Handling upload for", file.name);
})

Das Ablegen von 3 Dateien (mkv, mov, mkv) im Composer zeigt die Fehlermeldung “Ihre Datei ist größer als 4 MB”, die wir eigentlich umgehen wollten, da wir alles auf Gdrive hochladen.

Die Chrome-Konsole gibt Folgendes aus:

Das Ablegen einer einzelnen Datei mit 50 MB verursacht nicht den Fehler “Datei zu groß”, und unsere Datei wird ordnungsgemäß verarbeitet, wie erwartet. Der Fehler scheint also bei mehreren Dateien aufzutreten und einer Datei, die größer als ein Dateilimit von 4 MB ist (ich bin mir nicht sicher, wo dies festgelegt ist).

Vielen Dank für jede Hilfe. Ich denke, es hängt mit dem letzten Update von Discourse selbst zusammen.

@martin

Hallo @Sören_Geier. Es gab kürzlich einige Änderungen in diesem Bereich, obwohl ich versucht habe, die Parität mit dem vorhandenen Upload-Handler im Composer beizubehalten. Ich möchte nur ein besseres Verständnis Ihres Anwendungsfalls bekommen. Soweit ich das beurteilen kann, lädt selbst die Nicht-Uppy-Version des Composers über api.addComposerUploadHandler nur eine einzelne Datei gleichzeitig hoch:

https://github.com/discourse/discourse/blob/main/app/assets/javascripts/discourse/app/mixins/composer-upload.js#L215-L222

Wenn Sie also mehrere Dateien fallen lassen, geschieht der normale Ablauf, und ich vermute, dass Sie im Fall des OP dieses Themas einfach die Dateigrößenbeschränkungen des normalen Upload-Flows erreichen.

Was früher geschah oder was Sie erwarten, wenn Sie mehrere Dateien gleichzeitig per Drag & Drop ziehen? Es wäre hilfreich, Ihren Theme-Komponenten-Code zu sehen. Wenn Sie ihn nicht öffentlich teilen möchten, können Sie ihn mir hier auf Meta per PM zusenden.

Nur um zu bestätigen, werden Sie von uns gehostet?

2 „Gefällt mir“

Vielen Dank für die schnelle Antwort, @martin.

Ja, wir hosten bei Ihnen. Wenn Sie normalerweise eine Datei in den Composer ziehen, wird Text in den Composer eingefügt, z. B. „Processing “… Auch im Falle der Verwendung von API.addComposerUploadHandler([„mp4“, „mov“, „mkv“, „avi“, „m4v“]) geschieht dies durch Discourse, bevor die Datei an den benutzerdefinierten Handler hier übergeben wird. Das Einfügen von Platzhaltertext funktionierte irgendwann nicht mehr, weshalb ich den Code selbst in meinem Handler eingefügt habe:

composerController.model.appEvents.trigger("composer:insert-block", `[Processing: ${file.name}...]()`);

Das Nächste, was kaputt ging, war, dass unser Handler nicht ansprang, weil aus heiterem Himmel diese Videoerweiterungen aus der Einstellung „theme authorized extensions“ verschwanden – oder ich musste sie dort wieder hinzufügen, damit die Dinge wieder funktionierten.

Dann entdeckte ich das Problem mit dem „mehreren“ Dateien, die fallen gelassen wurden, wie oben beschrieben.

Wir hatten es so funktionierend, dass ich 2+ Dateien fallen lassen konnte, ohne dass Fehlermeldungen auftraten. Und es fühlte sich auch richtig an, weil wir die gesamte Discourse-Validierungslogik umgingen.

Hier sind relevante Codeausschnitte:

Hier erwarte ich einfach, dass Discourse mir die fallen gelassenen Dateien übergibt. Eine nach der anderen.

// Registriert benutzerdefinierten Upload-Handler für Videos.

api.addComposerUploadHandler(["mp4", "mov", "mkv", "avi", "m4v"], (file, editor) => {
console.log("Handling upload for", file.name);
sendToGDrive(file, api);
})

Da Discourse uns die Dateien einzeln übergab, erstellte ich eine Vermittlerfunktion, die einfach ein Array füllt und nach einem Timeout die eigentliche Uploader-Funktion startet. Ich sammle also die von Discourse übergebene Datei in meinem eigenen Array.

// Sammelt alle fallen gelassenen Dateien nacheinander – wie vom Discourse-Handler gemeldet.
function sendToGDrive(file, api) {
clearTimeout(uploaderStartTimeout);
filesHolder.push(file)
const composerController = api.container.lookup("controller:composer");
composerController.model.appEvents.trigger("composer:insert-block", `[Processing: ${file.name}...]()`);

uploaderStartTimeout = setTimeout(function () {
initFileSend(api);
}, 300);
}

Dann lade ich jede Datei einzeln auf Gdrive hoch.

// Behandelt jede Datei einzeln.
async function initFileSend(api) {
for (const file of filesHolder) {
const content = await sendFileToGdrive(file, api, uploadFolderId);
}
}

Beobachtete Probleme:

  • „Mehrere Dateien“-Drops verursachen eine Validierung der Dateigröße, während einzelne Datei-Drops dies nicht tun
1 „Gefällt mir“

Vielen Dank für diesen detaillierten Bericht und den dazugehörigen Code. Ich habe bereits in diese Richtung gedacht für die Upload-Handler; jedem File, das dem Handler entspricht, zu erlauben, in eine Art Warteschlange oder Pool zu gehen, wie Sie es hier getan haben, und sie dann alle auf einmal hochzuladen oder an eine andere Benutzeroberfläche weiterzuleiten, da ich die Beschränkung auf 1 pro Vorgang seltsam fand. Aber nach Ihren Ausführungen habe ich vielleicht missverstanden, wie die Beschränkung auf 1 pro Vorgang im alten Composer-Upload-Handler funktionierte.

Ich werde einige lokale Tests durchführen, um zu sehen, was der alte Uploader ohne Uppy mit mehreren Dateien über einen Upload-Handler gemacht hat, mit einer vereinfachten Version der von Ihnen bereitgestellten Funktion in einer Theme-Komponente, und dann versuchen, Parität zwischen der neuen und der alten Methode zu erreichen, da dies ohnehin viel flexibler sein wird, als nur eine Datei pro Vorgang zuzulassen.

Dies könnte einige Zeit in Anspruch nehmen, ich werde heute daran arbeiten.

2 „Gefällt mir“

Ich wollte nur ein kurzes Update geben; ich habe bestätigt, dass mit den Pre-Uppy-Composer-Upload-Handlern der Code zwar prüft, ob nur eine Datei hochgeladen wird, dies aber nicht korrekt ist, da der jQuery-Datei-Uploader nur eine Datei gleichzeitig über diesen Code-Pfad sendet, auch wenn Sie mehrere Dateien auf einmal fallen lassen. Dies steht im Gegensatz zu Uppy, das die hinzugefügten Dateien in Gruppen verarbeitet. Diese Annahme, dass nur eine Datei nach der anderen verarbeitet wird, wird in zwei anderen von uns erstellten Plugins gemacht, die api.addComposerUploadHandler verwenden, so dass dies ein häufiges Problem zu sein scheint.

Wie gesagt, ich denke, der beste Weg nach vorne wäre, es diesem Handler zu ermöglichen, mehrere Dateien zu verarbeiten, die dann gebündelt und an einer Stelle gesendet werden können, die für den Plugin-/Theme-Autor sinnvoll ist. Zumindest kann ich die Annahme des Uppy-Upload-Handlers beheben, dass nur eine Datei gleichzeitig gesendet werden kann. Ich werde mich hier wieder melden, sobald ich ein weiteres Update habe.

2 „Gefällt mir“

Ein letztes Update vor dem Wochenende. Ich habe diese Korrektur, die Anfang nächster Woche zusammengeführt werden sollte und die “alte” Vorgehensweise von vor Uppy wiederherstellt, aber innerhalb von Uppy. Ihre Implementierung wird also danach wieder korrekt funktionieren:

Ich werde jedoch auch einen nachfolgenden PR hinzufügen, der addComposerUploadHandler ändert, um mehrere Dateien als Array an den Handler-Callback zu senden, wodurch Sie keine Warteschlange und setTimeout-Callbacks mehr einrichten müssen, um mehrere eingehende Dateien zu verarbeiten. Ich denke, das ist sowieso korrekter und eine allgemeine Verbesserung der API.

Ihr Handler wird dann etwa so aussehen:

// Benutzerdefinierten Upload-Handler für Videos registrieren.
api.addComposerUploadHandler(
  ["mp4", "mov", "mkv", "avi", "m4v"],
  (files, editor) => {
    console.log("Handling upload for", files.map((file) => file.name).join(", "));
    sendToGDrive(files, api);
  }
);
2 „Gefällt mir“

Ausgezeichnet. Vielen Dank, dass Sie sich so schnell darum gekümmert haben!
Ich wünsche Ihnen ein schönes, wohlverdientes Wochenende :blush:

2 „Gefällt mir“

@Sören_Geier Ich habe gerade DEV: Send multiple files in batches to composer upload handlers when using uppy by martin-brennan · Pull Request #15124 · discourse/discourse · GitHub zusammengeführt, was uppy dazu veranlasst, mehrere Dateien gleichzeitig an den Upload-Handler zu senden. Sie müssen Ihre Theme-Komponente jetzt aktualisieren, um dies zu verarbeiten :slight_smile:

3 „Gefällt mir“

Das ist großartig. Es ist noch nicht bereitgestellt, oder?

Sind Sie auf unserem Standard-Hosting? Wenn ja, sollte es inzwischen bereitgestellt worden sein :slight_smile:

3 „Gefällt mir“

Okay, ich habe Beschwerden erhalten, dass die Dinge für Leute, die hochladen wollten, kaputt gegangen sind.
Ich habe es mir jetzt angesehen und hatte auch anfangs Probleme, meine Datei an GDRIVE zu senden, da ich nur das Dateiobjekt übergeben habe. Es stellte sich heraus, dass das Dateiobjekt eine Uppy-verpackte Darstellung der Binärdatei war, die so aussah.

Um tatsächlich auf das native Dateiobjekt zugreifen zu können, musste ich mit files[0].data arbeiten. (vielleicht eine Breaking Change?)

Vor dieser Änderung hat der Handler einfach das native Dateiobjekt übergeben. Ich könnte erwarten, dass andere Leute mit dieser Änderung ebenfalls von brechenden Funktionalitäten betroffen sind, ich bin mir nicht sicher.

Jetzt funktioniert alles. Vielen Dank für die schnelle Reaktion und Unterstützung!

3 „Gefällt mir“

Oh je, da haben Sie Recht, ich bin mir nicht sicher, wie ich das übersehen habe, als ich diese kürzliche Refaktorierung vorgenommen habe! :sweat: Ich werde heute Morgen eine Korrektur dafür einreichen, das wird nicht lange dauern.

Bearbeiten: Die Korrektur ist da, sie sollte in den nächsten Stunden auf unserem Standard-Hosting bereitgestellt werden.

3 „Gefällt mir“

Großartig, wir haben unseren Code ebenfalls angepasst. Ich denke, das Thema kann jetzt geschlossen werden. Vielen Dank für die außergewöhnliche Hilfe @martin

1 „Gefällt mir“

Kein Problem! Ich habe das Chaos verursacht, also ist es nur richtig, dass ich es auch aufräume :sweat_smile:

1 „Gefällt mir“