Skip to content

Commit

Permalink
Merge pull request #39 from tonysm/multiple-turbo-stream-responses
Browse files Browse the repository at this point in the history
Can build multiple turbo stream responses in a single response
  • Loading branch information
tonysm authored Oct 20, 2021
2 parents 9086262 + 7f4c61a commit fe9ded6
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 8 deletions.
47 changes: 47 additions & 0 deletions src/Http/MultiplePendingTurboStreamResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Tonysm\TurboLaravel\Http;

use Illuminate\Contracts\Support\Responsable;
use Illuminate\Support\Collection;

class MultiplePendingTurboStreamResponse implements Responsable
{
/** @var Collection|PendingTurboStreamResponse[] */
private Collection $pendingStreams;

/**
* @param Collection $pendingStreams
*/
public function __construct($pendingStreams)
{
$this->pendingStreams = collect($pendingStreams);
}

/**
* @param array|Collection $pendingStreams
*
* @return self
*/
public static function forStreams($pendingStreams): self
{
return new self($pendingStreams);
}

/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return TurboResponseFactory::makeStream(
$this->pendingStreams
->map(function (PendingTurboStreamResponse $pendingStream) {
return $pendingStream->render();
})
->implode(PHP_EOL)
);
}
}
17 changes: 11 additions & 6 deletions src/Http/PendingTurboStreamResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,15 +118,20 @@ public function toResponse($request)
}

return TurboResponseFactory::makeStream(
view('turbo-laravel::turbo-stream', [
'target' => $this->useTarget,
'action' => $this->useAction,
'partial' => $this->partialView,
'partialData' => $this->partialData,
])->render()
$this->render()
);
}

public function render(): string
{
return view('turbo-laravel::turbo-stream', [
'target' => $this->useTarget,
'action' => $this->useAction,
'partial' => $this->partialView,
'partialData' => $this->partialData,
])->render();
}

private function inserted(Model $model, string $action, ?string $target = null): self
{
$this->useTarget = $target ?: $this->getResourceNameFor($model);
Expand Down
8 changes: 6 additions & 2 deletions src/TurboServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace Tonysm\TurboLaravel;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Response;
Expand All @@ -15,6 +14,7 @@
use Tonysm\TurboLaravel\Broadcasters\LaravelBroadcaster;
use Tonysm\TurboLaravel\Commands\TurboInstallCommand;
use Tonysm\TurboLaravel\Facades\Turbo as TurboFacade;
use Tonysm\TurboLaravel\Http\MultiplePendingTurboStreamResponse;
use Tonysm\TurboLaravel\Http\PendingTurboStreamResponse;
use Tonysm\TurboLaravel\Http\TurboResponseFactory;
use Tonysm\TurboLaravel\Testing\AssertableTurboStream;
Expand Down Expand Up @@ -78,7 +78,11 @@ private function bindBladeMacros(): void

private function bindRequestAndResponseMacros(): void
{
Response::macro('turboStream', function (?Model $model = null, string $action = null) {
Response::macro('turboStream', function ($model = null, string $action = null) {
if (is_array($model)) {
return MultiplePendingTurboStreamResponse::forStreams($model);
}

if ($model === null) {
return new PendingTurboStreamResponse();
}
Expand Down
34 changes: 34 additions & 0 deletions tests/Http/ResponseMacrosTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,40 @@ public function after_shorthand()
$this->assertEquals(Turbo::TURBO_STREAM_FORMAT, $response->headers->get('Content-Type'));
}

/** @test */
public function builds_multiple_turbo_stream_responses()
{
$model = TestModel::create(['name' => 'Test model']);

$response = response()->turboStream([
response()->turboStream()->append($model)->target('append-target-id'),
response()->turboStream()->prepend($model)->target('prepend-target-id'),
response()->turboStream()->remove($model)->target('remove-target-id'),
])->toResponse(new Request());

$expected = collect([
view('turbo-laravel::turbo-stream', [
'action' => 'append',
'target' => 'append-target-id',
'partial' => 'test_models._test_model',
'partialData' => ['testModel' => $model],
])->render(),
view('turbo-laravel::turbo-stream', [
'action' => 'prepend',
'target' => 'prepend-target-id',
'partial' => 'test_models._test_model',
'partialData' => ['testModel' => $model],
])->render(),
view('turbo-laravel::turbo-stream', [
'action' => 'remove',
'target' => 'remove-target-id',
])->render(),
])->implode(PHP_EOL);

$this->assertEquals(trim($expected), trim($response->getContent()));
$this->assertEquals(Turbo::TURBO_STREAM_FORMAT, $response->headers->get('Content-Type'));
}

/** @test */
public function response_builder_fails_when_partial_is_missing_and_not_a_remove_action()
{
Expand Down

0 comments on commit fe9ded6

Please sign in to comment.