fix(ui): E31 S2 — the tab names the object, the channel header wraps, the player fits a short window
- The browser tab names the place and the object: PageHeading reports the view's own title (lib/documentTitle), so a channel, playlist or any Plex view reads "<object> · <module> · Siftlode" however it was opened; the Feed is named too; a season adds its show (tabTitle). - The channel page's tab + action row wraps and lets the tag lane fold into "+N": at 1024 it ran past the edge and the page scrolled sideways. - The YouTube player card's width is capped from the window height less the chrome measured under the video: at 133% zoom (685px) it cut its channel row. - Plex certificate words (Not Rated, Approved, Passed) are named through the vocabulary on the info badge, show page, collection, filter and chips. - DESIGN.md: the zoom target is 125% and 133%, not 200% (decision log).
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
// then browser Back — is still checked in a real browser: jsdom reproduces history ordering only as
|
||||
// bookkeeping.
|
||||
import { describe, it, expect, afterEach, beforeEach, vi } from "vitest";
|
||||
import { renderHook, act, cleanup } from "@testing-library/react";
|
||||
import { renderHook, render as rtlRender, act, cleanup } from "@testing-library/react";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
@@ -28,6 +28,7 @@ vi.mock("react-i18next", async (importOriginal) => {
|
||||
import { NavigationProvider } from "./NavigationProvider";
|
||||
import { useNavigation, useNavigationActions } from "./navigationContext";
|
||||
import { useBackToClose } from "../lib/history";
|
||||
import { PageHeading } from "./ui/Headings";
|
||||
|
||||
import { qk } from "../lib/queryKeys";
|
||||
|
||||
@@ -88,6 +89,41 @@ describe("NavigationProvider · the tab title", () => {
|
||||
expect(document.title).not.toBe("Siftlode");
|
||||
expect(document.title.endsWith(" · Siftlode")).toBe(true);
|
||||
});
|
||||
|
||||
// E31 S1: the Feed's tab read a bare "Siftlode" — the one page that named no place.
|
||||
it("names the Feed like every other page", async () => {
|
||||
window.history.replaceState({ sfPage: "feed" }, "", "/?page=feed");
|
||||
render();
|
||||
await settle();
|
||||
expect(document.title).toBe("header.account.feed · Siftlode");
|
||||
});
|
||||
|
||||
// E31 S1: a channel opened from a link was "Channels · Siftlode", the same channel opened in the
|
||||
// app was named; a Plex title, person or collection only "Plex". The object is the view's heading.
|
||||
it("puts the open view's own heading before the place, and drops it when the view closes", async () => {
|
||||
window.history.replaceState({ sfPage: "plex" }, "", "/?page=plex");
|
||||
function View({ name }: { name: string | null }) {
|
||||
return name === null ? null : <PageHeading>{name}</PageHeading>;
|
||||
}
|
||||
const view = rtlRender(<View name="" />, { wrapper });
|
||||
await settle();
|
||||
expect(document.title).toBe("plex.navLabel · Siftlode"); // no title yet: the place alone
|
||||
|
||||
view.rerender(<View name="Nicolas Cage" />);
|
||||
await settle();
|
||||
expect(document.title).toBe("Nicolas Cage · plex.navLabel · Siftlode");
|
||||
|
||||
view.rerender(<View name={null} />);
|
||||
await settle();
|
||||
expect(document.title).toBe("plex.navLabel · Siftlode");
|
||||
});
|
||||
|
||||
it("takes a heading's tabTitle over its text", async () => {
|
||||
window.history.replaceState({ sfPage: "plex" }, "", "/?page=plex");
|
||||
rtlRender(<PageHeading tabTitle="Voyager · Season 1">Season 1</PageHeading>, { wrapper });
|
||||
await settle();
|
||||
expect(document.title).toBe("Voyager · Season 1 · plex.navLabel · Siftlode");
|
||||
});
|
||||
});
|
||||
|
||||
describe("NavigationProvider · setPage's same-page guard", () => {
|
||||
|
||||
Reference in New Issue
Block a user