Uppy uploader se bloque avec plusieurs fichiers déposés sur composer

Bonjour,
depuis la dernière mise à jour (nous sommes dans un environnement géré), notre fonctionnalité de téléchargement semble cassée mais nous ne faisons rien de spécial.

Nous enregistrons simplement un nouveau api.addComposerUploadHandler() à partir d’un composant de thème.
Cela fonctionnait très bien avec plusieurs fichiers glissés dans le compositeur. Maintenant, des erreurs sont générées dans la console qui semblent liées à Uppy (ce que nous ne voulons pas).

Notre code est très simple, mais Uppy semble interférer avec lui.

// Enregistre un gestionnaire de téléchargement personnalisé pour les vidéos.

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

Le dépôt de 3 fichiers (mkv, mov, mkv) sur le compositeur affiche le message d’erreur “votre fichier est plus grand que 4 Mo” que nous voulions contourner en premier lieu car nous téléchargeons tout sur Gdrive.

La console Chrome génère ceci :

Le dépôt d’un seul fichier de 50 Mo ne provoque pas cette erreur “fichier trop volumineux” et notre fichier est correctement traité, comme prévu. L’erreur semble donc se produire avec plusieurs fichiers et un fichier plus volumineux qu’une limite de fichier de 4 Mo (je ne suis pas sûr d’où cela est défini).

Merci pour toute aide. Je pense que cela est lié à la dernière mise à jour de Discourse elle-même.

@martin

Salut @Sören_Geier. Il y a eu quelques changements dans ce domaine récemment, bien que j’aie essayé de maintenir la parité avec le gestionnaire de téléchargement existant dans le compositeur. Je veux juste mieux comprendre votre cas d’utilisation. D’après ce que je peux voir, même la version non-uppy du compositeur télécharge via api.addComposerUploadHandler ne gère qu’un seul fichier à la fois :

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

Donc, si vous déposez plusieurs fichiers, le flux normal se produira, et je suppose que dans le cas de l’OP de ce sujet, vous atteignez simplement les limites de taille de fichier du flux de téléchargement normal.

Que se passait-il auparavant, ou qu’attendez-vous qu’il se passe, lorsque vous faites glisser et déposez plusieurs fichiers à la fois ? Il serait utile de voir le code de votre composant de thème, si vous n’êtes pas à l’aise pour le partager publiquement, vous pouvez me l’envoyer en message privé ici sur Meta.

Donc, juste pour confirmer, êtes-vous hébergé par nous ?

2 « J'aime »

Merci pour la réponse rapide @martin .

Oui, nous hébergeons chez vous. Donc, ce qui se passe habituellement lorsque vous faites glisser un fichier dans le compositeur, c’est qu’il insère du texte dans le compositeur, du genre « Traitement de <nom_du_fichier> »… De plus, dans le cas de l’utilisation de API.addComposerUploadHandler([« mp4 », « mov », « mkv », « avi », « m4v »]), cela est fait par Discourse avant de transmettre le fichier au gestionnaire personnalisé ici. Cette insertion de texte d’espace réservé a cessé de fonctionner à un moment donné, c’est à ce moment-là que j’ai inséré le code moi-même dans mon gestionnaire :

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

La chose suivante qui s’est cassée, c’est que notre gestionnaire ne s’est pas déclenché car, soudainement, ces extensions vidéo avaient disparu du paramètre « extensions autorisées par le thème » - ou j’ai dû les rajouter là pour que les choses recommencent à fonctionner.

Ensuite, j’ai découvert le problème du dépôt de fichiers « multiples », comme décrit précédemment.

Nous avions cela fonctionnant d’une manière telle que je pouvais déposer 2+ fichiers sans messages d’erreur. Et cela semblait également correct car nous contournions toute cette logique de validation de Discourse.

Voici des extraits de code pertinents :

Ici, je m’attends simplement à ce que Discourse me transmette les fichiers déposés. Un par un.

// Enregistre un gestionnaire de téléchargement personnalisé pour les vidéos.

api.addComposerUploadHandler(["mp4", "mov", "mkv", "avi", "m4v"], (file, editor) => {
console.log("Gestion du téléchargement pour", file.name);
sendToGDrive(file, api);
})

Comme Discourse nous transmettait les fichiers individuellement, j’ai créé une fonction intermédiaire qui remplit simplement un tableau et, après un délai, déclenche la fonction de téléchargement réelle. Je collecte donc le fichier transmis par Discourse dans mon propre tableau.

// Collecte tous les fichiers déposés en séquence - tels que rapportés par le gestionnaire Discourse.
function sendToGDrive(file, api) {
clearTimeout(uploaderStartTimeout);
filesHolder.push(file)
const composerController = api.container.lookup("controller:composer");
composerController.model.appEvents.trigger("composer:insert-block", `[Traitement : ${file.name}...]()`);

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

Ensuite, je télécharge chaque fichier individuellement sur Gdrive.

// Gère chaque fichier individuellement.
async function initFileSend(api) {
for (const file of filesHolder) {
const content = await sendFileToGdrive(file, api, uploadFolderId);
}
}

Problèmes observés :

  • Les dépôts de « fichiers multiples » provoquent une validation de la taille du fichier alors que les dépôts de fichiers uniques n’en provoquent pas.
1 « J'aime »

Merci pour ce rapport détaillé et le code associé. J’étais déjà sur cette voie de réflexion pour les gestionnaires de téléchargement ; permettre à chaque fichier correspondant au gestionnaire d’entrer dans une sorte de file d’attente ou de pool comme vous l’avez fait ici, puis de les télécharger tous en même temps ou de les transmettre à une autre interface utilisateur, car j’avais trouvé étrange la limite de 1 à la fois. Bien que d’après ce que vous dites, j’aie peut-être mal compris comment fonctionnait la limite de 1 à la fois dans l’ancien gestionnaire de téléchargement du compositeur.

Ce que je vais faire, c’est quelques tests locaux pour voir ce que faisait l’ancien téléchargeur non-uppy avec plusieurs fichiers via un gestionnaire de téléchargement avec une version simplifiée de la fonction que vous avez fournie dans un composant de thème, puis essayer d’obtenir la parité entre la nouvelle façon et l’ancienne façon, car ce sera beaucoup plus flexible que de n’autoriser qu’un seul fichier à la fois de toute façon.

Cela peut prendre un peu de temps à corriger, je vais y travailler aujourd’hui.

2 « J'aime »

Je voulais juste faire une petite mise à jour ; j’ai confirmé qu’avec les gestionnaires de téléchargement de compositeurs pre-uppy, bien que le code vérifie si un seul fichier est téléchargé, ce n’est pas exact car le téléchargeur de fichiers jQuery n’envoie qu’un seul fichier à la fois par ce chemin de code, même si vous déposez plusieurs fichiers à la fois. Ceci est en contraste avec uppy, qui traite les fichiers ajoutés par groupes. Cette hypothèse d’un seul fichier à la fois est faite dans deux autres plugins que nous avons créés et qui utilisent api.addComposerUploadHandler, donc cela semble être un problème courant.

Comme je l’ai dit, je pense que la meilleure façon de procéder sera de permettre à ce gestionnaire de traiter plusieurs fichiers qui pourront ensuite être regroupés et envoyés ailleurs d’une manière qui ait du sens pour l’auteur du plugin / thème. À tout le moins, je peux corriger l’hypothèse du gestionnaire de téléchargement uppy selon laquelle un seul fichier peut être envoyé à la fois. Je posterai à nouveau ici une fois que j’aurai une autre mise à jour.

2 « J'aime »

Une dernière mise à jour avant le week-end. J’ai cette correction qui devrait être fusionnée en début de semaine prochaine et qui restaurera l’« ancienne » façon de faire les choses d’avant uppy, mais à l’intérieur d’uppy. Votre implémentation fonctionnera donc correctement après cela :

Cependant, j’ajouterai également une PR ultérieure qui modifiera addComposerUploadHandler pour qu’elle envoie plusieurs fichiers au callback du gestionnaire dans un tableau, ce qui supprimera la nécessité de configurer une file d’attente et des callbacks setTimeout pour gérer plusieurs fichiers entrants. Je pense que c’est de toute façon plus correct, et une amélioration générale de l’API.

Votre gestionnaire ressemblera alors à ceci :

// Enregistre un gestionnaire de téléchargement personnalisé pour les vidéos.
api.addComposerUploadHandler(
  ["mp4", "mov", "mkv", "avi", "m4v"],
  (files, editor) => {
    console.log("Gestion du téléchargement pour", files.map((file) => file.name).join(", "));
    sendToGDrive(files, api);
  }
);
2 « J'aime »

Excellent. Merci de vous en être occupé si rapidement !
Passez un excellent week-end bien mérité :blush:

2 « J'aime »

@Sören_Geier Je viens de fusionner DEV: Send multiple files in batches to composer upload handlers when using uppy by martin-brennan · Pull Request #15124 · discourse/discourse · GitHub qui change uppy pour envoyer plusieurs fichiers à la fois au gestionnaire de téléchargement ; vous devrez maintenant mettre à jour votre composant de thème pour gérer cela :slight_smile:

3 « J'aime »

C’est super. Ce n’est pas encore déployé, n’est-ce pas ?

Êtes-vous sur notre hébergement Standard ? Si oui, il devrait être déployé maintenant :slight_smile:

3 « J'aime »

D’accord, j’ai des plaintes indiquant que des choses ont cessé de fonctionner pour les personnes qui voulaient télécharger.
Je me suis penché sur le problème et j’ai également eu des problèmes initiaux pour envoyer mon fichier à GDRIVE car je venais de passer l’objet fichier. Il s’est avéré que l’objet fichier était une représentation enveloppée par Uppy du fichier binaire ressemblant à ceci.

Pour accéder réellement à l’objet fichier natif, j’ai dû travailler avec files[0].data. (peut-être un changement qui casse la compatibilité ?)

Avant ce changement, le gestionnaire passait simplement l’objet fichier natif. Je pourrais m’attendre à ce que d’autres personnes rencontrent des problèmes de fonctionnalité avec ce changement, je ne suis pas sûr.

Tout fonctionne maintenant. Merci beaucoup pour la rapidité de réponse et le support !

3 « J'aime »

Oh là là, vous avez raison, je ne sais pas comment j’ai pu manquer ça lors de ma récente refactorisation ! :sweat: Je vais pousser un correctif ce matin, cela ne prendra pas trop de temps.

Edit : Le correctif est là, il devrait être déployé sur notre hébergement standard dans les prochaines heures.

3 « J'aime »

Super, j’ai également ajusté notre code. Je pense que le sujet peut être clos maintenant. Merci pour votre aide exceptionnelle @martin

1 « J'aime »

Pas de problème ! J’ai fait le désordre, il est donc juste que je le nettoie :sweat_smile:

1 « J'aime »