Como posso atualizar a lista de tópicos após fazer uma alteração?

Implementei um botão personalizado no menu de ação do post que “expulsa” o post do tópico atual. É uma ação disponível para o autor do tópico que essencialmente executa a operação de mover, mas com menos cliques. A operação de backend é realizada por um novo endpoint de API personalizado. Meu botão está funcionando, exceto que tenho que atualizar a página manualmente para ver que o post foi movido.

Após a atualização, o post fica assim:

Minha pergunta é, qual é a melhor maneira de atualizar o DOM com essa alteração? Idealmente, eu apenas substituiria o post pelo placeholder de divisão mostrado acima, e evitaria atualizar a página inteira, ou a lista inteira de tópicos.

Posso imaginar que, se meu endpoint de API retornar o tópico alterado, então eu só preciso substituir/injetar o novo post na lista de tópicos?

Então, acho que esta é uma questão de como o gerenciamento de estado funciona dentro do Discourse, e como posso me conectar a esse ciclo de vida.

2 curtidas

Procure no core (ou no repositório all-the-plugins) por coisas que atualizam o MessageBus

1 curtida

Solução

Colocar isso no final do meu método de API resolveu o problema:

MessageBus.publish("/topic/#{@topic.id}", reload_topic: true, refresh_stream: true)

Isso deve atualizar não apenas para o usuário atual, mas para qualquer outra pessoa visualizando o tópico.

Exploração que me levou até aqui

Continue lendo se quiser acompanhar comigo pelo código. Compartilho isso para quem mais possa ser útil.

O que é MessageBus?

Da explicação de Sam em 2013 sobre o MessageBus, parece que o código Ruby pode publicar e assinar, enquanto o código Javascript só pode assinar. Ok, então sob essa arquitetura proposta, meu código do lado do servidor será responsável por notificar a UI.

Existe um exemplo de MessageBus que seja útil para mim?

Nenhum dos exemplos de plugin faz algo com MessageBus.

GroupArchivedMessage.move_to_inbox! chama este código que é um tanto próximo do que eu quero, mas o tipo de código usado aqui não funcionará para mim.

MessageBus.publish("/topic/#{topic_id}", { type: "move_to_inbox" }, group_ids: [group_id])

Este código parece promissor.

MessageBus.publish("/topic/#{@topic.id}", reload_topic: true, refresh_stream: true)

Esta foi a solução final que escolhi.

O que acontece quando o navegador recebe a atualização?

O controlador de Tópicos está inscrito para atualizações no tópico que está visualizando atualmente. Ele aciona “post-stream:refresh”, que inicia a atualização. A única coisa que consigo encontrar ouvindo do outro lado é o ScrollingPostStream, que vincula um método _refresh ao evento. Isso parece ser o que realmente está realizando a atualização.

Por isso, infiro que se eu quisesse apenas atualizar o cliente presente sem enviar a atualização para mais ninguém, eu poderia chamar o mesmo código:

this.appEvents.trigger("post-stream:refresh", args)

E parece que eu poderia chamar isso de qualquer componente.

E quanto à implementação original de move_posts? Ela publica no MessageBus?

Investigando o core, vejo: O método move_posts() do controlador de tópicos chama move_posts_to_destination(), que chama topic.move_posts(), que chama new PostMover() e então to_topic() ou to_new_topic(). Esses métodos não chamam MessageBus, mas chamam DiscourseEvent.trigger().

Eu chamo topic.move_posts() do meu método de API personalizado. Então, meu código chama diretamente o modelo, e pula qualquer lógica de controlador existente:

new_topic = topic.move_posts(current_user, [post.id], {title: title, category_id: category_id})

No meu caso, move_posts_to() é chamado como o passo final na sequência, que chama o seguinte:

DiscourseEvent.trigger(
  :posts_moved,
  destination_topic_id: destination_topic.id,
  original_topic_id: original_topic.id,
)

DiscourseEvent não parece ter nada a ver com MessageBus, no entanto. Talvez seja usado apenas para ciclos de vida internos dentro do servidor?

Então, concluo que o MessageBus normalmente não é publicado para uma movimentação de tópico.

4 curtidas

Ah. Desculpe. Isso é um pouco surpreendente! Acho que eu deveria ter te mandado para o core! Eu tenho um plugin que o usa, mas não é público e usa message buss para um modelo personalizado.

Não tenho certeza, mas acho que você provavelmente não precisa recarregar o tópico (a menos que coisas mudem que não são exibidas sem os atributos alterados?), mas tenho alguns lugares no meu plugin onde acho que isso pode resolver um problema!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.