From 0e010252f93f67018f4b189c282483c7ab3833e1 Mon Sep 17 00:00:00 2001 From: "waffle.lord" Date: Mon, 26 Aug 2024 12:39:19 -0400 Subject: [PATCH 01/20] add some basic logging to database seeding --- database/seeders/DatabaseSeeder.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 1cfedfb..28d487b 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -10,6 +10,8 @@ use App\Models\SptVersion; use App\Models\User; use App\Models\UserRole; use Illuminate\Database\Seeder; +use Symfony\Component\Console\Helper\ProgressBar; +use Symfony\Component\Console\Output\ConsoleOutput; class DatabaseSeeder extends Seeder { @@ -29,6 +31,16 @@ class DatabaseSeeder extends Seeder User::factory()->for($administrator, 'role')->create([ 'email' => 'test@example.com', ]); + + $this->command->outputComponents()->info('test account created: test@example.com'); + + $progress = $this->command->getOutput()->createProgressBar(5); + $progress->setFormat("%message%\n %current%/%max% [%bar%] %percent:3s%%"); + $progress->setMessage("starting ..."); + + $progress->start(); + + $progress->setMessage('adding users ...'); User::factory(4)->for($administrator, 'role')->create(); // Add 10 moderators. @@ -37,19 +49,27 @@ class DatabaseSeeder extends Seeder // Add 100 users. $users = User::factory(100)->create(); + $progress->advance(); + + // Add 300 mods, assigning them to the users we just created. + $progress->setMessage('adding mods ...'); $allUsers = $users->merge([$administrator, $moderator]); $mods = Mod::factory(300)->recycle([$licenses])->create(); foreach ($mods as $mod) { $userIds = $allUsers->random(rand(1, 3))->pluck('id')->toArray(); $mod->users()->attach($userIds); } + $progress->advance(); // Add 3000 mod versions, assigning them to the mods we just created. + $progress->setMessage('adding mod versions ...'); $modVersions = ModVersion::factory(3000)->recycle([$mods, $spt_versions])->create(); + $progress->advance(); // Add ModDependencies to a subset of ModVersions. + $progress->setMessage('adding mod dependencies ...'); foreach ($modVersions as $modVersion) { $hasDependencies = rand(0, 100) < 30; // 30% chance to have dependencies if ($hasDependencies) { @@ -59,5 +79,9 @@ class DatabaseSeeder extends Seeder } } } + $progress->advance(); + $progress->finish(); + $this->command->info(''); + $this->command->outputComponents()->success('Database seeded'); } } From 5d5d94eaeee455e2e4059ef427c4c715f6085629 Mon Sep 17 00:00:00 2001 From: "waffle.lord" Date: Tue, 27 Aug 2024 16:41:30 -0400 Subject: [PATCH 02/20] WIP --- resources/views/user/show.blade.php | 37 +++++++++++++++++++---------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/resources/views/user/show.blade.php b/resources/views/user/show.blade.php index 8e2874c..74ded89 100644 --- a/resources/views/user/show.blade.php +++ b/resources/views/user/show.blade.php @@ -2,32 +2,43 @@
- {{ $user->name }} + profile cover photo of {{ $user->name }}
- {{ $user->name }} + profile photo of {{ $user->name }}

{{ $user->name }}

+

{{__("Member Since")}} {{ $user->created_at->format("M d, h:m a") }}

- {{-- -
- -
- --}} + + @if(\Illuminate\Support\Facades\Auth::check()) +
+ +
+
+ +
+ @endif
From 681ef3ac914256e7619919f21f3322a83751b97e Mon Sep 17 00:00:00 2001 From: "waffle.lord" Date: Wed, 28 Aug 2024 13:00:23 -0400 Subject: [PATCH 03/20] add full progress to seeder --- database/seeders/DatabaseSeeder.php | 83 ++++++++++++++++++----------- 1 file changed, 51 insertions(+), 32 deletions(-) diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 28d487b..33d7d28 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -10,8 +10,8 @@ use App\Models\SptVersion; use App\Models\User; use App\Models\UserRole; use Illuminate\Database\Seeder; -use Symfony\Component\Console\Helper\ProgressBar; -use Symfony\Component\Console\Output\ConsoleOutput; + +use function Laravel\Prompts\progress; class DatabaseSeeder extends Seeder { @@ -20,6 +20,11 @@ class DatabaseSeeder extends Seeder */ public function run(): void { + // how many of each "thing" to make during seeding + $userCount = 100; + $modCount = 300; + $modVersionCount = 500; + // Create a few SPT versions. $spt_versions = SptVersion::factory(30)->create(); @@ -34,13 +39,6 @@ class DatabaseSeeder extends Seeder $this->command->outputComponents()->info('test account created: test@example.com'); - $progress = $this->command->getOutput()->createProgressBar(5); - $progress->setFormat("%message%\n %current%/%max% [%bar%] %percent:3s%%"); - $progress->setMessage("starting ..."); - - $progress->start(); - - $progress->setMessage('adding users ...'); User::factory(4)->for($administrator, 'role')->create(); // Add 10 moderators. @@ -48,40 +46,61 @@ class DatabaseSeeder extends Seeder User::factory(5)->for($moderator, 'role')->create(); // Add 100 users. - $users = User::factory(100)->create(); - $progress->advance(); + $users = progress( + label: 'adding users...', + steps: $userCount, + callback: fn () => User::factory()->create() + ); + // dd($users); + $users = collect($users); // Add 300 mods, assigning them to the users we just created. - $progress->setMessage('adding mods ...'); $allUsers = $users->merge([$administrator, $moderator]); - $mods = Mod::factory(300)->recycle([$licenses])->create(); - foreach ($mods as $mod) { - $userIds = $allUsers->random(rand(1, 3))->pluck('id')->toArray(); - $mod->users()->attach($userIds); - } - $progress->advance(); + + $mods = progress( + label: 'adding mods...', + steps: $modCount, + callback: fn () => Mod::factory()->recycle([$licenses])->create() + ); + + $mods = collect($mods); + + progress( + label: 'attaching mod users ...', + steps: $mods, + callback: function ($mod) use ($allUsers) { + $userIds = $allUsers->random(rand(1, 3))->pluck('id')->toArray(); + $mod->users()->attach($userIds); + } + ); // Add 3000 mod versions, assigning them to the mods we just created. - $progress->setMessage('adding mod versions ...'); - $modVersions = ModVersion::factory(3000)->recycle([$mods, $spt_versions])->create(); - $progress->advance(); + $modVersions = progress( + label: 'adding mods versions ...', + steps: $modVersionCount, + callback: fn () => ModVersion::factory()->recycle([$mods, $spt_versions])->create() + ); + + $modVersions = collect($modVersions); // Add ModDependencies to a subset of ModVersions. - $progress->setMessage('adding mod dependencies ...'); - foreach ($modVersions as $modVersion) { - $hasDependencies = rand(0, 100) < 30; // 30% chance to have dependencies - if ($hasDependencies) { - $dependencyMods = $mods->random(rand(1, 3)); // 1 to 3 dependencies - foreach ($dependencyMods as $dependencyMod) { - ModDependency::factory()->recycle([$modVersion, $dependencyMod])->create(); + + progress( + label: 'adding mods dependencies ...', + steps: $modVersions, + callback: function ($modVersion) use ($mods) { + $hasDependencies = rand(0, 100) < 30; // 30% chance to have dependencies + if ($hasDependencies) { + $dependencyMods = $mods->random(rand(1, 3)); // 1 to 3 dependencies + foreach ($dependencyMods as $dependencyMod) { + ModDependency::factory()->recycle([$modVersion, $dependencyMod])->create(); + } } } - } - $progress->advance(); - $progress->finish(); - $this->command->info(''); + ); + $this->command->outputComponents()->success('Database seeded'); } } From dbcbbc4d14ccc51ea2ffd807aa9e988d974b1b0e Mon Sep 17 00:00:00 2001 From: "waffle.lord" Date: Wed, 28 Aug 2024 13:07:00 -0400 Subject: [PATCH 04/20] cleanup seeder --- database/seeders/DatabaseSeeder.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 33d7d28..768d1bd 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -52,8 +52,6 @@ class DatabaseSeeder extends Seeder callback: fn () => User::factory()->create() ); - // dd($users); - $users = collect($users); // Add 300 mods, assigning them to the users we just created. @@ -67,6 +65,7 @@ class DatabaseSeeder extends Seeder $mods = collect($mods); + // attach users to mods progress( label: 'attaching mod users ...', steps: $mods, @@ -86,7 +85,6 @@ class DatabaseSeeder extends Seeder $modVersions = collect($modVersions); // Add ModDependencies to a subset of ModVersions. - progress( label: 'adding mods dependencies ...', steps: $modVersions, From 71a336ecabfb7f0df8285dfe540ce190ba3148df Mon Sep 17 00:00:00 2001 From: "waffle.lord" Date: Wed, 28 Aug 2024 14:03:33 -0400 Subject: [PATCH 05/20] collect progress when needed --- database/seeders/DatabaseSeeder.php | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 768d1bd..ae97eca 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -46,24 +46,20 @@ class DatabaseSeeder extends Seeder User::factory(5)->for($moderator, 'role')->create(); // Add 100 users. - $users = progress( + $users = collect(progress( label: 'adding users...', steps: $userCount, callback: fn () => User::factory()->create() - ); - - $users = collect($users); + )); // Add 300 mods, assigning them to the users we just created. $allUsers = $users->merge([$administrator, $moderator]); - $mods = progress( + $mods = collect(progress( label: 'adding mods...', steps: $modCount, callback: fn () => Mod::factory()->recycle([$licenses])->create() - ); - - $mods = collect($mods); + )); // attach users to mods progress( @@ -76,13 +72,11 @@ class DatabaseSeeder extends Seeder ); // Add 3000 mod versions, assigning them to the mods we just created. - $modVersions = progress( + $modVersions = collect(progress( label: 'adding mods versions ...', steps: $modVersionCount, callback: fn () => ModVersion::factory()->recycle([$mods, $spt_versions])->create() - ); - - $modVersions = collect($modVersions); + )); // Add ModDependencies to a subset of ModVersions. progress( From a7cd60a164566497b627b8ea7a1388d502cbf00f Mon Sep 17 00:00:00 2001 From: "waffle.lord" Date: Wed, 28 Aug 2024 16:59:28 -0400 Subject: [PATCH 06/20] add user follows --- app/Http/Controllers/UserController.php | 5 ++ app/Models/User.php | 16 +++++++ .../2024_08_28_141058_user_follows.php | 31 ++++++++++++ database/seeders/DatabaseSeeder.php | 47 +++++++++++++------ 4 files changed, 85 insertions(+), 14 deletions(-) create mode 100644 database/migrations/2024_08_28_141058_user_follows.php diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index a8e86d5..e8cc71a 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -20,6 +20,11 @@ class UserController extends Controller abort(403); } + // not sure if this is optimal. Some way to do $user->with(...) ??? + $user = User::where('id', $user->id) + ->with(['followers', 'following']) + ->firstOrFail(); + return view('user.show', compact('user')); } } diff --git a/app/Models/User.php b/app/Models/User.php index 157248b..f8f22c9 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -50,6 +50,22 @@ class User extends Authenticatable implements MustVerifyEmail return $this->belongsToMany(Mod::class); } + /** + * The relationship between a user and users they follow + */ + public function following(): BelongsToMany + { + return $this->belongsToMany(User::class, 'user_follows', 'follower_id', 'following_id'); + } + + /** + * The relationship between a user and users that follow them + */ + public function followers(): BelongsToMany + { + return $this->belongsToMany(User::class, 'user_follows', 'following_id', 'follower_id'); + } + /** * The data that is searchable by Scout. */ diff --git a/database/migrations/2024_08_28_141058_user_follows.php b/database/migrations/2024_08_28_141058_user_follows.php new file mode 100644 index 0000000..7b7fca3 --- /dev/null +++ b/database/migrations/2024_08_28_141058_user_follows.php @@ -0,0 +1,31 @@ +id(); + $table->unsignedBigInteger('follower_id'); + $table->unsignedBigInteger('following_id'); + $table->foreign('follower_id')->references('id')->on('users')->cascadeOnDelete()->cascadeOnUpdate(); + $table->foreign('following_id')->references('id')->on('users')->cascadeOnDelete()->cascadeOnUpdate(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('user_follows'); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index ae97eca..04b1591 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -31,29 +31,48 @@ class DatabaseSeeder extends Seeder // Create some code licenses. $licenses = License::factory(10)->create(); - // Add 5 administrators. - $administrator = UserRole::factory()->administrator()->create(); - User::factory()->for($administrator, 'role')->create([ + // Add administrators. + $administratorRole = UserRole::factory()->administrator()->create(); + $testAccount = User::factory()->for($administratorRole, 'role')->create([ 'email' => 'test@example.com', ]); - $this->command->outputComponents()->info('test account created: test@example.com'); + $this->command->outputComponents()->info("test account created: $testAccount->email"); - User::factory(4)->for($administrator, 'role')->create(); + User::factory(4)->for($administratorRole, 'role')->create(); - // Add 10 moderators. - $moderator = UserRole::factory()->moderator()->create(); - User::factory(5)->for($moderator, 'role')->create(); + // Add moderators. + $moderatorRole = UserRole::factory()->moderator()->create(); + User::factory(5)->for($moderatorRole, 'role')->create(); - // Add 100 users. - $users = collect(progress( + // Add users + progress( label: 'adding users...', steps: $userCount, callback: fn () => User::factory()->create() - )); + ); - // Add 300 mods, assigning them to the users we just created. - $allUsers = $users->merge([$administrator, $moderator]); + // get all users + $allUsers = User::all(); + + // Add user follows + progress( + label: 'adding user follows ...', + steps: $allUsers, + callback: function ($user) use ($allUsers) { + $hasFollowers = rand(0, 100) < 70; // 70% chance to have followers + $isFollowing = rand(0, 100) < 70; // 70% chance to be following other users + + if ($hasFollowers) { + $followers = $allUsers->random(rand(1, 10))->pluck('id')->toArray(); + $user->followers()->attach($followers); + } + + if ($isFollowing) { + $following = $allUsers->random(rand(1, 10))->pluck('id')->toArray(); + $user->following()->attach($following); + } + }); $mods = collect(progress( label: 'adding mods...', @@ -71,7 +90,7 @@ class DatabaseSeeder extends Seeder } ); - // Add 3000 mod versions, assigning them to the mods we just created. + // Add mod versions, assigning them to the mods we just created. $modVersions = collect(progress( label: 'adding mods versions ...', steps: $modVersionCount, From f4ae428bdc32c577091c5ba7ea7b02dcfc2ab327 Mon Sep 17 00:00:00 2001 From: "waffle.lord" Date: Wed, 28 Aug 2024 18:41:35 -0400 Subject: [PATCH 07/20] add followers and following info WIP I'm too lazy to finish this today --- resources/views/user/show.blade.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/resources/views/user/show.blade.php b/resources/views/user/show.blade.php index 74ded89..19e1e40 100644 --- a/resources/views/user/show.blade.php +++ b/resources/views/user/show.blade.php @@ -16,6 +16,7 @@ @if(\Illuminate\Support\Facades\Auth::check()) + @if(\Illuminate\Support\Facades\Auth::id() != $user->id)
+ @endif
+
+
+

Followers:

+ @foreach($user->followers as $follower) +

{{$follower->name}}

+ @endforeach +
+
+

Following:

+ @foreach($user->following as $following) +

{{$following->name}}

+ @endforeach +
+
From 05f2dfc2582057dc79f38a5fc0ea5f6d57071a4e Mon Sep 17 00:00:00 2001 From: "waffle.lord" Date: Thu, 29 Aug 2024 16:25:55 -0400 Subject: [PATCH 08/20] work dump WIP --- app/Livewire/UserStack.php | 19 ++++++ resources/views/livewire/user-stack.blade.php | 47 ++++++++++++++ resources/views/user/show.blade.php | 62 +++++++++++-------- 3 files changed, 102 insertions(+), 26 deletions(-) create mode 100644 app/Livewire/UserStack.php create mode 100644 resources/views/livewire/user-stack.blade.php diff --git a/app/Livewire/UserStack.php b/app/Livewire/UserStack.php new file mode 100644 index 0000000..2f0ea0c --- /dev/null +++ b/app/Livewire/UserStack.php @@ -0,0 +1,19 @@ + +
+

{{$label}}

+
+
+ @foreach($users->slice(0, $limit) as $user) +
+ + {{$user->name[0]}} + +
+ {{$user->name}} +
+
+ @endforeach + @if($users->count() > $limit) +
+ +{{$users->count()-$limit}} +
+ {{$users->count()}} total +
+
+ @endif +
+ @if($users->count() > $limit) +
+ +
+ @endif + + + +

testing

+
+ +

no u

+
+ + + + {{__('Close')}} + + + +
+ diff --git a/resources/views/user/show.blade.php b/resources/views/user/show.blade.php index 19e1e40..4df26d4 100644 --- a/resources/views/user/show.blade.php +++ b/resources/views/user/show.blade.php @@ -2,12 +2,14 @@
- profile cover photo of {{ $user->name }} + profile cover photo of {{ $user->name }}
- profile photo of {{ $user->name }} + profile photo of {{ $user->name }}
@@ -17,20 +19,28 @@ @if(\Illuminate\Support\Facades\Auth::check()) @if(\Illuminate\Support\Facades\Auth::id() != $user->id) -
- -
+
+ +
@endif
- @@ -43,20 +53,20 @@

{{__("Member Since")}} {{ $user->created_at->format("M d, h:m a") }}

-
-
-

Followers:

- @foreach($user->followers as $follower) -

{{$follower->name}}

- @endforeach +
+
+ {{-- column 1 placeholder --}}
-
-

Following:

- @foreach($user->following as $following) -

{{$following->name}}

- @endforeach +
+
+ @livewire('user-stack', ['label' => 'Followers', 'users' => $user->followers]); +{{-- --}} +
+
+ @livewire('user-stack', ['label' => 'Following', 'users' => $user->following]); +{{-- --}} +
- From 239b10ca9dc4843eb949ca535e317f8d663c35f9 Mon Sep 17 00:00:00 2001 From: "waffle.lord" Date: Thu, 29 Aug 2024 21:50:59 -0400 Subject: [PATCH 09/20] user stack and follows WIP --- app/Livewire/UserStack.php | 13 +++++ app/Models/User.php | 18 +++++++ resources/views/livewire/user-stack.blade.php | 40 ++++++++++---- resources/views/user/show.blade.php | 53 ++++++++++++------- 4 files changed, 95 insertions(+), 29 deletions(-) diff --git a/app/Livewire/UserStack.php b/app/Livewire/UserStack.php index 2f0ea0c..e0b8b46 100644 --- a/app/Livewire/UserStack.php +++ b/app/Livewire/UserStack.php @@ -2,6 +2,7 @@ namespace App\Livewire; +use Illuminate\Support\Facades\Auth; use Livewire\Component; class UserStack extends Component @@ -12,8 +13,20 @@ class UserStack extends Component public int $limit = 5; + public bool $viewAll = false; + public function render() { return view('livewire.user-stack'); } + + public function toggleViewAll() + { + $this->viewAll = ! $this->viewAll; + } + + public function followUser($user) + { + $user->followers->syncWithoutDetaching(Auth::id()); + } } diff --git a/app/Models/User.php b/app/Models/User.php index f8f22c9..a48cd1a 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -66,6 +66,24 @@ class User extends Authenticatable implements MustVerifyEmail return $this->belongsToMany(User::class, 'user_follows', 'following_id', 'follower_id'); } + public function isFollowing(User|int $user): bool + { + $userId = $user instanceof User ? $user->id : $user; + return $this->following()->where('following_id', $userId)->exists(); + } + + public function follow(User|int $user): void + { + $userId = $user instanceof User ? $user->id : $user; + $this->following()->syncWithoutDetaching($userId); + } + + public function unfollow(User|int $user): void + { + $userId = $user instanceof User ? $user->id : $user; + $this->following()->detach($userId); + } + /** * The data that is searchable by Scout. */ diff --git a/resources/views/livewire/user-stack.blade.php b/resources/views/livewire/user-stack.blade.php index 5796e44..0bff890 100644 --- a/resources/views/livewire/user-stack.blade.php +++ b/resources/views/livewire/user-stack.blade.php @@ -2,22 +2,26 @@

{{$label}}

-
+
@foreach($users->slice(0, $limit) as $user)
- + {{$user->name[0]}} -
+
{{$user->name}}
@endforeach @if($users->count() > $limit)
- +{{$users->count()-$limit}} -
+ +{{$users->count()-$limit}} +
{{$users->count()}} total
@@ -25,20 +29,38 @@
@if($users->count() > $limit)
- +
@endif -

testing

+

{{$user->name}}'s {{$label}}

-

no u

+
+ @foreach($users as $user) + {{-- user tile --}} +
+ {{$user->name}} +
+ {{$user->name}} + {{__("Member Since")}} {{ $user->created_at->format("M d, h:m a") }} +
+ +
+ @endforeach +
- + {{__('Close')}} diff --git a/resources/views/user/show.blade.php b/resources/views/user/show.blade.php index 4df26d4..8233df5 100644 --- a/resources/views/user/show.blade.php +++ b/resources/views/user/show.blade.php @@ -17,20 +17,35 @@

{{__("Member Since")}} {{ $user->created_at->format("M d, h:m a") }}

- @if(\Illuminate\Support\Facades\Auth::check()) - @if(\Illuminate\Support\Facades\Auth::id() != $user->id) -
- -
+ @if(auth()->check()) + @if(auth()->id() != $user->id) + @if(auth()->user()->isFollowing($user)) +
+ +
+ @else +
+ +
+ @endif @endif
+ + @if(auth()->id() != $user->id) + @if(auth()->user()->isFollowing($user)) + {{-- following button --}} + + @else + {{-- follow button --}} + + @endif + @else + {{-- 'you' card for auth user in list --}} + + @endif
@endforeach
diff --git a/resources/views/livewire/user/profile.blade.php b/resources/views/livewire/user/profile.blade.php new file mode 100644 index 0000000..2d4f4e7 --- /dev/null +++ b/resources/views/livewire/user/profile.blade.php @@ -0,0 +1,81 @@ +
+
+ profile cover photo of {{ $user->name }} +
+
+
+
+ profile photo of {{ $user->name }} +
+
+
+

{{ $user->name }}

+

{{__("Member Since")}} {{ $user->created_at->format("M d, h:m a") }}

+
+ + @if(auth()->check()) + @if(auth()->id() != $user->id) + @if(auth()->user()->isFollowing($user)) +
+ +
+ @else +
+ +
+ @endif + @endif +
+ +
+ @endif +
+
+ +
+
+
+ {{-- column 1 placeholder --}} +
+
+
+ +
+
+ +
+
+
+
diff --git a/resources/views/user/show.blade.php b/resources/views/user/show.blade.php index 8233df5..99917e8 100644 --- a/resources/views/user/show.blade.php +++ b/resources/views/user/show.blade.php @@ -1,85 +1,3 @@ - -
-
- profile cover photo of {{ $user->name }} -
-
-
-
- profile photo of {{ $user->name }} -
-
-
-

{{ $user->name }}

-

{{__("Member Since")}} {{ $user->created_at->format("M d, h:m a") }}

-
- - @if(auth()->check()) - @if(auth()->id() != $user->id) - @if(auth()->user()->isFollowing($user)) -
- -
- @else -
- -
- @endif - @endif -
- -
- @endif -
-
- -
-
-
- {{-- column 1 placeholder --}} -
-
-
- @livewire('user-stack', ['label' => 'Followers', 'users' => $user->followers]) -
-
- @livewire('user-stack', ['label' => 'Following', 'users' => $user->following]) -
-
-
-
+ @livewire('user.profile', ['user' => $user])
From aabf5a1b444de4fc3b419cb66b4b025fc6e0338b Mon Sep 17 00:00:00 2001 From: "waffle.lord" Date: Sat, 31 Aug 2024 22:40:36 -0400 Subject: [PATCH 11/20] improve user stack auth user following checks and some UI tweaks --- app/Livewire/User/Profile.php | 14 +++++++++++ app/Livewire/UserStack.php | 23 +++++++++++++++++ resources/views/livewire/user-stack.blade.php | 25 +++++++++++++------ .../views/livewire/user/profile.blade.php | 6 ++--- 4 files changed, 57 insertions(+), 11 deletions(-) diff --git a/app/Livewire/User/Profile.php b/app/Livewire/User/Profile.php index 648ef7c..d3a294c 100644 --- a/app/Livewire/User/Profile.php +++ b/app/Livewire/User/Profile.php @@ -9,11 +9,25 @@ class Profile extends Component { public User $user; + public $followers; + + public $following; + + protected $listeners = ['refreshNeeded' => 'render']; + public function render() { + $this->followers = $this->user->followers; + $this->following = $this->user->following; + return view('livewire.user.profile'); } + public function message() + { + $this->render(); + } + public function followUser(User $user) { auth()->user()->follow($user); diff --git a/app/Livewire/UserStack.php b/app/Livewire/UserStack.php index 2dbebd0..a003273 100644 --- a/app/Livewire/UserStack.php +++ b/app/Livewire/UserStack.php @@ -4,20 +4,31 @@ namespace App\Livewire; use App\Models\User; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Log; +use Livewire\Attributes\Reactive; use Livewire\Component; class UserStack extends Component { + #[Reactive] public $users; + public $authFollowingIds = []; + public string $label = 'Users'; public int $limit = 5; public bool $viewAll = false; + public bool $refreshNeeded = false; + public function render() { + if (Auth::check()) { + $this->authFollowingIds = Auth::user()->following()->pluck('following_id')->toArray(); + } + return view('livewire.user-stack'); } @@ -26,13 +37,25 @@ class UserStack extends Component $this->viewAll = ! $this->viewAll; } + public function closeDialog() + { + if ($this->refreshNeeded) + { + $this->dispatch('refreshNeeded'); + } + + $this->toggleViewAll(); + } + public function followUser(User $user) { Auth::user()->follow($user); + $this->refreshNeeded = true; } public function unfollowUser(User $user) { Auth::user()->unfollow($user); + $this->refreshNeeded = true; } } diff --git a/resources/views/livewire/user-stack.blade.php b/resources/views/livewire/user-stack.blade.php index 7f4a834..8bbb0c0 100644 --- a/resources/views/livewire/user-stack.blade.php +++ b/resources/views/livewire/user-stack.blade.php @@ -53,20 +53,29 @@
@if(auth()->id() != $user->id) - @if(auth()->user()->isFollowing($user)) + @if(count($authFollowingIds) !== 0 && in_array($user->id, $authFollowingIds)) {{-- following button --}} @else {{-- follow button --}} @endif @@ -82,7 +91,7 @@ - + {{__('Close')}} diff --git a/resources/views/livewire/user/profile.blade.php b/resources/views/livewire/user/profile.blade.php index 2d4f4e7..5c204f8 100644 --- a/resources/views/livewire/user/profile.blade.php +++ b/resources/views/livewire/user/profile.blade.php @@ -45,7 +45,7 @@ @endif @endif
-
- +
- +
From 4ba181900ebe57b3a3f2fe807ceea0d2e7705701 Mon Sep 17 00:00:00 2001 From: "waffle.lord" Date: Sun, 1 Sep 2024 23:42:44 -0400 Subject: [PATCH 12/20] add test --- app/Models/User.php | 12 +++- tests/Feature/User/FollowTest.php | 100 ++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 tests/Feature/User/FollowTest.php diff --git a/app/Models/User.php b/app/Models/User.php index 2401b3a..35d6fc3 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -76,13 +76,23 @@ class User extends Authenticatable implements MustVerifyEmail public function follow(User|int $user): void { $userId = $user instanceof User ? $user->id : $user; + + if ($this->id === $userId) { + // don't allow following yourself + return; + } + $this->following()->syncWithoutDetaching($userId); } public function unfollow(User|int $user): void { $userId = $user instanceof User ? $user->id : $user; - $this->following()->detach($userId); + + // make sure the user is being followed before trying to detach + if ($this->isFollowing($userId)) { + $this->following()->detach($userId); + } } /** diff --git a/tests/Feature/User/FollowTest.php b/tests/Feature/User/FollowTest.php new file mode 100644 index 0000000..c983d00 --- /dev/null +++ b/tests/Feature/User/FollowTest.php @@ -0,0 +1,100 @@ +create(); + + $user->follow($user); + + $this->assertEmpty($user->follwers); + $this->assertEmpty($user->following); +}); + +test('confirm a user can follow and unfollow another user', function () { + $user1 = User::factory()->create(); + $user2 = User::factory()->create(); + + $user1->follow($user2); + + $this->assertTrue($user1->isFollowing($user2)); + + $user1->unfollow($user2); + + $this->assertFalse($user1->isFollowing($user2)); +}); + +test('confirm following a user cannot be done twice', function () { + $user1 = User::factory()->create(); + $user2 = User::factory()->create(); + + $user1->follow($user2); + $user1->follow($user2); + + + $this->assertCount(1, $user1->following); + $this->assertCount(1, $user2->followers); +}); + +test('confirm unfollowing a user that isnt being followed doesnt throw', function () { + $user1 = User::factory()->create(); + $user2 = User::factory()->create(); + + $user1->unfollow($user2); + + $this->assertEmpty($user1->following); + $this->assertEmpty($user2->followers); +}); + +test('confirm unfollowing random number doesnt perform detach all', function () { + $user1 = User::factory()->create(); + $user2 = User::factory()->create(); + $user3 = User::factory()->create(); + + $user1->follow($user2); + $user1->follow($user3); + + $this->assertTrue($user1->isFollowing($user2)); + $this->assertTrue($user1->isFollowing($user3)); + + $this->assertCount(2, $user1->following); + $this->assertCount(1, $user2->followers); + $this->assertCount(1, $user3->followers); + + $user1->unfollow(111112222233333); + + $this->assertTrue($user1->isFollowing($user2)); + $this->assertTrue($user1->isFollowing($user3)); +}); + +test('confirm null follow input fails', function () { + $this->expectException(TypeError::class); + + $user = User::factory()->create(); + + $user->follow(null); +}); + +test('confirm empty follow input fails', function () { + $this->expectException(ArgumentCountError::class); + + $user = User::factory()->create(); + + $user->follow(); +}); + +test('confirm null unfollow input fails', function () { + $this->expectException(TypeError::class); + + $user = User::factory()->create(); + + $user->unfollow(null); +}); + +test('confirm empty unfollow input fails', function () { + $this->expectException(ArgumentCountError::class); + + $user = User::factory()->create(); + + $user->unfollow(); +}); From f150f2a37148cac8eecd214f2ae73e06cb8da47a Mon Sep 17 00:00:00 2001 From: "waffle.lord" Date: Tue, 3 Sep 2024 10:59:17 -0400 Subject: [PATCH 13/20] combine auth check shouldn't show follow or message if user isn't logged in or is viewing their own profile --- resources/views/livewire/user/profile.blade.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/resources/views/livewire/user/profile.blade.php b/resources/views/livewire/user/profile.blade.php index 5c204f8..c6445e2 100644 --- a/resources/views/livewire/user/profile.blade.php +++ b/resources/views/livewire/user/profile.blade.php @@ -15,9 +15,9 @@

{{__("Member Since")}} {{ $user->created_at->format("M d, h:m a") }}

- @if(auth()->check()) - @if(auth()->id() != $user->id) + @if(auth()->check() && auth()->id() != $user->id) @if(auth()->user()->isFollowing($user)) + {{-- Following button --}}
@else + {{-- Follow button --}}
- @endif @endif + {{-- Message button --}}
@@ -21,7 +22,7 @@ +{{$users->count()-$limit}}
+ 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"> {{$users->count()}} total
diff --git a/resources/views/livewire/user/profile.blade.php b/resources/views/livewire/user/profile.blade.php index c6445e2..f4779e8 100644 --- a/resources/views/livewire/user/profile.blade.php +++ b/resources/views/livewire/user/profile.blade.php @@ -68,7 +68,60 @@
- {{-- column 1 placeholder --}} +
+ {{-- Mobile Dropdown --}} +
+ + +
+ + {{-- Desktop Tabs --}} + +
+
+ @switch($section) + @case('wall') +

This is the wall. I don't think this can be implemented yet? requires comments or something

+ @break + @case('mods') +
+ @foreach($user->mods as $mod) + + @endforeach +
+ @break + @case('recentActivity') +

This is the recent activity. Probably need to implement some kind of activity tracking for this?

+ @break + @case('aboutMe') +

{{$user->about}}

+ @break + @endswitch +
From 90aeecc6d8db54899db6361ee171b019121e0293 Mon Sep 17 00:00:00 2001 From: "waffle.lord" Date: Wed, 11 Sep 2024 09:24:43 -0400 Subject: [PATCH 16/20] fix user-stack showing wrong name in dialog title --- app/Livewire/UserStack.php | 2 ++ resources/views/livewire/user-stack.blade.php | 2 +- resources/views/livewire/user/profile.blade.php | 6 +++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/Livewire/UserStack.php b/app/Livewire/UserStack.php index a003273..050ba81 100644 --- a/app/Livewire/UserStack.php +++ b/app/Livewire/UserStack.php @@ -13,6 +13,8 @@ class UserStack extends Component #[Reactive] public $users; + public string $parentUserName; + public $authFollowingIds = []; public string $label = 'Users'; diff --git a/resources/views/livewire/user-stack.blade.php b/resources/views/livewire/user-stack.blade.php index 5c17e47..fd3058e 100644 --- a/resources/views/livewire/user-stack.blade.php +++ b/resources/views/livewire/user-stack.blade.php @@ -37,7 +37,7 @@ {{-- view all dialog --}} -

{{$user->name}}'s {{$label}}

+

{{$parentUserName}}'s {{$label}}

diff --git a/resources/views/livewire/user/profile.blade.php b/resources/views/livewire/user/profile.blade.php index f4779e8..6faed79 100644 --- a/resources/views/livewire/user/profile.blade.php +++ b/resources/views/livewire/user/profile.blade.php @@ -123,12 +123,12 @@ @endswitch
-
+
- +
- +
From f4433647217bc63f678b3550ed964628d007d6f1 Mon Sep 17 00:00:00 2001 From: "waffle.lord" Date: Wed, 11 Sep 2024 09:25:02 -0400 Subject: [PATCH 17/20] paginate mods --- app/Livewire/User/Profile.php | 7 ++++++- resources/views/livewire/user/profile.blade.php | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/Livewire/User/Profile.php b/app/Livewire/User/Profile.php index 96cf616..82c4675 100644 --- a/app/Livewire/User/Profile.php +++ b/app/Livewire/User/Profile.php @@ -5,9 +5,12 @@ namespace App\Livewire\User; use App\Models\User; use Livewire\Attributes\Url; use Livewire\Component; +use Livewire\WithPagination; class Profile extends Component { + use WithPagination; + public User $user; #[Url] @@ -24,7 +27,9 @@ class Profile extends Component $this->followers = $this->user->followers; $this->following = $this->user->following; - return view('livewire.user.profile'); + $mods = $this->user->mods()->paginate(6); + + return view('livewire.user.profile', compact('mods')); } public function setSection(string $name) { diff --git a/resources/views/livewire/user/profile.blade.php b/resources/views/livewire/user/profile.blade.php index 6faed79..8d856f8 100644 --- a/resources/views/livewire/user/profile.blade.php +++ b/resources/views/livewire/user/profile.blade.php @@ -108,8 +108,11 @@

This is the wall. I don't think this can be implemented yet? requires comments or something

@break @case('mods') +
+ {{ $mods->links() }} +
- @foreach($user->mods as $mod) + @foreach($mods as $mod) @endforeach
From f16b3fe4970fe84218a9c320b5a11ba4f62f7536 Mon Sep 17 00:00:00 2001 From: "waffle.lord" Date: Wed, 11 Sep 2024 14:15:13 -0400 Subject: [PATCH 18/20] pint and some mod data changes --- app/Livewire/User/Profile.php | 5 +++-- app/Livewire/UserStack.php | 4 +--- database/factories/UserFactory.php | 1 + resources/views/livewire/user/profile.blade.php | 2 +- tests/Feature/User/FollowTest.php | 1 - 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/app/Livewire/User/Profile.php b/app/Livewire/User/Profile.php index 82c4675..f6336db 100644 --- a/app/Livewire/User/Profile.php +++ b/app/Livewire/User/Profile.php @@ -27,12 +27,13 @@ class Profile extends Component $this->followers = $this->user->followers; $this->following = $this->user->following; - $mods = $this->user->mods()->paginate(6); + $mods = $this->user->mods()->withWhereHas('latestVersion')->paginate(6); return view('livewire.user.profile', compact('mods')); } - public function setSection(string $name) { + public function setSection(string $name) + { $this->section = $name; } diff --git a/app/Livewire/UserStack.php b/app/Livewire/UserStack.php index 050ba81..874fff1 100644 --- a/app/Livewire/UserStack.php +++ b/app/Livewire/UserStack.php @@ -4,7 +4,6 @@ namespace App\Livewire; use App\Models\User; use Illuminate\Support\Facades\Auth; -use Illuminate\Support\Facades\Log; use Livewire\Attributes\Reactive; use Livewire\Component; @@ -41,8 +40,7 @@ class UserStack extends Component public function closeDialog() { - if ($this->refreshNeeded) - { + if ($this->refreshNeeded) { $this->dispatch('refreshNeeded'); } diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index 770667b..c4bfe9a 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -16,6 +16,7 @@ class UserFactory extends Factory /** * Define the user's default state. + * * @throws RandomException */ public function definition(): array diff --git a/resources/views/livewire/user/profile.blade.php b/resources/views/livewire/user/profile.blade.php index 8d856f8..115cc6d 100644 --- a/resources/views/livewire/user/profile.blade.php +++ b/resources/views/livewire/user/profile.blade.php @@ -113,7 +113,7 @@
@foreach($mods as $mod) - + @endforeach
@break diff --git a/tests/Feature/User/FollowTest.php b/tests/Feature/User/FollowTest.php index c983d00..d86275c 100644 --- a/tests/Feature/User/FollowTest.php +++ b/tests/Feature/User/FollowTest.php @@ -31,7 +31,6 @@ test('confirm following a user cannot be done twice', function () { $user1->follow($user2); $user1->follow($user2); - $this->assertCount(1, $user1->following); $this->assertCount(1, $user2->followers); }); From 6240c329977bcc493b8f691dd444db7a3385c093 Mon Sep 17 00:00:00 2001 From: "waffle.lord" Date: Thu, 12 Sep 2024 15:26:20 -0400 Subject: [PATCH 19/20] mobile constraints WIP --- resources/views/livewire/user-stack.blade.php | 13 ++++++++++++- resources/views/livewire/user/profile.blade.php | 14 +++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/resources/views/livewire/user-stack.blade.php b/resources/views/livewire/user-stack.blade.php index fd3058e..a5d3e61 100644 --- a/resources/views/livewire/user-stack.blade.php +++ b/resources/views/livewire/user-stack.blade.php @@ -1,9 +1,17 @@ - -
+
+
+
+ +
+
+ +
+
{{-- Mobile Dropdown --}} -
+