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

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