Skip to content

Commit c824787

Browse files
authored
Merge pull request #144 from hotwired-laravel/tm/custom-action-broadcasts
Allow custom action broadcasts
2 parents 4b1180e + 4e48a72 commit c824787

File tree

5 files changed

+71
-14
lines changed

5 files changed

+71
-14
lines changed

src/Broadcasting/PendingBroadcast.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,12 @@ public function toOthers(bool $toOthers = true): self
134134

135135
public function partial(?string $partial, array $data = []): self
136136
{
137-
return $this->rendering(new Rendering($partial, $data));
137+
return $this->view($partial, $data);
138+
}
139+
140+
public function view(?string $view, array $data = []): self
141+
{
142+
return $this->rendering(new Rendering($view, $data));
138143
}
139144

140145
public function content($content)

src/Commands/TurboInstallCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ private function updateImportmapsDependencies(): void
121121
private function jsDependencies(): array
122122
{
123123
return [
124-
'@hotwired/turbo' => '^8.0.3',
124+
'@hotwired/turbo' => '^8.0.4',
125125
'laravel-echo' => '^1.15.0',
126126
'pusher-js' => '^8.0.1',
127127
];

src/Models/Broadcasts.php

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public function broadcastInsert(): PendingBroadcast
9292
return $this->broadcastActionTo(
9393
$this->broadcastDefaultStreamables(inserting: true),
9494
$action,
95-
Rendering::forModel($this),
95+
rendering: Rendering::forModel($this),
9696
);
9797
}
9898

@@ -126,58 +126,60 @@ public function broadcastRefresh(): PendingBroadcast
126126

127127
public function broadcastAppendTo($streamable): PendingBroadcast
128128
{
129-
return $this->broadcastActionTo($streamable, 'append', Rendering::forModel($this));
129+
return $this->broadcastActionTo($streamable, 'append', rendering: Rendering::forModel($this));
130130
}
131131

132132
public function broadcastPrependTo($streamable): PendingBroadcast
133133
{
134-
return $this->broadcastActionTo($streamable, 'prepend', Rendering::forModel($this));
134+
return $this->broadcastActionTo($streamable, 'prepend', rendering: Rendering::forModel($this));
135135
}
136136

137137
public function broadcastBeforeTo($streamable, string $target): PendingBroadcast
138138
{
139-
return $this->broadcastActionTo($streamable, 'before', Rendering::forModel($this), $target);
139+
return $this->broadcastActionTo($streamable, 'before', $target, rendering: Rendering::forModel($this));
140140
}
141141

142142
public function broadcastAfterTo($streamable, string $target): PendingBroadcast
143143
{
144-
return $this->broadcastActionTo($streamable, 'after', Rendering::forModel($this), $target);
144+
return $this->broadcastActionTo($streamable, 'after', $target, rendering: Rendering::forModel($this));
145145
}
146146

147147
public function broadcastReplaceTo($streamable): PendingBroadcast
148148
{
149-
return $this->broadcastActionTo($streamable, 'replace', Rendering::forModel($this));
149+
return $this->broadcastActionTo($streamable, 'replace', rendering: Rendering::forModel($this));
150150
}
151151

152152
public function broadcastUpdateTo($streamable): PendingBroadcast
153153
{
154-
return $this->broadcastActionTo($streamable, 'update', Rendering::forModel($this));
154+
return $this->broadcastActionTo($streamable, 'update', rendering: Rendering::forModel($this));
155155
}
156156

157157
public function broadcastRemoveTo($streamable): PendingBroadcast
158158
{
159-
return $this->broadcastActionTo($streamable, 'remove', Rendering::empty());
159+
return $this->broadcastActionTo($streamable, 'remove', rendering: Rendering::empty());
160160
}
161161

162162
public function broadcastRefreshTo($streamable): PendingBroadcast
163163
{
164-
return TurboStream::broadcastRefresh($this->toChannels(Collection::wrap($streamable)))
165-
->cancelIf(fn () => static::isIgnoringTurboStreamBroadcasts());
164+
return TurboStream::broadcastRefresh(
165+
$this->toChannels(Collection::wrap($streamable))
166+
)->cancelIf(fn () => static::isIgnoringTurboStreamBroadcasts());
166167
}
167168

168169
public function asTurboStreamBroadcastingChannel()
169170
{
170171
return $this->toChannels(Collection::wrap($this->broadcastDefaultStreamables($this->wasRecentlyCreated)));
171172
}
172173

173-
protected function broadcastActionTo($streamables, string $action, Rendering $rendering, ?string $target = null): PendingBroadcast
174+
public function broadcastActionTo($streamables, string $action, ?string $target = null, array $attributes = [], ?Rendering $rendering = null): PendingBroadcast
174175
{
175176
return TurboStream::broadcastAction(
176177
action: $action,
177178
target: $target ?: $this->broadcastDefaultTarget($action),
178179
targets: null,
179180
channel: $this->toChannels(Collection::wrap($streamables)),
180-
content: $rendering,
181+
attributes: $attributes,
182+
content: $rendering ?? Rendering::empty(),
181183
)->cancelIf(static::isIgnoringTurboStreamBroadcasts());
182184
}
183185

tests/Models/BroadcastsModelTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,4 +718,53 @@ public function can_disable_auto_broadcasts()
718718
return true;
719719
}, times: 1);
720720
}
721+
722+
/** @test */
723+
public function broadcasts_with_extra_attributes_to_turbo_stream()
724+
{
725+
TurboStream::fake();
726+
727+
/** @var Board $board */
728+
$board = Board::withoutTurboStreamBroadcasts(fn () => Board::create(['name' => 'Hello World']));
729+
730+
$board->broadcastActionTo(
731+
$channel = 'messages',
732+
$action = 'test',
733+
attributes: $attributes = ['data-foo' => 'bar'],
734+
);
735+
736+
TurboStream::assertBroadcasted(function (PendingBroadcast $turboStream) use ($channel, $action, $attributes) {
737+
$this->assertEquals("private-{$channel}", $turboStream->channels[0]->name);
738+
$this->assertEquals($action, $turboStream->action);
739+
$this->assertEquals($attributes, $turboStream->attributes);
740+
741+
return true;
742+
});
743+
}
744+
745+
/** @test */
746+
public function broadcasts_with_extra_attributes_to_turbo_stream_with_rendering()
747+
{
748+
TurboStream::fake();
749+
750+
/** @var Board $board */
751+
$board = Board::withoutTurboStreamBroadcasts(fn () => Board::create(['name' => 'Hello World']));
752+
753+
$board->broadcastActionTo(
754+
$channel = 'messages',
755+
$action = 'test',
756+
attributes: $attributes = ['data-foo' => 'bar'],
757+
)->view('boards.partials.board', [
758+
'board' => $board,
759+
]);
760+
761+
TurboStream::assertBroadcasted(function (PendingBroadcast $turboStream) use ($channel, $action, $attributes) {
762+
$this->assertEquals("private-{$channel}", $turboStream->channels[0]->name);
763+
$this->assertEquals($action, $turboStream->action);
764+
$this->assertEquals($attributes, $turboStream->attributes);
765+
$this->assertStringContainsString('Hello World', $turboStream->render());
766+
767+
return true;
768+
});
769+
}
721770
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<div id="@domid($board)">{{ $board->name }}</div>

0 commit comments

Comments
 (0)