feat: ship creator journey v2 and profile updates

This commit is contained in:
2026-04-12 21:42:07 +02:00
parent a2457f4e49
commit d5cff21ea2
335 changed files with 20147 additions and 1545 deletions

View File

@@ -6,7 +6,7 @@ namespace App\Http\Controllers\Web;
use App\Http\Controllers\Controller;
use App\Models\Artwork;
use App\Models\ContentType;
use App\Services\ContentTypes\ContentTypeSlugResolver;
use Illuminate\Http\Response;
use Illuminate\View\View;
@@ -26,52 +26,6 @@ final class RssFeedController extends Controller
/** Number of items per legacy feed. */
private const FEED_LIMIT = 25;
/**
* Grouped feed definitions shown on the /rss-feeds info page.
* Each group has a 'label' and an array of 'feeds' with title + url.
*/
public const FEED_GROUPS = [
'global' => [
'label' => 'Global',
'feeds' => [
['title' => 'Latest Artworks', 'url' => '/rss', 'description' => 'All new artworks across the platform.'],
],
],
'discover' => [
'label' => 'Discover',
'feeds' => [
['title' => 'Fresh Uploads', 'url' => '/rss/discover/fresh', 'description' => 'The newest artworks just published.'],
['title' => 'Trending', 'url' => '/rss/discover/trending', 'description' => 'Most-viewed artworks over the past 7 days.'],
['title' => 'Rising', 'url' => '/rss/discover/rising', 'description' => 'Artworks gaining momentum right now.'],
],
],
'explore' => [
'label' => 'Explore',
'feeds' => [
['title' => 'All Artworks', 'url' => '/rss/explore/artworks', 'description' => 'Latest artworks of all types.'],
['title' => 'Wallpapers', 'url' => '/rss/explore/wallpapers', 'description' => 'Latest wallpapers.'],
['title' => 'Skins', 'url' => '/rss/explore/skins', 'description' => 'Latest skins.'],
['title' => 'Photography', 'url' => '/rss/explore/photography', 'description' => 'Latest photography.'],
['title' => 'Trending Wallpapers', 'url' => '/rss/explore/wallpapers/trending', 'description' => 'Trending wallpapers this week.'],
],
],
'blog' => [
'label' => 'Blog',
'feeds' => [
['title' => 'Blog Posts', 'url' => '/rss/blog', 'description' => 'Latest posts from the Skinbase blog.'],
],
],
'legacy' => [
'label' => 'Legacy Feeds',
'feeds' => [
['title' => 'Latest Uploads (XML)', 'url' => '/rss/latest-uploads.xml', 'description' => 'Legacy XML feed.'],
['title' => 'Latest Skins (XML)', 'url' => '/rss/latest-skins.xml', 'description' => 'Legacy XML feed.'],
['title' => 'Latest Wallpapers (XML)', 'url' => '/rss/latest-wallpapers.xml', 'description' => 'Legacy XML feed.'],
['title' => 'Latest Photos (XML)', 'url' => '/rss/latest-photos.xml', 'description' => 'Legacy XML feed.'],
],
],
];
/** Flat feed list kept for backward-compatibility (old view logic). */
public const FEEDS = [
'uploads' => ['title' => 'Latest Uploads', 'url' => '/rss/latest-uploads.xml'],
@@ -80,6 +34,10 @@ final class RssFeedController extends Controller
'photos' => ['title' => 'Latest Photos', 'url' => '/rss/latest-photos.xml'],
];
public function __construct(private readonly ContentTypeSlugResolver $contentTypeResolver)
{
}
/** Info page at /rss-feeds */
public function index(): View
{
@@ -94,7 +52,7 @@ final class RssFeedController extends Controller
(object) ['name' => 'RSS Feeds', 'url' => '/rss-feeds'],
]),
'feeds' => self::FEEDS,
'feed_groups' => self::FEED_GROUPS,
'feed_groups' => $this->feedGroups(),
'center_content' => true,
'center_max' => '3xl',
]);
@@ -134,7 +92,7 @@ final class RssFeedController extends Controller
private function feedByContentType(string $slug, string $title, string $feedPath): Response
{
$contentType = ContentType::where('slug', $slug)->first();
$contentType = $this->contentTypeResolver->resolve($slug)->contentType;
$query = Artwork::published()->with(['user'])->latest('published_at')->limit(self::FEED_LIMIT);
@@ -160,4 +118,70 @@ final class RssFeedController extends Controller
'Content-Type' => 'application/rss+xml; charset=utf-8',
]);
}
private function feedGroups(): array
{
$exploreFeeds = [[
'title' => 'All Artworks',
'url' => '/rss/explore/artworks',
'description' => 'Latest artworks of all types.',
]];
foreach ($this->contentTypeResolver->publicContentTypes() as $contentType) {
$name = (string) $contentType->name;
$slug = (string) $contentType->slug;
$exploreFeeds[] = [
'title' => $name,
'url' => '/rss/explore/' . $slug,
'description' => 'Latest ' . strtolower($name) . '.',
];
}
if ($this->contentTypeResolver->publicContentTypes()->isNotEmpty()) {
$firstType = $this->contentTypeResolver->publicContentTypes()->first();
$exploreFeeds[] = [
'title' => 'Trending ' . $firstType->name,
'url' => '/rss/explore/' . $firstType->slug . '/trending',
'description' => 'Trending ' . strtolower((string) $firstType->name) . ' this week.',
];
}
return [
'global' => [
'label' => 'Global',
'feeds' => [
['title' => 'Latest Artworks', 'url' => '/rss', 'description' => 'All new artworks across the platform.'],
],
],
'discover' => [
'label' => 'Discover',
'feeds' => [
['title' => 'Fresh Uploads', 'url' => '/rss/discover/fresh', 'description' => 'The newest artworks just published.'],
['title' => 'Trending', 'url' => '/rss/discover/trending', 'description' => 'Most-viewed artworks over the past 7 days.'],
['title' => 'Rising', 'url' => '/rss/discover/rising', 'description' => 'Artworks gaining momentum right now.'],
],
],
'explore' => [
'label' => 'Explore',
'feeds' => $exploreFeeds,
],
'blog' => [
'label' => 'Blog',
'feeds' => [
['title' => 'Blog Posts', 'url' => '/rss/blog', 'description' => 'Latest posts from the Skinbase blog.'],
],
],
'legacy' => [
'label' => 'Legacy Feeds',
'feeds' => [
['title' => 'Latest Uploads (XML)', 'url' => '/rss/latest-uploads.xml', 'description' => 'Legacy XML feed.'],
['title' => 'Latest Skins (XML)', 'url' => '/rss/latest-skins.xml', 'description' => 'Legacy XML feed.'],
['title' => 'Latest Wallpapers (XML)', 'url' => '/rss/latest-wallpapers.xml', 'description' => 'Legacy XML feed.'],
['title' => 'Latest Photos (XML)', 'url' => '/rss/latest-photos.xml', 'description' => 'Legacy XML feed.'],
],
],
];
}
}