Step 5: Real-time broadcasting (NewEmailReceived event, channel routes, Livewire listener)
This commit is contained in:
68
app/Events/NewEmailReceived.php
Normal file
68
app/Events/NewEmailReceived.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use App\Models\Email;
|
||||
use Illuminate\Broadcasting\Channel;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class NewEmailReceived implements ShouldBroadcast
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*/
|
||||
public function __construct(
|
||||
public Email $email,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* Broadcasts on a public channel keyed by domain.
|
||||
* Private user channels will be added when user-mailbox assignment is implemented.
|
||||
*
|
||||
* @return array<int, Channel>
|
||||
*/
|
||||
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<string, mixed>
|
||||
*/
|
||||
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(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -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<string, string>
|
||||
*/
|
||||
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<string, mixed> $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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user