now showing external profiles as well
This commit is contained in:
parent
96a7c5fefa
commit
809980786f
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 ()
|
||||
|
@ -14,6 +14,7 @@ class Actor extends Model
|
||||
|
||||
"type",
|
||||
"actor_id",
|
||||
"local_actor_id",
|
||||
|
||||
"following",
|
||||
"followers",
|
||||
|
@ -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 ();
|
||||
|
@ -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 ();
|
||||
|
@ -15,7 +15,7 @@
|
||||
<div class="inner">
|
||||
@foreach ($latest_users as $user)
|
||||
<div class="person">
|
||||
<a href="{{ route ('users.show', [ 'user' => $user ]) }}">
|
||||
<a href="{{ route ('users.show', [ 'user_name' => $user ]) }}">
|
||||
<p>{{ $user->name }}</p>
|
||||
</a>
|
||||
<a href="#">
|
||||
|
@ -23,7 +23,7 @@
|
||||
<div class="more-options">
|
||||
<p>
|
||||
View My
|
||||
<a href="{{ route('users.show', ['user' => auth()->user()]) }}">Profile</a>
|
||||
<a href="{{ route('users.show', ['user_name' => auth()->user()->name]) }}">Profile</a>
|
||||
|
|
||||
<a href="#">Blog</a>
|
||||
|
|
||||
@ -34,7 +34,7 @@
|
||||
<p>
|
||||
My URL:
|
||||
<a
|
||||
href="{{ route('users.show', ['user' => auth()->user()]) }}">{{ route('users.show', ['user' => auth()->user()]) }}</a>
|
||||
href="{{ route('users.show', ['user_name' => auth()->user()->name]) }}">{{ route('users.show', ['user_name' => auth()->user()->name]) }}</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -42,7 +42,7 @@
|
||||
|
||||
<div class="url-info view-full-profile">
|
||||
<p>
|
||||
<a href="{{ route('users.show', ['user' => auth()->user()]) }}"><b>View Your Profile</b></a>
|
||||
<a href="{{ route('users.show', ['user_name' => auth()->user()->name]) }}"><b>View Your Profile</b></a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
</div>
|
||||
|
||||
<div class="center">
|
||||
<form action="#">
|
||||
<form action="{{ route('search') }}" method="get">
|
||||
<label>OurSpace</label>
|
||||
<input type="text" placeholder="Search OurSpace" name="query">
|
||||
<input type="submit" value="Search" class="submit-btn">
|
||||
@ -67,7 +67,7 @@
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#"> Source </a>
|
||||
<a href="https://github.com/0xd011f4ce/OurSpace"> Source </a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<div class="col right">
|
||||
<h1>Edit profile</h1>
|
||||
<p>All fields are optional and can be left empty</p>
|
||||
<a href="{{ route ('users.show', [ 'user' => $user ]) }}">« View Profile</a>
|
||||
<a href="{{ route ('users.show', [ 'user_name' => $user->name ]) }}">« View Profile</a>
|
||||
|
||||
<div class="profile-pic">
|
||||
<h1>{{ $user->name }}</h1>
|
||||
|
@ -1,41 +1,49 @@
|
||||
@extends ("partials.layout")
|
||||
|
||||
@section('title', "$user->name's Profile")
|
||||
@section('title', "$actor->preferredUsername's Profile")
|
||||
|
||||
@section('content')
|
||||
<div class="row profile">
|
||||
|
||||
<div class="col w-40 left">
|
||||
<span>
|
||||
<h1>{{ $user->name }}</h1>
|
||||
<h1>{{ $actor->preferredUsername }}</h1>
|
||||
</span>
|
||||
|
||||
<div class="general-about">
|
||||
|
||||
<div class="profile-pic">
|
||||
<img loading="lazy" src="{{ $user->avatar }}" alt="{{ $user->name }}'s pfp" class="pfp-fa" style="width: 235px; height: auto">
|
||||
@if ($user == null)
|
||||
<img loading="lazy" src="{{ $actor->icon }}" alt="{{ $actor->preferredUsername }}'s pfp" class="pfp-fa" style="width: 235px; height: auto">
|
||||
@else
|
||||
<img loading="lazy" src="{{ $user->avatar }}" alt="{{ $actor->preferredUsername }}'s pfp" class="pfp-fa" style="width: 235px; height: auto">
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="details">
|
||||
<p>{{ $user->status }}</p>
|
||||
<p>{{ $user->about_you }}</p>
|
||||
<p class="online">
|
||||
<img loading="lazy" src="/resources/img/green_person.png" alt="online"> ONLINE!
|
||||
</p>
|
||||
</div>
|
||||
@if ($user != null)
|
||||
<div class="details">
|
||||
<p>{{ $user->status }}</p>
|
||||
<p>{{ $user->about_you }}</p>
|
||||
<p class="online">
|
||||
<img loading="lazy" src="/resources/img/green_person.png" alt="online"> ONLINE!
|
||||
</p>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
||||
<audio src="#" id="music" autoplay loop controls></audio>
|
||||
|
||||
<div class="mood">
|
||||
<p><b>Mood:</b> {{ $user->mood }}</p>
|
||||
<p><b>View my: <a href="#">Blog</a> | <a href="#">Bulletins</a></b></p>
|
||||
@if ($user != null)
|
||||
<p><b>Mood:</b> {{ $user->mood }}</p>
|
||||
<p><b>View my: <a href="#">Blog</a> | <a href="#">Bulletins</a></b></p>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="contact">
|
||||
<div class="heading">
|
||||
<h4>Contacting {{ $user->name }}</h4>
|
||||
<h4>Contacting {{ $actor->preferredUsername }}</h4>
|
||||
</div>
|
||||
|
||||
<div class="inner">
|
||||
@ -101,80 +109,87 @@
|
||||
<p>
|
||||
<b>Federation handle:</b>
|
||||
</p>
|
||||
<p>@php echo "@" . $user->name . "@" . explode ("/", env ("APP_URL"))[2] @endphp</p>
|
||||
@if ($user != null)
|
||||
<p>@php echo "@" . $user->name . "@" . explode ("/", env ("APP_URL"))[2] @endphp</p>
|
||||
@else
|
||||
<p>{{ $actor->local_actor_id }}</p>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="table-section">
|
||||
<div class="heading">
|
||||
<h4>{{ $user->name }}'s Interests</h4>
|
||||
@if ($user != null)
|
||||
<div class="table-section">
|
||||
<div class="heading">
|
||||
<h4>{{ $user->name }}'s Interests</h4>
|
||||
</div>
|
||||
<div class="inner">
|
||||
<table class="details-table" cellspacing="3" cellpadding="3">
|
||||
<tbody>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<p>General</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>{{ $user->interests_general }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<p>Music</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>{{ $user->interests_music }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<p>Movies</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>{{ $user->interests_movies }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<p>Television</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>{{ $user->interests_television }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<p>Books</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>{{ $user->interests_books }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<p>Heroes</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>{{ $user->interests_heroes }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="inner">
|
||||
<table class="details-table" cellspacing="3" cellpadding="3">
|
||||
<tbody>
|
||||
@endif
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<p>General</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>{{ $user->interests_general }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<p>Music</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>{{ $user->interests_music }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<p>Movies</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>{{ $user->interests_movies }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<p>Television</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>{{ $user->interests_television }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<p>Books</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>{{ $user->interests_books }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<p>Heroes</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>{{ $user->interests_heroes }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col right">
|
||||
@auth
|
||||
@if (auth()->user()->is($user))
|
||||
@if ($user != null && auth()->user()->is($user))
|
||||
<div class="profile-info">
|
||||
<h3>
|
||||
<a href="{{ route ('users.edit') }}">Edit Your Profile</a>
|
||||
@ -183,6 +198,7 @@
|
||||
@endif
|
||||
@endauth
|
||||
|
||||
@if ($user != null)
|
||||
<div class="blog-preview">
|
||||
<h4>
|
||||
{{ $user->name }}'s Latest Blog Entries [<a href="#">View Blog</a>]
|
||||
@ -191,57 +207,62 @@
|
||||
<i>There are no Blog Entries yet.</i>
|
||||
</p>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="blurbs">
|
||||
<div class="heading">
|
||||
<h4>
|
||||
{{ $user->name }}'s Bio
|
||||
{{ $actor->preferredUsername }}'s Bio
|
||||
</h4>
|
||||
</div>
|
||||
<div class="inner">
|
||||
<div class="section">
|
||||
<p>{{ $user->bio }}</p>
|
||||
<p>{!! $actor->summary !!}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="friends">
|
||||
<div class="heading">
|
||||
<h4>
|
||||
{{ $user->name }}'s Friend Space
|
||||
</h4>
|
||||
<a href="#" class="more">[view all]</a>
|
||||
@if ($user != null)
|
||||
<div class="friends">
|
||||
<div class="heading">
|
||||
<h4>
|
||||
{{ $actor->preferredUsername }}'s Friend Space
|
||||
</h4>
|
||||
<a href="#" class="more">[view all]</a>
|
||||
</div>
|
||||
|
||||
<div class="inner">
|
||||
|
||||
<p>
|
||||
<b>
|
||||
{{ $actor->preferredUsername }} has <span class="count">{{ count ($user->mutual_friends ()) }}</span> friends.
|
||||
</b>
|
||||
</p>
|
||||
|
||||
<div class="friends-grid"></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="inner">
|
||||
|
||||
<p>
|
||||
<b>
|
||||
{{ $user->name }} has <span class="count">{{ count ($user->mutual_friends ()) }}</span> friends.
|
||||
</b>
|
||||
</p>
|
||||
|
||||
<div class="friends-grid"></div>
|
||||
@if ($user != null)
|
||||
<div id="comments" class="friends">
|
||||
<div class="heading">
|
||||
<h4>{{ $actor->preferredUsername }}'s Friends Comments</h4>
|
||||
</div>
|
||||
<div class="inner">
|
||||
<p>
|
||||
<b>
|
||||
Displaying <span class="count">0</span> of <span class="count">0</span> comments (<a href="#">View all</a> | <a href="#">Add Comment</a>)
|
||||
</b>
|
||||
</p>
|
||||
|
||||
<table class="comments-table" cellspacing="0" cellpadding="3" bordercollor="#ffffff" border="1">
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="comments" class="friends">
|
||||
<div class="heading">
|
||||
<h4>{{ $user->name }}'s Friends Comments</h4>
|
||||
</div>
|
||||
<div class="inner">
|
||||
<p>
|
||||
<b>
|
||||
Displaying <span class="count">0</span> of <span class="count">0</span> comments (<a href="#">View all</a> | <a href="#">Add Comment</a>)
|
||||
</b>
|
||||
</p>
|
||||
|
||||
<table class="comments-table" cellspacing="0" cellpadding="3" bordercollor="#ffffff" border="1">
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -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";
|
||||
|
Loading…
x
Reference in New Issue
Block a user