Call the app by its name in every sentence that names it (#406)

APP_NAME renames an instance, but only the sign-in page, the title bar and
a few headings used it. Two dozen sentences wrote "ihasmail" into
themselves, so a renamed instance still told people to keep an ihasmail
tab open and offered to open mail links "in ihasmail".

Those sentences now take the name as {app}, which also lets a translator
put it where their language wants it. brand.ts grew useAppName() for
components and currentAppName() for the few places that build strings
outside React.

Left as they are: the Files folder "ihasmail", the Sieve script
"ihasmail" and ihasmail.org. Those name things a person can go and look
at, and renaming them would rename real data.

All nine catalogues keep their translations: the name inside each one
became the placeholder. Three of the strings had no translation before
and still fall back to English.

A test walks the sources and the catalogues so a new sentence can't
hard-code the name again.
This commit is contained in:
jcoffey authored and GitHub committed 2026-09-19 14:27:34 -07:00
1 parent 8a7ff5d42f
commit 9e3844e94a
25 files changed
+346 -225

No files matched your search

+1 -1
View File
@@ -186,7 +186,7 @@ export function AppShell({ children }: { children: ReactNode }) {
{/* The project site. It is linked from the login screen footer, which
is a page a signed-in user never sees again -- so from inside the
app there was no way back to it. */}
<MenuItem icon={<Globe size={16} />} label={t("About ihasmail")} href="https://ihasmail.org" external />
<MenuItem icon={<Globe size={16} />} label={t("About {app}", { app: appName })} href="https://ihasmail.org" external />
<MenuItem icon={<Settings size={16} />} label={t("Settings")} onClick={() => navigate("/settings")} />
{/* Only for an account whose Stalwart role manages other accounts.
Nobody else is shown an entry that would open onto refusals. */}