fix(boot): review round 1 — reconcile the tab pin, one loading clock, honest probe failures
Deep-review round 1 over main..improvement/watch-background-audio. BootGate - The tab's account pin is corrected to the account the server answered as. The server honours the pin only for an account still signed in to this browser and otherwise answers as the default, so a tab pinned to an account signed out in another tab ran as the default on the server while reading and writing the gone account's local state. - A mounted tab whose identity changes (its session ended, or the case above) reloads instead of rebuilding the tree in place, like every account switch; that also drops the previous account's query cache. The account key on the tree goes: the readyFor gate already unmounted it on every change. - An unanswered setup probe shows the error with Retry, like an unanswered account probe, instead of the signed-out landing to a signed-in user. - Comments: /api/me never 401s; the ended-session path is identity → nobody. Loading states - LoadingState's reveal delay is one clock across loading states that hand over to each other (boot screen → page-chunk fallback → the page's own fetching state), instead of a CSS delay restarted by each, which blanked a visible spinner for another 300 ms at every hand-off. BootScreen is now the shared loading visual, full screen, counting from navigation start. Plex shared link - Persists only the dimensions the link carries again. Writing the default filters for an omitted `pf` created the stored-filters key, which is what tells SavedViewsProvider the account picked filters, so the account's default Plex saved view was never applied again. Watch page - The Repeat toggle uses the shared pressed-pill paint (a solid fill when on) instead of Button variants that differ only in colour, and its flag goes through storage.ts readJSON/writeJSON. - The actions wrap under the title when the row is too narrow, instead of squeezing the title into a column a word wide on a phone; the title breaks long words. Comments that still justified code by the removed adopt effects (usePref, PrefsProvider, FeedViewProvider) are rewritten against the seed-once model. Tests: BootGate error/retry for both probes, setup mode, a failed background refetch keeping the app, the pin correction and the reload on an identity change; the shared reveal clock; the Plex link persist; the audio signature actually moved off version 4; a video download (av and v) still remuxed to an mp4. Each mutation-checked RED for its own reason.
This commit is contained in:
@@ -3,7 +3,7 @@ import { Download, File as FileIcon, Link2, Lock, PlayCircle, Repeat } from "luc
|
||||
import { Button } from "./ui/Button";
|
||||
import { formatBytes } from "../lib/format";
|
||||
import { exposeVideoToBackgroundPlay } from "../lib/browserBackgroundPlay";
|
||||
import { LS } from "../lib/storage";
|
||||
import { LS, readJSON, writeJSON } from "../lib/storage";
|
||||
|
||||
// Standalone, login-free video page for a shared /watch/<token> link. Rendered OUTSIDE the app
|
||||
// tree (no auth, no providers) — like the /privacy and /terms pages. Uses plain fetch and a tiny
|
||||
@@ -137,21 +137,11 @@ export default function WatchPage() {
|
||||
|
||||
// Repeat the shared media when it ends — on unless the viewer turned it off. Remembered per browser
|
||||
// (this page has no account); an unreadable storage just means the default.
|
||||
const [repeat, setRepeat] = useState(() => {
|
||||
try {
|
||||
return localStorage.getItem(LS.watchRepeat) !== "0";
|
||||
} catch {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
const [repeat, setRepeat] = useState(() => readJSON<boolean>(LS.watchRepeat, true) !== false);
|
||||
const toggleRepeat = () => {
|
||||
const next = !repeat;
|
||||
setRepeat(next);
|
||||
try {
|
||||
localStorage.setItem(LS.watchRepeat, next ? "1" : "0");
|
||||
} catch {
|
||||
/* storage unavailable — the toggle still applies to this visit */
|
||||
}
|
||||
writeJSON(LS.watchRepeat, next);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -310,9 +300,13 @@ export default function WatchPage() {
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="mt-3 flex items-start gap-3">
|
||||
<div className="min-w-0 flex-1">
|
||||
<h1 className="text-lg font-semibold leading-snug">{meta.title || "Video"}</h1>
|
||||
{/* The actions wrap under the title when the row is too narrow for both (a phone), rather
|
||||
than squeezing the title into a column a word wide. */}
|
||||
<div className="mt-3 flex flex-wrap items-start gap-x-3 gap-y-2">
|
||||
<div className="min-w-0 flex-1 basis-60">
|
||||
<h1 className="text-lg font-semibold leading-snug break-words">
|
||||
{meta.title || "Video"}
|
||||
</h1>
|
||||
{meta.uploader &&
|
||||
(meta.uploader_url ? (
|
||||
<a
|
||||
@@ -327,24 +321,26 @@ export default function WatchPage() {
|
||||
<div className="text-sm text-muted">{meta.uploader}</div>
|
||||
))}
|
||||
</div>
|
||||
<Button
|
||||
variant={repeat ? "outline-accent" : "outline"}
|
||||
size="md"
|
||||
icon={<Repeat className="w-4 h-4" />}
|
||||
aria-pressed={repeat}
|
||||
onClick={toggleRepeat}
|
||||
className="shrink-0"
|
||||
>
|
||||
{T.repeat}
|
||||
</Button>
|
||||
{meta.allow_download && (
|
||||
<a
|
||||
href={meta.file_url}
|
||||
className="shrink-0 inline-flex items-center gap-1.5 rounded-lg bg-surface hover:bg-card px-3 py-2 text-sm font-medium transition"
|
||||
<div className="flex shrink-0 items-center gap-2">
|
||||
{/* An on/off toggle, so the shared pressed-pill paint (a solid fill when on) — not a
|
||||
Button, whose variants differ only in colour. */}
|
||||
<button
|
||||
type="button"
|
||||
aria-pressed={repeat}
|
||||
onClick={toggleRepeat}
|
||||
className="pill inline-flex items-center gap-1.5 rounded-lg border px-3 py-2 text-sm font-medium"
|
||||
>
|
||||
<Download className="w-4 h-4" /> {T.download}
|
||||
</a>
|
||||
)}
|
||||
<Repeat className="w-4 h-4" aria-hidden /> {T.repeat}
|
||||
</button>
|
||||
{meta.allow_download && (
|
||||
<a
|
||||
href={meta.file_url}
|
||||
className="inline-flex items-center gap-1.5 rounded-lg bg-surface hover:bg-card px-3 py-2 text-sm font-medium transition"
|
||||
>
|
||||
<Download className="w-4 h-4" /> {T.download}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{(meta.source_url || (meta.extra_links && meta.extra_links.length > 0)) && (
|
||||
<div className="mt-3 flex flex-col gap-1.5">
|
||||
|
||||
Reference in New Issue
Block a user