Refactored the Actor Inbox

This commit is contained in:
Ghostie 2025-01-11 19:49:54 -05:00
parent d2a2e466ef
commit daa8b3eaeb
12 changed files with 245 additions and 100 deletions

View File

@ -0,0 +1,26 @@
<?php
namespace App\Events\AP;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class ActivityFollowEvent
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $activity;
/**
* Create a new event instance.
*/
public function __construct($activity)
{
$this->activity = $activity;
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace App\Events\AP;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class ActivityLikeEvent
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $activity;
/**
* Create a new event instance.
*/
public function __construct($activity)
{
$this->activity = $activity;
}
}

View File

@ -23,8 +23,6 @@ class ActivityUndoEvent
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable, InteractsWithSockets, SerializesModels;
public $activity; public $activity;
public $actor;
public $object;
/** /**
* Create a new event instance. * Create a new event instance.
@ -32,31 +30,5 @@ class ActivityUndoEvent
public function __construct($activity) public function __construct($activity)
{ {
$this->activity = $activity; $this->activity = $activity;
$this->actor = TypeActor::actor_exists_or_obtain ($activity ["actor"]);
$child_activity = $activity ["object"];
$child_activity_id = "";
if (is_array ($child_activity))
$child_activity_id = $child_activity ["id"];
else
$child_activity_id = $child_activity;
if (!TypeActivity::activity_exists ($child_activity_id))
return ["error" => "Activity not found",];
$child_activity = Activity::where ("activity_id", $child_activity_id)->first ();
$this->object = $child_activity;
switch ($this->object->type)
{
case "Follow":
$unfollowed_actor = Actor::where ("actor_id", $this->object->object)->first ();
UserUnfollowedEvent::dispatch ($this->object, $this->actor, $unfollowed_actor);
break;
}
$child_activity->delete ();
} }
} }

View File

@ -18,14 +18,14 @@ class NoteLikedEvent
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable, InteractsWithSockets, SerializesModels;
public Activity $activity; public $activity;
public Actor $actor; public $actor;
public Note $note; public $note;
/** /**
* Create a new event instance. * Create a new event instance.
*/ */
public function __construct(Activity $activity, Actor $actor, Note $note) public function __construct($activity, $actor, $note)
{ {
$this->activity = $activity; $this->activity = $activity;
$this->actor = $actor; $this->actor = $actor;

View File

@ -19,13 +19,13 @@ class NoteRepliedEvent
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable, InteractsWithSockets, SerializesModels;
public $activity; public $activity;
public Actor $actor; public $actor;
public Note $object; public $object;
/** /**
* Create a new event instance. * Create a new event instance.
*/ */
public function __construct($activity, Actor $actor, Note $object) public function __construct($activity, $actor, $object)
{ {
$this->activity = $activity; $this->activity = $activity;
$this->actor = $actor; $this->actor = $actor;

View File

@ -18,9 +18,9 @@ class UserFollowedEvent
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable, InteractsWithSockets, SerializesModels;
public Activity $activity; public $activity;
public Actor $actor; public $actor;
public Actor $object; public $object;
/** /**
* Create a new event instance. * Create a new event instance.

View File

@ -17,14 +17,14 @@ class UserUnfollowedEvent
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable, InteractsWithSockets, SerializesModels;
public Activity $activity; public $activity;
public Actor $actor; public $actor;
public Actor $object; public $object;
/** /**
* Create a new event instance. * Create a new event instance.
*/ */
public function __construct(Activity $activity, Actor $actor, Actor $object) public function __construct($activity, $actor, $object)
{ {
$this->activity = $activity; $this->activity = $activity;
$this->actor = $actor; $this->actor = $actor;

View File

@ -13,10 +13,11 @@ use App\Models\Like;
use App\Types\TypeActor; use App\Types\TypeActor;
use App\Types\TypeActivity; use App\Types\TypeActivity;
use App\Events\UserFollowedEvent;
use App\Events\NoteLikedEvent; use App\Events\NoteLikedEvent;
use App\Events\AP\ActivityUndoEvent; use App\Events\AP\ActivityUndoEvent;
use App\Events\AP\ActivityFollowEvent;
use App\Events\AP\ActivityLikeEvent;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
@ -54,69 +55,16 @@ class APInboxController extends Controller
private function handle_follow (User $user, $activity) private function handle_follow (User $user, $activity)
{ {
if (TypeActivity::activity_exists ($activity["id"])) ActivityFollowEvent::dispatch ($activity);
return response ()->json (["error" => "Activity already exists",], 409);
$actor = TypeActor::actor_exists_or_obtain ($activity ["actor"]);
$target = TypeActor::actor_get_local ($activity ["object"]);
if (!$target || !$target->user)
return response ()->json (["error" => "Target not found",], 404);
// check follow doesn't exist
$follow_exists = Follow::where ("actor", $actor->id)
->where ("object", $target->id)
->first ();
if ($follow_exists)
return response ()->json (["error" => "Follow already exists",], 409);
$activity ["activity_id"] = $activity ["id"];
$act = Activity::create ($activity);
UserFollowedEvent::dispatch ($act, $actor, $target);
// TODO: Users should be able to manually check this
$accept_activity = TypeActivity::craft_accept ($act);
$response = TypeActivity::post_activity ($accept_activity, $target, $actor);
if (!$response)
{
return response ()->json ([
"error" => "Error posting activity",
], 500);
}
} }
public function handle_undo (User $user, $activity) public function handle_undo (User $user, $activity)
{ {
ActivityUndoEvent::dispatch ($activity, $activity); ActivityUndoEvent::dispatch ($activity);
return response ()->json (ActionsActivity::activity_undo ($activity));
} }
public function handle_like (User $user, $activity) public function handle_like (User $user, $activity)
{ {
$actor = TypeActor::actor_exists_or_obtain ($activity ["actor"]); ActivityLikeEvent::dispatch ($activity);
$note_id = $activity ["object"];
$note = Note::where ("note_id", $note_id)->first ();
if (!$note)
{
Log::info ("Note not found: " . $note_id);
return response ()->json (["error" => "Note not found",], 404);
}
// check like doesn't already exist
$like_exists = $actor->liked_note ($note);
if ($like_exists)
return response ()->json (["error" => "Like already exists",], 409);
$activity ["activity_id"] = $activity ["id"];
$activity_exists = TypeActivity::activity_exists ($activity ["id"]);
if (!$activity_exists)
$act = Activity::create ($activity);
else
$act = Activity::where ("activity_id", $activity ["id"])->first ();
NoteLikedEvent::dispatch ($act, $actor, $note);
return response ()->json (["success" => "Like created",], 200);
} }
} }

View File

@ -0,0 +1,58 @@
<?php
namespace App\Listeners\AP;
use App\Models\Activity;
use App\Models\Follow;
use App\Types\TypeActivity;
use App\Types\TypeActor;
use App\Events\UserFollowedEvent;
use App\Events\AP\ActivityFollowEvent;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class ActivityFollowListener
{
/**
* Create the event listener.
*/
public function __construct()
{
//
}
/**
* Handle the event.
*/
public function handle(ActivityFollowEvent $event): void
{
if (TypeActivity::activity_exists ($event->activity["id"]))
return;
$actor = TypeActor::actor_exists_or_obtain ($event->activity ["actor"]);
$target = TypeActor::actor_get_local ($event->activity ["object"]);
if (!$target || !$target->user)
return;
// check follow doesn't exist
$follow_exists = Follow::where ("actor", $actor->id)
->where ("object", $target->id)
->first ();
if ($follow_exists)
return;
$event->activity ["activity_id"] = $event->activity ["id"];
$act = Activity::create ($event->activity);
UserFollowedEvent::dispatch ($act, $actor, $target);
// TODO: Users should be able to manually check this
$accept_activity = TypeActivity::craft_accept ($act);
TypeActivity::post_activity ($accept_activity, $target, $actor);
}
}

View File

@ -0,0 +1,57 @@
<?php
namespace App\Listeners\AP;
use App\Models\Note;
use App\Models\Activity;
use App\Types\TypeActivity;
use App\Types\TypeActor;
use App\Events\AP\ActivityLikeEvent;
use App\Events\NoteLikedEvent;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class ActivityLikeListener
{
/**
* Create the event listener.
*/
public function __construct()
{
//
}
/**
* Handle the event.
*/
public function handle(ActivityLikeEvent $event): void
{
$actor = TypeActor::actor_exists_or_obtain ($event->activity ["actor"]);
$note_id = $event->activity ["object"];
$note = Note::where ("note_id", $note_id)->first ();
if (!$note)
{
return;
}
// check like doesn't already exist
$like_exists = $actor->liked_note ($note);
if ($like_exists)
return;
$event->activity ["activity_id"] = $event->activity ["id"];
$activity_exists = TypeActivity::activity_exists ($event->activity ["id"]);
if (!$activity_exists)
$act = Activity::create ($event->activity);
else
$act = Activity::where ("activity_id", $event->activity ["id"])->first ();
NoteLikedEvent::dispatch ($act, $actor, $note);
return;
}
}

View File

@ -0,0 +1,58 @@
<?php
namespace App\Listeners\AP;
use App\Models\Activity;
use App\Models\Actor;
use App\Types\TypeActor;
use App\Types\TypeActivity;
use App\Events\AP\ActivityUndoEvent;
use App\Events\UserUnfollowedEvent;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class ActivityUndoListener
{
/**
* Create the event listener.
*/
public function __construct()
{
//
}
/**
* Handle the event.
*/
public function handle(ActivityUndoEvent $event): void
{
$actor = TypeActor::actor_exists_or_obtain ($event->activity ["actor"]);
$child_activity = $event->activity ["object"];
$child_activity_id = "";
if (is_array ($child_activity))
$child_activity_id = $child_activity ["id"];
else
$child_activity_id = $child_activity;
if (!TypeActivity::activity_exists ($child_activity_id))
return;
$child_activity = Activity::where ("activity_id", $child_activity_id)->first ();
$object = $child_activity;
switch ($object->type)
{
case "Follow":
$unfollowed_actor = Actor::where ("actor_id", $object->object)->first ();
UserUnfollowedEvent::dispatch ($object, $actor, $unfollowed_actor);
break;
}
$child_activity->delete ();
}
}

View File

@ -29,7 +29,7 @@
| |
<a href="#">Bulletins</a> <a href="#">Bulletins</a>
| |
<a href="#">Friends</a> <a href="{{ route ('users.friends', [ 'user_name' => auth ()->user ()->name ]) }}">Friends</a>
</p> </p>
<p> <p>
My URL: My URL: