fix(shorts): embeds par fournisseur + flux infini (153/Forbidden/not-found)
This commit is contained in:
@@ -12,31 +12,33 @@
|
||||
|
||||
<!-- Player area: height is derived from dvh *and* vw so a 9:16 frame never
|
||||
overflows either a portrait phone or a landscape one. -->
|
||||
<div class="flex w-full min-h-0 items-center justify-center"
|
||||
(wheel)="onWheel($event)" (touchstart)="onTouchStart($event)" (touchend)="onTouchEnd($event)">
|
||||
<!-- Center column -->
|
||||
<div class="relative flex w-full min-w-0 items-center justify-center">
|
||||
<div class="flex w-full min-h-0 items-center justify-center gap-2 sm:gap-3"
|
||||
(wheel)="onWheel($event)" (touchstart)="onTouchStart($event)" (touchend)="onTouchEnd($event)">
|
||||
<!-- Center column : cadre 9:16 + rail d'actions (jamais en dehors de l'écran) -->
|
||||
<div class="relative flex w-full min-w-0 items-end sm:items-center justify-center gap-2 sm:gap-3">
|
||||
<!-- Video frame (9:16) -->
|
||||
<div class="shorts-frame rounded-xl overflow-hidden shadow-2xl ring-1 ring-slate-700/50 bg-black/90">
|
||||
<div class="shorts-frame relative shrink-0 rounded-xl overflow-hidden shadow-2xl ring-1 ring-slate-700/50 bg-black/90">
|
||||
@if (embedUrl(); as url) {
|
||||
<iframe [src]="url" [title]="current()?.title || 'Short video'" class="w-full h-full" frameborder="0" playsinline
|
||||
<iframe [src]="url" [title]="current()?.title || 'Short video'" class="absolute inset-0 w-full h-full" frameborder="0" playsinline
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
allowfullscreen></iframe>
|
||||
allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe>
|
||||
} @else if (loading()) {
|
||||
<div class="w-full h-full flex flex-col gap-3 items-center justify-center bg-slate-800 text-slate-400 text-sm">
|
||||
<div class="absolute inset-0 flex flex-col gap-3 items-center justify-center bg-slate-800 text-slate-400 text-sm">
|
||||
<div class="h-8 w-8 rounded-full border-2 border-slate-600 border-t-red-500 animate-spin" aria-hidden="true"></div>
|
||||
<span role="status">Chargement des Shorts…</span>
|
||||
</div>
|
||||
} @else if (error()) {
|
||||
<div class="w-full h-full flex flex-col gap-3 items-center justify-center text-slate-300 p-6 text-center">
|
||||
<div class="absolute inset-0 flex flex-col gap-3 items-center justify-center text-slate-300 p-6 text-center">
|
||||
<span>{{ error() }}</span>
|
||||
<button (click)="retry()" class="chip px-4 py-3 rounded bg-slate-700 hover:bg-slate-600 text-white text-sm">Réessayer</button>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- Bottom overlay: meta -->
|
||||
<!-- Bottom overlay: meta. pointer-events-none pour ne jamais bloquer
|
||||
les boutons du lecteur (play / volume / plein écran). Seul le
|
||||
lien "Ouvrir" reste cliquable. -->
|
||||
@if (current(); as v) {
|
||||
<div class="absolute left-0 right-0 bottom-0 p-3 sm:p-4 bg-gradient-to-t from-black/70 to-transparent text-white">
|
||||
<div class="pointer-events-none absolute left-0 right-0 bottom-0 p-3 sm:p-4 bg-gradient-to-t from-black/70 to-transparent text-white">
|
||||
<div class="flex items-center gap-3 text-sm">
|
||||
<img [src]="v.uploaderAvatar" [alt]="v.uploaderName" class="h-8 w-8 shrink-0 rounded-full object-cover">
|
||||
<div class="flex-1 min-w-0">
|
||||
@@ -44,12 +46,26 @@
|
||||
<div class="opacity-80 line-clamp-1">@{{ v.uploaderName }}</div>
|
||||
</div>
|
||||
<a *ngIf="watchLink()" [routerLink]="watchLink()" [queryParams]="watchQueryParams()"
|
||||
class="chip shrink-0 px-3 py-2 rounded bg-white/20 hover:bg-white/30 text-xs">Ouvrir</a>
|
||||
class="chip pointer-events-auto shrink-0 px-3 py-2 rounded bg-white/20 hover:bg-white/30 text-xs">Ouvrir</a>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<!-- Rail d'actions façon YouTube Shorts (à droite du cadre 9:16) -->
|
||||
<div class="flex shrink-0 flex-col items-center gap-2 pb-1">
|
||||
<a *ngIf="providerUrl()" [href]="providerUrl()" target="_blank" rel="noopener"
|
||||
class="flex h-11 w-11 items-center justify-center rounded-full bg-slate-800/80 text-white hover:bg-slate-700"
|
||||
title="Ouvrir chez le fournisseur" aria-label="Ouvrir chez le fournisseur">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>
|
||||
</a>
|
||||
<button type="button" (click)="skipUnplayable()"
|
||||
class="flex h-11 w-11 items-center justify-center rounded-full bg-slate-800/80 text-white hover:bg-slate-700"
|
||||
title="Vidéo illisible ? Passer à la suivante" aria-label="Passer la vidéo illisible">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@if (busyMore()) {
|
||||
<div class="absolute top-2 left-1/2 -translate-x-1/2 px-3 py-2 rounded-full bg-black/70 text-white text-xs" role="status">Chargement…</div>
|
||||
}
|
||||
@@ -80,4 +96,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 inline" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M7 10l5 5 5-5H7z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<p class="max-w-lg text-center text-xs text-slate-500">Si une vidéo affiche une erreur (153, Forbidden, introuvable…), utilisez ⏭ Passer : elle est retirée du flux.</p>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user