450 lines
29 KiB
PHP
450 lines
29 KiB
PHP
<?php
|
|
|
|
use Illuminate\Support\Facades\Route;
|
|
use App\Http\Controllers\User\ProfileController;
|
|
use App\Models\ContentType;
|
|
use App\Http\Controllers\User\AvatarController;
|
|
use App\Http\Controllers\Dashboard\ArtworkController as DashboardArtworkController;
|
|
use App\Http\Controllers\Web\ArtworkPageController;
|
|
use App\Http\Controllers\ArtworkDownloadController;
|
|
use App\Http\Controllers\Web\BrowseGalleryController;
|
|
use App\Http\Controllers\Web\FeaturedArtworksController;
|
|
use App\Http\Controllers\Web\DailyUploadsController;
|
|
use App\Http\Controllers\Web\DiscoverController;
|
|
use App\Http\Controllers\Web\ExploreController;
|
|
use App\Http\Controllers\Web\BlogController;
|
|
use App\Http\Controllers\Web\PageController;
|
|
use App\Http\Controllers\StoryController;
|
|
use App\Http\Controllers\Web\HomeController;
|
|
use App\Http\Controllers\Web\FooterController;
|
|
use App\Http\Controllers\Web\StaffController;
|
|
use App\Http\Controllers\Web\RssFeedController;
|
|
use App\Http\Controllers\Web\ApplicationController;
|
|
use App\Http\Controllers\Web\CategoryController;
|
|
use App\Http\Controllers\News\NewsController as FrontendNewsController;
|
|
use App\Http\Controllers\News\NewsRssController;
|
|
use App\Http\Controllers\RSS\GlobalFeedController;
|
|
use App\Http\Controllers\RSS\DiscoverFeedController;
|
|
use App\Http\Controllers\RSS\ExploreFeedController;
|
|
use App\Http\Controllers\RSS\TagFeedController;
|
|
use App\Http\Controllers\RSS\CreatorFeedController;
|
|
use App\Http\Controllers\RSS\BlogFeedController;
|
|
use App\Http\Controllers\Studio\StudioController;
|
|
use App\Http\Controllers\DashboardController;
|
|
use App\Http\Controllers\Community\LatestController;
|
|
use App\Http\Controllers\User\MembersController;
|
|
use App\Http\Controllers\User\TodayDownloadsController;
|
|
use App\Http\Controllers\User\MonthlyCommentatorsController;
|
|
use App\Models\Artwork;
|
|
use Inertia\Inertia;
|
|
|
|
Route::get('/', [HomeController::class, 'index'])->name('index');
|
|
Route::get('/home', [HomeController::class, 'index']);
|
|
|
|
// ── PUBLIC GALLERIES / LISTS ─────────────────────────────────────────────────
|
|
Route::get('/featured', [FeaturedArtworksController::class, 'index'])->name('featured');
|
|
Route::get('/uploads/latest', [LatestController::class, 'index'])->name('uploads.latest');
|
|
Route::get('/uploads/daily', [DailyUploadsController::class, 'index'])->name('uploads.daily');
|
|
Route::get('/members/photos', [MembersController::class, 'photos'])->name('members.photos');
|
|
Route::get('/downloads/today', [TodayDownloadsController::class, 'index'])->name('downloads.today');
|
|
Route::get('/comments/monthly', [MonthlyCommentatorsController::class, 'index'])->name('comments.monthly');
|
|
|
|
// ── DISCOVER (/discover/*) ────────────────────────────────────────────────────
|
|
Route::prefix('discover')->name('discover.')->group(function () {
|
|
Route::get('/', fn () => redirect('/discover/trending', 301));
|
|
|
|
Route::get('/trending', [DiscoverController::class, 'trending'])->name('trending');
|
|
Route::get('/rising', [DiscoverController::class, 'rising'])->name('rising');
|
|
Route::get('/fresh', [DiscoverController::class, 'fresh'])->name('fresh');
|
|
Route::get('/top-rated', [DiscoverController::class, 'topRated'])->name('top-rated');
|
|
Route::get('/most-downloaded', [DiscoverController::class, 'mostDownloaded'])->name('most-downloaded');
|
|
Route::get('/on-this-day', [DiscoverController::class, 'onThisDay'])->name('on-this-day');
|
|
|
|
Route::middleware('auth')->get('/following', [DiscoverController::class, 'following'])->name('following');
|
|
Route::middleware('auth')->get('/for-you', [DiscoverController::class, 'forYou'])->name('for-you');
|
|
});
|
|
|
|
// ── EXPLORE (/explore/*) ──────────────────────────────────────────────────────
|
|
Route::prefix('explore')->name('explore.')->group(function () {
|
|
Route::get('/', [ExploreController::class, 'index'])->name('index');
|
|
Route::get('/members', fn () => redirect()->route('creators.top', request()->query(), 301))->name('members.redirect');
|
|
Route::get('/memebers', fn () => redirect()->route('creators.top', request()->query(), 301))->name('memebers.redirect');
|
|
Route::get('/{type}', [ExploreController::class, 'byType'])
|
|
->where('type', 'artworks|wallpapers|skins|photography|other')
|
|
->name('type');
|
|
Route::get('/{type}/{mode}', [ExploreController::class, 'byTypeMode'])
|
|
->where('type', 'artworks|wallpapers|skins|photography|other')
|
|
->where('mode', 'trending|new-hot|best|latest')
|
|
->name('type.mode');
|
|
});
|
|
|
|
// ── BLOG (/blog/*) ────────────────────────────────────────────────────────────
|
|
Route::prefix('blog')->name('blog.')->group(function () {
|
|
Route::get('/', [BlogController::class, 'index'])->name('index');
|
|
Route::get('/{slug}', [BlogController::class, 'show'])->where('slug', '[a-z0-9\-]+')->name('show');
|
|
});
|
|
|
|
// ── PAGES (DB-driven static pages) ───────────────────────────────────────────
|
|
Route::get('/pages/{slug}', [PageController::class, 'show'])
|
|
->where('slug', '[a-z0-9\-]+')
|
|
->name('pages.show');
|
|
|
|
Route::get('/about', [PageController::class, 'marketing'])->defaults('slug', 'about')->name('about');
|
|
Route::get('/help', [PageController::class, 'marketing'])->defaults('slug', 'help')->name('help');
|
|
Route::get('/contact', [PageController::class, 'marketing'])->defaults('slug', 'contact')->name('contact');
|
|
|
|
Route::get('/legal/{section}', [PageController::class, 'legal'])
|
|
->where('section', 'terms|privacy|cookies')
|
|
->name('legal');
|
|
|
|
// ── FOOTER ────────────────────────────────────────────────────────────────────
|
|
Route::get('/rss-feeds', [RssFeedController::class, 'index'])->name('rss-feeds');
|
|
Route::get('/faq', [FooterController::class, 'faq'])->name('faq');
|
|
Route::get('/rules-and-guidelines', [FooterController::class, 'rules'])->name('rules');
|
|
Route::get('/privacy-policy', [FooterController::class, 'privacyPolicy'])->name('privacy-policy');
|
|
Route::get('/terms-of-service', [FooterController::class, 'termsOfService'])->name('terms-of-service');
|
|
Route::get('/staff', [StaffController::class, 'index'])->name('staff');
|
|
|
|
Route::get('/contact', [ApplicationController::class, 'show'])->name('contact.show');
|
|
Route::post('/contact', [ApplicationController::class, 'submit'])->middleware('throttle:6,1')->name('contact.submit');
|
|
|
|
$cpPrefix = trim((string) config('cpad.webroot', config('cp.webroot', 'cp')), '/');
|
|
|
|
// ── LEGACY RSS (.xml feeds — old site compatibility) ──────────────────────────
|
|
Route::get('/rss/latest-uploads.xml', [RssFeedController::class, 'latestUploads'])->name('rss.uploads');
|
|
Route::get('/rss/latest-skins.xml', [RssFeedController::class, 'latestSkins'])->name('rss.skins');
|
|
Route::get('/rss/latest-wallpapers.xml', [RssFeedController::class, 'latestWallpapers'])->name('rss.wallpapers');
|
|
Route::get('/rss/latest-photos.xml', [RssFeedController::class, 'latestPhotos'])->name('rss.photos');
|
|
|
|
// ── RSS 2.0 feeds (/rss/*) ────────────────────────────────────────────────────
|
|
Route::middleware('throttle:60,1')->group(function () {
|
|
Route::get('/rss', GlobalFeedController::class)->name('rss.global');
|
|
|
|
Route::prefix('rss/discover')->name('rss.discover.')->group(function () {
|
|
Route::get('/', [DiscoverFeedController::class, 'index'])->name('index');
|
|
Route::get('/trending', [DiscoverFeedController::class, 'trending'])->name('trending');
|
|
Route::get('/fresh', [DiscoverFeedController::class, 'fresh'])->name('fresh');
|
|
Route::get('/rising', [DiscoverFeedController::class, 'rising'])->name('rising');
|
|
});
|
|
|
|
Route::prefix('rss/explore')->name('rss.explore.')->group(function () {
|
|
Route::get('/{type}', [ExploreFeedController::class, 'byType'])
|
|
->where('type', 'artworks|wallpapers|skins|photography|other')
|
|
->name('type');
|
|
Route::get('/{type}/{mode}', [ExploreFeedController::class, 'byTypeMode'])
|
|
->where('type', 'artworks|wallpapers|skins|photography|other')
|
|
->where('mode', 'trending|latest|best')
|
|
->name('type.mode');
|
|
});
|
|
|
|
Route::get('/rss/tag/{slug}', TagFeedController::class)
|
|
->where('slug', '[a-z0-9\-]+')
|
|
->name('rss.tag');
|
|
|
|
Route::get('/rss/creator/{username}', CreatorFeedController::class)
|
|
->where('username', '[A-Za-z0-9_\-]{3,20}')
|
|
->name('rss.creator');
|
|
|
|
Route::get('/rss/blog', BlogFeedController::class)->name('rss.blog');
|
|
});
|
|
|
|
// ── CREATORS (/creators/*) ────────────────────────────────────────────────────
|
|
Route::prefix('creators')->name('creators.')->group(function () {
|
|
Route::get('/top', [\App\Http\Controllers\User\TopAuthorsController::class, 'index'])->name('top');
|
|
Route::get('/rising', [DiscoverController::class, 'risingCreators'])->name('rising');
|
|
});
|
|
|
|
Route::get('/leaderboard', \App\Http\Controllers\Web\LeaderboardPageController::class)
|
|
->name('leaderboard');
|
|
|
|
// ── STORIES (/stories/*) ──────────────────────────────────────────────────────
|
|
Route::prefix('stories')->name('stories.')->group(function () {
|
|
Route::get('/', [StoryController::class, 'index'])->name('index');
|
|
Route::get('/tag/{tag}', [StoryController::class, 'tag'])
|
|
->where('tag', '[a-z0-9\-]+')
|
|
->name('tag');
|
|
Route::get('/creator/{username}', [StoryController::class, 'creator'])
|
|
->where('username', '[A-Za-z0-9_\-]{1,50}')
|
|
->name('creator');
|
|
Route::get('/author/{username}', fn (string $username) => redirect()->route('stories.creator', ['username' => $username], 301))
|
|
->where('username', '[A-Za-z0-9_\-]{1,50}')
|
|
->name('author');
|
|
Route::get('/category/{category}', [StoryController::class, 'category'])
|
|
->where('category', 'creator_story|tutorial|interview|project_breakdown|announcement|resource')
|
|
->name('category');
|
|
Route::get('/{slug}', [StoryController::class, 'show'])
|
|
->where('slug', '[a-z0-9\-]+')
|
|
->name('show');
|
|
});
|
|
|
|
Route::middleware(['auth', 'ensure.onboarding.complete', 'creator.access'])->prefix('creator/stories')->name('creator.stories.')->group(function () {
|
|
Route::get('/', [StoryController::class, 'dashboard'])->name('index');
|
|
Route::get('/create', [StoryController::class, 'create'])->name('create');
|
|
Route::post('/', [StoryController::class, 'store'])->name('store');
|
|
Route::get('/artworks/search', [StoryController::class, 'searchArtworks'])->name('artworks.search');
|
|
Route::post('/upload-image', [StoryController::class, 'uploadImage'])->name('upload-image');
|
|
Route::get('/{story}/edit', [StoryController::class, 'edit'])->name('edit');
|
|
Route::put('/{story}', [StoryController::class, 'update'])->name('update');
|
|
Route::delete('/{story}', [StoryController::class, 'destroy'])->name('destroy');
|
|
Route::post('/{story}/autosave', [StoryController::class, 'autosave'])->name('autosave');
|
|
Route::post('/{story}/submit-review', [StoryController::class, 'submitForReview'])->name('submit-review');
|
|
Route::post('/{story}/publish', [StoryController::class, 'publishNow'])->name('publish-now');
|
|
Route::get('/{story}/preview', [StoryController::class, 'preview'])->name('preview');
|
|
Route::get('/{story}/analytics', [StoryController::class, 'analytics'])->name('analytics');
|
|
});
|
|
|
|
// ── TAGS ──────────────────────────────────────────────────────────────────────
|
|
Route::get('/tags', [\App\Http\Controllers\Web\TagController::class, 'index'])->name('tags.index');
|
|
Route::get('/tag/{tag:slug}', [\App\Http\Controllers\Web\TagController::class, 'show'])
|
|
->where('tag', '[a-z0-9\-]+')
|
|
->name('tags.show');
|
|
Route::get('/tags/{tag}', [\App\Http\Controllers\Web\Posts\HashtagFeedController::class, 'index'])
|
|
->where('tag', '[A-Za-z][A-Za-z0-9_]{1,63}')
|
|
->name('feed.hashtag');
|
|
|
|
// ── CATEGORIES DIRECTORY ─────────────────────────────────────────────────────
|
|
Route::get('/categories', [CategoryController::class, 'index'])->name('categories.index');
|
|
|
|
// ── FOLLOWING (shortcut) ──────────────────────────────────────────────────────
|
|
Route::middleware('auth')->get('/following', function () {
|
|
return redirect()->route('dashboard.following');
|
|
})->name('following.redirect');
|
|
|
|
// ── ART / ARTWORKS ────────────────────────────────────────────────────────────
|
|
Route::get('/art/{id}/{slug?}', [ArtworkPageController::class, 'show'])
|
|
->where('id', '\d+')
|
|
->name('art.show');
|
|
|
|
Route::get('/download/artwork/{id}', ArtworkDownloadController::class)
|
|
->whereNumber('id')
|
|
->middleware('throttle:downloads')
|
|
->name('art.download');
|
|
|
|
// ── NEWS (/news/*) ────────────────────────────────────────────────────────────
|
|
Route::prefix('news')->name('news.')->group(function () {
|
|
Route::get('/', [FrontendNewsController::class, 'index'])->name('index');
|
|
Route::get('category/{slug}', [FrontendNewsController::class, 'category'])->name('category');
|
|
Route::get('tag/{slug}', [FrontendNewsController::class, 'tag'])->name('tag');
|
|
Route::get('{slug}', [FrontendNewsController::class, 'show'])
|
|
->where('slug', '[a-z0-9\-]+')
|
|
->name('show');
|
|
});
|
|
Route::get('/rss/news', [NewsRssController::class, 'feed'])->name('news.rss');
|
|
|
|
// ── PROFILES (@username) ──────────────────────────────────────────────────────
|
|
Route::get('/@{username}/gallery', [ProfileController::class, 'showGalleryByUsername'])
|
|
->where('username', '[A-Za-z0-9_-]{3,20}')
|
|
->name('profile.gallery');
|
|
|
|
Route::get('/@{username}/{tab}', [ProfileController::class, 'showTabByUsername'])
|
|
->where('username', '[A-Za-z0-9_-]{3,20}')
|
|
->where('tab', 'posts|artworks|stories|achievements|collections|about|stats|favourites|activity')
|
|
->name('profile.tab');
|
|
|
|
Route::get('/@{username}', [ProfileController::class, 'showByUsername'])
|
|
->where('username', '[A-Za-z0-9_-]{3,20}')
|
|
->name('profile.show');
|
|
|
|
Route::middleware('auth')->post('/@{username}/follow', [ProfileController::class, 'toggleFollow'])
|
|
->where('username', '[A-Za-z0-9_-]{3,20}')
|
|
->name('profile.follow');
|
|
|
|
Route::middleware('auth')->post('/@{username}/comment', [ProfileController::class, 'storeComment'])
|
|
->where('username', '[A-Za-z0-9_-]{3,20}')
|
|
->name('profile.comment');
|
|
|
|
// ── DASHBOARD ─────────────────────────────────────────────────────────────────
|
|
Route::get('/dashboard', [DashboardController::class, 'index'])
|
|
->middleware(['auth', 'verified'])
|
|
->name('dashboard');
|
|
|
|
Route::middleware(['auth', 'creator.access'])->prefix('creator')->name('creator.')->group(function () {
|
|
Route::get('/artworks', fn () => redirect()->route('studio.artworks'))->name('artworks');
|
|
Route::get('/analytics', fn () => redirect()->route('studio.analytics'))->name('analytics');
|
|
});
|
|
|
|
Route::middleware(['auth', \App\Http\Middleware\NoIndexDashboard::class])->prefix('dashboard')->name('dashboard.')->group(function () {
|
|
Route::get('/artworks', [DashboardArtworkController::class, 'index'])->name('artworks.index');
|
|
Route::get('/artworks/{id}/edit', [DashboardArtworkController::class, 'edit'])->whereNumber('id')->name('artworks.edit');
|
|
Route::put('/artworks/{id}', [DashboardArtworkController::class, 'update'])->whereNumber('id')->name('artworks.update');
|
|
Route::delete('/artworks/{id}', [DashboardArtworkController::class, 'destroy'])->whereNumber('id')->name('artworks.destroy');
|
|
|
|
Route::get('/favorites', [\App\Http\Controllers\Dashboard\FavoriteController::class, 'index'])->name('favorites');
|
|
Route::delete('/favorites/{artwork}', [\App\Http\Controllers\Dashboard\FavoriteController::class, 'destroy'])->name('favorites.destroy');
|
|
|
|
Route::get('/followers', [\App\Http\Controllers\Dashboard\FollowerController::class, 'index'])->name('followers');
|
|
Route::get('/following', [\App\Http\Controllers\Dashboard\FollowingController::class, 'index'])->name('following');
|
|
Route::get('/comments', fn () => redirect()->route('dashboard.comments.received', request()->query(), 302))->name('comments');
|
|
Route::get('/comments/received', [\App\Http\Controllers\Dashboard\CommentController::class, 'received'])->name('comments.received');
|
|
Route::get('/notifications', [\App\Http\Controllers\Dashboard\NotificationController::class, 'index'])->name('notifications');
|
|
Route::get('/gallery', [\App\Http\Controllers\Dashboard\DashboardGalleryController::class, 'index'])->name('gallery');
|
|
Route::get('/awards', [\App\Http\Controllers\Dashboard\DashboardAwardsController::class, 'index'])->name('awards');
|
|
});
|
|
|
|
// Canonical dashboard profile / settings
|
|
Route::middleware(['auth'])->get('/dashboard/profile', [ProfileController::class, 'editSettings'])->name('dashboard.profile');
|
|
Route::middleware(['auth'])->get('/settings/profile', [ProfileController::class, 'editSettings'])->name('settings.profile');
|
|
|
|
// ── STUDIO Pro (/studio/*) ────────────────────────────────────────────────────
|
|
Route::middleware(['auth', 'ensure.onboarding.complete'])->prefix('studio')->name('studio.')->group(function () {
|
|
Route::get('/', [StudioController::class, 'index'])->name('index');
|
|
Route::get('/artworks', [StudioController::class, 'artworks'])->name('artworks');
|
|
Route::get('/artworks/drafts', [StudioController::class, 'drafts'])->name('drafts');
|
|
Route::get('/artworks/archived', [StudioController::class, 'archived'])->name('archived');
|
|
Route::get('/artworks/{id}/edit', [StudioController::class, 'edit'])->whereNumber('id')->name('artworks.edit');
|
|
Route::get('/artworks/{id}/analytics', [StudioController::class, 'analytics'])->whereNumber('id')->name('artworks.analytics');
|
|
Route::get('/analytics', [StudioController::class, 'analyticsOverview'])->name('analytics');
|
|
});
|
|
|
|
// ── SETTINGS / PROFILE EDIT ───────────────────────────────────────────────────
|
|
Route::middleware(['auth', 'normalize.username', 'ensure.onboarding.complete'])->group(function () {
|
|
Route::get('/profile', fn () => redirect()->route('dashboard.profile', [], 301))->name('legacy.profile.redirect');
|
|
Route::get('/settings', fn () => redirect()->route('dashboard.profile', [], 302))->name('settings');
|
|
Route::get('/profile/edit', fn () => redirect()->route('dashboard.profile', [], 302))->name('profile.edit');
|
|
Route::match(['post','put','patch'], '/profile', [ProfileController::class, 'update'])->name('profile.update');
|
|
Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
|
|
Route::match(['post', 'put'], '/profile/password', [ProfileController::class, 'password'])->name('profile.password');
|
|
Route::post('/avatar/upload', [AvatarController::class, 'upload'])->middleware('throttle:20,1')->name('avatar.upload');
|
|
|
|
Route::post('/settings/profile/update', [ProfileController::class, 'updateProfileSection'])->middleware('forum.bot.protection:profile_update')->name('settings.profile.update');
|
|
Route::post('/settings/account/username', [ProfileController::class, 'updateUsername'])->middleware('forum.bot.protection:profile_update')->name('settings.account.username');
|
|
Route::post('/settings/account/update', [ProfileController::class, 'updateAccountSection'])->middleware('forum.bot.protection:profile_update')->name('settings.account.update');
|
|
Route::post('/settings/email/request', [ProfileController::class, 'requestEmailChange'])
|
|
->middleware('throttle:email-change-request')
|
|
->name('settings.email.request');
|
|
Route::post('/settings/email/verify', [ProfileController::class, 'verifyEmailChange'])
|
|
->middleware('throttle:10,1')
|
|
->name('settings.email.verify');
|
|
Route::post('/settings/personal/update', [ProfileController::class, 'updatePersonalSection'])->middleware('forum.bot.protection:profile_update')->name('settings.personal.update');
|
|
Route::post('/settings/notifications/update', [ProfileController::class, 'updateNotificationsSection'])->middleware('forum.bot.protection:profile_update')->name('settings.notifications.update');
|
|
Route::post('/settings/security/password', [ProfileController::class, 'updateSecurityPassword'])->middleware('forum.bot.protection:profile_update')->name('settings.security.password');
|
|
});
|
|
|
|
// ── UPLOAD ────────────────────────────────────────────────────────────────────
|
|
Route::middleware(['auth', 'ensure.onboarding.complete'])->group(function () {
|
|
Route::get('/upload', function () {
|
|
$contentTypes = ContentType::with(['rootCategories.children'])->get()->map(function ($ct) {
|
|
return [
|
|
'id' => $ct->id,
|
|
'name' => $ct->name,
|
|
'categories' => $ct->rootCategories->map(function ($c) {
|
|
return [
|
|
'id' => $c->id,
|
|
'name' => $c->name,
|
|
'children' => $c->children->map(function ($ch) {
|
|
return ['id' => $ch->id, 'name' => $ch->name];
|
|
})->values()->all(),
|
|
];
|
|
})->values()->all(),
|
|
];
|
|
})->values()->all();
|
|
|
|
return Inertia::render('Upload/Index', [
|
|
'draftId' => null,
|
|
'content_types' => $contentTypes,
|
|
'suggested_tags' => [],
|
|
'filesCdnUrl' => config('cdn.files_url'),
|
|
'chunkSize' => (int) config('uploads.chunk.max_bytes', 5242880),
|
|
'feature_flags' => [
|
|
'uploads_v2' => (bool) config('features.uploads_v2', false),
|
|
],
|
|
]);
|
|
})->name('upload');
|
|
|
|
Route::get('/upload/draft/{id}', function (string $id) {
|
|
$contentTypes = ContentType::with(['rootCategories.children'])->get()->map(function ($ct) {
|
|
return [
|
|
'id' => $ct->id,
|
|
'name' => $ct->name,
|
|
'categories' => $ct->rootCategories->map(function ($c) {
|
|
return [
|
|
'id' => $c->id,
|
|
'name' => $c->name,
|
|
'children' => $c->children->map(function ($ch) {
|
|
return ['id' => $ch->id, 'name' => $ch->name];
|
|
})->values()->all(),
|
|
];
|
|
})->values()->all(),
|
|
];
|
|
})->values()->all();
|
|
|
|
return Inertia::render('Upload/Index', [
|
|
'draftId' => $id,
|
|
'content_types' => $contentTypes,
|
|
'suggested_tags' => [],
|
|
'filesCdnUrl' => config('cdn.files_url'),
|
|
'chunkSize' => (int) config('uploads.chunk.max_bytes', 5242880),
|
|
'feature_flags' => [
|
|
'uploads_v2' => (bool) config('features.uploads_v2', false),
|
|
],
|
|
]);
|
|
})->whereUuid('id')->name('upload.draft');
|
|
});
|
|
|
|
// ── AUTH ──────────────────────────────────────────────────────────────────────
|
|
require __DIR__.'/auth.php';
|
|
|
|
// ── LEGACY ROUTES ─────────────────────────────────────────────────────────────
|
|
require __DIR__.'/legacy.php';
|
|
|
|
// ── SEARCH ────────────────────────────────────────────────────────────────────
|
|
Route::get('/search', [\App\Http\Controllers\Web\SearchController::class, 'index'])->name('search');
|
|
|
|
// ── MISC ──────────────────────────────────────────────────────────────────────
|
|
Route::view('/data-deletion', 'privacy.data-deletion')->name('privacy.data_deletion');
|
|
Route::view('/blank', 'blank')->name('blank');
|
|
|
|
// ── MESSAGES ──────────────────────────────────────────────────────────────────
|
|
Route::middleware(['auth', 'ensure.onboarding.complete'])
|
|
->get('/messages/attachments/{id}', [\App\Http\Controllers\Api\Messaging\AttachmentController::class, 'show'])
|
|
->whereNumber('id')
|
|
->name('messages.attachments.show');
|
|
|
|
Route::middleware(['auth', 'ensure.onboarding.complete'])->prefix('messages')->name('messages.')->group(function () {
|
|
Route::get('/', [\App\Http\Controllers\Messaging\MessagesPageController::class, 'index'])->name('index');
|
|
Route::get('/{id}', [\App\Http\Controllers\Messaging\MessagesPageController::class, 'show'])->whereNumber('id')->name('show');
|
|
});
|
|
|
|
// ── COMMUNITY ACTIVITY ────────────────────────────────────────────────────────
|
|
|
|
Route::get('/community/activity', [\App\Http\Controllers\Web\CommunityActivityController::class, 'index'])
|
|
->name('community.activity');
|
|
|
|
// ── FEEDS ─────────────────────────────────────────────────────────────────────
|
|
Route::middleware(['auth', 'ensure.onboarding.complete'])
|
|
->get('/feed/following', [\App\Http\Controllers\Web\Posts\FollowingFeedController::class, 'index'])
|
|
->name('feed.following');
|
|
|
|
Route::get('/feed/trending', [\App\Http\Controllers\Web\Posts\TrendingFeedController::class, 'index'])
|
|
->name('feed.trending');
|
|
|
|
Route::middleware(['auth'])
|
|
->get('/feed/saved', [\App\Http\Controllers\Web\Posts\SavedFeedController::class, 'index'])
|
|
->name('feed.saved');
|
|
|
|
Route::get('/feed/search', [\App\Http\Controllers\Web\Posts\SearchFeedController::class, 'index'])
|
|
->name('feed.search');
|
|
|
|
// ── CONTENT BROWSER (artwork / category universal router) ─────────────────────
|
|
// Bind the artwork route parameter by slug when possible, but don't hard-fail.
|
|
// Some URLs that match this shape are actually nested category paths such as
|
|
// /skins/audio/blazemedia-pro, which should fall through to category handling.
|
|
Route::bind('artwork', function ($value) {
|
|
return Artwork::where('slug', $value)->first();
|
|
});
|
|
|
|
Route::get('/{contentTypeSlug}/{categoryPath}/{artwork}', [BrowseGalleryController::class, 'showArtwork'])
|
|
->where('contentTypeSlug', 'photography|wallpapers|skins|other')
|
|
->where('categoryPath', '[^/]+(?:/[^/]+)*')
|
|
->name('artworks.show');
|
|
|
|
Route::get('/{contentTypeSlug}/{path?}', [BrowseGalleryController::class, 'content'])
|
|
->where('contentTypeSlug', 'photography|wallpapers|skins|other')
|
|
->where('path', '.*')
|
|
->name('content.route');
|
|
|
|
// ── FALLBACK 404 — must be last ───────────────────────────────────────────────
|
|
Route::fallback(function (\Illuminate\Http\Request $request) {
|
|
return app(\App\Http\Controllers\Web\ErrorController::class)->handleNotFound($request);
|
|
})->name('404.fallback');
|