Le sélecteur d'emoji fait planter l'éditeur de messages sous Android / Chrome

Ce problème existe depuis quelques mois, et je peux le reproduire ici chez Meta avec un appareil Android/Chrome (les deux en version la plus récente) — en réalité, cela se produit depuis plusieurs mois, depuis janvier environ.

L’éditeur de message semble « planter » de temps en temps lorsqu’on choisit un emoji proposé.

Étapes de reproduction :

  1. Publiez une réponse à un sujet et ajoutez du texte.
  2. Commencez à ajouter un pouce levé en tapant « :+1 », puis appuyez sur l’emoji proposé :+1:

Ce qui se produit :

L’éditeur semble planter ou être redessiné. Une partie du texte écrit est généralement perdue.

Ce n’est pas une reproduction à 100 %, mais je parviens facilement à déclencher le problème en moins d’une minute d’essais.

2 « J'aime »

Quelle version exacte d’Android/Chrome utilisez-vous ?

Je peux reproduire le problème. Voici la trace de la pile :

_application-bfbda341c2eb6dd7d61c681e17bdccec057c30e045ddc332927a7363150e9b1b.js:16386 Uncaught TypeError: Cannot read property '0' of null
    at HTMLLIElement.<anonymous> (application-bfbda341c2eb6dd7d61c681e17bdccec057c30e045ddc332927a7363150e9b1b.br.js:1)
    at HTMLLIElement.dispatch (ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.br.js:1)
    at HTMLLIElement.d.handle (ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.br.js:1)
(anonymous) @ application-bfbda341c2eb6dd7d61c681e17bdccec057c30e045ddc332927a7363150e9b1b.br.js:1
dispatch @ ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.br.js:1
d.handle @ ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.br.js:1

Cela correspond à cette ligne :

https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/app/lib/autocomplete.js#L308

L’erreur se produit parce que selectedOption est 0 (une seule suggestion, c’est-à-dire la première) tandis que autocompleteOptions est d’une manière ou d’une autre null.

J’essaie actuellement de comprendre pourquoi…

Pour l’instant, je ne suis pas sûr de la cause. Au début, je soupçonnais cette PR de @Osama :

Mais j’ai ajouté plusieurs points d’arrêt et je n’arrive pas vraiment à identifier « qui » modifie autocompleteOptions et le définit comme null.

Le fait que autocompleteOptions provienne de la portée de la fermeture parente située deux niveaux au-dessus est également assez étrange et rend le code un peu difficile à suivre et à déboguer.

8 « J'aime »

Android 11 / Chrome 89, les dernières versions disponibles.

1 « J'aime »

@ljpp / @falco, pouvez-vous toujours reproduire ce bug ? J’ai essayé de nombreuses variantes d’insertion d’un emoji et je n’ai pas réussi à le reproduire, pas même une seule fois. Si vous pouvez toujours le reproduire, pourriez-vous s’il vous plaît partager les étapes exactes ? Merci !

1 « J'aime »

Oui, cela plante toujours sur Chrome Android pour moi. Vous devez suivre les instructions à la lettre pour reproduire le problème, car le cas est très spécifique.

1 « J'aime »

Je viens d’essayer et je n’ai pas pu reproduire cela facilement. Cependant, je suis tout à fait certain de l’avoir observé plusieurs fois cet été, par inadvertance, en rédigeant un vrai message.

Édit : Je vais demander à notre communauté si elle peut fournir une couverture de test plus étendue.

Édit 2 : Ah oui, je l’ai reproduit moi-même maintenant. Notre communauté teste actuellement et il semble que d’autres utilisateurs réguliers aient également réussi à le reproduire.

1 « J'aime »

Je l’ai reproduit par erreur, donc cela reste ouvert.

Cela figure toujours sur notre liste, mais nous trouvons extrêmement difficile de reproduire et de déboguer ce problème.

Je ne peux pas vraiment ajouter l’étiquette pr-welcome à ce sujet car c’est beaucoup trop complexe. Nous y reviendrons à un moment donné, en fixant un délai de six mois.

Ce problème persiste-t-il toujours ?

Oui, il persiste. Personnellement, je n’ai pas réussi à le reproduire après 15 minutes de manipulations intensives, j’ai donc demandé de l’aide à notre communauté. Plusieurs utilisateurs ont réussi à le reproduire, et l’un d’eux l’a même prouvé avec une capture d’écran. Les symptômes restent inchangés : une fois que vous tapez sur l’émoji « pouce vers le haut » dans le sélecteur, le clavier se replie et une partie du contenu écrit est perdue dans l’éditeur.

