Use streams to update/remove reactions

Prevents race condition causing flickering https://app.fizzy.do/5986089/cards/2906

This will prevent these from udpating live, but we will tackle that as part of live card
updates with page refreshes, which I will tackle soon.
This commit is contained in:
Jorge Manrubia
2025-11-12 18:02:50 +01:00
parent 285328ec60
commit 2d96e7c9c6
5 changed files with 13 additions and 27 deletions
@@ -10,29 +10,16 @@ class Cards::Comments::ReactionsController < ApplicationController
end
def create
reaction = @comment.reactions.create!(params.expect(reaction: :content))
broadcast_create(reaction)
redirect_to card_comment_reactions_path(@card, @comment)
@reaction = @comment.reactions.create!(params.expect(reaction: :content))
end
def destroy
reaction = @comment.reactions.find(params[:id])
reaction.destroy
broadcast_remove(reaction)
@reaction = @comment.reactions.find(params[:id])
@reaction.destroy
end
private
def set_comment
@comment = @card.comments.find(params[:comment_id])
end
def broadcast_create(reaction)
reaction.broadcast_append_to @card, target: [ @comment, :reactions ], partial: "cards/comments/reactions/reaction"
end
def broadcast_remove(reaction)
reaction.broadcast_remove_to @card
end
end
@@ -0,0 +1 @@
<%= turbo_stream.append([ @comment, :reactions ], partial: "cards/comments/reactions/reaction", locals: { reaction: @reaction }) %>
@@ -0,0 +1 @@
<%= turbo_stream.remove @reaction %>
@@ -2,7 +2,7 @@
<%= form_with model: [ @comment.card, @comment, Reaction.new ],
class: "reaction reaction__form expanded",
html: { aria: { label: "New reaction" } },
data: { controller: "form reaction-emoji", turbo_frame: dom_id(@comment, :reacting), action: "keydown.esc->form#cancel submit->form#preventEmptySubmit" } do |form| %>
data: { controller: "form reaction-emoji", turbo_frame: dom_id(@comment, :reacting), action: "keydown.esc->form#cancel submit->form#preventEmptySubmit turbo:submit-end->form#reset" } do |form| %>
<label class="reaction__form-label flex gap" style="--column-gap: 0.4ch;">
<figure class="reaction__avatar margin-none flex-item-no-shrink">
<%= avatar_tag Current.user %>
@@ -8,20 +8,17 @@ class Cards::Comments::ReactionsControllerTest < ActionDispatch::IntegrationTest
end
test "create" do
assert_turbo_stream_broadcasts @card, count: 1 do
assert_difference -> { @comment.reactions.count }, 1 do
post card_comment_reactions_path(@comment.card, @comment, format: :turbo_stream), params: { reaction: { content: "Great work!" } }
assert_redirected_to card_comment_reactions_path(@comment.card, @comment)
end
assert_difference -> { @comment.reactions.count }, 1 do
post card_comment_reactions_path(@comment.card, @comment, format: :turbo_stream), params: { reaction: { content: "Great work!" } }
assert_turbo_stream action: :append, target: dom_id(@comment, :reactions)
end
end
test "destroy" do
assert_turbo_stream_broadcasts @card, count: 1 do
assert_difference -> { @comment.reactions.count }, -1 do
delete card_comment_reaction_path(@comment.card, @comment, reactions(:kevin), format: :turbo_stream)
assert_response :success
end
reaction = reactions(:kevin)
assert_difference -> { @comment.reactions.count }, -1 do
delete card_comment_reaction_path(@comment.card, @comment, reaction, format: :turbo_stream)
assert_turbo_stream action: :remove, target: dom_id(reaction)
end
end
end