conversationId = $conversationId; $this->authorizeConversation(); $this->markAsRead(); } public function loadEarlier(): void { $this->messageLimit += 25; } #[On('message-created')] public function refreshMessages(int $conversationId): void { if ($conversationId !== $this->conversationId) { return; } unset($this->messages, $this->hasMoreMessages); $this->markAsRead(); } #[On('conversation-updated')] public function refreshConversation(int $conversationId): void { if ($conversationId === $this->conversationId) { unset($this->conversation); } } #[Computed] public function conversation(): Conversation { $conversation = Conversation::query() ->forUser(Auth::user()) ->with([ 'participants' => fn ($query) => $query ->select(['id', 'conversation_id', 'user_id', 'role', 'last_read_at']) ->with('user:id,name,email'), ]) ->findOrFail($this->conversationId); Gate::authorize('view', $conversation); return $conversation; } /** * @return Collection */ #[Computed] public function messages(): Collection { return Message::query() ->where('conversation_id', $this->conversationId) ->with('sender:id,name,email') ->latest() ->limit($this->messageLimit) ->get() ->reverse() ->values(); } #[Computed] public function hasMoreMessages(): bool { return Message::query() ->where('conversation_id', $this->conversationId) ->count() > $this->messageLimit; } public function dateLabel(CarbonInterface $timestamp): string { if ($timestamp->isToday()) { return __('Today'); } if ($timestamp->isYesterday()) { return __('Yesterday'); } return $timestamp->format('F j, Y'); } private function authorizeConversation(): void { $conversation = Conversation::query() ->forUser(Auth::user()) ->findOrFail($this->conversationId); Gate::authorize('view', $conversation); } private function markAsRead(): void { ConversationParticipant::query() ->where('conversation_id', $this->conversationId) ->where('user_id', Auth::id()) ->update(['last_read_at' => now()]); } public function render(): View { return view('livewire.chat.conversation-view'); } }