Je parvenais autrefois à reproduire ce problème très facilement, mais maintenant, je n’arrive plus à le cibler. Le problème existe donc, mais il n’est pas reproductible à 100 %. Nous continuerons à faire des essais pour déterminer s’il existe une étape spécifique de l’interface utilisateur qui déclenche ce comportement.

1 « J'aime »

Pourriez-vous demander à la personne qui peut reproduire le problème de vérifier si elle peut le faire sur try.discourse.org ?

Je viens de le reproduire sans essayer.

Firefox 94.1.1 (Build #2015842491)

Et Chrome 95.0.4638.74

2 « J'aime »

J’ai l’impression que les sélecteurs d’emoji non natifs de la plateforme sont le vrai bug ici. :wink: La solution de contournement triviale est d’utiliser le sélecteur d’emoji natif de votre système d’exploitation ?

Bien sûr, il existe généralement une solution de contournement. Pas toujours, par exemple, il peut y avoir des emoji personnalisés utilisés sur Discourse.

Quoi qu’il en soit, recharger la page et perdre le contenu écrit est un comportement médiocre que nous devrions corriger.

Ok, j’ai réexaminé la situation aujourd’hui et j’ai réussi à reproduire le problème après avoir basculé le clavier virtuel de mon téléphone sur Gboard. Gboard déclenche parfois les événements keydown et keyup deux fois pour une seule pression de touche, et si cela se produit pour la dernière touche que vous appuyez avant de sélectionner un emoji dans l’autocomplétion, vous obtiendrez un crash.

Je ne suis pas sûr de ce qui cause Gboard à déclencher ces événements deux fois, mais cela semble dépendre de ce que vous avez tapé et de vos paramètres Gboard.

Les doubles événements provoquent un crash en raison de la façon dont notre bibliothèque d’autocomplétion est conçue. Ainsi, la bibliothèque écoute les événements keydown et keyup, et lors de keydown, elle efface les suggestions d’autocomplétion et lors de keyup, elle propose de nouvelles suggestions basées sur le nouveau terme d’autocomplétion.

Cependant, il existe une petite protection/optimisation pour empêcher la bibliothèque d’effectuer un travail en double lorsque le terme n’a pas changé depuis les suggestions précédentes, et c’est là que le problème se produit. La première paire d’événements keydown et keyup efface les anciennes suggestions et en propose de nouvelles comme prévu, mais la seconde paire erronée effacera à nouveau les suggestions lors de keydown mais n’en proposera pas de nouvelles lors de keyup car le terme d’autocomplétion n’a pas changé.

La seule “correction” la moins “hacky” à laquelle je puisse penser est de supprimer la protection/optimisation afin que la bibliothèque propose toujours de nouvelles suggestions lors de keyup, mais je ne suis pas sûr si cela est souhaitable ou si cela en vaut la peine.

Je sais que nous voulons réécrire notre bibliothèque d’autocomplétion à un moment donné (c’est une partie du code le plus ancien de la base de code et elle a désespérément besoin d’une réécriture), donc peut-être que ce bug pourrait attendre jusqu’à ce que nous arrivions à la réécriture ?

5 « J'aime »

Le crash est-il une sorte de « boucle infinie » ? Pouvons-nous simplement suivre le fait que nous venons de rencontrer une boucle de rétroaction et tout nettoyer ?

1 « J'aime »

Non, le crash accède à une variable nulle. Lorsque les suggestions sont effacées, la variable autocompleteOptions est définie sur null, puis lorsque vous appuyez sur l’une des suggestions rendues, nous nous attendons à ce que autocompleteOptions soit un tableau, mais il est null.

Cela me donne une autre idée : peut-être pourrions-nous vérifier si autocompleteOptions est null lorsqu’une suggestion est sélectionnée et si la variable est null, alors nous récupérons à nouveau les suggestions pour le terme donné ?

2 « J'aime »

Oui, cela semble être une bonne solution de contournement.

2 « J'aime »

Ah, je me sens tellement bête de ne pas avoir signalé ce détail. Mon téléphone précédent était un Android One épuré, il avait donc Gboard par défaut, et il m’a suivi depuis lors sur mon appareil suivant (Sammy A42 5G). Mais la plupart des appareils Android vendus aujourd’hui utilisent une application de clavier tierce par défaut.

C’est formidable de voir ces progrès.

2 « J'aime »

J’ai fusionné ma correction pour ce bug :

La correction a été déployée sur Meta et sur votre site @ljpp, faites-moi savoir si vos utilisateurs peuvent toujours le reproduire.

5 « J'aime »