Replace Auth System #3
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,11 +94,9 @@
|
||||
<button
|
||||
class="inline-flex items-center px-3 py-2 border text-sm leading-4 font-medium rounded-md text-gray-500 border-neutral-300/50 dark:text-gray-400 bg-white/20 dark:bg-neutral-950/20 dark:border-neutral-800/50 hover:text-gray-700 dark:hover:text-gray-300 focus:outline-none transition ease-in-out duration-150">
|
||||
@auth
|
||||
@if (Auth::user()->discord_avatar)
|
||||
<img class="h-8 w-8 rounded-full object-cover mr-2"
|
||||
src="https://external-content.duckduckgo.com/iu/?u=https://cdn.discordapp.com/avatars/{{ Auth::user()->discord_id }}/{{ Auth::user()->discord_avatar }}.webp"
|
||||
alt="{{ Auth::user()->name }}" />
|
||||
@endif
|
||||
<img class="h-8 w-8 rounded-full object-cover mr-2"
|
||||
src="{{ Auth::user()->getAvatar() }}"
|
||||
alt="{{ Auth::user()->name }}" />
|
||||
@else
|
||||
<img class="h-8 w-8 rounded-full object-cover mr-2" src="/images/default-avatar.webp"
|
||||
alt="Guest" />
|
||||
@@ -231,15 +229,11 @@
|
||||
<div class="pt-4 pb-1 border-t border-gray-200 dark:border-gray-600 dark:bg-neutral-900/30">
|
||||
|
||||
<div class="flex justify-center">
|
||||
@if (Auth::user()->discord_avatar)
|
||||
<img class="h-8 w-8 rounded-full object-cover mr-2"
|
||||
src="https://external-content.duckduckgo.com/iu/?u=https://cdn.discordapp.com/avatars/{{ Auth::user()->discord_id }}/{{ Auth::user()->discord_avatar }}.webp"
|
||||
alt="{{ Auth::user()->name }}" />
|
||||
@else
|
||||
<img class="h-8 w-8 rounded-full object-cover mr-2" src="/images/default-avatar.webp"
|
||||
alt="Guest" />
|
||||
@endif
|
||||
<span class="font-medium text-base text-gray-800 dark:text-neutral-200">{{ Auth::user()->name }}
|
||||
<img class="h-8 w-8 rounded-full object-cover mr-2"
|
||||
src="{{ Auth::user()->getAvatar() }}"
|
||||
alt="{{ Auth::user()->name }}" />
|
||||
<span class="font-medium text-base text-gray-800 dark:text-neutral-200">
|
||||
{{ Auth::user()->name }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -5,12 +5,8 @@
|
||||
<!-- Header -->
|
||||
<div class="flex text-sm font-light bg-neutral-950/50 backdrop-blur-lg rounded-lg p-10 gap-2">
|
||||
<div>
|
||||
@if ($playlist->user->discord_avatar)
|
||||
<img class="relative w-24 h-24 flex-none rounded-full shadow-lg"
|
||||
src="https://external-content.duckduckgo.com/iu/?u=https://cdn.discordapp.com/avatars/{{ $playlist->user->discord_id }}/{{ $playlist->user->discord_avatar }}.webp">
|
||||
@else
|
||||
<img class="relative w-24 h-24 flex-none rounded-full shadow-lg" src="/images/default-avatar.webp">
|
||||
@endif
|
||||
<img class="relative w-24 h-24 flex-none rounded-full shadow-lg"
|
||||
src="{{ $playlist->user->getAvatar() }}">
|
||||
</div>
|
||||
<div class="flex flex-col justify-center flex-1 pl-4">
|
||||
<h1 class="font-bold text-3xl">{{ $playlist->name }}</h1>
|
||||
|
||||
@@ -6,11 +6,7 @@
|
||||
<div id="comment-{{ $comment->id }}" class="flex rounded-lg bg-white p-1 mb-2 shadow-[0_2px_15px_-3px_rgba(0,0,0,0.07),0_10px_20px_-2px_rgba(0,0,0,0.04)] dark:bg-neutral-900">
|
||||
@php $user = cache()->rememberForever('commentUser'.$comment->commenter_id, fn () => \App\Models\User::where('id', $comment->commenter_id)->first()); @endphp
|
||||
<div>
|
||||
@if($user->discord_avatar)
|
||||
<img class="w-16 h-16 rounded-full m-2" src="https://external-content.duckduckgo.com/iu/?u=https://cdn.discordapp.com/avatars/{{ $user->discord_id }}/{{ $user->discord_avatar }}.webp" alt="{{ $user->name }} Avatar">
|
||||
@else
|
||||
<img class="w-16 h-16 rounded-full m-2" src="/images/default-avatar.webp" alt="{{ $user->name }} Avatar">
|
||||
@endif
|
||||
<img class="w-16 h-16 rounded-full m-2" src="{{ $user->getAvatar() }}" alt="{{ $user->name }} Avatar">
|
||||
</div>
|
||||
<div class="text-gray-800 dark:text-gray-200">
|
||||
<div>
|
||||
|
||||
@@ -23,10 +23,36 @@
|
||||
@csrf
|
||||
</form>
|
||||
|
||||
<form method="post" action="{{ route('profile.update') }}" class="mt-6 space-y-6">
|
||||
<form method="post" action="{{ route('profile.update') }}" class="mt-6 space-y-6" enctype="multipart/form-data">
|
||||
@csrf
|
||||
@method('patch')
|
||||
|
||||
<div>
|
||||
<x-input-label for="image" :value="__('Avatar')" />
|
||||
<div class="mt-2 flex items-center gap-4">
|
||||
<img
|
||||
src="{{ $user->getAvatar() }}"
|
||||
alt="{{ $user->name }}"
|
||||
class="h-16 w-16 rounded-full object-cover"
|
||||
>
|
||||
<input
|
||||
id="image"
|
||||
name="image"
|
||||
type="file"
|
||||
accept="image/*"
|
||||
class="block w-full text-sm text-gray-900 dark:text-gray-100
|
||||
file:mr-4 file:rounded-md file:border-0
|
||||
file:bg-rose-600 file:px-4 file:py-2
|
||||
file:text-sm file:font-semibold file:text-white
|
||||
hover:file:bg-rose-500"
|
||||
/>
|
||||
</div>
|
||||
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
||||
JPG, PNG, WebP or GIF. Max 8MB. Will be cropped to 128×128.
|
||||
</p>
|
||||
<x-input-error class="mt-2" :messages="$errors->get('image')" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<x-input-label for="name" :value="__('Name')" />
|
||||
<x-text-input id="name" name="name" type="text" class="mt-1 block w-full" :value="old('name', $user->name)" required autofocus autocomplete="name" />
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
<div
|
||||
class="overflow-hidden relative max-w-sm min-w-80 mx-auto bg-white/40 shadow-lg ring-1 ring-black/5 rounded-xl flex items-center gap-6 dark:bg-neutral-950/40 backdrop-blur dark:highlight-white/5">
|
||||
@if($user->discord_avatar)
|
||||
<img class="absolute -left-6 w-24 h-24 rounded-full shadow-lg"
|
||||
src="https://external-content.duckduckgo.com/iu/?u=https://cdn.discordapp.com/avatars/{{ $user->discord_id }}/{{ $user->discord_avatar }}.webp">
|
||||
@else
|
||||
<img class="absolute -left-6 w-24 h-24 rounded-full shadow-lg" src="/images/default-avatar.webp">
|
||||
@endif
|
||||
<img class="absolute -left-6 w-24 h-24 rounded-full shadow-lg" src="{{ $user->getAvatar() }}">
|
||||
<div class="flex flex-col py-5 pl-24">
|
||||
<strong class="text-slate-900 text-xl font-bold dark:text-slate-200">
|
||||
{{ $user->name }}
|
||||
|
||||
@@ -8,11 +8,7 @@
|
||||
<div id="comment-{{ $comment->getKey() }}" class="flex rounded-lg p-1 mb-2 ">
|
||||
|
||||
<div class="contents">
|
||||
@if($comment->commenter->discord_avatar)
|
||||
<img class="w-12 h-12 rounded-lg m-2" src="https://external-content.duckduckgo.com/iu/?u=https://cdn.discordapp.com/avatars/{{ $comment->commenter->discord_id }}/{{ $comment->commenter->discord_avatar }}.webp" alt="{{ $comment->commenter->name }} Avatar">
|
||||
@else
|
||||
<img class="w-12 h-12 rounded-lg m-2" src="/images/default-avatar.webp" alt="{{ $comment->commenter->name }} Avatar">
|
||||
@endif
|
||||
<img class="w-12 h-12 rounded-lg m-2" src="{{ $comment->commenter->getAvatar() }}" alt="{{ $comment->commenter->name }} Avatar">
|
||||
</div>
|
||||
|
||||
<div class="text-gray-800 dark:text-gray-200">
|
||||
|
||||
Reference in New Issue
Block a user