Skip to content

Commit

Permalink
WIP add turbo stream morph actions to rails turbo-streams broadcasts
Browse files Browse the repository at this point in the history
  • Loading branch information
omarluq committed Feb 15, 2024
1 parent 07d3488 commit 41d8b84
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 2 deletions.
8 changes: 8 additions & 0 deletions app/channels/turbo/streams/broadcasts.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ def refresh_debouncer_for(*streamables, request_id: nil) # :nodoc:
Turbo::ThreadDebouncer.for("turbo-refresh-debouncer-#{stream_name_from(streamables.including(request_id))}")
end

def broadcast_morph_to(*streamables, **opts)
broadcast_action_to(*streamables, action: :morph, **opts)
end

def broadcast_morph_later_to(*streamables, **opts)
broadcast_action_later_to(*streamables, action: :morph, **opts)
end

private
def render_format(format, **rendering)
ApplicationController.render(formats: [ format ], **rendering)
Expand Down
23 changes: 23 additions & 0 deletions app/models/concerns/turbo/broadcastable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,29 @@ def broadcast_render_later_to(*streamables, **rendering)
Turbo::StreamsChannel.broadcast_render_later_to(*streamables, **broadcast_rendering_with_defaults(rendering)) unless suppressed_turbo_broadcasts?
end

# Broadcast a morph action to the stream name identified by the passed <tt>streamables</tt>. Example:
# sends <turbo-stream action="morph" target="clearance_5"><template><div id="clearance_5">My Clearance</div></template></turbo-stream>
# to the stream named "identity:2:clearances"
# clearance.broadcast_morph_to examiner.identity, :clearances
def broadcast_morph_to(*streamables, target: broadcast_target_default, **rendering)
Turbo::StreamsChannel.broadcast_morph_to(*streamables, target: target, **broadcast_rendering_with_defaults(rendering)) unless suppressed_turbo_broadcasts?
end

# Same as <tt>broadcast_morph_to</tt> but the designated stream is automatically set to the current model.
def broadcast_morph(target: broadcast_target_default, **rendering)
broadcast_morph_to(self, target: target, **rendering)
end

# Same as <tt>broadcast_morph_to</tt> but run asynchronously via a <tt>Turbo::Streams::BroadcastJob</tt>.
def broadcast_morph_later_to(*streamables, target: broadcast_target_default, **rendering)
Turbo::StreamsChannel.broadcast_morph_later_to(*streamables,target: target, **broadcast_rendering_with_defaults(rendering)) unless suppressed_turbo_broadcasts?
end

# Same as <tt>broadcast_morph_later_to</tt> but the designated stream is automatically set to the current model.
def broadcast_morph_later(target: broadcast_target_default, **rendering)
broadcast_morph_later_to(self, target: target, **rendering)
end

private
def broadcast_target_default
self.class.broadcast_target_default
Expand Down
54 changes: 52 additions & 2 deletions test/streams/broadcastable_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,58 @@ class Turbo::SuppressingBroadcastsTest < ActionCable::Channel::TestCase
end
end

test "broadcasting morph to stream now" do
assert_broadcast_on "stream", turbo_stream_action_tag("morph", target: "message_1", template: render(@message)) do
@message.broadcast_morph_to "stream", target: "message_1"
end
end

test "broadcasting morph to stream later" do
assert_broadcast_on "stream", turbo_stream_action_tag("morph", target: "message_1", template: render(@message)) do
perform_enqueued_jobs do
@message.broadcast_morph_later_to "stream", target: "message_1"
end
end
end

test "broadcasting morph now" do
assert_broadcast_on @message.to_gid_param, turbo_stream_action_tag("morph", target: "message_1", template: render(@message)) do
@message.broadcast_morph target: "message_1"
end
end

test "broadcasting morph later" do
assert_broadcast_on @message.to_gid_param, turbo_stream_action_tag("morph", target: "message_1", template: render(@message)) do
perform_enqueued_jobs do
@message.broadcast_morph_later target: "message_1"
end
end
end

test "suppressing broadcasting morph to stream now" do
assert_no_broadcasts_when_suppressing do
@message.broadcast_morph_to "stream"
end
end

test "suppressing broadcasting morph to stream later" do
assert_no_broadcasts_later_when_supressing do
@message.broadcast_morph_later_to "stream"
end
end

test "suppressing broadcasting morph now" do
assert_no_broadcasts_when_suppressing do
@message.broadcast_morph
end
end

test "suppressing broadcasting morph later" do
assert_no_broadcasts_later_when_supressing do
@message.broadcast_morph_later
end
end

private
def assert_no_broadcasts_when_suppressing
assert_no_broadcasts @message.to_gid_param do
Expand All @@ -535,5 +587,3 @@ def assert_no_broadcasts_later_when_supressing
end
end
end


30 changes: 30 additions & 0 deletions test/streams/streams_channel_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -255,4 +255,34 @@ class Turbo::StreamsChannelTest < ActionCable::Channel::TestCase
Turbo::StreamsChannel.broadcast_stream_to "stream", content: "direct"
end
end

test "broadcasting morph now" do
options = { partial: "messages/message", locals: { message: "hello!" } }

assert_broadcast_on "stream", turbo_stream_action_tag("morph", target: "message_1", template: render(options)) do
Turbo::StreamsChannel.broadcast_morph_to "stream", target: "message_1", **options
end

assert_broadcast_on "stream", turbo_stream_action_tag("morph", targets: ".message", template: render(options)) do
Turbo::StreamsChannel.broadcast_morph_to "stream", targets: ".message", **options
end
end

test "broadcasting morph later" do
options = { partial: "messages/message", locals: { message: "hello!" } }

assert_broadcast_on "stream", turbo_stream_action_tag("morph", target: "message_1", template: render(options)) do
perform_enqueued_jobs do
Turbo::StreamsChannel.broadcast_morph_later_to \
"stream", target: "message_1", **options
end
end

assert_broadcast_on "stream", turbo_stream_action_tag("morph", targets: ".message", template: render(options)) do
perform_enqueued_jobs do
Turbo::StreamsChannel.broadcast_morph_later_to \
"stream", targets: ".message", **options
end
end
end
end

0 comments on commit 41d8b84

Please sign in to comment.