From fb3722036aba31beab62dc7bce8a2b85c3b84fc0 Mon Sep 17 00:00:00 2001 From: w33b Date: Thu, 8 Jan 2026 18:47:31 +0100 Subject: [PATCH] Add ability to set custom avatar --- app/Http/Controllers/ProfileController.php | 42 ++++++++++++++++++- app/Http/Requests/ProfileUpdateRequest.php | 6 +++ app/Models/User.php | 19 +++++++++ resources/views/layouts/navigation.blade.php | 22 ++++------ .../livewire/playlist-overview.blade.php | 8 +--- resources/views/partials/comment.blade.php | 6 +-- .../update-profile-information-form.blade.php | 28 ++++++++++++- .../views/user/partials/profile.blade.php | 7 +--- .../views/vendor/comments/_comment.blade.php | 6 +-- 9 files changed, 105 insertions(+), 39 deletions(-) diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index b087a1e..fedb723 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers; use App\Models\Episode; use App\Models\Playlist; use App\Models\PlaylistEpisode; +use App\Models\User; use App\Http\Requests\ProfileUpdateRequest; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; @@ -12,8 +13,11 @@ use Illuminate\Support\Str; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Redirect; +use Illuminate\Support\Facades\Storage; use Illuminate\View\View; +use Intervention\Image\Laravel\Facades\Image; + use Conner\Tagging\Model\Tag; class ProfileController extends Controller @@ -46,13 +50,20 @@ class ProfileController extends Controller */ public function update(ProfileUpdateRequest $request): RedirectResponse { - $request->user()->fill($request->validated()); + $user = $request->user(); + + // Fill everything except the image + $user->fill($request->safe()->except('image')); if ($request->user()->isDirty('email')) { $request->user()->email_verified_at = null; } - $request->user()->save(); + if ($request->hasFile('image')) { + $this->storeAvatar($request->file('image'), $user); + } + + $user->save(); return Redirect::route('profile.settings')->with('status', 'profile-updated'); } @@ -156,4 +167,31 @@ class ProfileController extends Controller return Redirect::to('/'); } + + /** + * Store custom user avatar. + */ + protected function storeAvatar(\Illuminate\Http\UploadedFile $file, User $user): void + { + // Create Folder for Image Upload + if (! Storage::disk('public')->exists("/images/avatars")) { + Storage::disk('public')->makeDirectory("/images/avatars"); + } + + // Delete old avatar if it exists + if ($user->avatar) { + Storage::disk('public')->delete($user->avatar); + } + + $filename = "images/avatars/{$user->id}.webp"; + + $image = Image::read($file->getRealPath()) + ->cover(128, 128) + ->toWebp(quality: 85); + + Storage::disk('public')->put($filename, $image); + + $user->avatar = $filename; + } + } diff --git a/app/Http/Requests/ProfileUpdateRequest.php b/app/Http/Requests/ProfileUpdateRequest.php index 3622a8f..d3cdaa8 100644 --- a/app/Http/Requests/ProfileUpdateRequest.php +++ b/app/Http/Requests/ProfileUpdateRequest.php @@ -17,6 +17,12 @@ class ProfileUpdateRequest extends FormRequest { return [ 'name' => ['required', 'string', 'max:255'], + 'image' => [ + 'nullable', + 'image', + 'mimes:jpg,png,jpeg,webp,gif', + 'max:8192' + ], 'email' => [ 'required', 'string', diff --git a/app/Models/User.php b/app/Models/User.php index 37d6ac4..fb8b0bb 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -7,6 +7,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; +use Illuminate\Support\Facades\Storage; use Laravelista\Comments\Commenter; @@ -94,4 +95,22 @@ class User extends Authenticatable { return DB::table('comments')->where('commenter_id', $this->id)->count(); } + + /** + * Returns the user avatar image url. + */ + public function getAvatar(): string + { + if ($this->discord_id && $this->discord_avatar && !$this->avatar) + { + return "https://external-content.duckduckgo.com/iu/?u=https://cdn.discordapp.com/avatars/{$this->discord_id}/{$this->discord_avatar}.webp"; + } + + if ($this->avatar) + { + return Storage::url($this->avatar); + } + + return asset('images/default-avatar.webp'); + } } diff --git a/resources/views/layouts/navigation.blade.php b/resources/views/layouts/navigation.blade.php index c33ad5d..2944318 100644 --- a/resources/views/layouts/navigation.blade.php +++ b/resources/views/layouts/navigation.blade.php @@ -94,11 +94,9 @@