fix(player): letterbox the picture, and stop racing the session
Two bugs found by resizing the window during playback. Neither was introduced by this branch; both are the kind that only surface when somebody actually drags a window edge. The picture cropped and sat at the top instead of letterboxing. The video's flex wrapper had no `min-h-0`, and a flex item defaults to `min-height: auto` — it refuses to shrink below its content's intrinsic size, and a <video> reports the *media's* natural dimensions. So whenever the picture was larger than the window the wrapper grew past the viewport, the overflow went off the bottom, and what was visible was the top-left of an uncentred, uncropped image. `object-contain` was doing its job the whole time, inside a box that was the wrong size. This is also what put the picture at the bottom in fullscreen, reported earlier and unexplained until now. "Not connected to a server", shown as a *playback* error. The player page asks for the repository on mount, but the session is restored asynchronously at startup, so losing that race turned a perfectly good stream into a fatal error screen. `getRepository()` throwing instantly is right for a click handler, where the user is present; it is wrong for anything that runs on mount. `waitForRepository()` resolves as soon as the session lands and still rejects when there genuinely is not one, so a real logged-out state surfaces — just not as a race. Worth recording how this was found, because it was nearly misdiagnosed: the symptom correlated with window resizes, but the log showed 230 Vite HMR updates against a single app start — the frontend was being remounted under the test by edits made while it ran, and a remount empties the in-memory auth store. The race is real and worth fixing on its own merits, but "resize causes it" was an artifact of how it was being observed, not a property of the bug. UT-215 covers the waiting contract: resolves when already restored, resolves when the session arrives late, still rejects when there is none, unsubscribes once settled, and leaves no armed timer to reject an already-resolved promise.
This commit is contained in:
@@ -2533,7 +2533,22 @@
|
||||
aria-label="Video player"
|
||||
>
|
||||
<!-- Video -->
|
||||
<div class="flex-1 flex items-center justify-center relative">
|
||||
<!--
|
||||
`min-h-0` / `min-w-0` are load-bearing, not defensive. A flex item defaults
|
||||
to `min-height: auto`, which refuses to shrink below its content's intrinsic
|
||||
size — and the <video> inside reports the *media's* natural dimensions. So
|
||||
without them this wrapper grows past the viewport whenever the picture is
|
||||
larger than the window: the overflow goes off the bottom, which reads as the
|
||||
image being cropped and aligned to the top rather than letterboxed and
|
||||
centred. `object-contain` was never the problem; it was doing its job inside
|
||||
a box that was itself the wrong size.
|
||||
|
||||
Reproduces by resizing the window during playback, and by entering
|
||||
fullscreen — where the same overflow put the picture at the bottom.
|
||||
|
||||
TRACES: UR-005 | DR-024
|
||||
-->
|
||||
<div class="flex-1 min-h-0 min-w-0 flex items-center justify-center relative">
|
||||
{#if !!useHtml5Element}
|
||||
<!-- HTML5 video for desktop/non-Android platforms -->
|
||||
<video
|
||||
|
||||
Reference in New Issue
Block a user