fix(shorts): hover-chrome, swipe mobile garanti, avance auto fiabilisee
CI / build-and-test (push) Successful in 15m2s
CI / build-and-test (push) Successful in 15m2s
Chrome auto-hide au hover desktop (2,5 s). Capteur tactile mobile : swipe garanti (l'iframe mangeait les touchers), tap = play/pause YT ou 6 s d'acces direct au lecteur sinon. Fleche retour accueil mobile, cadre quasi plein ecran. Avance auto : handshake YT listening (les evenements player n'arrivaient jamais), onStateChange canonique, retry borne anti-prefetch. Docs 9.9.
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
<div class="shorts-stage relative flex min-h-[calc(var(--app-vh,100dvh)-var(--header-offset,0px))] w-full flex-col items-center overflow-hidden bg-black" (click)="closeMenu()">
|
||||
<div class="shorts-stage relative flex min-h-[calc(var(--app-vh,100dvh)-var(--header-offset,0px))] w-full flex-col items-center overflow-hidden bg-black"
|
||||
[class.shorts-chrome-hidden]="!chromeVisible()"
|
||||
(click)="closeMenu()" (mousemove)="pokeChrome()">
|
||||
<!-- Fond d'ambiance : vignette du short courant, floutée (façon YouTube). -->
|
||||
<div class="shorts-ambient" aria-hidden="true">
|
||||
@if (current()?.thumbnail) {
|
||||
@@ -6,8 +8,15 @@
|
||||
}
|
||||
</div>
|
||||
|
||||
<!-- Retour accueil (mobile plein écran : la vidéo occupe tout, pas de header visible) -->
|
||||
<a routerLink="/"
|
||||
class="absolute top-2 left-2 z-20 flex h-11 w-11 items-center justify-center rounded-full bg-black/60 text-white hover:bg-black/80 sm:hidden"
|
||||
title="Retour à l'accueil NewTube" aria-label="Retour à l'accueil NewTube" (click)="$event.stopPropagation()">
|
||||
<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="M19 12H5m7-7l-7 7 7 7"/></svg>
|
||||
</a>
|
||||
|
||||
<!-- Sélecteur : Pour toi + fournisseurs -->
|
||||
<div class="scroll-rail no-scrollbar relative z-10 flex w-full max-w-full items-center justify-start gap-2 overflow-x-auto px-3 pt-3 sm:justify-center" role="tablist" aria-label="Fournisseur des Shorts" (click)="$event.stopPropagation()">
|
||||
<div class="scroll-rail no-scrollbar shorts-chrome relative z-10 flex w-full max-w-full items-center justify-start gap-2 overflow-x-auto px-3 pt-3 sm:justify-center" role="tablist" aria-label="Fournisseur des Shorts" (click)="$event.stopPropagation()">
|
||||
<button (click)="toggleForYou()"
|
||||
[attr.aria-pressed]="forYou()"
|
||||
class="chip shrink-0 px-3 py-2 rounded-full text-[13px] border transition-colors min-h-[44px]"
|
||||
@@ -29,7 +38,7 @@
|
||||
(wheel)="onWheel($event)" (touchstart)="onTouchStart($event)" (touchend)="onTouchEnd($event)">
|
||||
<!-- Flèche précédent (bureau, façon YouTube) -->
|
||||
<button type="button" (click)="prev(); $event.stopPropagation()" [disabled]="!canPrev()"
|
||||
class="chip hidden sm:flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/20 disabled:opacity-30"
|
||||
class="shorts-chrome chip hidden sm:flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/20 disabled:opacity-30"
|
||||
aria-label="Short précédent">
|
||||
<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="M7 14l5-5 5 5H7z"/></svg>
|
||||
</button>
|
||||
@@ -55,8 +64,23 @@
|
||||
}
|
||||
|
||||
@if (current(); as v) {
|
||||
<!-- Capteur tactile (mobile uniquement) : l'iframe mange les
|
||||
touchers, donc le swipe up/down passerait à la trappe. Cette
|
||||
couche transparente capte swipe (navigue) et tap (play/pause
|
||||
YouTube, ou accès direct au lecteur 6 s sinon). `touch-action`
|
||||
via CSS : le navigateur ne scrolle/zoome pas, nos handlers
|
||||
possèdent le geste. En mode passthrough, elle s'efface
|
||||
(les boutons du fournisseur deviennent touchables). -->
|
||||
<div class="shorts-gesture absolute inset-0 z-[1] sm:hidden"
|
||||
[class.pointer-events-none]="passthrough()"
|
||||
aria-hidden="true"></div>
|
||||
|
||||
@if (passthroughHint()) {
|
||||
<div class="absolute left-1/2 top-14 z-20 -translate-x-1/2 whitespace-nowrap px-3 py-1.5 rounded-full bg-black/75 text-white text-xs" role="status">Commandes du lecteur accessibles</div>
|
||||
}
|
||||
|
||||
<!-- Haut droite : plein écran, partage rapide, menu ⋯ -->
|
||||
<div class="absolute top-2 right-2 flex items-center gap-1.5" (click)="$event.stopPropagation()">
|
||||
<div class="shorts-chrome absolute top-2 right-2 z-10 flex items-center gap-1.5" (click)="$event.stopPropagation()">
|
||||
<button type="button" (click)="toggleFullscreen()" class="flex h-10 w-10 items-center justify-center rounded-full bg-black/60 text-white hover:bg-black/80" [title]="isFullscreen() ? 'Quitter le plein écran' : 'Plein écran'" aria-label="Plein écran">
|
||||
@if (isFullscreen()) {
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3"/></svg>
|
||||
@@ -86,7 +110,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Rail d'actions OVERLAY façon YouTube (dans le cadre, comme sur mobile natif) -->
|
||||
<div class="absolute right-1.5 sm:right-2.5 bottom-32 sm:bottom-36 flex flex-col items-center gap-2 sm:gap-2.5" (click)="$event.stopPropagation()">
|
||||
<div class="shorts-chrome absolute right-1.5 sm:right-2.5 bottom-32 sm:bottom-36 z-10 flex flex-col items-center gap-2 sm:gap-2.5" (click)="$event.stopPropagation()">
|
||||
<div class="flex flex-col items-center">
|
||||
<button type="button" (click)="toggleLike()" [disabled]="!isLoggedIn() || likeBusy()"
|
||||
class="flex h-12 w-12 items-center justify-center rounded-full bg-black/55 text-white hover:bg-black/75 disabled:opacity-40"
|
||||
@@ -126,7 +150,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Bas : avatar + titre + méta + fraîcheur + S'abonner (safe-area incluse) -->
|
||||
<div class="shorts-meta pointer-events-none absolute left-0 right-0 bottom-0 p-3 sm:p-4 text-white bg-gradient-to-t from-black/85 via-black/35 to-transparent">
|
||||
<div class="shorts-meta shorts-chrome pointer-events-none absolute left-0 right-0 bottom-0 z-10 p-3 sm:p-4 text-white bg-gradient-to-t from-black/85 via-black/35 to-transparent">
|
||||
<div class="flex items-end gap-2.5 text-sm" (click)="$event.stopPropagation()">
|
||||
@if (v.uploaderAvatar) {
|
||||
<img [src]="v.uploaderAvatar" [alt]="v.uploaderName" class="h-10 w-10 shrink-0 rounded-full object-cover ring-2 ring-white/40" loading="lazy" />
|
||||
@@ -180,7 +204,7 @@
|
||||
|
||||
<!-- Flèche suivant (bureau, façon YouTube) -->
|
||||
<button type="button" (click)="next(); $event.stopPropagation()" [disabled]="!canNext()"
|
||||
class="chip hidden sm:flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/20 disabled:opacity-30"
|
||||
class="shorts-chrome chip hidden sm:flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/20 disabled:opacity-30"
|
||||
aria-label="Short suivant">
|
||||
<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="M7 10l5 5 5-5H7z"/></svg>
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user