Language filter chips on the videos feed
Adds one chip per language currently present in public content —
counting both primary language and any secondary audio track, sorted
by video count, capped at 12. Clicking a chip lists every video whose
primary is that language or that has a matching secondary track; cards
surfaced only via a secondary track link straight to /videos/{key}?track=<id>
so the pinned playback wiring loads the right audio, get a small flag
badge on the thumbnail, and their hover-preview streams the track file
instead of the primary.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
1 parent
8d27520bdb
commit
fcb752dd76
4 files changed
+163
-10
No files matched your search
@@ -3,7 +3,15 @@
|
||||
@php
|
||||
use App\Data\Languages;
|
||||
|
||||
$videoUrl = $video ? route('videos.stream', $video) : null;
|
||||
// When a specific audio track is being surfaced (e.g. via the language
|
||||
// filter chips), the hover-preview should play that language, not the
|
||||
// primary. audio-track route serves the track file directly.
|
||||
$forceTrackIdEarly = $video ? $video->getAttribute('_force_track_id') : null;
|
||||
$videoUrl = $video
|
||||
? ($forceTrackIdEarly
|
||||
? route('videos.audio-track', ['video' => $video, 'track' => $forceTrackIdEarly])
|
||||
: route('videos.stream', $video))
|
||||
: null;
|
||||
$thumbnailUrl = $video && $video->thumbnail
|
||||
? route('media.thumbnail', $video->thumbnail)
|
||||
: ($video ? 'https://picsum.photos/seed/' . $video->id . '/640/360' : 'https://picsum.photos/seed/random/640/360');
|
||||
@@ -20,8 +28,18 @@ $isShorts = $video && $video->isShorts();
|
||||
// Check if current user is the owner of the video
|
||||
$isOwner = $video && auth()->check() && auth()->id() == $video->user_id;
|
||||
|
||||
// Language flag code (null when no language set)
|
||||
$langFlag = $video ? Languages::flag($video->language) : null;
|
||||
// When surfacing a video via a secondary audio track (e.g. from the
|
||||
// language filter chips) the controller tags it with these runtime
|
||||
// attributes so the card links straight to that track and badges the
|
||||
// thumbnail with its flag.
|
||||
$forceTrackId = $video ? $video->getAttribute('_force_track_id') : null;
|
||||
$forceTrackFlag = $video ? $video->getAttribute('_force_track_flag') : null;
|
||||
|
||||
// Language flag code (null when no language set). Prefer the forced
|
||||
// track flag when set — it's the language the card is being surfaced for.
|
||||
$langFlag = $forceTrackFlag ?: ($video ? Languages::flag($video->language) : null);
|
||||
|
||||
$showUrl = $video ? route('videos.show', $video) . ($forceTrackId ? ('?track=' . $forceTrackId) : '') : '#';
|
||||
|
||||
// Size classes
|
||||
$sizeClasses = match($size) {
|
||||
@@ -31,7 +49,7 @@ $sizeClasses = match($size) {
|
||||
@endphp
|
||||
|
||||
<div class="yt-video-card {{ $sizeClasses }}" data-video-url="{{ $videoUrl }}">
|
||||
<a href="{{ $video ? route('videos.show', $video) : '#' }}">
|
||||
<a href="{{ $showUrl }}">
|
||||
<div class="yt-video-thumb" onmouseenter="playVideo(this)" onmouseleave="stopVideo(this)"
|
||||
data-audio="{{ $video && $video->isAudioOnly() ? 'true' : 'false' }}">
|
||||
<img src="{{ $thumbnailUrl }}" alt="{{ $video->title ?? 'Video' }}" loading="lazy" decoding="async" onload="this.classList.add('loaded');this.closest('.yt-video-thumb').classList.add('loaded')">
|
||||
@@ -54,6 +72,12 @@ $sizeClasses = match($size) {
|
||||
<i class="bi bi-collection-play-fill"></i> SHORTS
|
||||
</span>
|
||||
@endif
|
||||
@if($forceTrackId && $forceTrackFlag)
|
||||
<span class="yt-track-lang-badge" title="Plays the {{ strtoupper($video->language ?? '') }} track's language variant">
|
||||
<span class="fi fi-{{ $forceTrackFlag }}"></span>
|
||||
<span>Track</span>
|
||||
</span>
|
||||
@endif
|
||||
@if($isOwner && $video->visibility === 'private')
|
||||
<span class="yt-visibility-badge yt-visibility-private">
|
||||
<i class="bi bi-lock-fill"></i> Private
|
||||
@@ -74,7 +98,7 @@ $sizeClasses = match($size) {
|
||||
</a>
|
||||
<div class="yt-video-details">
|
||||
<h3 class="yt-video-title">
|
||||
<a href="{{ $video ? route('videos.show', $video) : '#' }}">
|
||||
<a href="{{ $showUrl }}">
|
||||
@if($langFlag)
|
||||
<span class="fi fi-{{ $langFlag }} vc-lang-flag"></span>
|
||||
@endif
|
||||
|
||||
Reference in new issue
Block a user