Improved browse and added the search page

This commit is contained in:
Ghostie 2025-01-06 20:53:27 -05:00
parent ccdf7d9b29
commit 44385282e8
10 changed files with 227 additions and 2514 deletions

View File

@ -59,3 +59,4 @@
- [x] Use jobs when posting activities - [x] Use jobs when posting activities
- [ ] Sign the get activities for mastodon when secure mode is enable - [ ] Sign the get activities for mastodon when secure mode is enable
- [x] Set a minimum font size for the tags cloud - [x] Set a minimum font size for the tags cloud
- [ ] Pagination, pagination, AND MORE PAGINATION

View File

@ -25,13 +25,31 @@ class HomeController extends Controller
public function browse () public function browse ()
{ {
$latest_users = User::latest ()->take (8)->get (); $users = [];
$popular_hashtags = Hashtag::withCount ("get_notes")->orderBy ("get_notes_count", "desc")->take (16)->get ()->shuffle (); $notes = [];
$popular_notes = Note::withCount ([ "get_likes" => function ($query) { if (request ()->get ("users") == "all")
$query->where ("created_at", ">=", now ()->subDay ()); {
}])->where ("in_reply_to", null)->orderBy ("get_likes_count", "desc")->take (8)->get (); $users = Actor::latest ()->take (8)->get ();
}
else
{
$users = User::latest ()->take (8)->get ();
}
return view ("browse", compact ("latest_users", "popular_hashtags", "popular_notes")); $popular_hashtags = Hashtag::withCount ("get_notes")->orderBy ("get_notes_count", "desc")->take (16)->get ()->shuffle ();
if (request ()->get ("posts") == "latest")
{
$notes = Note::latest ()->where ("in_reply_to", null)->take (8)->get ();
}
else
{
$notes = Note::withCount ([ "get_likes" => function ($query) {
$query->where ("created_at", ">=", now ()->subDay ());
}])->where ("in_reply_to", null)->orderBy ("get_likes_count", "desc")->take (8)->get ();
}
return view ("browse", compact ("users", "popular_hashtags", "notes"));
} }
public function tag ($tag) public function tag ($tag)
@ -44,22 +62,45 @@ class HomeController extends Controller
$query = request ()->get ("query"); $query = request ()->get ("query");
// check if the query is empty // check if the query is empty
if (empty ($query)) { if ($query == null) {
return redirect ()->route ("home"); return view ("search");
} }
// check if the search is a federated user // check if the search is a federated user
$user_handle = array_slice (explode ("@", $query), 1); $user_handle = array_slice (explode ("@", $query), 1);
if (count ($user_handle) > 1) { $at_count = count ($user_handle);
$username = $user_handle[0]; if ($at_count >= 1) {
$domain = $user_handle[1]; switch ($at_count)
{
case 1:
$user = User::where ("name", $user_handle[0])->first ();
if (!$user)
break;
$actor = TypeActor::actor_exists_or_obtain_from_handle ($username, $domain); return redirect ()->route ("users.show", $user->name);
if (!$actor) break;
return redirect ()->route ("home");
return redirect ()->route ("users.show", "@$username@$domain"); case 2:
$username = $user_handle[0];
$domain = $user_handle[1];
$actor = TypeActor::actor_exists_or_obtain_from_handle ($username, $domain);
if (!$actor)
break;
return redirect ()->route ("users.show", "@$username@$domain");
break;
}
} }
$local_users = User::where ("name", "like", "%$query%")->get ();
$actors = Actor::where ("name", "like", "%$query%")->orWhere ("preferredUsername", "like", "%$query%")->get ();
$users = $local_users->merge ($actors);
$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);
return view ("search", compact ("users", "hashtags", "posts"));
} }
public function requests () public function requests ()

View File

@ -1,5 +1,4 @@
@import url("./base.css"); @import url("./base.css");
@import url("./header.css"); @import url("./header.css");
@import url("./my.css");
@import url("./normalize.min.css"); @import url("./normalize.min.css");
@import url("./style.css"); @import url("./style.css");

