Wire admin studio SSR and search infrastructure
This commit is contained in:
@@ -11,6 +11,7 @@ use App\Models\ForumPost;
|
||||
use App\Models\ForumThread;
|
||||
use App\Models\User;
|
||||
use App\Models\UserActivity;
|
||||
use App\Models\WorldRewardGrant;
|
||||
use App\Support\AvatarUrl;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
@@ -20,7 +21,7 @@ use Illuminate\Support\Str;
|
||||
final class UserActivityService
|
||||
{
|
||||
public const DEFAULT_PER_PAGE = 20;
|
||||
private const FEED_SCHEMA_VERSION = 2;
|
||||
private const FEED_SCHEMA_VERSION = 3;
|
||||
|
||||
private const FILTER_ALL = 'all';
|
||||
private const FILTER_UPLOADS = 'uploads';
|
||||
@@ -65,6 +66,11 @@ final class UserActivityService
|
||||
return $this->log($userId, UserActivity::TYPE_ACHIEVEMENT, UserActivity::ENTITY_ACHIEVEMENT, $achievementId, $meta);
|
||||
}
|
||||
|
||||
public function logWorldReward(int $userId, int $worldRewardGrantId, array $meta = []): ?UserActivity
|
||||
{
|
||||
return $this->log($userId, UserActivity::TYPE_WORLD_REWARD, UserActivity::ENTITY_WORLD_REWARD, $worldRewardGrantId, $meta);
|
||||
}
|
||||
|
||||
public function logForumPost(int $userId, int $threadId, array $meta = []): ?UserActivity
|
||||
{
|
||||
return $this->log($userId, UserActivity::TYPE_FORUM_POST, UserActivity::ENTITY_FORUM_THREAD, $threadId, $meta);
|
||||
@@ -220,6 +226,14 @@ final class UserActivityService
|
||||
->values()
|
||||
->all();
|
||||
|
||||
$worldRewardIds = $rows
|
||||
->filter(fn (UserActivity $activity): bool => $activity->entity_type === UserActivity::ENTITY_WORLD_REWARD)
|
||||
->pluck('entity_id')
|
||||
->map(fn (mixed $id): int => (int) $id)
|
||||
->unique()
|
||||
->values()
|
||||
->all();
|
||||
|
||||
return [
|
||||
'artworks' => empty($artworkIds)
|
||||
? collect()
|
||||
@@ -245,7 +259,7 @@ final class UserActivityService
|
||||
? collect()
|
||||
: User::query()
|
||||
->with('profile:user_id,avatar_hash')
|
||||
->withCount('artworks')
|
||||
->with('statistics:user_id,uploads_count')
|
||||
->whereIn('id', $userIds)
|
||||
->where('is_active', true)
|
||||
->whereNull('deleted_at')
|
||||
@@ -276,6 +290,13 @@ final class UserActivityService
|
||||
->whereHas('thread', fn ($query) => $query->where('visibility', 'public')->whereNull('deleted_at'))
|
||||
->get()
|
||||
->keyBy('id'),
|
||||
'world_rewards' => empty($worldRewardIds)
|
||||
? collect()
|
||||
: WorldRewardGrant::query()
|
||||
->with(['world', 'artwork'])
|
||||
->whereIn('id', $worldRewardIds)
|
||||
->get()
|
||||
->keyBy('id'),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -299,6 +320,7 @@ final class UserActivityService
|
||||
UserActivity::TYPE_REPLY => $this->formatCommentActivity($base, $activity, $related),
|
||||
UserActivity::TYPE_FOLLOW => $this->formatFollowActivity($base, $activity, $related),
|
||||
UserActivity::TYPE_ACHIEVEMENT => $this->formatAchievementActivity($base, $activity, $related),
|
||||
UserActivity::TYPE_WORLD_REWARD => $this->formatWorldRewardActivity($base, $activity, $related),
|
||||
UserActivity::TYPE_FORUM_POST,
|
||||
UserActivity::TYPE_FORUM_REPLY => $this->formatForumActivity($base, $activity, $related),
|
||||
default => null,
|
||||
@@ -374,6 +396,37 @@ final class UserActivityService
|
||||
];
|
||||
}
|
||||
|
||||
private function formatWorldRewardActivity(array $base, UserActivity $activity, array $related): ?array
|
||||
{
|
||||
/** @var WorldRewardGrant|null $grant */
|
||||
$grant = $related['world_rewards']->get((int) $activity->entity_id);
|
||||
if (! $grant || ! $grant->world) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
...$base,
|
||||
'world_reward' => [
|
||||
'id' => (int) $grant->id,
|
||||
'reward_type' => $grant->reward_type->value,
|
||||
'reward_label' => $grant->reward_type->label(),
|
||||
'badge_label' => trim($grant->world->title . ' ' . $grant->reward_type->label()),
|
||||
'tone' => $grant->reward_type->tone(),
|
||||
'world' => [
|
||||
'id' => (int) $grant->world->id,
|
||||
'title' => (string) $grant->world->title,
|
||||
'url' => $grant->world->publicUrl(),
|
||||
],
|
||||
'artwork' => $grant->artwork ? [
|
||||
'id' => (int) $grant->artwork->id,
|
||||
'title' => (string) ($grant->artwork->title ?? 'Artwork'),
|
||||
'url' => route('art.show', ['id' => (int) $grant->artwork->id, 'slug' => $grant->artwork->slug ?: Str::slug((string) $grant->artwork->title)]),
|
||||
] : null,
|
||||
'note' => (string) ($grant->note ?? ''),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
private function formatForumActivity(array $base, UserActivity $activity, array $related): ?array
|
||||
{
|
||||
if ($activity->type === UserActivity::TYPE_FORUM_POST) {
|
||||
@@ -510,7 +563,7 @@ final class UserActivityService
|
||||
return ['label' => 'Moderator', 'tone' => 'amber'];
|
||||
}
|
||||
|
||||
if ((int) ($user->artworks_count ?? 0) > 0) {
|
||||
if ((int) ($user->statistics?->uploads_count ?? $user->artworks_count ?? 0) > 0) {
|
||||
return ['label' => 'Creator', 'tone' => 'sky'];
|
||||
}
|
||||
|
||||
@@ -533,6 +586,7 @@ final class UserActivityService
|
||||
UserActivity::TYPE_FAVOURITE,
|
||||
UserActivity::TYPE_FOLLOW,
|
||||
UserActivity::TYPE_ACHIEVEMENT,
|
||||
UserActivity::TYPE_WORLD_REWARD,
|
||||
UserActivity::TYPE_FORUM_POST,
|
||||
UserActivity::TYPE_FORUM_REPLY,
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user