last message gone when selecting a chat

Viewed 61

We are currently building a chat for the application with livewire. There is an issue, when no chats are selected the last message shows but when selecting a chat. The last messages are gone. And I have no idea why. SQL queries look the same... photo of problem

photo of problem

code, livewire component:

class Inbox extends Component
{
    public ?Collection $chats = null;
    public ?User $selectedUser = null;
    public ?Collection $selectedChat = null;

    public string $newMessage = '';

    public function mount()
    {
        $this->chats = Auth::user()->getChats();
    }

    public function selectChat(int $userId)
    {
        $this->selectedUser = User::find($userId);
        $this->selectedChat = Auth::user()->getChatWith($this->selectedUser);
        $this->newMessage = '';
        $this->dispatchBrowserEvent('scroll-to-bottom');
    }

    public function unselectChat()
    {
        $this->selectedUser = null;
        $this->selectedChat = null;
        $this->newMessage = '';
    }

    public function send()
    {
        if (empty($this->newMessage)) {
            return;
        }

        $this->selectedChat->push(
            Message::from(Auth::user())
            ->to($this->selectedUser)
            ->send($this->newMessage)
        );

        $this->newMessage = '';

        $this->dispatchBrowserEvent('scroll-to-bottom');
    }

    public function render()
    {
        return view('livewire.inbox', [
            'chats' => Auth::user()->getChats(),
        ]);
    }
}

traits

trait HasMessages
{
    public function lastMessage()
    {
        return $this->belongsTo(Message::class);
    }

    public function scopeWithLastMessage(Builder $query, int $id)
    {
        return $query->addSelect([
            'last_message_id' => Message::select('id')
                ->where(
                    fn ($q) => $q->where('sender_id', $id)->whereColumn('receiver_id', 'users.id')
                )->orWhere(
                    fn ($q) => $q->where('receiver_id', $id)->whereColumn('sender_id', 'users.id')
                )
                ->latest('created_at')->latest('id')
                ->take(1)
            ])->whereExists(
                fn ($q) => $q->select('id')
                    ->from('messages')
                    ->where(
                        fn ($q) => $q->where('sender_id', $id)->whereColumn('receiver_id', 'users.id')
                    )->orWhere(
                        fn ($q) => $q->where('receiver_id', $id)->whereColumn('sender_id', 'users.id')
                    )
            )->with('lastMessage');
    }

    public function getChats()
    {
        return User::query()
            ->withLastMessage($this->id)
            ->where('id', '<>', $this->id)
            ->get()
            ->sortBy([
                ['lastMessage.created_at', 'desc'],
                ['lastMessage.id', 'desc'],
            ]);
    }

    public function getChatWith(User $user)
    {
        return Message::where(
            fn ($q) => $q->where('sender_id', $this->id)->where('receiver_id', $user->id)
        )->orWhere(
            fn ($q) => $q->where('receiver_id', $this->id)->where('sender_id', $user->id)
        )->oldest('created_at')->oldest('id')
        ->with(['sender', 'receiver'])
        ->get();
    }
}

the view, inbox chat blade:

<div {{ $attributes->merge(['class' => 'flex items-center px-4 sm:px-6 py-3 bg-white hover:bg-gray-100 cursor-pointer transition']) }}>
    <img src="{{ $chat->profilePhotoUrl }}"
         class="flex-shirink-0 w-10 h-10 rounded-full" />

    <div class="flex-1 ml-4 mr-2 min-w-0">
        <h5 class="text-gray-700 font-bold truncate">
            {{ $chat->name }}
        </h5>
        <p class="text-gray-500 text-sm truncate---">
            {{-- {{ $chat->lastMessage->body }} --}}
            lastMessage: {{ $chat->lastMessage }}
        </p>
    </div>

    {{-- <time class="text-gray-500 text-xs"
          datetime="{{ $chat->lastMessage->created_at }}">
        {{ $chat->lastMessage->created_at->diffForHumans() }}
    </time> --}}
</div>

inbox chat header

@props(['user', 'clickHandler'])

<div class="flex items-center px-4 sm:px-6 py-3 bg-white border-t border-gray-200 shadow-lg">
    <button class="md:hidden -ml-2 p-2 rounded-lg text-gray-500 hover:bg-gray-100 transition"
            wire:click.prevent="{{ $clickHandler }}">
        <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path>
        </svg>
    </button>
    <img src="{{ $user->profilePhotoUrl }}"
         class="ml-2 flex-shirink-0 w-10 h-10 rounded-full" />
    <div class="flex-1 ml-4 mr-2 min-w-0">
        <h5 class="text-gray-700 font-bold">
            {{ $user->name }}
        </h5>
    </div>
</div>
0 Answers
Related