Reworked Follow Livewire Components

Fixes PHPStan errors and makes it a little more performant. Still not good enough. Making way to many queries for what it's doing.
This commit is contained in:
Refringe 2024-09-30 22:56:06 -04:00
parent df8e7f958d
commit 39a7640e92
Signed by: Refringe
SSH Key Fingerprint: SHA256:t865XsQpfTeqPRBMN2G6+N8wlDjkgUCZF3WGW6O9N/k
2 changed files with 52 additions and 31 deletions

View File

@ -3,7 +3,6 @@
namespace App\Livewire\User;
use App\Models\User;
use Illuminate\Support\Collection;
use Illuminate\View\View;
use Livewire\Attributes\Locked;
use Livewire\Attributes\On;
@ -40,12 +39,16 @@ class FollowCard extends Component
public string $dialogTitle;
/**
* The users to display in the card.
*
* @var Collection<User>
* The user data to display in the card.
*/
#[Locked]
public Collection $followUsers;
public array $display = [];
/**
* The limited user data to display in the card.
*/
#[Locked]
public array $displayLimit = [];
/**
* The maximum number of users to display on the card.
@ -64,6 +67,12 @@ class FollowCard extends Component
#[Locked]
public User $profileUser;
/**
* The number of users being displayed.
*/
#[Locked]
public int $followUsersCount;
/**
* Called when the component is initialized.
*/
@ -130,18 +139,31 @@ class FollowCard extends Component
public function populateFollowUsers(): void
{
// Fetch IDs of all users the authenticated user is following.
$followingIds = auth()->user()->following()->pluck('following_id');
$followingIds = collect();
$authUser = auth()->user();
if ($authUser) {
$followingIds = $authUser->following()->pluck('following_id');
}
// Load the profile user's followers (or following) and map the follow status.
$this->followUsers = $this->profileUser->{$this->relationship}
// Load the profile user's followers (or following).
$users = $this->profileUser->{$this->relationship}()->with([])->get();
// Count the number of users.
$this->followUsersCount = $users->count();
// Load the users to display and whether the authenticated user is following each user.
$this->display = $users
->map(function (User $user) use ($followingIds) {
// Add the follow status based on the preloaded IDs.
$user->follows = $followingIds->contains($user->id);
return [
'user' => $user,
'isFollowing' => $followingIds->contains($user->id),
];
})->toArray();
// TODO: The above follows property doesn't exist on the User model. What was I smoking?
return $user;
});
// Store limited users for the main view.
$this->displayLimit = collect($this->display)
->take($this->limit)
->toArray();
}
/**

View File

@ -4,37 +4,37 @@
<h2 class="text-2xl">{{ $title }}</h2>
</div>
@if (! $followUsers->count())
@if ($followUsersCount === 0)
<div class="flex justify-center text-sm pt-2">
{{ $emptyMessage }}
</div>
@else
<div class="flex ml-6 py-2 justify-center items-center">
@foreach ($followUsers->slice(0, $limit) as $user)
@foreach ($displayLimit as $data)
{{-- User Badge --}}
<div class="relative group">
<a href="{{ $user->profileUrl() }}" class="rounded-full -ml-6 z-20 bg-[#ebf4ff] h-16 w-16 flex justify-center items-center border">
<img src="{{ $user->profile_photo_url }}" alt="{{ $user->name }}" class="h-full w-full rounded-full" />
<a href="{{ $data['user']->profileUrl() }}" class="rounded-full -ml-6 z-20 bg-[#ebf4ff] h-16 w-16 flex justify-center items-center border">
<img src="{{ $data['user']->profile_photo_url }}" alt="{{ $data['user']->name }}" class="h-full w-full rounded-full" />
</a>
<div class="absolute bottom-full -ml-3 left-1/2 transform -translate-x-1/2 mb-2 w-max px-2 py-1 text-sm text-white bg-gray-700 rounded shadow-lg opacity-0 group-hover:opacity-100">
{{ $user->name }}
{{ $data['user']->name }}
</div>
</div>
@endforeach
@if ($followUsers->count() > $limit)
@if ($followUsersCount > $limit)
{{-- Count Badge --}}
<div class="relative group">
<button wire:click="toggleFollowDialog" class="rounded-full -ml-6 z-20 bg-cyan-500 dark:bg-cyan-700 h-16 w-16 flex justify-center items-center border text-white">+{{ $followUsers->count() - $limit }}</button>
<button wire:click="toggleFollowDialog" class="rounded-full -ml-6 z-20 bg-cyan-500 dark:bg-cyan-700 h-16 w-16 flex justify-center items-center border text-white">+{{ $followUsersCount - $limit }}</button>
<div class="absolute bottom-full -ml-3 left-1/2 transform -translate-x-1/2 mb-2 w-max px-2 py-1 text-sm text-white bg-gray-700 rounded shadow-lg opacity-0 group-hover:opacity-100">
{{ $followUsers->count() }} total
{{ $followUsersCount }} total
</div>
</div>
@endif
</div>
@endif
@if ($followUsers->count() > $limit)
@if ($followUsersCount > $limit)
{{-- View All Button --}}
<div class="flex justify-center items-center">
<button wire:click="toggleFollowDialog" class="hover:underline active:underline">View All</button>
@ -49,28 +49,27 @@
</x-slot>
<x-slot name="content">
<div class="h-96 overflow-y-auto">
@foreach ($followUsers as $user)
@foreach ($display as $data)
<div class="flex group/item dark:hover:bg-gray-950 items-center p-2 pr-3 rounded-md">
<a href="{{ $user->profileUrl() }}" class="flex-shrink-0 w-16 h-16 items-center">
<img src="{{ $user->profile_photo_url }}" alt="{{ $user->name }}" class="block w-full h-full rounded-full" />
<a href="{{ $data['user']->profileUrl() }}" class="flex-shrink-0 w-16 h-16 items-center">
<img src="{{ $data['user']->profile_photo_url }}" alt="{{ $data['user']->name }}" class="block w-full h-full rounded-full" />
</a>
<div class="flex flex-col w-full pl-3">
<a href="{{ $user->profileUrl() }}" class="text-2xl group-hover/item:underline group-hover/item:text-white">{{ $user->name }}</a>
<a href="{{ $data['user']->profileUrl() }}" class="text-2xl group-hover/item:underline group-hover/item:text-white">{{ $data['user']->name }}</a>
<span>
{{ __("Member Since") }}
<x-time :datetime="$user->created_at" />
<x-time :datetime="$data['user']->created_at" />
</span>
</div>
@if (auth()->check() && auth()->user()->id !== $user->id)
<livewire:user.follow-buttons :profile-user-id="$user->id" :is-following="$user->follows" />
@if (auth()->check() && auth()->user()->id !== $data['user']->id)
<livewire:user.follow-buttons :profile-user-id="$data['user']->id" :is-following="$data['isFollowing']" />
@endif
</div>
@endforeach
</div>
</x-slot>
<x-slot name="footer">
<x-button x-on:click="show = false">
{{ __('Close') }}