Implement creator studio and upload updates
This commit is contained in:
156
app/Services/Studio/CreatorStudioInboxService.php
Normal file
156
app/Services/Studio/CreatorStudioInboxService.php
Normal file
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Services\Studio;
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
final class CreatorStudioInboxService
|
||||
{
|
||||
public function __construct(
|
||||
private readonly CreatorStudioActivityService $activity,
|
||||
private readonly CreatorStudioPreferenceService $preferences,
|
||||
) {
|
||||
}
|
||||
|
||||
public function build(User $user, array $filters = []): array
|
||||
{
|
||||
$type = $this->normalizeType((string) ($filters['type'] ?? 'all'));
|
||||
$module = $this->normalizeModule((string) ($filters['module'] ?? 'all'));
|
||||
$readState = $this->normalizeReadState((string) ($filters['read_state'] ?? 'all'));
|
||||
$priority = $this->normalizePriority((string) ($filters['priority'] ?? 'all'));
|
||||
$query = trim((string) ($filters['q'] ?? ''));
|
||||
$page = max(1, (int) ($filters['page'] ?? 1));
|
||||
$perPage = min(max((int) ($filters['per_page'] ?? 20), 12), 40);
|
||||
|
||||
$lastReadAt = $this->preferences->forUser($user)['activity_last_read_at'] ?? null;
|
||||
$lastReadTimestamp = strtotime((string) $lastReadAt) ?: 0;
|
||||
|
||||
$items = $this->activity->feed($user)->map(function (array $item) use ($lastReadTimestamp): array {
|
||||
$timestamp = strtotime((string) ($item['created_at'] ?? '')) ?: 0;
|
||||
$item['is_new'] = $timestamp > $lastReadTimestamp;
|
||||
$item['priority'] = $this->priorityFor($item);
|
||||
|
||||
return $item;
|
||||
});
|
||||
|
||||
if ($type !== 'all') {
|
||||
$items = $items->where('type', $type)->values();
|
||||
}
|
||||
|
||||
if ($module !== 'all') {
|
||||
$items = $items->where('module', $module)->values();
|
||||
}
|
||||
|
||||
if ($readState === 'unread') {
|
||||
$items = $items->filter(fn (array $item): bool => (bool) ($item['is_new'] ?? false))->values();
|
||||
} elseif ($readState === 'read') {
|
||||
$items = $items->filter(fn (array $item): bool => ! (bool) ($item['is_new'] ?? false))->values();
|
||||
}
|
||||
|
||||
if ($priority !== 'all') {
|
||||
$items = $items->where('priority', $priority)->values();
|
||||
}
|
||||
|
||||
if ($query !== '') {
|
||||
$needle = mb_strtolower($query);
|
||||
$items = $items->filter(function (array $item) use ($needle): bool {
|
||||
return collect([
|
||||
$item['title'] ?? '',
|
||||
$item['body'] ?? '',
|
||||
$item['actor']['name'] ?? '',
|
||||
$item['module_label'] ?? '',
|
||||
])->contains(fn ($value): bool => is_string($value) && str_contains(mb_strtolower($value), $needle));
|
||||
})->values();
|
||||
}
|
||||
|
||||
$total = $items->count();
|
||||
$lastPage = max(1, (int) ceil($total / $perPage));
|
||||
$page = min($page, $lastPage);
|
||||
|
||||
return [
|
||||
'items' => $items->forPage($page, $perPage)->values()->all(),
|
||||
'meta' => [
|
||||
'current_page' => $page,
|
||||
'last_page' => $lastPage,
|
||||
'per_page' => $perPage,
|
||||
'total' => $total,
|
||||
],
|
||||
'filters' => [
|
||||
'type' => $type,
|
||||
'module' => $module,
|
||||
'read_state' => $readState,
|
||||
'priority' => $priority,
|
||||
'q' => $query,
|
||||
],
|
||||
'type_options' => [
|
||||
['value' => 'all', 'label' => 'Everything'],
|
||||
['value' => 'notification', 'label' => 'Notifications'],
|
||||
['value' => 'comment', 'label' => 'Comments'],
|
||||
['value' => 'follower', 'label' => 'Followers'],
|
||||
],
|
||||
'module_options' => [
|
||||
['value' => 'all', 'label' => 'All modules'],
|
||||
['value' => 'artworks', 'label' => 'Artworks'],
|
||||
['value' => 'cards', 'label' => 'Cards'],
|
||||
['value' => 'collections', 'label' => 'Collections'],
|
||||
['value' => 'stories', 'label' => 'Stories'],
|
||||
['value' => 'followers', 'label' => 'Followers'],
|
||||
['value' => 'system', 'label' => 'System'],
|
||||
],
|
||||
'read_state_options' => [
|
||||
['value' => 'all', 'label' => 'All'],
|
||||
['value' => 'unread', 'label' => 'Unread'],
|
||||
['value' => 'read', 'label' => 'Read'],
|
||||
],
|
||||
'priority_options' => [
|
||||
['value' => 'all', 'label' => 'All priorities'],
|
||||
['value' => 'high', 'label' => 'High priority'],
|
||||
['value' => 'medium', 'label' => 'Medium priority'],
|
||||
['value' => 'low', 'label' => 'Low priority'],
|
||||
],
|
||||
'summary' => [
|
||||
'unread_count' => $items->filter(fn (array $item): bool => (bool) ($item['is_new'] ?? false))->count(),
|
||||
'high_priority_count' => $items->where('priority', 'high')->count(),
|
||||
'comment_count' => $items->where('type', 'comment')->count(),
|
||||
'follower_count' => $items->where('type', 'follower')->count(),
|
||||
'last_read_at' => $lastReadAt,
|
||||
],
|
||||
'panels' => [
|
||||
'attention_now' => $items->filter(fn (array $item): bool => ($item['priority'] ?? 'low') === 'high')->take(5)->values()->all(),
|
||||
'follow_up_queue' => $items->filter(fn (array $item): bool => (bool) ($item['is_new'] ?? false))->take(5)->values()->all(),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
private function priorityFor(array $item): string
|
||||
{
|
||||
return match ((string) ($item['type'] ?? '')) {
|
||||
'comment' => 'high',
|
||||
'notification' => (bool) ($item['read'] ?? false) ? 'medium' : 'high',
|
||||
'follower' => 'medium',
|
||||
default => 'low',
|
||||
};
|
||||
}
|
||||
|
||||
private function normalizeType(string $value): string
|
||||
{
|
||||
return in_array($value, ['all', 'notification', 'comment', 'follower'], true) ? $value : 'all';
|
||||
}
|
||||
|
||||
private function normalizeModule(string $value): string
|
||||
{
|
||||
return in_array($value, ['all', 'artworks', 'cards', 'collections', 'stories', 'followers', 'system'], true) ? $value : 'all';
|
||||
}
|
||||
|
||||
private function normalizeReadState(string $value): string
|
||||
{
|
||||
return in_array($value, ['all', 'read', 'unread'], true) ? $value : 'all';
|
||||
}
|
||||
|
||||
private function normalizePriority(string $value): string
|
||||
{
|
||||
return in_array($value, ['all', 'high', 'medium', 'low'], true) ? $value : 'all';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user