now boosts are supported
This commit is contained in:
parent
c556441b4c
commit
6b9ec6531c
3
TODO.md
3
TODO.md
@ -50,4 +50,5 @@
|
||||
- [ ] Announcements
|
||||
|
||||
- [ ] Fixes
|
||||
- [ ] Fix that weird json encoding in the object field of an activity
|
||||
- [x] Fix that weird json encoding in the object field of an activity
|
||||
- [ ] The profile attachments are not working, they are not being federalised somehow (the interests thingy)
|
||||
|
33
app/Actions/ActionsActivity.php
Normal file
33
app/Actions/ActionsActivity.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions;
|
||||
|
||||
use App\Models\Activity;
|
||||
|
||||
use App\Types\TypeActor;
|
||||
use App\Types\TypeActivity;
|
||||
|
||||
class ActionsActivity
|
||||
{
|
||||
public static function activity_undo ($activity)
|
||||
{
|
||||
$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 ();
|
||||
$child_activity->delete ();
|
||||
|
||||
// TODO: Should Undo create a new activity in database?
|
||||
return ["success" => "Activity undone",];
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\AP;
|
||||
|
||||
use App\Actions\ActionsActivity;
|
||||
use App\Models\User;
|
||||
use App\Models\Actor;
|
||||
use App\Models\Activity;
|
||||
@ -87,24 +88,7 @@ class APInboxController extends Controller
|
||||
|
||||
public function handle_undo (User $user, $activity)
|
||||
{
|
||||
$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 response ()->json (["error" => "Child activity doesn't exist",], 404);
|
||||
|
||||
$child_activity = Activity::where ("activity_id", $child_activity_id)->first ();
|
||||
$child_activity->delete ();
|
||||
|
||||
// TODO: Should Undo create a new activity in database?
|
||||
return response ()->json (["success" => "Activity undone",], 200);
|
||||
return response ()->json (ActionsActivity::activity_undo ($activity));
|
||||
}
|
||||
|
||||
public function handle_like (User $user, $activity)
|
||||
|
@ -2,11 +2,13 @@
|
||||
|
||||
namespace App\Http\Controllers\AP;
|
||||
|
||||
use App\Actions\ActionsActivity;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use App\Models\Actor;
|
||||
use App\Models\Activity;
|
||||
use App\Models\Announcement;
|
||||
|
||||
use App\Types\TypeActor;
|
||||
use App\Types\TypeActivity;
|
||||
@ -26,6 +28,14 @@ class APInstanceInboxController extends Controller
|
||||
|
||||
switch ($activity_type)
|
||||
{
|
||||
case "Announce":
|
||||
return $this->handle_announce ($activity);
|
||||
break;
|
||||
|
||||
case "Undo":
|
||||
return $this->handle_undo ($activity);
|
||||
break;
|
||||
|
||||
case "Create":
|
||||
return $this->handle_create ($activity);
|
||||
break;
|
||||
@ -47,6 +57,41 @@ class APInstanceInboxController extends Controller
|
||||
return response ()->json (["status" => "ok"]);
|
||||
}
|
||||
|
||||
public function handle_announce ($activity)
|
||||
{
|
||||
// we suppose an announce is always a note
|
||||
$note_exists = TypeNote::note_exists ($activity ["object"]);
|
||||
if (!$note_exists)
|
||||
{
|
||||
$note_exists = TypeNote::obtain_external ($activity ["object"]);
|
||||
if (!$note_exists)
|
||||
return response ()->json (["status" => "error"]);
|
||||
}
|
||||
|
||||
$announcement_exists = TypeActivity::activity_exists ($activity ["id"]);
|
||||
if ($announcement_exists)
|
||||
return response ()->json (["status" => "ok"]);
|
||||
|
||||
$announcement_actor = TypeActor::actor_exists_or_obtain ($activity ["actor"]);
|
||||
if (!$announcement_actor)
|
||||
return response ()->json (["status" => "error"]);
|
||||
|
||||
$activity["activity_id"] = $activity["id"];
|
||||
$ann_act = Activity::create ($activity);
|
||||
$announcement = Announcement::create ([
|
||||
"activity_id" => $ann_act->id,
|
||||
"actor_id" => $announcement_actor->id,
|
||||
"note_id" => $note_exists->id
|
||||
]);
|
||||
|
||||
return response ()->json (["status" => "ok"]);
|
||||
}
|
||||
|
||||
public function handle_undo ($activity)
|
||||
{
|
||||
return response ()->json (ActionsActivity::activity_undo($activity));
|
||||
}
|
||||
|
||||
public function handle_create ($activity)
|
||||
{
|
||||
if (TypeActivity::activity_exists ($activity ["id"]))
|
||||
|
@ -53,9 +53,14 @@ class Actor extends Model
|
||||
return $this->belongsTo (User::class);
|
||||
}
|
||||
|
||||
public function posts ()
|
||||
public function get_posts ()
|
||||
{
|
||||
return $this->hasMany (Note::class, "actor_id")->orderBy ("created_at", "desc");
|
||||
$posts = $this->hasMany (Note::class, "actor_id")->orderBy ("created_at", "desc")->get ();
|
||||
$announcements = $this->hasMany (Announcement::class, "actor_id")->orderBy ("created_at", "desc")->get ();
|
||||
|
||||
$all = $posts->merge ($announcements)->sortByDesc ("created_at");
|
||||
|
||||
return $all;
|
||||
}
|
||||
|
||||
public function create_from_user (User $user)
|
||||
|
29
app/Models/Announcement.php
Normal file
29
app/Models/Announcement.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Announcement extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
"activity_id",
|
||||
"actor_id",
|
||||
"note_id"
|
||||
];
|
||||
|
||||
public function activity ()
|
||||
{
|
||||
return $this->belongsTo(Activity::class);
|
||||
}
|
||||
|
||||
public function actor ()
|
||||
{
|
||||
return $this->belongsTo(Actor::class);
|
||||
}
|
||||
|
||||
public function note ()
|
||||
{
|
||||
return $this->belongsTo(Note::class);
|
||||
}
|
||||
}
|
@ -148,7 +148,10 @@ class User extends Authenticatable
|
||||
}
|
||||
|
||||
$notes = Note::whereIn ("actor_id", $friends_id)->orderBy ("created_at", "desc")->get ();
|
||||
$announcements = Announcement::whereIn ("actor_id", $friends_id)->orderBy ("created_at", "desc")->get ();
|
||||
|
||||
return $notes;
|
||||
$feed = $notes->merge ($announcements)->sortByDesc ("created_at");
|
||||
|
||||
return $feed;
|
||||
}
|
||||
}
|
||||
|
@ -96,6 +96,9 @@ class TypeActor {
|
||||
"url" => $actor->image
|
||||
],
|
||||
|
||||
"published" => $actor->created_at,
|
||||
"updated" => $actor->updated_at,
|
||||
|
||||
"publicKey" => [
|
||||
"id" => $actor->actor_id . "#main-key",
|
||||
"owner" => $actor->actor_id,
|
||||
|
@ -8,6 +8,8 @@ use App\Models\Actor;
|
||||
use App\Models\Activity;
|
||||
use App\Models\NoteAttachment;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class TypeNote
|
||||
@ -78,13 +80,30 @@ class TypeNote
|
||||
return $note;
|
||||
}
|
||||
|
||||
public static function update_from_request (Note $note, $request, Activity $activity, Actor $actor)
|
||||
public static function update_from_request (Note $note, $request, Activity $activity = null, Actor $actor = null)
|
||||
{
|
||||
$note->activity_id = $activity->id;
|
||||
$note->actor_id = $actor->id;
|
||||
if ($activity)
|
||||
$note->activity_id = $activity->id;
|
||||
|
||||
if ($actor)
|
||||
$note->actor_id = $actor->id;
|
||||
else
|
||||
{
|
||||
$actor = TypeActor::actor_exists ($request ["attributedTo"]);
|
||||
if (!$actor)
|
||||
{
|
||||
$actor = TypeActor::obtain_actor_info($request ["attributedTo"]);
|
||||
if (!$actor)
|
||||
{
|
||||
Log::error ("TypeNote::update_from_request: Could not obtain actor info.");
|
||||
}
|
||||
}
|
||||
|
||||
$note->actor_id = $actor->id;
|
||||
}
|
||||
|
||||
$note->note_id = $request["id"] ?? null;
|
||||
$note->in_reply_to = $request["inReplyTo"] ?? null;
|
||||
// $note->in_reply_to = $request["inReplyTo"] ?? null;
|
||||
$note->summary = $request["summary"] ?? null;
|
||||
$note->url = $request["url"] ?? null;
|
||||
$note->attributedTo = $request["attributedTo"] ?? null;
|
||||
@ -116,6 +135,9 @@ class TypeNote
|
||||
{
|
||||
foreach ($request ["tag"] as $tag)
|
||||
{
|
||||
if ($tag ["type"] != "Hashtag")
|
||||
continue;
|
||||
|
||||
$tag_name = $tag ["name"];
|
||||
|
||||
$hashtag_exists = Hashtag::where ("name", $tag_name)->first ();
|
||||
@ -131,6 +153,17 @@ class TypeNote
|
||||
$note->get_hashtags ()->attach ($hashtag->id);
|
||||
}
|
||||
}
|
||||
|
||||
if ($request ["inReplyTo"])
|
||||
{
|
||||
$parent_exists = Note::where ("note_id", $request ["inReplyTo"])->first ();
|
||||
if (!$parent_exists)
|
||||
{
|
||||
$parent = TypeNote::obtain_external ($request ["inReplyTo"]);
|
||||
if ($parent)
|
||||
$note->in_reply_to = $parent->note_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function create_from_request ($request, Activity $activity, Actor $actor)
|
||||
@ -144,6 +177,36 @@ class TypeNote
|
||||
return $note;
|
||||
}
|
||||
|
||||
public static function obtain_external ($note_id)
|
||||
{
|
||||
$note = Note::where ("note_id", $note_id)->first ();
|
||||
if ($note)
|
||||
return $note;
|
||||
|
||||
try {
|
||||
$client = new Client ();
|
||||
$res = $client->request ("GET", $note_id, [
|
||||
"headers" => [
|
||||
"Accept" => "application/activity+json"
|
||||
]
|
||||
]);
|
||||
$body = $res->getBody ()->getContents ();
|
||||
|
||||
$note = Note::create ([
|
||||
"note_id" => $note_id
|
||||
]);
|
||||
TypeNote::update_from_request ($note, json_decode ($body, true));
|
||||
$note->save ();
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
Log::error ("TypeNote::obtain_external: " . $e->getMessage ());
|
||||
return null;
|
||||
}
|
||||
|
||||
return $note;
|
||||
}
|
||||
|
||||
// some little functions
|
||||
public static function note_exists ($note_id)
|
||||
{
|
||||
|
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('announcements', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId ("activity_id")->constrained ()->onDelete ('cascade');
|
||||
$table->foreignId ('actor_id')->constrained ()->onDelete ('cascade');
|
||||
$table->foreignId ("note_id")->constrained ()->onDelete ('cascade');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('announcements');
|
||||
}
|
||||
};
|
@ -46,7 +46,7 @@
|
||||
<table class="comments-table" cellspacing="0" cellpadding="3" bordercollor="#ffffff" border="1">
|
||||
<tbody>
|
||||
@foreach ($popular_notes as $post)
|
||||
<x-comment_block :post="$post" :actor="$post->get_actor ()->first ()" />
|
||||
<x-comment_block :post="$post" />
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -1,6 +1,14 @@
|
||||
@php
|
||||
$actor_url = "";
|
||||
|
||||
$display_post = null;
|
||||
if ($post instanceof App\Models\Note)
|
||||
$display_post = $post;
|
||||
else if ($post instanceof App\Models\Announcement)
|
||||
$display_post = $post->note ()->first ();
|
||||
|
||||
$actor = $display_post->get_actor ()->first ();
|
||||
|
||||
if ($actor->user_id)
|
||||
$actor_url = route ('users.show', [ 'user_name' => $actor->user->name ]);
|
||||
else
|
||||
@ -27,32 +35,32 @@ else
|
||||
<td>
|
||||
<p>
|
||||
<b>
|
||||
<time>{{ $post->created_at->diffForHumans () }}</time>
|
||||
<time>{{ $display_post->created_at->diffForHumans () }}</time>
|
||||
</b>
|
||||
</p>
|
||||
|
||||
@if ($post->in_reply_to)
|
||||
@if ($display_post->in_reply_to)
|
||||
<small>
|
||||
In response to
|
||||
<a href="{{ route ('posts.show', [ 'note' => $post->get_parent ()->first ()->id ]) }}">this post</a>
|
||||
<a href="{{ route ('posts.show', [ 'note' => $display_post->get_parent ()->first ()->id ]) }}">this post</a>
|
||||
</small>
|
||||
@endif
|
||||
|
||||
<h4>{{ $post->summary }}</h4>
|
||||
<h4>{{ $display_post->summary }}</h4>
|
||||
|
||||
{!! $post->content !!}
|
||||
{!! $display_post->content !!}
|
||||
|
||||
<p>
|
||||
@foreach ($post->attachments as $attachment)
|
||||
@foreach ($display_post->attachments as $attachment)
|
||||
<img loading="lazy" src="{{ $attachment->url }}" alt="{{ $attachment->name }}" width="100">
|
||||
@endforeach
|
||||
</p>
|
||||
|
||||
<br>
|
||||
|
||||
@if ($post->get_replies ()->count () > 0)
|
||||
@if ($display_post->get_replies ()->count () > 0)
|
||||
<div class="comment-replies">
|
||||
@foreach ($post->get_replies ()->get () as $reply)
|
||||
@foreach ($display_post->get_replies ()->get () as $reply)
|
||||
<div class="comment-reply">
|
||||
<h4>{{ $reply->summary }}</h4>
|
||||
|
||||
@ -79,7 +87,7 @@ else
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($post->get_hashtags ()->count () > 0)
|
||||
@if ($display_post->get_hashtags ()->count () > 0)
|
||||
<p>
|
||||
<b>Tags:</b>
|
||||
@foreach ($post->get_hashtags ()->get () as $hashtag)
|
||||
@ -93,13 +101,13 @@ else
|
||||
<hr>
|
||||
|
||||
<p>
|
||||
<b>Likes:</b> {{ $post->get_likes ()->count () }}
|
||||
<b>Likes:</b> {{ $display_post->get_likes ()->count () }}
|
||||
</p>
|
||||
<p>
|
||||
<b>Replies:</b> {{ $post->get_replies ()->count () }}
|
||||
<b>Replies:</b> {{ $display_post->get_replies ()->count () }}
|
||||
</p>
|
||||
|
||||
<a href="{{ route ('posts.show', [ 'note' => $post ]) }}">
|
||||
<a href="{{ route ('posts.show', [ 'note' => $display_post ]) }}">
|
||||
<button type="button">View</button>
|
||||
</a>
|
||||
{{-- @if ($actor->user && auth ()->check () && auth ()->user ()->is ($actor->user))
|
||||
|
@ -139,7 +139,7 @@
|
||||
<table class="comments-table" cellspacing="0" cellpadding="3" bordercollor="#ffffff" border="1">
|
||||
<tbody>
|
||||
@foreach (auth ()->user ()->feed () as $post)
|
||||
<x-comment_block :actor="$post->get_actor ()->first ()" :post="$post" />
|
||||
<x-comment_block :post="$post" />
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -100,7 +100,7 @@
|
||||
<table class="comments-table" cellspacing="0" cellpadding="3" bordercolor="ffffff" border="1">
|
||||
<tbody>
|
||||
@foreach ($note->get_replies ()->get () as $reply)
|
||||
<x-comment_block :actor="$reply->get_actor ()->first ()" :post="$reply" />
|
||||
<x-comment_block :post="$reply" />
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -303,7 +303,7 @@
|
||||
</div>
|
||||
<div class="inner">
|
||||
<p>
|
||||
<b>{{ $actor->name }} has <span class="count">{{ count ($actor->posts) }}</span> posts.</b>
|
||||
<b>{{ $actor->name }} has <span class="count">{{ count ($actor->get_posts ()) }}</span> posts.</b>
|
||||
</p>
|
||||
|
||||
@if (auth ()->user () && auth ()->user ()->is ($user))
|
||||
@ -314,8 +314,8 @@
|
||||
|
||||
<table class="comments-table" cellspacing="0" cellpadding="3" bordercollor="#ffffff" border="1">
|
||||
<tbody>
|
||||
@foreach ($actor->posts as $post)
|
||||
<x-comment_block :actor="$actor" :post="$post" />
|
||||
@foreach ($actor->get_posts () as $post)
|
||||
<x-comment_block :post="$post" />
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
|
Loading…
x
Reference in New Issue
Block a user