Files
SkinbaseNova/app/Http/Controllers/Web/CommunityActivityController.php
2026-02-27 09:46:51 +01:00

125 lines
4.0 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Http\Controllers\Web;
use App\Http\Controllers\Controller;
use App\Models\ActivityEvent;
use App\Models\Artwork;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
/**
* Community activity feed.
*
* GET /community/activity?type=global|following
*/
final class CommunityActivityController extends Controller
{
private const PER_PAGE = 30;
public function index(Request $request)
{
$user = $request->user();
$type = $request->query('type', 'global'); // global | following
$perPage = self::PER_PAGE;
$query = ActivityEvent::query()
->orderByDesc('created_at')
->with(['actor:id,name,username']);
if ($type === 'following' && $user) {
// Show only events from followed users
$followingIds = DB::table('user_followers')
->where('follower_id', $user->id)
->pluck('user_id')
->all();
if (empty($followingIds)) {
$query->whereRaw('0 = 1'); // empty result set
} else {
$query->whereIn('actor_id', $followingIds);
}
}
$events = $query->paginate($perPage)->withQueryString();
$enriched = $this->enrich($events->getCollection());
return view('web.community.activity', [
'events' => $events,
'enriched' => $enriched,
'active_tab' => $type,
'page_title' => 'Community Activity',
]);
}
/**
* Attach target object data to each event for display.
*/
private function enrich(\Illuminate\Support\Collection $events): \Illuminate\Support\Collection
{
// Collect artwork IDs and user IDs to eager-load
$artworkIds = $events
->where('target_type', ActivityEvent::TARGET_ARTWORK)
->pluck('target_id')
->unique()
->values()
->all();
$userIds = $events
->where('target_type', ActivityEvent::TARGET_USER)
->pluck('target_id')
->unique()
->values()
->all();
$artworks = Artwork::whereIn('id', $artworkIds)
->with('user:id,name,username')
->get(['id', 'title', 'slug', 'user_id', 'hash', 'thumb_ext'])
->keyBy('id');
$users = User::whereIn('id', $userIds)
->with('profile:user_id,avatar_hash')
->get(['id', 'name', 'username'])
->keyBy('id');
return $events->map(function (ActivityEvent $event) use ($artworks, $users): array {
$target = null;
if ($event->target_type === ActivityEvent::TARGET_ARTWORK) {
$artwork = $artworks->get($event->target_id);
$target = $artwork ? [
'id' => $artwork->id,
'title' => $artwork->title,
'url' => '/art/' . $artwork->id . '/' . $artwork->slug,
'thumb' => $artwork->thumbUrl('sm'),
] : null;
} elseif ($event->target_type === ActivityEvent::TARGET_USER) {
$u = $users->get($event->target_id);
$target = $u ? [
'id' => $u->id,
'name' => $u->name,
'username' => $u->username,
'url' => '/@' . $u->username,
] : null;
}
return [
'id' => $event->id,
'type' => $event->type,
'target_type' => $event->target_type,
'actor' => [
'id' => $event->actor?->id,
'name' => $event->actor?->name,
'username' => $event->actor?->username,
'url' => '/@' . $event->actor?->username,
],
'target' => $target,
'created_at' => $event->created_at?->toIso8601String(),
];
});
}
}