Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions app/Http/Livewire/Like.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace App\Http\Livewire;

use App\Models\Post;
use Livewire\Component;

class Like extends Component
{
public Post $post;
public int $count;

public function mount(Post $post)
{
$this->post = $post;
$this->count = $post->likes_count;
}

public function like()
{
if ($this->post->isLiked()) {
$this->post->removeLike();
$this->count--;
} elseif (auth()->user()) {
$this->post->likes()->create([
'user_id' => auth()->id(),
]);
$this->count++;
} elseif (($ip = request()->ip()) && ($userAgent = request()->userAgent())) {
$this->post->likes()->create([
'ip' => $ip,
'user_agent' => $userAgent,
]);
$this->count++;
}
}

public function render()
{
return view('livewire.like');
}
}
36 changes: 36 additions & 0 deletions app/Models/Post.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,47 @@ public static function boot()
'published_at' => 'datetime',
];

protected $withCount = [
'likes',
];

/**
* Get the user that made this post.
*/
public function user()
{
return $this->belongsTo(User::class);
}

public function likes()
{
return $this->hasMany(PostLike::class);
}

public function isLiked()
{
if (auth()->user()) {
return auth()->user()->likes()->forPost($this)->count();
}

if (($ip = request()->ip()) && ($userAgent = request()->userAgent())) {
return $this->likes()->forIp($ip)->forUserAgent($userAgent)->count();
}

return false;
}

public function removeLike()
{
if (auth()->user()) {
return auth()->user()->likes()->forPost($this)->delete();
}

if (($ip = request()->ip()) && ($userAgent = request()->userAgent())) {
return $this->likes()->forIp($ip)->forUserAgent($userAgent)->delete();
}

return false;
}

}
32 changes: 32 additions & 0 deletions app/Models/PostLike.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class PostLike extends Model
{
use HasFactory;

protected $fillable = [
'user_id',
'ip',
'user_agent',
];

public function scopeForPost($query, Post $post)
{
return $query->where('post_id', $post->id);
}

public function scopeForIp($query, string $ip)
{
return $query->where('ip', $ip);
}

public function scopeForUserAgent($query, string $userAgent)
{
return $query->where('user_agent', $userAgent);
}
}
5 changes: 5 additions & 0 deletions app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,9 @@ class User extends Authenticatable implements MustVerifyEmail
protected $appends = [
'profile_photo_url',
];

public function likes()
{
return $this->hasMany(PostLike::class);
}
}
35 changes: 35 additions & 0 deletions database/migrations/2021_12_31_122354_create_post_likes_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostLikesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('post_likes', function (Blueprint $table) {
$table->id();
$table->foreignId('post_id');
$table->foreignId('user_id')->nullable();
$table->ipAddress('ip')->nullable();
$table->string('user_agent')->nullable();
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('post_likes');
}
}
2 changes: 1 addition & 1 deletion public/css/app.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/mix-manifest.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"/js/app.js": "/js/app.js?id=1c3ea411ff1a96757432",
"/css/app.css": "/css/app.css?id=16d379844c93c143ee7f"
"/css/app.css": "/css/app.css?id=3693b56668ee9937d8e8"
}
2 changes: 1 addition & 1 deletion resources/views/blog/index.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
{{--<img alt="blog photo" src="{{ asset('img/daniel.jpg') }}" class="object-cover w-full max-h-28"/>--}}
<div class="w-full p-4 bg-white dark:bg-gray-800 hover:dark:bg-gray-700">
<p class="text-sm font-medium text-orange-400">
{{ $post->user->name }} &middot; {{ now()->subMonth(1) > $post->published_at ? $post->published_at->isoFormat('D MMMM YYYY') : $post->published_at->diffForHumans() }} &middot; {{ read_time($post->body)}} &middot; {{ App\Helpers\NumberHelper::nearestK(views($post)->count()) }} {{ Str::plural('view', views($post)->count()) }}
{{ $post->user->name }} &middot; {{ now()->subMonth(1) > $post->published_at ? $post->published_at->isoFormat('D MMMM YYYY') : $post->published_at->diffForHumans() }} &middot; {{ read_time($post->body)}} &middot; {{ App\Helpers\NumberHelper::nearestK(views($post)->count()) }} {{ Str::plural('view', views($post)->count()) }} &middot; {{ $post->likes_count }} {{ Str::plural('like', $post->likes_count) }}
</p>
<p class="my-2 text-2xl font-semibold text-gray-800 sm:text-3xl dark:text-white">
{{ $post->title }}
Expand Down
4 changes: 3 additions & 1 deletion resources/views/blog/show.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<h1 class="text-3xl font-semibold sm:text-4xl lg:text-5xl break-word"><x-gradient-text>{{ $post->title }}</x-gradient-text></h1>

