diff --git a/app/Livewire/AlertBanner.php b/app/Livewire/AlertBanner.php index c0a1fcfbd..f9a19e53b 100644 --- a/app/Livewire/AlertBanner.php +++ b/app/Livewire/AlertBanner.php @@ -10,6 +10,7 @@ use Filament\Notifications\Concerns\HasStatus; use Filament\Notifications\Concerns\HasTitle; use Filament\Support\Components\ViewComponent; use Illuminate\Contracts\Support\Arrayable; +use Livewire\Livewire; final class AlertBanner extends ViewComponent implements Arrayable { @@ -83,7 +84,13 @@ final class AlertBanner extends ViewComponent implements Arrayable public function send(): AlertBanner { - session()->push('alert-banners', $this->toArray()); + $data = $this->toArray(); + + if (Livewire::isLivewireRequest()) { + $data['from_livewire'] = true; + } + + session()->push('alert-banners', $data); return $this; } diff --git a/app/Livewire/AlertBannerCollection.php b/app/Livewire/AlertBannerCollection.php new file mode 100644 index 000000000..ab9550fb6 --- /dev/null +++ b/app/Livewire/AlertBannerCollection.php @@ -0,0 +1,15 @@ +transform( + fn (array $alertBanner): AlertBanner => AlertBanner::fromArray($alertBanner), + ); + } +} diff --git a/app/Livewire/AlertBannerContainer.php b/app/Livewire/AlertBannerContainer.php index 66dba002d..1202975b3 100644 --- a/app/Livewire/AlertBannerContainer.php +++ b/app/Livewire/AlertBannerContainer.php @@ -2,25 +2,35 @@ namespace App\Livewire; -use Filament\Notifications\Collection; use Illuminate\Contracts\View\View; use Livewire\Attributes\On; use Livewire\Component; class AlertBannerContainer extends Component { - public Collection $alertBanners; + public AlertBannerCollection $alertBanners; public function mount(): void { - $this->alertBanners = new Collection(); - $this->pullFromSession(); + $this->alertBanners = new AlertBannerCollection(); + + foreach (session()->pull('alert-banners', []) as $alertBanner) { + // Alerts created during Livewire requests should have been consumed by the event handler on the same page. + if (!empty($alertBanner['from_livewire'])) { + // If they weren't, then discard them instead of showing on the wrong page. + continue; + } + + $alertBanner = AlertBanner::fromArray($alertBanner); + $this->alertBanners->put($alertBanner->getId(), $alertBanner); + } } #[On('alertBannerSent')] public function pullFromSession(): void { foreach (session()->pull('alert-banners', []) as $alertBanner) { + unset($alertBanner['from_livewire']); $alertBanner = AlertBanner::fromArray($alertBanner); $this->alertBanners->put($alertBanner->getId(), $alertBanner); } diff --git a/app/Providers/Filament/FilamentServiceProvider.php b/app/Providers/Filament/FilamentServiceProvider.php index 5b30646aa..f97490aa9 100644 --- a/app/Providers/Filament/FilamentServiceProvider.php +++ b/app/Providers/Filament/FilamentServiceProvider.php @@ -34,7 +34,7 @@ use Illuminate\Support\ServiceProvider; use Livewire\Component; use Livewire\Livewire; -use function Livewire\on; +use function Livewire\before; use function Livewire\store; class FilamentServiceProvider extends ServiceProvider @@ -74,7 +74,7 @@ class FilamentServiceProvider extends ServiceProvider fn () => Blade::render("@vite(['resources/js/app.js'])"), ); - on('dehydrate', function (Component $component) { + before('dehydrate', function (Component $component) { if (!Livewire::isLivewireRequest()) { return; }