id : (int) $user; return $query->addSelect([ 'unread_count' => Message::query() ->selectRaw('count(*)') ->whereColumn('messages.conversation_id', 'conversations.id') ->where('messages.sender_id', '!=', $userId) ->whereNull('messages.deleted_at') ->where(function ($nested) use ($participantAlias) { $nested->where(function ($group) use ($participantAlias) { $group->whereNull($participantAlias . '.last_read_message_id') ->whereNull($participantAlias . '.last_read_at'); })->orWhereColumn('messages.id', '>', $participantAlias . '.last_read_message_id') ->orWhereColumn('messages.created_at', '>', $participantAlias . '.last_read_at'); }), ]); } public function unreadCountForConversation(Conversation $conversation, User|int $user): int { $userId = $user instanceof User ? (int) $user->id : (int) $user; $participant = ConversationParticipant::query() ->where('conversation_id', $conversation->id) ->where('user_id', $userId) ->whereNull('left_at') ->first(); if (! $participant) { return 0; } return $this->unreadCountForParticipant($participant); } public function unreadCountForParticipant(ConversationParticipant $participant): int { $query = Message::query() ->where('conversation_id', $participant->conversation_id) ->where('sender_id', '!=', $participant->user_id) ->whereNull('deleted_at'); if ($participant->last_read_message_id) { $query->where('id', '>', $participant->last_read_message_id); } elseif ($participant->last_read_at) { $query->where('created_at', '>', $participant->last_read_at); } return (int) $query->count(); } public function totalUnreadForUser(User|int $user): int { $userId = $user instanceof User ? (int) $user->id : (int) $user; return (int) Conversation::query() ->select('conversations.id') ->join('conversation_participants as cp_me', function ($join) use ($userId) { $join->on('cp_me.conversation_id', '=', 'conversations.id') ->where('cp_me.user_id', '=', $userId) ->whereNull('cp_me.left_at'); }) ->where('conversations.is_active', true) ->get() ->sum(fn (Conversation $conversation) => $this->unreadCountForConversation($conversation, $userId)); } }