now posts can be boosted locally

This commit is contained in:
Ghostie 2025-01-06 21:45:01 -05:00
parent 132696b330
commit 61b272625b
11 changed files with 122 additions and 10 deletions

View File

@ -14,10 +14,14 @@
- [x] Likes
- [x] Comments
- [x] Boosts
- [ ] Local Boost
- [x] Local Boost
- [x] Tags
- [ ] Mentions
- [ ] Local mentions
- [ ] Private post
- [ ] Pinned Posts
- [ ] Nodeinfo
- [ ] Notifications
- [-] Social features
- [x] Profile
@ -37,7 +41,7 @@
- [x] Delete posts
- [x] Like posts
- [x] Comment posts
- [ ] Boost posts
- [x] Boost posts
- [x] Post tags
- [ ] Blog
- [ ] Bulletin

View File

@ -127,4 +127,25 @@ class ActionsPost
return $response;
}
public static function boost_post (Actor $actor, Note $note)
{
$client = new Client ();
try
{
$response = $client->post ($actor->outbox, [
"json" => [
"type" => "Boost",
"object" => $note->note_id,
]
]);
}
catch (\Exception $e)
{
return ["error" => "Could not connect to server: " . $e->getMessage ()];
}
return $response;
}
}

View File

@ -4,6 +4,7 @@ namespace App\Http\Controllers\AP;
use App\Models\Note;
use App\Models\NoteAttachment;
use App\Models\Announcement;
use App\Models\User;
use App\Models\Actor;
use App\Models\Activity;
@ -55,6 +56,10 @@ class APOutboxController extends Controller
return $this->handle_like ($user, $request->get ("object"));
break;
case "Boost":
return $this->handle_boost ($user, $request->get ("object"));
break;
case "Post":
return $this->handle_post ($user, $request);
break;
@ -250,6 +255,46 @@ class APOutboxController extends Controller
];
}
public function handle_boost (User $user, $object)
{
$object = Note::where ("note_id", $object)->first ();
if (!$object)
return response ()->json ([ "error" => "object not found" ], 404);
$actor = $user->actor ()->first ();
$already_boosted = $actor->boosted_note ($object);
if ($already_boosted)
{
$boost_activity = $already_boosted->activity;
$undo_activity = TypeActivity::craft_undo ($boost_activity, $actor);
$response = TypeActivity::post_to_instances ($undo_activity, $actor);
$boost_exists = Announcement::where ("note_id", $object->id)
->where ("actor_id", $actor->id)
->first ();
if ($boost_exists)
$boost_exists->delete ();
return [
"success" => "unboosted"
];
}
$boost_activity = TypeActivity::craft_announce ($actor, $object->note_id);
$announcement = Announcement::create ([
"activity_id" => $boost_activity->id,
"actor_id" => $actor->id,
"note_id" => $object->id,
]);
$response = TypeActivity::post_to_instances ($boost_activity, $actor);
return [
"success" => "boosted"
];
}
public function handle_post (User $user, $request)
{
$actor = $user->actor ()->first ();

View File

@ -93,12 +93,12 @@ class HomeController extends Controller
}
}
$local_users = User::where ("name", "like", "%$query%")->get ();
$actors = Actor::where ("name", "like", "%$query%")->orWhere ("preferredUsername", "like", "%$query%")->get ();
$local_users = User::where ("name", "like", "%$query%")->orderBy ("created_at", "desc")->get ();
$actors = Actor::where ("name", "like", "%$query%")->orWhere ("preferredUsername", "like", "%$query%")->orderBy ("created_at", "desc")->get ();
$users = $local_users->merge ($actors)->take (10);
$hashtags = Hashtag::withCount ("get_notes")->where ("name", "like", "%$query%")->orderBy ("get_notes_count", "desc")->take (16)->get ()->shuffle ();
$posts = Note::where ("content", "like", "%$query%")->paginate (10);
$posts = Note::where ("content", "like", "%$query%")->orderBy ("created_at", "desc")->paginate (10);
return view ("search", compact ("users", "hashtags", "posts"));
}

View File

