feat: ship creator journey v2 and profile updates
This commit is contained in:
@@ -7,7 +7,10 @@ use App\Models\ContentType;
|
||||
use App\Models\Artwork;
|
||||
use App\Services\ArtworkSearchService;
|
||||
use App\Services\ArtworkService;
|
||||
use App\Services\ContentTypes\ContentTypeSlugResolver;
|
||||
use App\Services\Maturity\ArtworkMaturityService;
|
||||
use App\Services\ThumbnailPresenter;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
@@ -17,8 +20,6 @@ use Illuminate\Pagination\AbstractCursorPaginator;
|
||||
|
||||
class BrowseGalleryController extends \App\Http\Controllers\Controller
|
||||
{
|
||||
private const CONTENT_TYPE_SLUGS = ['photography', 'wallpapers', 'skins', 'other', 'digital-art'];
|
||||
|
||||
/**
|
||||
* Meilisearch sort-field arrays per sort alias.
|
||||
* First element is primary sort; subsequent elements are tie-breakers.
|
||||
@@ -74,6 +75,8 @@ class BrowseGalleryController extends \App\Http\Controllers\Controller
|
||||
public function __construct(
|
||||
private ArtworkService $artworks,
|
||||
private ArtworkSearchService $search,
|
||||
private ContentTypeSlugResolver $contentTypeResolver,
|
||||
private ArtworkMaturityService $maturity,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -121,14 +124,18 @@ class BrowseGalleryController extends \App\Http\Controllers\Controller
|
||||
|
||||
public function content(Request $request, string $contentTypeSlug, ?string $path = null)
|
||||
{
|
||||
$contentSlug = strtolower($contentTypeSlug);
|
||||
if (! in_array($contentSlug, self::CONTENT_TYPE_SLUGS, true)) {
|
||||
$requestedSlug = strtolower($contentTypeSlug);
|
||||
$resolution = $this->contentTypeResolver->resolve($requestedSlug);
|
||||
|
||||
if (! $resolution->found() || $resolution->contentType === null) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$contentType = ContentType::where('slug', $contentSlug)->first();
|
||||
if (! $contentType) {
|
||||
abort(404);
|
||||
$contentType = $resolution->contentType;
|
||||
$contentSlug = strtolower((string) $contentType->slug);
|
||||
|
||||
if ($resolution->requiresRedirect()) {
|
||||
return $this->redirectToContentTypePath($request, $contentSlug, $path, 301);
|
||||
}
|
||||
|
||||
// Default sort: trending (not chronological)
|
||||
@@ -265,12 +272,25 @@ class BrowseGalleryController extends \App\Http\Controllers\Controller
|
||||
$contentTypeSlug = strtolower((string) $contentTypeSlug);
|
||||
$categoryPath = $categoryPath !== null ? trim((string) $categoryPath, '/') : (isset($pathSegments[1]) ? implode('/', array_slice($pathSegments, 1, max(0, count($pathSegments) - 2))) : '');
|
||||
|
||||
$resolution = $this->contentTypeResolver->resolve($contentTypeSlug);
|
||||
if (! $resolution->found() || $resolution->contentType === null) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$resolvedContentTypeSlug = strtolower((string) $resolution->contentType->slug);
|
||||
|
||||
// Normalize artwork param if route-model binding returned an Artwork model
|
||||
$artworkSlug = $artwork instanceof Artwork ? (string) $artwork->slug : (string) $artwork;
|
||||
|
||||
if ($resolution->requiresRedirect()) {
|
||||
$path = trim($categoryPath . '/' . $artworkSlug, '/');
|
||||
|
||||
return $this->redirectToContentTypePath($req, $resolvedContentTypeSlug, $path, 301);
|
||||
}
|
||||
|
||||
return app(\App\Http\Controllers\ArtworkController::class)->show(
|
||||
$req,
|
||||
$contentTypeSlug,
|
||||
$resolvedContentTypeSlug,
|
||||
$categoryPath,
|
||||
$artworkSlug
|
||||
);
|
||||
@@ -293,7 +313,7 @@ class BrowseGalleryController extends \App\Http\Controllers\Controller
|
||||
$username = $isGroupPublisher ? '' : ($artwork->user?->username ?? '');
|
||||
$profileUrl = $isGroupPublisher ? $group->publicUrl() : ($username !== '' ? '/@' . $username : null);
|
||||
|
||||
return (object) [
|
||||
return (object) $this->maturity->decoratePayload([
|
||||
'id' => $artwork->id,
|
||||
'name' => $artwork->title,
|
||||
'content_type_name' => $primaryCategory?->contentType?->name ?? '',
|
||||
@@ -317,7 +337,7 @@ class BrowseGalleryController extends \App\Http\Controllers\Controller
|
||||
'published_at' => $artwork->published_at,
|
||||
'width' => $artwork->width ?? null,
|
||||
'height' => $artwork->height ?? null,
|
||||
];
|
||||
], $artwork, request()->user());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -372,9 +392,8 @@ class BrowseGalleryController extends \App\Http\Controllers\Controller
|
||||
|
||||
private function mainCategories(): Collection
|
||||
{
|
||||
return ContentType::ordered()
|
||||
->whereIn('slug', self::CONTENT_TYPE_SLUGS)
|
||||
->get(['name', 'slug'])
|
||||
return $this->contentTypeResolver
|
||||
->publicContentTypes()
|
||||
->map(function (ContentType $type) {
|
||||
return (object) [
|
||||
'id' => $type->id,
|
||||
@@ -385,6 +404,18 @@ class BrowseGalleryController extends \App\Http\Controllers\Controller
|
||||
});
|
||||
}
|
||||
|
||||
private function redirectToContentTypePath(Request $request, string $contentTypeSlug, ?string $path = null, int $status = 301): RedirectResponse
|
||||
{
|
||||
$target = url('/' . trim($contentTypeSlug . '/' . trim((string) $path, '/'), '/'));
|
||||
$queryString = $request->getQueryString();
|
||||
|
||||
if ($queryString) {
|
||||
$target .= '?' . $queryString;
|
||||
}
|
||||
|
||||
return redirect()->to($target, $status);
|
||||
}
|
||||
|
||||
private function buildPaginationSeo(Request $request, string $canonicalBaseUrl, mixed $paginator): array
|
||||
{
|
||||
$canonicalQuery = $request->query();
|
||||
|
||||
Reference in New Issue
Block a user