From 8ac8fcad3f2b401830199e4139d1ccff7a5d8301 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 21 Jul 2021 03:41:28 -0600 Subject: [PATCH] Update LikeController, add UndoLikePipeline and federate Undo Like activities --- app/Http/Controllers/LikeController.php | 8 +- app/Jobs/LikePipeline/UnlikePipeline.php | 109 ++++++++++++++++++ app/Transformer/ActivityPub/Verb/UndoLike.php | 25 ++++ 3 files changed, 137 insertions(+), 5 deletions(-) create mode 100644 app/Jobs/LikePipeline/UnlikePipeline.php create mode 100644 app/Transformer/ActivityPub/Verb/UndoLike.php diff --git a/app/Http/Controllers/LikeController.php b/app/Http/Controllers/LikeController.php index 44e6e9bfe..9597465ba 100644 --- a/app/Http/Controllers/LikeController.php +++ b/app/Http/Controllers/LikeController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use App\Jobs\LikePipeline\LikePipeline; +use App\Jobs\LikePipeline\UnlikePipeline; use App\Like; use App\Status; use App\User; @@ -28,15 +29,12 @@ class LikeController extends Controller $profile = $user->profile; $status = Status::findOrFail($request->input('item')); - $count = $status->likes()->count(); if ($status->likes()->whereProfileId($profile->id)->count() !== 0) { $like = Like::whereProfileId($profile->id)->whereStatusId($status->id)->firstOrFail(); - $like->forceDelete(); - $count--; - $status->likes_count = $count; - $status->save(); + UnlikePipeline::dispatch($like); } else { + $count = $status->likes_count > 4 ? $status->likes_count : $status->likes()->count(); $like = Like::firstOrCreate([ 'profile_id' => $user->profile_id, 'status_id' => $status->id diff --git a/app/Jobs/LikePipeline/UnlikePipeline.php b/app/Jobs/LikePipeline/UnlikePipeline.php new file mode 100644 index 000000000..1a8afb58b --- /dev/null +++ b/app/Jobs/LikePipeline/UnlikePipeline.php @@ -0,0 +1,109 @@ +like = $like; + } + + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + $like = $this->like; + + $status = $this->like->status; + $actor = $this->like->actor; + + if (!$status) { + // Ignore notifications to deleted statuses + return; + } + + $count = $status->likes_count > 1 ? $status->likes_count : $status->likes()->count(); + $status->likes_count = $count - 1; + $status->save(); + + StatusService::del($status->id); + + if($actor->id !== $status->profile_id && $status->url && $actor->domain == null) { + $this->remoteLikeDeliver(); + } + + $exists = Notification::whereProfileId($status->profile_id) + ->whereActorId($actor->id) + ->whereAction('like') + ->whereItemId($status->id) + ->whereItemType('App\Status') + ->first(); + + if($exists) { + $exists->delete(); + } + + $like = Like::whereProfileId($actor->id)->whereStatusId($status->id)->first(); + + if(!$like) { + return; + } + + $like->forceDelete(); + + return; + } + + public function remoteLikeDeliver() + { + $like = $this->like; + $status = $this->like->status; + $actor = $this->like->actor; + + $fractal = new Fractal\Manager(); + $fractal->setSerializer(new ArraySerializer()); + $resource = new Fractal\Resource\Item($like, new LikeTransformer()); + $activity = $fractal->createData($resource)->toArray(); + + $url = $status->profile->sharedInbox ?? $status->profile->inbox_url; + + Helpers::sendSignedObject($actor, $url, $activity); + } +} diff --git a/app/Transformer/ActivityPub/Verb/UndoLike.php b/app/Transformer/ActivityPub/Verb/UndoLike.php new file mode 100644 index 000000000..4a88455e3 --- /dev/null +++ b/app/Transformer/ActivityPub/Verb/UndoLike.php @@ -0,0 +1,25 @@ + 'https://www.w3.org/ns/activitystreams', + 'id' => $like->actor->permalink('#likes/'.$like->id.'/undo'), + 'type' => 'Undo', + 'actor' => $like->actor->permalink(), + 'object' => [ + 'id' => $like->actor->permalink('#likes/'.$like->id), + 'type' => 'Like', + 'actor' => $like->actor->permalink(), + 'object' => $like->status->url() + ] + ]; + } +}