From 809980786f107ebe36409782399e67d0a2ba0da9 Mon Sep 17 00:00:00 2001 From: Ghostie Date: Sat, 28 Dec 2024 16:20:34 -0500 Subject: [PATCH] now showing external profiles as well --- README.md | 2 +- app/Http/Controllers/AP/APInboxController.php | 3 - app/Http/Controllers/HomeController.php | 25 ++ app/Http/Controllers/ProfileController.php | 19 +- app/Models/Actor.php | 1 + app/Types/TypeActor.php | 59 ++++- .../2024_12_27_002726_create_actors_table.php | 1 + resources/views/home.blade.php | 2 +- resources/views/home_loggedin.blade.php | 6 +- resources/views/partials/header.blade.php | 4 +- resources/views/users/edit.blade.php | 2 +- resources/views/users/profile.blade.php | 249 ++++++++++-------- routes/web.php | 6 +- 13 files changed, 243 insertions(+), 136 deletions(-) diff --git a/README.md b/README.md index eea5099..e6c54c0 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Notice that the styles were taken from [AnySpace](https://anyspace.3to.moe/about - [ ] Posts - [ ] Local posts should be federated - [ ] Remote posts should be fetched - - [ ] Follows + - [x] Follows - [ ] Likes - [ ] Comments diff --git a/app/Http/Controllers/AP/APInboxController.php b/app/Http/Controllers/AP/APInboxController.php index ab06aa3..b75605e 100644 --- a/app/Http/Controllers/AP/APInboxController.php +++ b/app/Http/Controllers/AP/APInboxController.php @@ -59,9 +59,6 @@ class APInboxController extends Controller "error" => "Error posting activity", ], 500); } - - $target->user->friends += 1; - $target->user->save (); } public function handle_undo (User $user, $activity) diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 71a17cb..5bab41e 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -2,6 +2,8 @@ namespace App\Http\Controllers; +use App\Types\TypeActor; + use App\Models\User; use Illuminate\Http\Request; @@ -13,4 +15,27 @@ class HomeController extends Controller return view ("home", compact ("latest_users")); } + + public function search () + { + $query = request ()->get ("query"); + + // check if the query is empty + if (empty ($query)) { + return redirect ()->route ("home"); + } + + // check if the search is a federated user + $user_handle = array_slice (explode ("@", $query), 1); + if (count ($user_handle) > 1) { + $username = $user_handle[0]; + $domain = $user_handle[1]; + + $actor = TypeActor::actor_exists_or_obtain_from_handle ($username, $domain); + if (!$actor) + return redirect ()->route ("home"); + + return redirect ()->route ("users.show", "@$actor->preferredUsername@$domain"); + } + } } diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index 02450c7..193bc02 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -9,12 +9,27 @@ use Intervention\Image\ImageManager; use Intervention\Image\Drivers\Gd\Driver; use App\Models\User; +use App\Models\Actor; class ProfileController extends Controller { - public function show (User $user) + public function show ($user_name) { - return view ("users.profile", compact ("user")); + $actor = null; + $user = null; + + if (str_starts_with ($user_name, "@")) { + $actor = Actor::where ("local_actor_id", $user_name)->first (); + } + else + { + $user = User::where ("name", $user_name)->first (); + if (!$user) + return redirect ()->route ("home"); + $actor = $user->actor; + } + + return view ("users.profile", compact ("actor", "user")); } public function edit () diff --git a/app/Models/Actor.php b/app/Models/Actor.php index 2db52c0..753d999 100644 --- a/app/Models/Actor.php +++ b/app/Models/Actor.php @@ -14,6 +14,7 @@ class Actor extends Model "type", "actor_id", + "local_actor_id", "following", "followers", diff --git a/app/Types/TypeActor.php b/app/Types/TypeActor.php index 085f0d4..f420980 100644 --- a/app/Types/TypeActor.php +++ b/app/Types/TypeActor.php @@ -111,6 +111,7 @@ class TypeActor { // Use null coalescing operator `??` for safety $actor->actor_id = $request['id'] ?? ''; + $actor->local_actor_id = TypeActor::actor_build_private_id ($actor->actor_id) ?? ''; $actor->type = $request['type'] ?? ''; $actor->following = $request['following'] ?? ''; @@ -141,25 +142,21 @@ class TypeActor { public static function obtain_actor_info ($actor_id) { - $client = new Client (); - $parsed_url = parse_url ($actor_id); $url_instance = $parsed_url["scheme"] . "://" . $parsed_url["host"]; $url_path = explode ("/", $parsed_url["path"]); $actor_name = end ($url_path); - $well_known_url = $url_instance . "/.well-known/webfinger?resource=acct:" . $actor_name . "@" . $parsed_url["host"]; - $res = $client->get ($well_known_url); + $well_known = TypeActor::query_wellknown ($actor_name, $parsed_url ["host"]); - $response = json_decode ($res->getBody ()->getContents ()); - - foreach ($response->links as $link) + foreach ($well_known->links as $link) { if ($link->rel == "self") { + $client = new Client (); $res = $client->request ("GET", $link->href, [ "headers" => [ - "Accept" => "application/activity+json" + "Accept" => "application/json" ] ]); $actor = json_decode ($res->getBody ()->getContents (), true); @@ -172,6 +169,25 @@ class TypeActor { return null; } + public static function query_wellknown ($name, $domain) + { + $client = new Client (); + + $well_known_url = "https://" . $domain . "/.well-known/webfinger?resource=acct:" . $name . "@" . $domain; + + try { + $res = $client->get ($well_known_url, [ + "headers" => [ + "Accept" => "application/json" + ] + ]); + } catch (\Exception $e) { + return json_encode (["error" => "Actor not found"]); + } + + return json_decode ($res->getBody ()->getContents ()); + } + // some little functions public static function actor_exists ($actor_id) { @@ -190,6 +206,33 @@ class TypeActor { return $actor; } + public static function actor_exists_or_obtain_from_handle ($name, $domain) + { + $well_known = TypeActor::query_wellknown ($name, $domain); + if (!$well_known) + return null; + + foreach ($well_known->links as $link) + { + if ($link->rel == "self") + { + return TypeActor::actor_exists_or_obtain ($link->href); + } + } + + return null; + } + + public static function actor_build_private_id ($actor_id) + { + $parsed_url = parse_url ($actor_id); + $split_path = explode ("/", $parsed_url ["path"]); + $username = end ($split_path); + $domain = $parsed_url ["host"]; + + return "@" . $username . "@" . $domain; + } + public static function actor_get_local ($actor_id) { $actor = Actor::where ("actor_id", $actor_id)->first (); diff --git a/database/migrations/2024_12_27_002726_create_actors_table.php b/database/migrations/2024_12_27_002726_create_actors_table.php index fcc5a62..ed6057d 100644 --- a/database/migrations/2024_12_27_002726_create_actors_table.php +++ b/database/migrations/2024_12_27_002726_create_actors_table.php @@ -18,6 +18,7 @@ return new class extends Migration $table->string ("type")->nullable (); $table->string ("actor_id")->unique (); + $table->string ("local_actor_id")->unique ()->nullable (); $table->string ("following")->nullable (); $table->string ("followers")->nullable (); diff --git a/resources/views/home.blade.php b/resources/views/home.blade.php index cb25c75..93aa8e3 100644 --- a/resources/views/home.blade.php +++ b/resources/views/home.blade.php @@ -15,7 +15,7 @@
@foreach ($latest_users as $user) @@ -42,7 +42,7 @@ diff --git a/resources/views/partials/header.blade.php b/resources/views/partials/header.blade.php index 461d0de..0a33975 100644 --- a/resources/views/partials/header.blade.php +++ b/resources/views/partials/header.blade.php @@ -12,7 +12,7 @@
-
+ @@ -67,7 +67,7 @@
  • -  Source +  Source
  • diff --git a/resources/views/users/edit.blade.php b/resources/views/users/edit.blade.php index 6beedb5..97c54df 100644 --- a/resources/views/users/edit.blade.php +++ b/resources/views/users/edit.blade.php @@ -9,7 +9,7 @@

    Edit profile

    All fields are optional and can be left empty

    - « View Profile + « View Profile

    {{ $user->name }}

    diff --git a/resources/views/users/profile.blade.php b/resources/views/users/profile.blade.php index c59e9da..ed33a6a 100644 --- a/resources/views/users/profile.blade.php +++ b/resources/views/users/profile.blade.php @@ -1,41 +1,49 @@ @extends ("partials.layout") -@section('title', "$user->name's Profile") +@section('title', "$actor->preferredUsername's Profile") @section('content')
    -

    {{ $user->name }}

    +

    {{ $actor->preferredUsername }}

    - {{ $user->name }}'s pfp + @if ($user == null) + {{ $actor->preferredUsername }}'s pfp + @else + {{ $actor->preferredUsername }}'s pfp + @endif
    -
    -

    {{ $user->status }}

    -

    {{ $user->about_you }}

    -

    - online ONLINE! -

    -
    + @if ($user != null) +
    +

    {{ $user->status }}

    +

    {{ $user->about_you }}

    +

    + online ONLINE! +

    +
    + @endif
    -

    Mood: {{ $user->mood }}

    -

    View my: Blog | Bulletins

    + @if ($user != null) +

    Mood: {{ $user->mood }}

    +

    View my: Blog | Bulletins

    + @endif
    -

    Contacting {{ $user->name }}

    +

    Contacting {{ $actor->preferredUsername }}

    @@ -101,80 +109,87 @@

    Federation handle:

    -

    @php echo "@" . $user->name . "@" . explode ("/", env ("APP_URL"))[2] @endphp

    + @if ($user != null) +

    @php echo "@" . $user->name . "@" . explode ("/", env ("APP_URL"))[2] @endphp

    + @else +

    {{ $actor->local_actor_id }}

    + @endif
    -
    -
    -

    {{ $user->name }}'s Interests

    + @if ($user != null) +
    +
    +

    {{ $user->name }}'s Interests

    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    General

    +
    +

    {{ $user->interests_general }}

    +
    +

    Music

    +
    +

    {{ $user->interests_music }}

    +
    +

    Movies

    +
    +

    {{ $user->interests_movies }}

    +
    +

    Television

    +
    +

    {{ $user->interests_television }}

    +
    +

    Books

    +
    +

    {{ $user->interests_books }}

    +
    +

    Heroes

    +
    +

    {{ $user->interests_heroes }}

    +
    +
    -
    - - + @endif - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -

    General

    -
    -

    {{ $user->interests_general }}

    -
    -

    Music

    -
    -

    {{ $user->interests_music }}

    -
    -

    Movies

    -
    -

    {{ $user->interests_movies }}

    -
    -

    Television

    -
    -

    {{ $user->interests_television }}

    -
    -

    Books

    -
    -

    {{ $user->interests_books }}

    -
    -

    Heroes

    -
    -

    {{ $user->interests_heroes }}

    -
    -
    -
    @auth - @if (auth()->user()->is($user)) + @if ($user != null && auth()->user()->is($user))

    Edit Your Profile @@ -183,6 +198,7 @@ @endif @endauth + @if ($user != null)

    {{ $user->name }}'s Latest Blog Entries [View Blog] @@ -191,57 +207,62 @@ There are no Blog Entries yet.

    + @endif

    - {{ $user->name }}'s Bio + {{ $actor->preferredUsername }}'s Bio

    -

    {{ $user->bio }}

    +

    {!! $actor->summary !!}

    -
    -
    -

    - {{ $user->name }}'s Friend Space -

    - [view all] + @if ($user != null) +
    +
    +

    + {{ $actor->preferredUsername }}'s Friend Space +

    + [view all] +
    + +
    + +

    + + {{ $actor->preferredUsername }} has {{ count ($user->mutual_friends ()) }} friends. + +

    + +
    + +
    + @endif -
    - -

    - - {{ $user->name }} has {{ count ($user->mutual_friends ()) }} friends. - -

    - -
    + @if ($user != null) +
    +
    +

    {{ $actor->preferredUsername }}'s Friends Comments

    +
    +
    +

    + + Displaying 0 of 0 comments (View all | Add Comment) + +

    + + +
    +
    -
    - -
    -
    -

    {{ $user->name }}'s Friends Comments

    -
    -
    -

    - - Displaying 0 of 0 comments (View all | Add Comment) - -

    - - - -
    -
    -
    + @endif
    diff --git a/routes/web.php b/routes/web.php index fe108fd..c514d01 100644 --- a/routes/web.php +++ b/routes/web.php @@ -15,8 +15,12 @@ Route::get ("/auth/logout", [ UserController::class, "logout" ])->name ("logout" Route::post ("/auth/signup", [ UserController::class, "do_signup" ])->middleware ("guest"); Route::post ("/auth/login", [ UserController::class, "do_login" ])->middleware ("guest"); +// user routes Route::get ("/user/edit", [ ProfileController::class, "edit" ])->name ("users.edit")->middleware ("auth"); Route::post ("/user/edit", [ ProfileController::class, "update" ])->middleware ("auth"); -Route::get ("/user/{user:name}", [ ProfileController::class, "show" ])->name ("users.show"); +Route::get ("/user/{user_name}", [ ProfileController::class, "show" ])->name ("users.show"); + +// other routes +Route::get ("/search", [ HomeController::class, "search" ])->name ("search"); require __DIR__ . "/api.php";