@ -83,6 +83,19 @@ class PostController extends Controller
return back ()->with ("success", "Post liked successfully.");
}
public function boost (Note $note)
{
if (!auth ()->check ())
return back ()->with ("error", "You need to be logged in to boost a post.");
$user = auth ()->user ();
$actor = $user->actor ()->first ();
$response = ActionsPost::boost_post ($actor, $note);
return back ()->with ("success", "Post boosted successfully.");
}
public function delete (Note $note)
{
$actor = auth ()->user ()->actor ()->first ();

View File

@ -3,7 +3,7 @@
namespace App\Models;
use App\Models\User;
use App\Models\Activity;
use App\Models\Announcement;
use App\Models\Note;
use App\Types\TypeActor;
@ -86,4 +86,9 @@ class Actor extends Model
{
return Like::where ("actor_id", $this->id)->where ("note_id", $note->id)->first ();
}
public function boosted_note (Note $note)
{
return Announcement::where ("actor_id", $this->id)->where ("note_id", $note->id)->first ();
}
}

View File

@ -36,6 +36,11 @@ class Note extends Model
return $this->hasMany (Like::class);
}
public function get_boosts ()
{
return $this->hasMany (Announcement::class);
}
public function get_replies ()
{
return $this->hasMany (Note::class, "in_reply_to", "note_id");

View File

@ -133,6 +133,18 @@ class TypeActivity {
return $like_activity;
}
public static function craft_announce (Actor $actor, $id)
{
$announce_activity = new Activity ();
$announce_activity->activity_id = env ("APP_URL") . "/activity/" . uniqid ();
$announce_activity->type = "Announce";
$announce_activity->actor = $actor->actor_id;
$announce_activity->object = $id;
$announce_activity->save ();
return $announce_activity;
}
public static function get_private_key (Actor $actor)
{
return openssl_get_privatekey ($actor->private_key);

View File

@ -118,7 +118,7 @@ class TypeNote
foreach ($attachments as $attachment)
$attachment->delete ();
if ($request ["attachment"])
if (isset ($request ["attachment"]) && $request ["attachment"])
{
foreach ($request ["attachment"] as $attachment)
@ -135,7 +135,7 @@ class TypeNote
}
}
if ($request ["tag"])
if (isset ($request ["tag"]) && $request ["tag"])
{
foreach ($request ["tag"] as $tag)
{

View File

@ -70,16 +70,22 @@
<br>
@auth
<div class="buttons">
<div class="buttons" style="display: flex; gap: 10px;">
<form action="{{ route ('posts.like', [ 'note' => $note->id ]) }}" method="POST">
@csrf
<button type="submit">{{ auth ()->user ()->actor ()->first ()->liked_note ($note) ? "Undo Like" : "Like" }}</button>
</form>
<form action="{{ route ('posts.boost', [ 'note' => $note->id ]) }}" method="POST">
@csrf
<button type="submit">{{ auth ()->user ()->actor ()->first ()->boosted_note ($note) ? "Unboost" : "Boost" }}</button>
</form>
</div>
@endauth
<p>
<b>Likes</b>: {{ $note->get_likes ()->count () }}
<b>Likes</b>: {{ $note->get_likes ()->count () }}<br>
<b>Boosts</b>: {{ $note->get_boosts ()->count () }}
</p>
<div class="comments" id="comments">

View File

@ -33,6 +33,7 @@ Route::middleware ("update_online")->group (function () {
Route::get ("/post/{note}/edit", [ PostController::class, "edit" ])->name ("posts.edit")->middleware ("auth");
Route::post ("/post/{note}/edit", [ PostController::class, "update" ])->middleware ("auth");
Route::post ("/post/{note}/like", [ PostController::class, "like" ])->name ("posts.like")->middleware ("auth");
Route::post ("/post/{note}/boost", [ PostController::class, "boost" ])->name ("posts.boost")->middleware ("auth");
Route::get ("/post/{note}", [ PostController::class, "show" ])->name ("posts.show");
Route::delete ("/post/{note}", [ PostController::class, "delete" ])->name ("posts.delete")->middleware ("auth");