Seletor de emoji trava o editor de mensagens no Android / Chrome

Este problema existe há alguns meses, e consigo reproduzi-lo aqui na Meta usando um dispositivo Android/Chrome (ambos na versão mais recente) — na verdade, isso vem acontecendo há vários meses, desde janeiro ou por aí.

O editor de mensagens parece “travar” de vez em quando quando se escolhe um emoji sugerido.

Passos para reproduzir:

  1. Publique uma resposta em um tópico e adicione algum texto
  2. Comece a adicionar um polegar para cima digitando “:+1” e depois toque no emoji sugerido :+1:

O que acontece:

O editor parece travar de alguma forma ou é redesenhado. Geralmente, algum texto escrito é perdido.

Não é 100% reproduzível, mas consigo encontrar o problema facilmente em menos de um minuto de testes.

2 curtidas

Qual versão exata do Android/Chrome você está usando?

Consegui reproduzir. Segue o stack trace:

_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

Isso ocorre nesta linha:

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

O erro acontece porque selectedOption é 0 (primeira sugestão única), enquanto autocompleteOptions está, de alguma forma, como null.

Investigando o motivo agora…

Ainda não tenho certeza do porquê. Inicialmente, eu suspeitava deste PR de @Osama:

https://github.com/discourse/discourse/pull/11637

Mas adicionei vários pontos de interrupção e não consegui realmente descobrir “quem” está mutando autocompleteOptions e definindo-o como null.

Ter autocompleteOptions vindo do escopo do fechamento pai, dois níveis acima, também é bastante estranho e torna o código um pouco difícil de seguir e depurar.

8 curtidas

Android 11/Chrome 89, os mais recentes disponíveis.

1 curtida

@ljpp / @falco, vocês ainda conseguem reproduzir esse bug? Tentei várias variações de inserir um emoji e não consegui reproduzir nem uma única vez. Se vocês ainda conseguirem reproduzir, por favor, compartilhem os passos exatos. Obrigado!

1 curtida

Sim, ainda trava no Chrome para Android para mim. Você deve seguir as instruções 100% para que o problema se reproduza, pois é muito específico.

1 curtida

Acabei de tentar e não consegui reproduzir facilmente isso. No entanto, tenho bastante certeza de que vi isso algumas vezes durante o verão, acidentalmente, ao digitar uma postagem real.

Edição: Vou perguntar à nossa comunidade se eles podem fornecer uma cobertura de teste mais extensa.

Edição 2: Ah, sim, consegui reproduzir isso agora. Nossa comunidade está testando e parece que há mais reproduções por usuários comuns.

1 curtida

Acabei de reproduzir isso sem querer, então isso ainda está aberto.

Ainda temos isso em nossa lista, mas estamos achando extremamente difícil reproduzir e depurar.

Não posso realmente adicionar um pr-welcome aqui, pois é muito complexo. Vamos revisar isso em algum momento, estabelecendo um prazo de 6 meses.

Esse problema ainda persiste?

Sim, persiste. Pessoalmente, não consegui reproduzi-lo após 15 minutos de testes intensivos, então pedi apoio à nossa comunidade. Vários usuários conseguiram reproduzir o erro e um deles até provou com uma captura de tela. Os sintomas permanecem inalterados: ao tocar no emoji de “joinha” no seletor, o teclado se recolhe e parte do conteúdo digitado é perdida no editor.

Antes eu conseguia reproduzir isso muito facilmente, mas agora não consigo mais acertar o momento. O problema existe, mas não é reproduzível em 100% dos casos. Vamos continuar testando para tentar descobrir se há alguma etapa na interface que desencadeia isso.

1 curtida

Você pode pedir para alguém que consiga reproduzir o problema verificar se consegue fazê-lo no try.discourse.org?

Acabei de reproduzi-lo sem tentar.

Firefox 94.1.1 (Build #2015842491)

E Chrome 95.0.4638.74

2 curtidas

Sinto que os seletores de emoji de plataforma não nativos são o verdadeiro bug aqui. :wink: A solução trivial é usar o seletor de emoji nativo do seu sistema operacional de preferência?

Claro, geralmente existe uma solução alternativa. Nem sempre, por exemplo, pode haver emojis personalizados em uso no Discourse.

De qualquer forma, recarregar a página e perder o conteúdo escrito é um comportamento ruim que devemos corrigir.

Ok, analisei isso novamente hoje e consegui reproduzir o problema depois de mudar o teclado virtual do meu telefone para o Gboard. O Gboard às vezes dispara eventos keydown e keyup duas vezes para uma única pressionada de tecla e, se isso acontecer para a última tecla que você pressiona antes de selecionar um emoji da autocompletar, você terá um travamento.

Não tenho certeza do que causa o Gboard a disparar esses eventos duas vezes, mas parece depender do que você digitou e das suas configurações do Gboard.

Os eventos duplos causam um travamento devido à forma como nossa biblioteca de autocompletar é projetada. Assim, a biblioteca escuta os eventos keydown e keyup, e no keydown ela limpa as sugestões de autocompletar e no keyup ela oferece novas sugestões com base no novo termo de autocompletar.

No entanto, há uma pequena proteção/otimização para proteger a biblioteca de fazer trabalho duplicado quando o termo não mudou desde as sugestões anteriores, e é aqui que o problema ocorre. O primeiro par de eventos keydown e keyup limpa as sugestões antigas e oferece novas como esperado, mas o segundo par errôneo limpará as sugestões novamente no keydown, mas não oferecerá novas no keyup porque o termo de autocompletar não mudou.

A única “correção” menos improvisada que consigo pensar é remover a proteção/otimização para que a biblioteca sempre ofereça novas sugestões no keyup, mas não tenho certeza se isso é desejado ou se vale a pena.

Eu sei que queremos reescrever nossa biblioteca de autocompletar em algum momento (é um dos códigos mais antigos na base de código e desesperadamente precisa de uma reescrita), então talvez esse bug possa esperar até chegarmos à reescrita?

5 curtidas

O travamento é uma espécie de "loop infinito"? Podemos simplesmente rastrear que atingimos um loop de feedback e limpar as coisas?

1 curtida

Não, a falha está acessando uma variável nula. Quando as sugestões são limpas, a variável autocompleteOptions é definida como nula e, em seguida, quando você toca em uma das sugestões renderizadas, esperamos que autocompleteOptions seja um array, mas é nulo.

Isso me dá outra ideia: talvez possamos verificar se autocompleteOptions é nulo quando uma sugestão é selecionada e, se a variável for nula, então podemos buscar novamente as sugestões para o termo fornecido?

2 curtidas

Sim, isso parece uma boa solução alternativa.

2 curtidas

Ah, me sinto tão burro por não ter relatado esse detalhe. Meu telefone anterior era um Android One limpo, então ele tinha o Gboard como padrão, e ele me acompanhou desde então para o próximo dispositivo (Sammy A42 5G). Mas a maioria dos dispositivos Android vendidos hoje usa um aplicativo de teclado de terceiros por padrão.

Ótimo ver esse progresso.

2 curtidas

Eu mesclei minha correção para este bug:

A correção foi implantada no Meta e no seu site @ljpp, me avise se seus usuários ainda conseguem reproduzir.

5 curtidas