feat(profiles): switch profile from the account menu

Switching was reachable only from Settings, which is the wrong place for
it: on a shared device changing who is watching is a frequent, front-door
action, not a configuration change buried three screens deep.

It sits directly under the identity block rather than among the
destinations (Downloads/Settings/Display), because it answers "who is
this?" and not "where do I go?". Shown even with one account, since the
picker is also where a second is added -- gating it on a second profile
existing would leave no way in from here.

The picker also gains a Back affordance when a session is already live.
Reaching it from the menu and changing your mind -- or failing a PIN on
someone else's tile -- previously had no way back to the session you
still had. At startup there is nothing behind it, so it stays hidden.
This commit is contained in:
2026-08-30 19:38:53 +02:00
parent fb3d0014ef
commit f902caa07f
3 changed files with 69 additions and 2 deletions
+16 -1
View File
@@ -73,7 +73,22 @@ describe("AccountMenu", () => {
render(AccountMenu);
openMenu();
const items = screen.getAllByRole("menuitem").map((el) => el.textContent?.trim());
expect(items).toEqual(["Downloads", "Settings", "Display", "Sign out"]);
expect(items).toEqual(["Switch profile", "Downloads", "Settings", "Display", "Sign out"]);
});
/**
* "Switch profile" sits directly under the identity block, before the
* destinations. It answers "who is this?", not "where do I go?", and burying
* it in Settings is what this entry exists to undo.
*
* TRACES: UR-082 | DR-276
*/
it("puts Switch profile first, next to the identity block", async () => {
render(AccountMenu);
openMenu();
const items = screen.getAllByRole("menuitem");
expect(items[0].textContent?.trim()).toBe("Switch profile");
expect(items[0].getAttribute("href")).toBe("/profiles");
});
it("shows the identity block with name and server host", async () => {