Remove dead admin UI code, redesign dashboard followers/following and upload experiences, and add schema audit tooling with repair migrations for forum and upload drift.
105 lines
4.4 KiB
PHP
105 lines
4.4 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Dashboard;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Support\AvatarUrl;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class FollowingController extends Controller
|
|
{
|
|
public function index(Request $request)
|
|
{
|
|
$user = $request->user();
|
|
$perPage = 30;
|
|
$search = trim((string) $request->query('q', ''));
|
|
$sort = (string) $request->query('sort', 'recent');
|
|
$relationship = (string) $request->query('relationship', 'all');
|
|
|
|
$allowedSorts = ['recent', 'oldest', 'name', 'uploads', 'followers'];
|
|
$allowedRelationships = ['all', 'mutual', 'one-way'];
|
|
|
|
if (! in_array($sort, $allowedSorts, true)) {
|
|
$sort = 'recent';
|
|
}
|
|
|
|
if (! in_array($relationship, $allowedRelationships, true)) {
|
|
$relationship = 'all';
|
|
}
|
|
|
|
// People that $user follows (follower_id = $user)
|
|
$baseQuery = DB::table('user_followers as uf')
|
|
->join('users as u', 'u.id', '=', 'uf.user_id')
|
|
->leftJoin('user_profiles as up', 'up.user_id', '=', 'u.id')
|
|
->leftJoin('user_statistics as us', 'us.user_id', '=', 'u.id')
|
|
->leftJoin('user_followers as mutual', function ($join) use ($user): void {
|
|
$join->on('mutual.follower_id', '=', 'uf.user_id')
|
|
->where('mutual.user_id', '=', $user->id);
|
|
})
|
|
->where('uf.follower_id', $user->id)
|
|
->whereNull('u.deleted_at')
|
|
->when($search !== '', function ($query) use ($search): void {
|
|
$query->where(function ($inner) use ($search): void {
|
|
$inner->where('u.username', 'like', '%' . $search . '%')
|
|
->orWhere('u.name', 'like', '%' . $search . '%');
|
|
});
|
|
})
|
|
->when($relationship === 'mutual', function ($query): void {
|
|
$query->whereNotNull('mutual.created_at');
|
|
})
|
|
->when($relationship === 'one-way', function ($query): void {
|
|
$query->whereNull('mutual.created_at');
|
|
});
|
|
|
|
$summaryBaseQuery = clone $baseQuery;
|
|
|
|
$following = $baseQuery
|
|
->when($sort === 'recent', fn ($query) => $query->orderByDesc('uf.created_at'))
|
|
->when($sort === 'oldest', fn ($query) => $query->orderBy('uf.created_at'))
|
|
->when($sort === 'name', fn ($query) => $query->orderByRaw('COALESCE(u.username, u.name) asc'))
|
|
->when($sort === 'uploads', fn ($query) => $query->orderByDesc('us.uploads_count')->orderByRaw('COALESCE(u.username, u.name) asc'))
|
|
->when($sort === 'followers', fn ($query) => $query->orderByDesc('us.followers_count')->orderByRaw('COALESCE(u.username, u.name) asc'))
|
|
->select([
|
|
'u.id', 'u.username', 'u.name',
|
|
'up.avatar_hash',
|
|
'us.uploads_count',
|
|
'us.followers_count',
|
|
'uf.created_at as followed_at',
|
|
'mutual.created_at as follows_you_at',
|
|
])
|
|
->paginate($perPage)
|
|
->withQueryString()
|
|
->through(fn ($row) => (object) [
|
|
'id' => $row->id,
|
|
'username' => $row->username,
|
|
'name' => $row->name,
|
|
'uname' => $row->username ?? $row->name,
|
|
'avatar_url' => AvatarUrl::forUser((int) $row->id, $row->avatar_hash, 64),
|
|
'profile_url' => '/@' . strtolower((string) ($row->username ?? $row->id)),
|
|
'uploads' => $row->uploads_count ?? 0,
|
|
'followers_count' => $row->followers_count ?? 0,
|
|
'follows_you' => $row->follows_you_at !== null,
|
|
'follows_you_at' => $row->follows_you_at,
|
|
'followed_at' => $row->followed_at,
|
|
]);
|
|
|
|
$summary = [
|
|
'total_following' => (clone $summaryBaseQuery)->count(),
|
|
'mutual' => (clone $summaryBaseQuery)->whereNotNull('mutual.created_at')->count(),
|
|
'one_way' => (clone $summaryBaseQuery)->whereNull('mutual.created_at')->count(),
|
|
];
|
|
|
|
return view('dashboard.following', [
|
|
'following' => $following,
|
|
'filters' => [
|
|
'q' => $search,
|
|
'sort' => $sort,
|
|
'relationship' => $relationship,
|
|
],
|
|
'summary' => $summary,
|
|
'page_title' => 'People I Follow',
|
|
]);
|
|
}
|
|
}
|