Repair: copy legacy joinDate into new user's created_at when creating users from legacy wallz
This commit is contained in:
81
app/Services/Messaging/UnreadCounterService.php
Normal file
81
app/Services/Messaging/UnreadCounterService.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Messaging;
|
||||
|
||||
use App\Models\Conversation;
|
||||
use App\Models\ConversationParticipant;
|
||||
use App\Models\Message;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class UnreadCounterService
|
||||
{
|
||||
public function applyUnreadCountSelect(Builder $query, User|int $user, string $participantAlias = 'cp_me'): Builder
|
||||
{
|
||||
$userId = $user instanceof User ? (int) $user->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));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user