now local users can post as well
This commit is contained in:
parent
66da68f5c8
commit
dcfa475a01
64
app/Actions/ActionsPost.php
Normal file
64
app/Actions/ActionsPost.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
use App\Models\Actor;
|
||||
use App\Models\Activity;
|
||||
use App\Models\Note;
|
||||
use App\Models\NoteAttachment;
|
||||
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
use Intervention\Image\ImageManager;
|
||||
use Intervention\Image\Drivers\Gd\Driver;
|
||||
|
||||
class ActionsPost
|
||||
{
|
||||
public static function post_new ($request)
|
||||
{
|
||||
if (!auth ()->check ())
|
||||
return ["error" => "You must be logged in to post."];
|
||||
|
||||
$processed_content = Str::markdown ($request->get ("content"));
|
||||
$attachments = [];
|
||||
|
||||
if ($request->hasFile ("files"))
|
||||
{
|
||||
$files = $request->file ("files");
|
||||
|
||||
foreach ($files as $file)
|
||||
{
|
||||
$manager = new ImageManager (new Driver ());
|
||||
$image = $manager->read ($file);
|
||||
$image_data = $image->toJpeg ();
|
||||
|
||||
$fname = $file->hashName () . uniqid () . ".jpg";
|
||||
Storage::disk ("public")->put ("images/" . $fname, $image_data);
|
||||
$attachments[] = env ("APP_URL") . "/storage/images/" . $fname;
|
||||
}
|
||||
}
|
||||
|
||||
$actor = auth ()->user ()->actor ()->first ();
|
||||
|
||||
try {
|
||||
$client = new Client ();
|
||||
$response = $client->post ($actor->outbox, [
|
||||
"json" => [
|
||||
"type" => "Post",
|
||||
"content" => $processed_content,
|
||||
"attachments" => $attachments,
|
||||
]
|
||||
]);
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
return ["error" => "Could not connect to server."];
|
||||
}
|
||||
|
||||
return ["success" => "Post created"];
|
||||
}
|
||||
}
|
@ -69,10 +69,17 @@ class APInboxController extends Controller
|
||||
$actor = TypeActor::actor_exists_or_obtain ($activity ["actor"]);
|
||||
|
||||
$child_activity = $activity ["object"];
|
||||
if (!TypeActivity::activity_exists ($child_activity ["id"]))
|
||||
$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 not found",], 404);
|
||||
|
||||
$child_activity = Activity::where ("activity_id", $child_activity ["id"])->first ();
|
||||
$child_activity = Activity::where ("activity_id", $child_activity_id)->first ();
|
||||
$child_activity->delete ();
|
||||
|
||||
// TODO: Should Undo create a new activity in database?
|
||||
|
@ -41,6 +41,9 @@ class APInstanceInboxController extends Controller
|
||||
break;
|
||||
}
|
||||
|
||||
Log::info ("APInstanceInboxController:inbox");
|
||||
Log::info ($activity);
|
||||
|
||||
return response ()->json (["status" => "ok"]);
|
||||
}
|
||||
|
||||
|
@ -6,9 +6,12 @@ use App\Models\User;
|
||||
use App\Models\Actor;
|
||||
use App\Models\Activity;
|
||||
use App\Models\Instance;
|
||||
use App\Models\Note;
|
||||
use App\Models\NoteAttachment;
|
||||
|
||||
use App\Types\TypeActivity;
|
||||
use App\Types\TypeActor;
|
||||
use App\Types\TypeNote;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
@ -33,6 +36,10 @@ class APOutboxController extends Controller
|
||||
return $this->handle_unfollow ($user, $request->get ("object"));
|
||||
break;
|
||||
|
||||
case "Post":
|
||||
return $this->handle_post ($user, $request);
|
||||
break;
|
||||
|
||||
default:
|
||||
Log::info ("APOutboxController@index");
|
||||
Log::info (json_encode (request ()->all ()));
|
||||
@ -109,4 +116,35 @@ class APOutboxController extends Controller
|
||||
"success" => "unfollowed"
|
||||
];
|
||||
}
|
||||
|
||||
public function handle_post (User $user, $request)
|
||||
{
|
||||
$actor = $user->actor ()->first ();
|
||||
$note = TypeNote::craft_from_outbox ($actor, $request);
|
||||
|
||||
if (isset ($request ["attachments"]))
|
||||
{
|
||||
foreach ($request ["attachments"] as $attachment)
|
||||
{
|
||||
$attachment_note = NoteAttachment::create ([
|
||||
"note_id" => $note->id,
|
||||
"url" => $attachment
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$create_activity = TypeActivity::craft_create ($actor, $note);
|
||||
|
||||
$note->activity_id = $create_activity->id;
|
||||
$note->save ();
|
||||
|
||||
$instances = Instance::all ();
|
||||
|
||||
foreach ($instances as $instance)
|
||||
{
|
||||
$response = TypeActivity::post_activity ($create_activity, $actor, $instance->inbox);
|
||||
if ($response->getStatusCode () < 200 || $response->getStatusCode () >= 300)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ namespace App\Http\Controllers;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
use App\Actions\ActionsFriends;
|
||||
use App\Actions\ActionsPost;
|
||||
|
||||
class UserActionController extends Controller
|
||||
{
|
||||
@ -25,4 +26,18 @@ class UserActionController extends Controller
|
||||
|
||||
return back ()->with ("success", $response ["success"]);
|
||||
}
|
||||
|
||||
public function post_new (Request $request)
|
||||
{
|
||||
$request->validate ([
|
||||
"content" => "required",
|
||||
"files.*" => "mimes:jpeg,png,jpg,gif,webm|max:4096"
|
||||
]);
|
||||
|
||||
$response = ActionsPost::post_new ($request);
|
||||
if (isset ($response ["error"]))
|
||||
return back ()->with ("error", $response ["error"]);
|
||||
|
||||
return back ()->with ("success", $response ["success"]);
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ class Note extends Model
|
||||
"url",
|
||||
"attributedTo",
|
||||
"content",
|
||||
"tags",
|
||||
"tag",
|
||||
];
|
||||
|
||||
public function get_activity ()
|
||||
|
@ -81,6 +81,25 @@ class TypeActivity {
|
||||
return $update_activity;
|
||||
}
|
||||
|
||||
public static function craft_create (Actor $actor, $fields)
|
||||
{
|
||||
$create_activity = new Activity ();
|
||||
$create_activity->activity_id = env ("APP_URL") . "/activity/" . uniqid ();
|
||||
$create_activity->type = "Create";
|
||||
$create_activity->actor = $actor->actor_id;
|
||||
|
||||
switch ($fields ["type"])
|
||||
{
|
||||
case "Note":
|
||||
$create_activity->object = TypeNote::build_response ($fields);
|
||||
break;
|
||||
}
|
||||
|
||||
$create_activity->save ();
|
||||
|
||||
return $create_activity;
|
||||
}
|
||||
|
||||
public static function craft_signed_headers ($activity, Actor $source, $target)
|
||||
{
|
||||
if (!$source->user)
|
||||
|
@ -103,6 +103,42 @@ class TypeActor {
|
||||
]
|
||||
];
|
||||
|
||||
if ($actor->user)
|
||||
{
|
||||
$response ["attachment"] = [
|
||||
[
|
||||
"type" => "PropertyValue",
|
||||
"name" => "Interests General",
|
||||
"value" => $actor->user->interests_general
|
||||
],
|
||||
[
|
||||
"type" => "PropertyValue",
|
||||
"name" => "Interests Music",
|
||||
"value" => $actor->user->interests_music
|
||||
],
|
||||
[
|
||||
"type" => "PropertyValue",
|
||||
"name" => "Interests Movies",
|
||||
"value" => $actor->user->interests_movies
|
||||
],
|
||||
[
|
||||
"type" => "PropertyValue",
|
||||
"name" => "Interests Television",
|
||||
"value" => $actor->user->interests_television
|
||||
],
|
||||
[
|
||||
"type" => "PropertyValue",
|
||||
"name" => "Interests Books",
|
||||
"value" => $actor->user->interests_books
|
||||
],
|
||||
[
|
||||
"type" => "PropertyValue",
|
||||
"name" => "Interests Heroes",
|
||||
"value" => $actor->user->interests_heroes
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,58 @@ use Illuminate\Support\Facades\Log;
|
||||
|
||||
class TypeNote
|
||||
{
|
||||
public static function build_response (Note $note)
|
||||
{
|
||||
$author = $note->get_actor ()->first ();
|
||||
|
||||
$response = [
|
||||
"id" => $note->note_id,
|
||||
"type" => "Note",
|
||||
"summary" => $note->summary,
|
||||
"inReplyTo" => $note->in_reply_to,
|
||||
"published" => $note->created_at,
|
||||
"url" => $note->url,
|
||||
"attributedTo" => $note->attributedTo,
|
||||
"to" => [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"cc" => [
|
||||
$author->following
|
||||
],
|
||||
"content" => $note->content
|
||||
];
|
||||
|
||||
$attachments = $note->attachments ()->get ();
|
||||
foreach ($attachments as $attachment)
|
||||
{
|
||||
$response ["attachment"] [] = [
|
||||
"type" => "Document",
|
||||
"mediaType" => "image/jpeg",
|
||||
"url" => $attachment->url
|
||||
];
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public static function craft_from_outbox (Actor $actor, $request)
|
||||
{
|
||||
// TODO: url should be route ('posts.show', $note->id)
|
||||
$note = Note::create ([
|
||||
"actor_id" => $actor->id,
|
||||
"note_id" => env ("APP_URL") . "/ap/v1/note/" . uniqid (),
|
||||
"in_reply_to" => $request ["inReplyTo"] ?? null,
|
||||
"type" => "Note",
|
||||
"summary" => $request ["summary"] ?? null,
|
||||
"url" => "TODO",
|
||||
"attributedTo" => $actor->actor_id,
|
||||
"content" => $request ["content"] ?? null,
|
||||
"tag" => $request ["tag"] ?? null
|
||||
]);
|
||||
|
||||
return $note;
|
||||
}
|
||||
|
||||
public static function update_from_request (Note $note, $request, Activity $activity, Actor $actor)
|
||||
{
|
||||
$note->activity_id = $activity->id;
|
||||
|
@ -1,11 +1,20 @@
|
||||
@php
|
||||
$actor_url = "";
|
||||
|
||||
if ($actor->user_id)
|
||||
$actor_url = route ('users.show', [ 'user_name' => $actor->user->name ]);
|
||||
else
|
||||
$actor_url = route ('users.show', [ 'user_name' => $actor->local_actor_id ]);
|
||||
@endphp
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{ route ('users.show', [ 'user_name' => $actor->local_actor_id ]) }}">
|
||||
<a href="{{ $actor_url }}">
|
||||
<p>
|
||||
<b>{{ $actor->name }}</b>
|
||||
</p>
|
||||
</a>
|
||||
<a href="{{ route ('users.show', [ 'user_name' => $actor->local_actor_id ]) }}">
|
||||
<a href="{{ $actor_url }}">
|
||||
<p>
|
||||
@if ($actor->user)
|
||||
<img loading="lazy" src="{{ $actor->user->avatar }}" class="pfp-fallback" width="50">
|
||||
|
@ -274,6 +274,26 @@
|
||||
<b>{{ $actor->preferredUsername }} has <span class="count">{{ count ($actor->posts) }}</span> posts.</b>
|
||||
</p>
|
||||
|
||||
@if (auth ()->user () && auth ()->user ()->is ($user))
|
||||
<form action="{{ route ('user.post.new') }}" method="post" enctype="multipart/form-data">
|
||||
@csrf
|
||||
<textarea name="content" placeholder="What's on your mind?" cols="60" rows="5"></textarea>
|
||||
<input type="file" name="files[]" accept="image/*" multiple>
|
||||
<button type="submit">Post</button>
|
||||
<small>Markdown is supported</small>
|
||||
|
||||
@error ("content")
|
||||
<div class="error">{{ $message }}</div>
|
||||
@enderror
|
||||
|
||||
@error ("files.*")
|
||||
<div class="error">{{ $message }}</div>
|
||||
@enderror
|
||||
</form>
|
||||
@endif
|
||||
|
||||
<br>
|
||||
|
||||
<table class="comments-table" cellspacing="0" cellpadding="3" bordercollor="#ffffff" border="1">
|
||||
<tbody>
|
||||
@foreach ($actor->posts as $post)
|
||||
|
@ -19,6 +19,7 @@ Route::post ("/auth/login", [ UserController::class, "do_login" ])->middleware (
|
||||
// user actions
|
||||
Route::post ("/user/action/friend", [ UserActionController::class, "friend" ])->name ("user.friend")->middleware ("auth");
|
||||
Route::post ("/user/action/unfriend", [ UserActionController::class, "unfriend" ])->name ("user.unfriend")->middleware ("auth");
|
||||
Route::post ("/user/action/post/new", [ UserActionController::class, "post_new" ])->name ("user.post.new")->middleware ("auth");
|
||||
|
||||
// user routes
|
||||
Route::get ("/user/edit", [ ProfileController::class, "edit" ])->name ("users.edit")->middleware ("auth");
|
||||
|
Loading…
x
Reference in New Issue
Block a user