feat(e24): reach the Home surface — the landing toggle, a palette command, Shift+W
S4's reachability half. Home already led the nav order; what was missing was every way IN other than the rail. - Settings → Appearance → Startup: "Start on Home", the documented escape hatch for the landing override. Deliberately still localStorage and not a server pref — `loadInitialPage` answers before /api/me lands, and a landing module decided after the first paint is a visible jump. Its two stored values are now ONE exported constant, so the writer and the boot-time reader cannot drift on a magic string. - The command palette gets "Meglepetés" / "Surprise me": it navigates to Home and rerolls the hero on arrival. No second "Mit nézzek?" row beside it — the Home module row already matches that phrase through its descriptive title. - A global Shift+W jumps to Home. A chord, not a bare `w`: the Plex player binds bare letters and `w` sits on `s`, so a blind reach for the subtitle key would have thrown a viewer out of the film. The palette's request crosses a lazy module boundary, so it is a token that waits (lib/homeIntent) rather than an event fired into an empty room. Browser-measured: taken with a compare-and-clear, because StrictMode's double-invoked mount effect otherwise rerolled twice and landed on the page two picks deep. HU/EN parity kept; UAT on localdev in both languages, including the empty shelf.
This commit is contained in:
@@ -27,9 +27,9 @@ afterEach(() => {
|
||||
closeKeyboardHelp();
|
||||
});
|
||||
|
||||
/** App's job: it binds the `global` scope (h / Mod+K) once for the whole tree. */
|
||||
/** App's job: it binds the `global` scope (h / Mod+K / Shift+W) once for the whole tree. */
|
||||
function Host({ children }: { children?: React.ReactNode }) {
|
||||
useGlobalKeymap();
|
||||
useGlobalKeymap(true, () => {});
|
||||
return (
|
||||
<>
|
||||
{children}
|
||||
@@ -83,13 +83,13 @@ describe("KeyboardHelp", () => {
|
||||
const rows = descriptions();
|
||||
// A plexPlayer row first, the app-wide rows last — the reading order the reader wants.
|
||||
expect(rows[0]).toBe("keys.playPause");
|
||||
expect(rows.slice(-2)).toEqual(["keys.palette", "keys.help"]);
|
||||
expect(rows.slice(-3)).toEqual(["keys.palette", "keys.help", "keys.home"]);
|
||||
});
|
||||
|
||||
it("lists only the app-wide keys when no surface is registered", () => {
|
||||
render(<Host />);
|
||||
pressH();
|
||||
expect(descriptions()).toEqual(["keys.palette", "keys.help"]);
|
||||
expect(descriptions()).toEqual(["keys.palette", "keys.help", "keys.home"]);
|
||||
});
|
||||
|
||||
// The context menu is NOT app-wide: it has its own scope, registered by `useContextMenu`, so the
|
||||
|
||||
Reference in New Issue
Block a user