From 843b48cd590f61447933293283c5aedb0126023d Mon Sep 17 00:00:00 2001 From: Lukas Remis Date: Thu, 8 Oct 2026 19:12:54 +0200 Subject: [PATCH] Phone: Settings in the menu, sliding Settings layout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The left panel shows Settings on a phone again, with Install app moved above the divider. On a phone, Settings is a full-width list of sections; the chosen one slides in from the right over it and back out on ‹ Settings or the phone's Back (each section is its own URL; opened directly, ‹ Settings goes to the list). A section's own first heading is hidden there when it repeats the title in the header. The account rows wrap on a narrow screen instead of running off it. Desktop Settings is unchanged. Co-Authored-By: Claude Opus 5.5 --- frontend/src/routes/MailLayout.tsx | 9 +- frontend/src/routes/settings/Settings.tsx | 230 +++++++++++++++++----- 2 files changed, 189 insertions(+), 50 deletions(-) diff --git a/frontend/src/routes/MailLayout.tsx b/frontend/src/routes/MailLayout.tsx index e65a357..f9d3a48 100644 --- a/frontend/src/routes/MailLayout.tsx +++ b/frontend/src/routes/MailLayout.tsx @@ -980,19 +980,22 @@ export function MailLayout() { {/* Plugin-contributed sidebar sections (SPEC §11.3 sidebar.section). */} {!collapsed && } + {mobile && ( +
+ setDrawerOpen(false)} /> +
+ )}
- {/* Settings has no phone layout yet either. */} {!collapsed && t("nav.settings")} - {mobile && setDrawerOpen(false)} />} +

{title}

+ {/* Balances the back button, so the title sits in the middle. */} + + + {t("settings.title")} + + +
+ {open ? content : shown?.content} +
+ + )} +
+ + ); +} + +function Chevron({ left = false }: { left?: boolean }) { + return ( + + + + ); +} + function ProfileSection() { const t = useT(); const { data } = useMe(); @@ -559,10 +694,11 @@ function AccountsSection() { ) : editing?.id === a.id && editing.mode === "signature" ? ( setEditing(null)} onSaved={close} /> ) : ( -
- - - {a.email} + // Wraps on a narrow screen: the actions move below the address. +
+ + + {a.email} {a.state === "auth_failed" ? ( {t("settings.stateAuthFailed")} @@ -585,7 +721,7 @@ function AccountsSection() { )} - + {a.sync_window !== "all" && (