<p class="text-sm font-medium text-orange-800/90 dark:text-orange-100/50">
{{ $post->user->name }} &middot; {{ now()->subMonth(1) > $post->published_at ? $post->published_at->isoFormat('D MMMM YYYY') : $post->published_at->diffForHumans() }} &middot; {{ read_time($post->body)}} &middot; {{ App\Helpers\NumberHelper::nearestK(views($post)->count()) }} {{ Str::plural('view', views($post)->count()) }}
{{ $post->user->name }} &middot; {{ now()->subMonth(1) > $post->published_at ? $post->published_at->isoFormat('D MMMM YYYY') : $post->published_at->diffForHumans() }} &middot; {{ read_time($post->body)}} &middot; {{ App\Helpers\NumberHelper::nearestK(views($post)->count()) }} {{ Str::plural('view', views($post)->count()) }} &middot; {{ $post->likes_count }} {{ Str::plural('like', $post->likes_count) }}
{{--@foreach ($post->tags as $tag)
<span class="inline-flex items-center justify-center mr-1 font-semibold leading-none uppercase">{{ $tag->name }}</span>
@endforeach--}}
Expand All @@ -31,6 +31,8 @@
{!! $html !!}
{{--<x-markdown>{{ $post->body }}</x-markdown>--}}
</article>

<livewire:like :post="$post" />

</div>
</x-guest-layout>
2 changes: 1 addition & 1 deletion resources/views/home.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
{{--<img alt="blog photo" src="{{ asset('img/daniel.jpg') }}" class="object-cover w-full max-h-28"/>--}}
<div class="w-full p-4 bg-white dark:bg-gray-800 hover:dark:bg-gray-700">
<p class="text-xs font-medium text-orange-500 dark:text-orange-400">
{{ $post->user->name }} &middot; {{ $post->published_at->diffForHumans() }} &middot; {{ read_time($post->body)}} &middot; {{ App\Helpers\NumberHelper::nearestK(views($post)->count()) }} {{ Str::plural('view', views($post)->count()) }}
{{ $post->user->name }} &middot; {{ $post->published_at->diffForHumans() }} &middot; {{ read_time($post->body)}} &middot; {{ App\Helpers\NumberHelper::nearestK(views($post)->count()) }} {{ Str::plural('view', views($post)->count()) }} &middot; {{ $post->likes_count }} {{ Str::plural('like', $post->likes_count) }}
</p>
<p class="my-2 text-xl font-semibold text-gray-800 truncate dark:text-white">
{{ $post->title }}
Expand Down
3 changes: 3 additions & 0 deletions resources/views/layouts/guest.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

<!-- Styles -->
<link rel="stylesheet" href="{{ mix('css/app.css') }}">
@livewireStyles

<!-- FavIcon -->
<link rel="apple-touch-icon" sizes="180x180" href="{{ asset('favicon/apple-touch-icon.png') }}">
Expand Down Expand Up @@ -77,5 +78,7 @@ class="inline-flex items-center justify-center p-2 text-gray-800 rounded-md dark
</div>
</div>
</div>

@livewireScripts
</body>
</html>
15 changes: 15 additions & 0 deletions resources/views/livewire/like.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<span class="flex items-center w-full mt-12 text-3xl align-center">
<button wire:click="like" wire:loading.attr="disabled" class="flex mx-auto {{ $post->isLiked() ? 'text-orange-400 hover:text-orange-500' : 'text-gray-200 hover:text-orange-300' }} focus:outline-none focus:ring-0 disabled:text-gray-700">
@if($post->isLiked())
<svg xmlns="http://www.w3.org/2000/svg" class="inline-block w-8 h-8" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M3.172 5.172a4 4 0 015.656 0L10 6.343l1.172-1.171a4 4 0 115.656 5.656L10 17.657l-6.828-6.829a4 4 0 010-5.656z" clip-rule="evenodd" />
</svg>
@else
<svg xmlns="http://www.w3.org/2000/svg" class="inline-block w-8 h-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" />
</svg>
@endif
<span class="ml-1 font-medium">{{ $count }}</span>
<span class="sr-only">likes</span>
</button>
</span>