File diff suppressed because it is too large Load Diff

View File

@ -1506,16 +1506,6 @@ table.forum-table,
vertical-align: 2px; vertical-align: 2px;
} }
.pagination {
width: 100%;
margin: 15px 0 5px 0;
min-height: 20px;
}
.pagination .next {
float: right;
}
.blog-entries .entry { .blog-entries .entry {
background: #BFDBFE; background: #BFDBFE;
background: var(--even-lighter-blue); background: var(--even-lighter-blue);
@ -3747,3 +3737,53 @@ ul.cloud a {
text-decoration: none; text-decoration: none;
position: relative; position: relative;
} }
.pagination {
display: flex;
justify-content: center;
padding: 1rem 0;
list-style: none;
margin: 0;
font-family: "Arial", sans-serif;
font-size: 0.9rem;
}
.pagination li {
margin: 0 5px;
}
.pagination {
display: flex;
justify-content: center;
padding: 1rem 0;
list-style: none;
margin: 0;
font-family: "Arial", sans-serif;
font-size: 0.9rem;
}
.pagination li {
margin: 0 5px;
}
.pagination li a,
.pagination li span {
color: #1e90ff; /* Light blue for links */
text-decoration: none;
transition: color 0.3s;
}
.pagination li a:hover {
color: #0056b3; /* Darker blue on hover */
}
.pagination li.active span {
font-weight: bold;
color: #0056b3; /* Darker blue for the active link */
cursor: default;
}
.pagination li.disabled span {
color: #99c3e0; /* Muted blue for disabled links */
cursor: not-allowed;
}

View File

@ -6,6 +6,13 @@
<div class="simple-container"> <div class="simple-container">
<h1>Browse Users</h1> <h1>Browse Users</h1>
<p>
Filter:
<a @if(request ()->get("users") == null) class="filter-active" @endif href="?users=">Local</a>
|
<a @if(request ()->get("users") == "all") class="filter-active" @endif href="?users=all">All</a>
</p>
<div class="new-people"> <div class="new-people">
<div class="top"> <div class="top">
<h4>Active Users</h4> <h4>Active Users</h4>
@ -13,7 +20,7 @@
</div> </div>
<div class="inner"> <div class="inner">
@foreach ($latest_users as $user) @foreach ($users as $user)
<x-user_block :user="$user" /> <x-user_block :user="$user" />
@endforeach @endforeach
</div> </div>
@ -27,52 +34,24 @@
</div> </div>
<div class="inner"> <div class="inner">
<ul class="cloud"> <x-tag_cloud :hashtags="$popular_hashtags" />
@foreach ($popular_hashtags as $hashtag)
<li>
<a href="{{ route ('tags', [ 'tag' => substr ($hashtag->name, 1) ]) }}"
data-weight="{{ $hashtag->get_notes_count }}">
{{ $hashtag->name }}
</a>
</li>
@endforeach
</ul>
</div> </div>
</div> </div>
<h1>Trending Posts</h1> <h1>Posts</h1>
<small>The posts with the most likes in the last 24 hours</small> <p>
Filter:
<a @if(request ()->get("posts") == null) class="filter-active" @endif href="?posts=">Trending</a>
|
<a @if(request ()->get("posts") == "latest") class="filter-active" @endif href="?posts=latest">Newest</a>
</p>
<table class="comments-table" cellspacing="0" cellpadding="3" bordercollor="#ffffff" border="1"> <table class="comments-table" cellspacing="0" cellpadding="3" bordercollor="#ffffff" border="1">
<tbody> <tbody>
@foreach ($popular_notes as $post) @foreach ($notes as $post)
<x-comment_block :post="$post" /> <x-comment_block :post="$post" />
@endforeach @endforeach
</tbody> </tbody>
</table> </table>
</div> </div>
<script>
document.addEventListener ("DOMContentLoaded", () => {
const links = document.querySelectorAll ("ul.cloud a");
let max_weight = 0;
links.forEach ((link) => {
const weight = parseInt (link.getAttribute ("data-weight"));
if (weight > max_weight) {
max_weight = weight;
}
});
links.forEach ((link) => {
const weight = parseInt (link.getAttribute ("data-weight"));
// set a minimum size
const min_size = 100;
const size = min_size + (weight / max_weight) * 100;
link.style.fontSize = `${size}%`;
});
})
</script>
@endsection @endsection

View File

@ -0,0 +1,34 @@
<ul class="cloud">
@foreach ($hashtags as $hashtag)
<li>
<a href="{{ route ('tags', [ 'tag' => substr ($hashtag->name, 1) ]) }}"
data-weight="{{ $hashtag->get_notes_count }}">
{{ $hashtag->name }}
</a>
</li>
@endforeach
</ul>
<script>
document.addEventListener ("DOMContentLoaded", () => {
const links = document.querySelectorAll ("ul.cloud a");
let max_weight = 0;
links.forEach ((link) => {
const weight = parseInt (link.getAttribute ("data-weight"));
if (weight > max_weight) {
max_weight = weight;
}
});
links.forEach ((link) => {
const weight = parseInt (link.getAttribute ("data-weight"));
// set a minimum size
const min_size = 100;
const size = min_size + (weight / max_weight) * 100;
link.style.fontSize = `${size}%`;
});
})
</script>

View File

@ -43,7 +43,7 @@
</li> </li>
<li> <li>
<a href="#">&nbsp;Search </a> <a href="{{ route ('search') }}">&nbsp;Search </a>
</li> </li>
<li> <li>

View File

@ -0,0 +1,67 @@
@extends ("partials.layout")
@section ("title", "Search")
@section ("content")
<div class="simple-container">
<h1>Search</h1>
<label for="search">
<p>Search for People, Posts and Hashtags using the following <b>field:</b></p>
</label>
<form method="GET">
<input type="text" name="query" id="search" value="{{ request()->get('query') }}" placeholder="Search for People, Posts and Hashtags">
<button type="submit">Search</button>
</form>
<br>
@if (request ()->get ("query") != null)
<div class="new-people">
<div class="top">
<h4>People</h4>
<a class="more" href="#">[view all]</a>
</div>
<div class="inner">
@forelse ($users as $user)
<x-user_block :user="$user" />
@empty
<p><i>No users found.</i></p>
@endforelse
</div>
</div>
<br>
<div class="new-people">
<div class="top">
<h4>Hashtags</h4>
<a class="more" href="#">[view all]</a>
</div>
<div class="inner">
@if (count ($hashtags) == 0)
<p><i>No hashtags found.</i></p>
@else
<x-tag_cloud :hashtags="$hashtags" />
@endif
</div>
</div>
<br>
<h1>Posts</h1>
<table class="comments-table" cellspacing="0" cellpadding="3" bordercollor="#ffffff" border="1">
<tbody>
@forelse ($posts as $post)
<x-comment_block :post="$post" />
@empty
<p><i>No posts found.</i></p>
@endforelse
</tbody>
</table>
{{ $posts->withQueryString ()->links ("pagination::default") }}
@endif
</div>
@endsection

View File

@ -38,6 +38,7 @@ Route::middleware ("update_online")->group (function () {
// other routes // other routes
Route::get ("/browse", [ HomeController::class, "browse" ])->name ("browse"); Route::get ("/browse", [ HomeController::class, "browse" ])->name ("browse");
Route::get ("/search", [ HomeController::class, "search" ])->name ("search");
Route::get ("/tags/{tag}", [ HomeController::class, "tag" ])->name ("tags"); // TODO: This Route::get ("/tags/{tag}", [ HomeController::class, "tag" ])->name ("tags"); // TODO: This
Route::get ("/search", [ HomeController::class, "search" ])->name ("search"); Route::get ("/search", [ HomeController::class, "search" ])->name ("search");
Route::get ("/requests", [ HomeController::class, "requests" ])->name ("requests")->middleware ("auth"); Route::get ("/requests", [ HomeController::class, "requests" ])->name ("requests")->middleware ("auth");