fix(ui): toasts raised while a full-screen player is open show inside it, not under its scrim

The app's Toaster lives in the content column, which is a stacking context (its `@container` implies
layout containment), so both full-screen players — portalled to <body> at the same z-index — painted
over every toast. Round 1's "a failed Remove is reported" fix was therefore still silent inside the
player: its toast sat under an 80% black, blurred scrim (elementFromPoint returned the scrim), and a
click on it closed the player.

An overlay now mounts its own `<Toaster overlay />`, and exactly one host shows the toasts: the most
recently mounted overlay, else the app's. Same component, same look — and inside the aria-modal
dialog, where a screen reader can still reach it. A click on a toast inside an overlay stays there.
Both players get one (the Plex player's also works in native fullscreen, where nothing outside the
fullscreen element is drawn). Verified on localdev: the removal failure reads above the scrim,
bottom-left, and clicking it leaves the player open.
This commit is contained in:
2026-09-11 03:18:55 +02:00
parent 645d14f45d
commit 6de2cd950d
5 changed files with 118 additions and 3 deletions
+4
View File
@@ -43,6 +43,7 @@ import { PlexPlayerSettings } from "./PlexPlayerSettings";
import { PlexStatsOverlay } from "./PlexStatsOverlay";
import { createFragMeter } from "../lib/plexStats";
import { UpNextCard } from "./UpNextCard";
import Toaster from "./ui/Toaster";
import {
useAutoSkip,
useControlsVisibility,
@@ -1379,6 +1380,9 @@ export default function PlexPlayer({ itemId, onClose, queue }: Props) {
</div>
</div>
)}
{/* The app's Toaster is underneath this full-screen player (and outside it in native
fullscreen), so toasts raised while watching show here instead. See ui/Toaster. */}
<Toaster overlay />
</div>,
document.body,
);