feat(home): Shorts shelf above the main feed

The home grid used to interleave shorts with regular videos ordered by
upload date, so a cluster of 60-second portrait clips could fill the
first row and push the non-shorts off the fold. Split them:

- The main feed grid now excludes shorts (notShorts() filter).
- A horizontally-scrolling Shorts shelf renders above the grid with
  up to 12 latest shorts, each a real <a href> to /shorts/{id} so
  tapping it deep-links the vertical feed to that short.
- "See all" link in the shelf header jumps to the full /shorts feed.
- Shelf is skipped entirely when there are no shorts to show.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
ghassanandClaude Opus 4.7 committed 2026-10-21 10:31:27 +03:00
1 parent 9e613c05d2
commit c3955c4a7c
2 files changed
+61 -2

No files matched your search

+7 -2
View File
@@ -176,7 +176,12 @@ class VideoController extends Controller
}
// ── All (home) — mixed chronological feed ─────────────────
$videos = Video::public()->latest()->limit(60)->get();
// Videos shown in the grid are the newest non-shorts. Shorts render
// in their own horizontally-scrolling shelf injected after the first
// row of cards (see videos/index.blade.php), so the home grid isn't
// diluted by 60-second portrait clips.
$videos = Video::public()->notShorts()->latest()->limit(60)->get();
$homeShorts = Video::public()->where('is_shorts', true)->latest()->limit(12)->get();
$playlistQuery = Playlist::withCount('videos')
->with(['user', 'videos' => fn($q) => $q->orderBy('playlist_videos.position')->limit(1)])
@@ -193,7 +198,7 @@ class VideoController extends Controller
->sortByDesc('date')
->values();
return view('videos.index', compact('feedItems', 'filter', 'langChips') + [
return view('videos.index', compact('feedItems', 'filter', 'langChips', 'homeShorts') + [
'videos' => collect(), 'shorts' => collect(), 'matches' => collect(), 'playlists' => collect(),
]);
}