watchparty/client/src/shell/Shell.html
Nicolas afae977b49
Some checks failed
Publier l'image Docker / test (pull_request) Failing after 4s
Publier l'image Docker / publish (pull_request) Has been skipped
Make the mobile nav sheet swipe-to-close instead of fighting pull-to-refresh
Reported directly: the only way to close the bottom sheet was tapping
the scrim, and the instinctive swipe-it-down gesture fell straight
through to the browser's own pull-to-refresh instead - nothing was
telling the browser this app's own code owned that gesture.

touch-action: none on the scrim and the (now real, not just visual)
grabber handle stops the browser's default touch handling from
kicking in there at all; overscroll-behavior: contain on the sheet
itself stops a drag that hits its own scroll boundary (the library
grid can run taller than the sheet's 75vh cap) from chaining to the
page underneath. The grabber's small 36x4px pill now sits inside a
much bigger invisible touch target that actually drags the sheet
(pointerdown/move/up, 1:1 tracking, snap back under 90px or close past
it) - scoped to the grabber alone, not the whole sheet, so the
library grid's own taps/scroll keep working untouched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 17:58:56 +02:00

49 lines
2.4 KiB
HTML

<div class="appShell">
<aside class="sidebar">
<div class="sidebarBrand">Watch Party</div>
<nav class="sidebarNav" id="sidebarNav">
<a href="#/home" class="navItem">Accueil</a>
<div class="navSectionLabel">Bibliothèques</div>
<p class="hint" id="libStatus"><span class="spinner"></span>Chargement...</p>
</nav>
<button class="linklike sidebarLogout logoutBtn" id="logout"></button>
</aside>
<!-- Mobile-only (see Shell.css's 720px breakpoint) - the sidebar
above is display:none there instead of reshaping into a
horizontal bar. See docs/architecture.md's "Mobile navigation". -->
<header class="mobileTopBar">
<span class="mobileBrand">Watch Party</span>
</header>
<main id="mainContent" class="mainContent"></main>
<!-- Wraps #musicBar so the trigger below always sits directly above
whatever height the bar actually renders at - see Shell.css. -->
<div class="bottomStack">
<div id="musicBar" class="musicBar"></div>
<button class="mobileNavTrigger" id="mobileNavTrigger" aria-expanded="false" aria-controls="mobileNavSheet">
Parcourir
<svg viewBox="0 0 24 24" width="14" height="14" aria-hidden="true">
<path d="M6 9l6 6 6-6" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
</button>
</div>
<div class="mobileNavScrim" id="mobileNavScrim"></div>
<div class="mobileNavSheet" id="mobileNavSheet">
<!-- Bigger invisible drag target than the visible pill itself (see
.sheetGrabberHandle) - touch-action:none so this app's own
pointer handlers (Shell.ts) drive the drag instead of the
browser's default touch handling, which otherwise reads a
downward drag here as pull-to-refresh (the sheet sits right at
the top of the page's own scroll position, same conflict a
plain scrim tap-only close used to leave unsolved). -->
<div class="sheetGrabberHandle" id="sheetGrabberHandle"><div class="sheetGrabber"></div></div>
<a href="#/home" class="navItem sheetPrimary"><span class="navIcon" data-icon="home"></span>Accueil</a>
<div class="navSectionLabel">Bibliothèques</div>
<div class="sheetGrid" id="mobileLibGrid"></div>
<div id="mobilePlaylistsSlot"></div>
<button class="linklike sheetLogout logoutBtn" id="mobileLogout"></button>
</div>
</div>