update
This commit is contained in:
@@ -7,9 +7,8 @@ namespace App\Http\Controllers\Api;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Artwork;
|
||||
use App\Models\User;
|
||||
use Carbon\CarbonInterface;
|
||||
use App\Services\ThumbnailPresenter;
|
||||
use App\Services\ThumbnailService;
|
||||
use App\Support\AvatarUrl;
|
||||
use App\Support\UsernamePolicy;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -57,20 +56,9 @@ final class ProfileApiController extends Controller
|
||||
$perPage = 24;
|
||||
$paginator = $query->cursorPaginate($perPage);
|
||||
|
||||
$data = collect($paginator->items())->map(function (Artwork $art) {
|
||||
$present = ThumbnailPresenter::present($art, 'md');
|
||||
return [
|
||||
'id' => $art->id,
|
||||
'name' => $art->title,
|
||||
'thumb' => $present['url'],
|
||||
'thumb_srcset' => $present['srcset'] ?? $present['url'],
|
||||
'width' => $art->width,
|
||||
'height' => $art->height,
|
||||
'username' => $art->user->username ?? null,
|
||||
'uname' => $art->user->username ?? $art->user->name ?? 'Skinbase',
|
||||
'published_at' => $art->published_at,
|
||||
];
|
||||
})->values();
|
||||
$data = collect($paginator->items())
|
||||
->map(fn (Artwork $art) => $this->mapArtworkCardPayload($art))
|
||||
->values();
|
||||
|
||||
return response()->json([
|
||||
'data' => $data,
|
||||
@@ -85,7 +73,8 @@ final class ProfileApiController extends Controller
|
||||
*/
|
||||
public function favourites(Request $request, string $username): JsonResponse
|
||||
{
|
||||
if (! Schema::hasTable('user_favorites')) {
|
||||
$favouriteTable = $this->resolveFavouriteTable();
|
||||
if ($favouriteTable === null) {
|
||||
return response()->json(['data' => [], 'next_cursor' => null, 'has_more' => false]);
|
||||
}
|
||||
|
||||
@@ -95,16 +84,18 @@ final class ProfileApiController extends Controller
|
||||
}
|
||||
|
||||
$perPage = 24;
|
||||
$cursor = $request->input('cursor');
|
||||
$offset = max(0, (int) base64_decode((string) $request->input('cursor', ''), true));
|
||||
|
||||
$favIds = DB::table('user_favorites as uf')
|
||||
->join('artworks as a', 'a.id', '=', 'uf.artwork_id')
|
||||
->where('uf.user_id', $user->id)
|
||||
$favIds = DB::table($favouriteTable . ' as af')
|
||||
->join('artworks as a', 'a.id', '=', 'af.artwork_id')
|
||||
->where('af.user_id', $user->id)
|
||||
->whereNull('a.deleted_at')
|
||||
->where('a.is_public', true)
|
||||
->where('a.is_approved', true)
|
||||
->orderByDesc('uf.created_at')
|
||||
->offset($cursor ? (int) base64_decode($cursor) : 0)
|
||||
->whereNotNull('a.published_at')
|
||||
->orderByDesc('af.created_at')
|
||||
->orderByDesc('af.artwork_id')
|
||||
->offset($offset)
|
||||
->limit($perPage + 1)
|
||||
->pluck('a.id');
|
||||
|
||||
@@ -120,24 +111,14 @@ final class ProfileApiController extends Controller
|
||||
->get()
|
||||
->keyBy('id');
|
||||
|
||||
$data = $favIds->filter(fn ($id) => $indexed->has($id))->map(function ($id) use ($indexed) {
|
||||
$art = $indexed[$id];
|
||||
$present = ThumbnailPresenter::present($art, 'md');
|
||||
return [
|
||||
'id' => $art->id,
|
||||
'name' => $art->title,
|
||||
'thumb' => $present['url'],
|
||||
'thumb_srcset' => $present['srcset'] ?? $present['url'],
|
||||
'width' => $art->width,
|
||||
'height' => $art->height,
|
||||
'username' => $art->user->username ?? null,
|
||||
'uname' => $art->user->username ?? $art->user->name ?? 'Skinbase',
|
||||
];
|
||||
})->values();
|
||||
$data = $favIds
|
||||
->filter(fn ($id) => $indexed->has($id))
|
||||
->map(fn ($id) => $this->mapArtworkCardPayload($indexed[$id]))
|
||||
->values();
|
||||
|
||||
return response()->json([
|
||||
'data' => $data,
|
||||
'next_cursor' => null, // Simple offset pagination for now
|
||||
'next_cursor' => $hasMore ? base64_encode((string) ($offset + $perPage)) : null,
|
||||
'has_more' => $hasMore,
|
||||
]);
|
||||
}
|
||||
@@ -174,4 +155,48 @@ final class ProfileApiController extends Controller
|
||||
$normalized = UsernamePolicy::normalize($username);
|
||||
return User::query()->whereRaw('LOWER(username) = ?', [$normalized])->first();
|
||||
}
|
||||
|
||||
private function resolveFavouriteTable(): ?string
|
||||
{
|
||||
foreach (['artwork_favourites', 'user_favorites', 'artworks_favourites', 'favourites'] as $table) {
|
||||
if (Schema::hasTable($table)) {
|
||||
return $table;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function mapArtworkCardPayload(Artwork $art): array
|
||||
{
|
||||
$present = ThumbnailPresenter::present($art, 'md');
|
||||
|
||||
return [
|
||||
'id' => $art->id,
|
||||
'name' => $art->title,
|
||||
'thumb' => $present['url'],
|
||||
'thumb_srcset' => $present['srcset'] ?? $present['url'],
|
||||
'width' => $art->width,
|
||||
'height' => $art->height,
|
||||
'username' => $art->user->username ?? null,
|
||||
'uname' => $art->user->username ?? $art->user->name ?? 'Skinbase',
|
||||
'published_at' => $this->formatIsoDate($art->published_at),
|
||||
];
|
||||
}
|
||||
|
||||
private function formatIsoDate(mixed $value): ?string
|
||||
{
|
||||
if ($value instanceof CarbonInterface) {
|
||||
return $value->toISOString();
|
||||
}
|
||||
|
||||
if ($value instanceof \DateTimeInterface) {
|
||||
return $value->format(DATE_ATOM);
|
||||
}
|
||||
|
||||
return is_string($value) ? $value : null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user