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])
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.