From ac9e7227e63de2ad1685556658ed8a58a5d6bacd Mon Sep 17 00:00:00 2001 From: idevakk <219866223+idevakk@users.noreply.github.com> Date: Thu, 5 Mar 2026 14:14:04 +0530 Subject: [PATCH] Step 5: Real-time broadcasting (NewEmailReceived event, channel routes, Livewire listener) --- app/Events/NewEmailReceived.php | 68 +++++++++++++++++++++++++++++++++ app/Livewire/Mailbox.php | 31 +++++++++++++++ routes/channels.php | 8 ++-- 3 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 app/Events/NewEmailReceived.php diff --git a/app/Events/NewEmailReceived.php b/app/Events/NewEmailReceived.php new file mode 100644 index 0000000..f7e9d74 --- /dev/null +++ b/app/Events/NewEmailReceived.php @@ -0,0 +1,68 @@ + + */ + public function broadcastOn(): array + { + return [ + new Channel('mailbox.'.$this->email->domain), + ]; + } + + /** + * The event's broadcast name. + */ + public function broadcastAs(): string + { + return 'new.email'; + } + + /** + * Get the data to broadcast. + * + * @return array + */ + public function broadcastWith(): array + { + return [ + 'id' => $this->email->id, + 'unique_id_hash' => $this->email->unique_id_hash, + 'recipient_email' => $this->email->recipient_email, + 'sender_email' => $this->email->sender_email, + 'sender_name' => $this->email->sender_name, + 'domain' => $this->email->domain, + 'subject' => $this->email->subject, + 'preview' => $this->email->preview, + 'attachments_json' => $this->email->attachments_json, + 'attachment_size' => $this->email->attachment_size, + 'is_read' => $this->email->is_read, + 'received_at' => $this->email->received_at?->toISOString(), + ]; + } +} diff --git a/app/Livewire/Mailbox.php b/app/Livewire/Mailbox.php index 044d6f6..4bfe05b 100644 --- a/app/Livewire/Mailbox.php +++ b/app/Livewire/Mailbox.php @@ -40,6 +40,37 @@ class Mailbox extends Component public $availableDomains = ['imail.com', 'devmail.ai', 'temp-inbox.net']; + /** + * Get Reverb/Echo event listeners for the current mailbox domain. + * + * @return array + */ + public function getListeners(): array + { + $currentMailbox = collect($this->activeMailboxes)->firstWhere('id', $this->currentMailboxId); + $domain = $currentMailbox ? explode('@', $currentMailbox['address'])[1] ?? '' : ''; + + if (empty($domain)) { + return []; + } + + return [ + "echo:mailbox.{$domain},.new.email" => 'onNewEmail', + ]; + } + + /** + * Handle a new email broadcast event from Reverb. + * + * @param array $eventData The email data from the broadcast. + */ + public function onNewEmail(array $eventData): void + { + // TODO: When real data integration is complete, prepend the new email to the list. + // For now, trigger a component refresh to pick up new data. + $this->dispatch('$refresh'); + } + public function getEmailsProperty() { // Mock emails based on mailbox ID diff --git a/routes/channels.php b/routes/channels.php index df2ad28..9202ba5 100644 --- a/routes/channels.php +++ b/routes/channels.php @@ -2,6 +2,8 @@ use Illuminate\Support\Facades\Broadcast; -Broadcast::channel('App.Models.User.{id}', function ($user, $id) { - return (int) $user->id === (int) $id; -}); +// Private channel: authenticated user can only listen to their own channel +Broadcast::channel('user.{id}', fn ($user, $id) => (int) $user->id === (int) $id); + +// Public channel: mailbox.{domain} — no auth needed for temp email service +// The domain channel is public so guests can receive real-time updates