diff --git a/app/Console/Commands/AddSiteSettings.php b/app/Console/Commands/AddSiteSettings.php index c2d344059..d2449453a 100644 --- a/app/Console/Commands/AddSiteSettings.php +++ b/app/Console/Commands/AddSiteSettings.php @@ -73,7 +73,7 @@ public function handle() { $this->addSiteSetting('group_currency', 1, 'ID of the group currency to award from gallery submissions (if enabled).'); - $this->addSiteSetting('character_likes', 1, '0: Characters can be liked only once, 1: Characters can be liked daily.'); + $this->addSiteSetting('daily_character_likes', 1, '0: Characters can be liked only once, 1: Characters can be liked daily.'); $this->addSiteSetting('character_likes_leaderboard_enable', 1, '0: Disable leaderboard, 1: Enable leaderboard.'); diff --git a/app/Http/Controllers/BrowseController.php b/app/Http/Controllers/BrowseController.php index a5ec7025f..3d3f9492a 100644 --- a/app/Http/Controllers/BrowseController.php +++ b/app/Http/Controllers/BrowseController.php @@ -651,33 +651,22 @@ public function getSublist(Request $request, $key) { * @return \Illuminate\Contracts\Support\Renderable */ public function getLikesLeaderboard(Request $request) { - //this is a mess. please don't look. - - //abort if logged out to reduce strain - if (!Auth::check()) { - abort(404); - } - - //check if enabled, if not, there's no point to fetch anything lol - if (!Settings::get('character_likes_leaderboard_enable')) { + if (!Auth::check() || !Settings::get('character_likes_leaderboard_enable')) { abort(404); } - //fetch characters $query = Character::with('user.rank')->with('image.features')->with('rarity')->with('image.species')->myo(0)->where(function ($query) { //only display characters whose users allow likes $query = $query->whereRelation('user.settings', 'allow_character_likes', 1); }); $imageQuery = CharacterImage::images(Auth::check() ? Auth::user() : null)->with('features')->with('rarity')->with('species')->with('features'); - $query->whereIn('id', $imageQuery->pluck('character_id')->toArray()); - $randomcharacter = $query->visible()->get()->random(1)->first() ?? null; - if ($request->get('name')) { + if ($request->get('id')) { $query->where(function ($query) use ($request) { - $query->where('characters.name', 'LIKE', '%'.$request->get('name').'%')->orWhere('characters.slug', 'LIKE', '%'.$request->get('name').'%'); + $query->where('characters.id', $request->get('id')); }); } @@ -705,6 +694,7 @@ public function getLikesLeaderboard(Request $request) { return view('browse.character_likes_leaderboard', [ 'isMyo' => false, + 'sortCharacters' => Character::visible(Auth::user() ?? null)->get()->pluck('fullName', 'id')->toArray(), 'characters' => $query->get()->$sort('likeTotal')->paginate(24)->appends($request->query()), 'sublists' => Sublist::orderBy('sort', 'DESC')->get(), 'userOptions' => User::query()->orderBy('name')->pluck('name', 'id')->toArray(), diff --git a/app/Http/Controllers/Characters/CharacterController.php b/app/Http/Controllers/Characters/CharacterController.php index 1fcfe7d02..b73f41516 100644 --- a/app/Http/Controllers/Characters/CharacterController.php +++ b/app/Http/Controllers/Characters/CharacterController.php @@ -52,10 +52,6 @@ public function __construct() { $this->character->updateOwner(); - if (Auth::check()) { - Auth::user()->checkLike($this->character); - } - if (config('lorekeeper.extensions.previous_and_next_characters.display')) { $query = Character::myo(0); // Get only characters of this category if pull number is limited to category @@ -566,25 +562,27 @@ public function postLikeCharacter(Request $request, CharacterManager $service, $ abort(404); } - //owned by same user - if (Auth::user()->id == $this->character->user->id) { - abort(404); - } - - //user disabled likes - if (!$this->character->user->settings->allow_character_likes) { + if (Auth::user()->id == $this->character->user->id || !$this->character->user->settings->allow_character_likes) { abort(404); } - if ($service->likeCharacter($this->character, Auth::user())) { - flash('Character '.__('character_likes.liked').' successfully.')->success(); - } else { + if (!$service->likeCharacter($this->character, Auth::user())) { + $message = []; foreach ($service->errors()->getMessages()['error'] as $error) { - flash($error)->error(); + $message[] = $error; } + + return response()->json([ + 'success' => false, + 'message' => implode(' ', $message), + ]); } - return redirect()->back(); + return response()->json([ + 'success' => true, + 'message' => 'That was very skibidi of you.', + 'likes' => Settings::get('daily_character_likes') ? $this->character->likes->count() : $this->character->likes()->sum('total_likes'), + ]); } /** diff --git a/app/Models/Character/Character.php b/app/Models/Character/Character.php index 5ccfa419d..2b74581f3 100644 --- a/app/Models/Character/Character.php +++ b/app/Models/Character/Character.php @@ -195,10 +195,10 @@ public function items() { } /** - * Get all of the likes that are not NULL. + * Get all of the likes. */ - public function characterLikes() { - return $this->hasMany('App\Models\Character\CharacterLike')->where('character_id', $this->id)->whereNotNull('liked_at'); + public function likes() { + return $this->hasMany(CharacterLike::class)->where('character_id', $this->id); } /********************************************************************************************** @@ -571,14 +571,9 @@ public function notifyBookmarkers($type) { /** * Return like count based on site setting. * - * Will always return the accurate count even if settings are flip flopped around (i am paranoid.) + * Will always return the accurate count even if settings are flipped in future. */ public function getLikeTotalAttribute() { - //can like only once - if (!Settings::get('character_likes')) { - return $this->characterLikes->count(); - } else { - return $this->profile->like_count; - } + return Settings::get('daily_character_likes') ? $this->likes->count() : $this->likes()->sum('total_likes'); } } diff --git a/app/Models/Character/CharacterLike.php b/app/Models/Character/CharacterLike.php index efe394d6e..6474e5b2a 100644 --- a/app/Models/Character/CharacterLike.php +++ b/app/Models/Character/CharacterLike.php @@ -3,6 +3,7 @@ namespace App\Models\Character; use App\Models\Model; +use App\Models\User\User; class CharacterLike extends Model { /** @@ -11,7 +12,7 @@ class CharacterLike extends Model { * @var array */ protected $fillable = [ - 'character_id', 'user_id', 'liked_at', + 'character_id', 'user_id', 'liked_at', 'total_likes', ]; /** @@ -22,11 +23,13 @@ class CharacterLike extends Model { protected $table = 'character_likes'; /** - * Dates on the model to convert to Carbon instances. + * The attributes that should be cast to native types. * * @var array */ - public $dates = ['liked_at']; + protected $casts = [ + 'liked_at' => 'datetime', + ]; /********************************************************************************************** @@ -38,19 +41,13 @@ class CharacterLike extends Model { * Character associated with the like. */ public function character() { - return $this->belongsTo('App\Models\Character\Character', 'character_id'); + return $this->belongsTo(Character::class, 'character_id'); } /** * User associated with the like. */ public function user() { - return $this->belongsTo('App\Models\User\User', 'user_id'); + return $this->belongsTo(User::class, 'user_id'); } - - /********************************************************************************************** - - ATTRIBUTES - - **********************************************************************************************/ } diff --git a/app/Models/Character/CharacterProfile.php b/app/Models/Character/CharacterProfile.php index 0487b6a69..1e58dc400 100644 --- a/app/Models/Character/CharacterProfile.php +++ b/app/Models/Character/CharacterProfile.php @@ -11,7 +11,7 @@ class CharacterProfile extends Model { * @var array */ protected $fillable = [ - 'character_id', 'text', 'parsed_text', 'link', 'like_count', + 'character_id', 'text', 'parsed_text', 'link', ]; /** diff --git a/app/Models/User/User.php b/app/Models/User/User.php index a577d23a0..283a2aa73 100644 --- a/app/Models/User/User.php +++ b/app/Models/User/User.php @@ -5,6 +5,7 @@ use App\Facades\Settings; use App\Models\Character\Character; use App\Models\Character\CharacterBookmark; +use App\Models\Character\CharacterLike; use App\Models\Character\CharacterImageCreator; use App\Models\Comment\CommentLike; use App\Models\Currency\Currency; @@ -200,7 +201,7 @@ public function commentLikes() { * Get all of the user's character like data. */ public function characterLikes() { - return $this->hasMany('App\Models\Character\CharacterLike')->where('user_id', $this->id); + return $this->hasMany(CharacterLike::class)->where('user_id', $this->id); } /********************************************************************************************** @@ -374,7 +375,7 @@ public function getDisplayAliasAttribute() { return '(Unverified)'; } - return $this->primaryAlias->displayAlias; + return $this->primaryAlias?->displayAlias ?? '(No Alias)'; } /** @@ -682,62 +683,27 @@ public function hasBookmarked($character) { return CharacterBookmark::where('user_id', $this->id)->where('character_id', $character->id)->first(); } - /** - * Check the user's like for the character. - * - * @param mixed $character - */ - public function checkLike($character) { - //check for the like and create if nonexistent - - $like = $this->characterLikes()->where('character_id', $character->id)->first(); - - if (!$like) { - $createdlike = $this->characterLikes()->create([ - 'user_id' => $this->id, - 'character_id' => $character->id, - ]); - $this->refresh(); - $createdlike->refresh(); - } - } - /** * Check if user can like the character again. * * @param mixed $character + * + * @return bool */ public function canLike($character) { - //triplecheck that a like exists even though we spammed this check literally everywhere. - $like = $this->characterLikes()->where('character_id', $character->id)->first(); + if (!$character->user->settings->allow_character_likes) { + return false; + } + $like = $this->characterLikes()->where('character_id', $character->id)->first(); if (!$like) { - $createdlike = $this->characterLikes()->create([ - 'user_id' => $this->id, - 'character_id' => $character->id, - ]); - $this->refresh(); - $createdlike->refresh(); + return true; } - //user disabled likes on their characters - if (!$character->user->settings->allow_character_likes) { + if (!Settings::get('daily_character_likes') || ($like->liked_at && $like->liked_at->isToday())) { return false; } - //already liked - if ($like->liked_at) { - //can only like once - if (!Settings::get('character_likes')) { - return false; - } - //can like daily - if ($like->liked_at->isToday()) { - return false; - } - } - - //else you can :) return true; } } diff --git a/app/Services/CharacterManager.php b/app/Services/CharacterManager.php index 75419d0af..abbfc8a92 100644 --- a/app/Services/CharacterManager.php +++ b/app/Services/CharacterManager.php @@ -10,6 +10,7 @@ use App\Models\Character\CharacterCurrency; use App\Models\Character\CharacterDesignUpdate; use App\Models\Character\CharacterFeature; +use App\Models\Character\CharacterLike; use App\Models\Character\CharacterImage; use App\Models\Character\CharacterTransfer; use App\Models\Sales\SalesCharacter; @@ -1842,31 +1843,28 @@ public function likeCharacter($character, $user) { DB::beginTransaction(); try { - //throw in another like check - $user->checkLike($character); - - //check all the like criteria if (!$user->canLike($character)) { throw new \Exception('You cannot '.__('character_likes.like').' this character.'); } - //character is owned by you! if ($user->id == $character->user->id) { throw new \Exception('You cannot '.__('character_likes.like').' a character that you own.'); } - //character's owner disabled likes if (!$character->user->settings->allow_character_likes) { throw new \Exception("This character's user is not allowing ".__('character_likes.likes').'.'); } - //increment like count - $character->profile->like_count += 1; - $character->profile->save(); - //mark the like as liked now $like = $user->characterLikes()->where('character_id', $character->id)->first(); + if (!$like) { + $like = CharacterLike::create([ + 'user_id' => $user->id, + 'character_id' => $character->id, + ]); + } $like->liked_at = Carbon::now(); + $like->total_likes += 1; $like->save(); return $this->commitReturn(true); diff --git a/database/migrations/2024_03_19_235014_add_character_likes.php b/database/migrations/2024_03_19_235014_add_character_likes.php index 84a581c71..7539424b6 100644 --- a/database/migrations/2024_03_19_235014_add_character_likes.php +++ b/database/migrations/2024_03_19_235014_add_character_likes.php @@ -13,13 +13,10 @@ public function up() { $table->id(); $table->unsignedInteger('character_id'); $table->unsignedInteger('user_id'); + $table->integer('total_likes')->default(0); $table->timestamp('liked_at')->nullable()->default(null); }); - Schema::table('character_profiles', function (Blueprint $table) { - $table->unsignedInteger('like_count')->default(0); - }); - Schema::table('user_settings', function (Blueprint $table) { $table->boolean('allow_character_likes')->default(true); }); @@ -30,9 +27,6 @@ public function up() { */ public function down() { Schema::dropIfExists('character_likes'); - Schema::table('character_profiles', function (Blueprint $table) { - $table->dropColumn('like_count'); - }); Schema::table('user_settings', function (Blueprint $table) { $table->dropColumn('allow_character_likes'); }); diff --git a/resources/views/browse/character_likes_leaderboard.blade.php b/resources/views/browse/character_likes_leaderboard.blade.php index 7e65f2d81..0cbd6014d 100644 --- a/resources/views/browse/character_likes_leaderboard.blade.php +++ b/resources/views/browse/character_likes_leaderboard.blade.php @@ -19,8 +19,8 @@ {!! Form::open(['method' => 'GET']) !!}
- {!! Form::label('name', 'Character Name/Code: ', ['class' => 'mr-2']) !!} - {!! Form::text('name', Request::get('name'), ['class' => 'form-control']) !!} + {!! Form::label('id', 'Character Name/Code: ', ['class' => 'mr-2']) !!} + {!! Form::select('id', $sortCharacters, null, ['class' => 'form-control selectize mt-2', 'style' => 'width: 250px', 'placeholder' => 'Select a Character']) !!}
{!! Form::label('owner', 'Owner Username: ') !!} @@ -74,3 +74,10 @@
{{ $characters->total() }} result{{ $characters->total() == 1 ? '' : 's' }} found.
@endsection +@section('scripts') + +@endsection \ No newline at end of file diff --git a/resources/views/character/_header.blade.php b/resources/views/character/_header.blade.php index 05799b29d..9583a96cc 100644 --- a/resources/views/character/_header.blade.php +++ b/resources/views/character/_header.blade.php @@ -1,3 +1,4 @@ +
@if (!$character->is_myo_slot && config('lorekeeper.extensions.previous_and_next_characters.display') && isset($extPrevAndNextBtnsUrl)) @if ($extPrevAndNextBtns['prevCharName'] || $extPrevAndNextBtns['nextCharName'])
@@ -32,17 +33,28 @@

@if (!$character->is_myo_slot) @if ($character->user && $character->user->settings->allow_character_likes) -
- {{ $character->likeTotal }} +
+
+ +
@endif - @if (Auth::check() && $character->user && $character->user->settings->allow_character_likes && Auth::user()->canLike($character) && Auth::user()->id != $character->user_id) - - {!! Form::open(['url' => $character->url . '/like']) !!} - {!! Form::submit(ucfirst(__('character_likes.like')), ['class' => 'btn btn-success']) !!} - {!! Form::close() !!} - + @if (Auth::check() && $character->user && $character->user->settings->allow_character_likes) + @if (Auth::user()->canLike($character) && Auth::user()->id != $character->user_id) +
+ +
+ @else + @if (Auth::user()->id != $character->user_id) +
+
+ Liked! +
+
+ @endif + @endif @endif @endif @if (config('lorekeeper.extensions.character_status_badges')) @@ -60,8 +72,12 @@ class="fas fa-comments-dollar"> @endif @if ($character->is_visible && Auth::check() && $character->user_id != Auth::user()->id) hasBookmarked($character); ?> - - {{ $bookmark ? 'Edit Bookmark' : 'Bookmark' }} +
+
+ + {{ $bookmark ? 'Edit Bookmark' : 'Bookmark' }} +
+
@endif @if (config('lorekeeper.extensions.character_TH_profile_link') && $character->profile->link) Profile @@ -80,6 +96,25 @@ class="fas fa-comments-dollar">