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
+26
View File
@@ -13,6 +13,8 @@
import { onMount } from "svelte";
import { goto } from "$app/navigation";
import { profiles } from "$lib/stores/profiles";
import { isAuthenticated } from "$lib/stores/auth";
import { navigateBack } from "$lib/utils/navigation";
import type { Profile, UnlockOutcome } from "$lib/api/bindings";
import PinPad from "$lib/components/PinPad.svelte";
import { orderProfiles, initialsFor, tileColour, lockoutMessage } from "$lib/utils/profileTiles";
@@ -152,6 +154,30 @@
<div class="min-h-full flex items-center justify-center p-6">
<div class="w-full max-w-3xl">
<!--
Reached from the account menu, the picker must not be a one-way door: a
signed-in viewer who opens it and changes their mind (or fails a PIN on
someone else's tile) needs a way back to the session they still have. At
startup there is no session behind it, so there is nothing to go back to
and this stays hidden. (DR-276)
-->
{#if $isAuthenticated && mode !== "pin" && mode !== "password"}
<button
type="button"
onclick={() => navigateBack("/")}
class="mb-6 text-sm text-gray-400 hover:text-white flex items-center gap-1"
>
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M15 19l-7-7 7-7"
/>
</svg>
Back
</button>
{/if}
{#if mode === "picker" || mode === "manage"}
<h1 class="text-3xl font-semibold text-center mb-2">
{mode === "manage" ? "Manage profiles" : "Who's watching?"}