Write the name in lowercase where people see it
ci / version (pull_request) Skipped
ci / node (pull_request) Successful in 2m21s
ci / publish (pull_request) Skipped
ci / docker-build (pull_request) Successful in 1m10s

The brand is lowercase inbuxa. This changes what the app calls itself by
default, the wordmark's accessible name, the sign-in card's version line, the
installed app's name in the manifest, and the four translated strings that
name the console or the mail server.

Those four are source strings, so their catalog keys changed with them in all
nine languages; the translations keep their text with the name corrected. No
key was left behind, and no language falls back on more strings than before:
1643/1662 translated, 19 falling back, in each of the nine, unchanged.

Code identifiers, capability URNs, env var names and comments are untouched.
This commit is contained in:
jcoffey-dev committed 2026-09-22 15:13:53 -07:00
1 parent c2f13d6a1a
commit 8d717e0037
18 files changed
+43 -43

No files matched your search

+1 -1
View File
@@ -153,7 +153,7 @@ export function LoginPage() {
margin-top, which a second paragraph would repeat as a gap.
*/}
{/* ihasmail-inbuxa: this build is INBUXA's webmail, and its site is INBUXA's. */}
<span className="notranslate" translate="no">INBUXA webmail v{APP_VERSION}</span>
<span className="notranslate" translate="no">inbuxa webmail v{APP_VERSION}</span>
<br />
<a href="https://inbuxa.org" target="_blank" rel="noopener noreferrer" className="notranslate" translate="no">inbuxa.org</a>
{" · "}
+2 -2
View File
@@ -126,12 +126,12 @@ export function AdminDashboard() {
more numbers will be: this is a glance, and operating the server is
Stalwart's own administration. The link is the operator's to give. */}
<p className="hint admin-dashboard-note">
{t("Detailed metrics, the delivery queue, logs and server settings are in INBUXA Admin.")}
{t("Detailed metrics, the delivery queue, logs and server settings are in inbuxa Admin.")}
{adminUrl && (
<>
{" "}
<a href={adminUrl} target="_blank" rel="noopener noreferrer">
{t("Open INBUXA Admin")} <ExternalLink size={13} aria-hidden="true" />
{t("Open inbuxa Admin")} <ExternalLink size={13} aria-hidden="true" />
</a>
</>
)}
+1 -1
View File
@@ -186,7 +186,7 @@ export function RoleSheet({ role, roles, defaults, entries, permissionsError, on
{!creating && can(perms, "Role", "Destroy") && (
<DeleteRole
role={role}
blocked={kinds.length ? t("The mail server gives this role by default, so it can't be deleted. Change the defaults in INBUXA Admin first.") : locked ? t("This role carries permissions yours doesn't.") : null}
blocked={kinds.length ? t("The mail server gives this role by default, so it can't be deleted. Change the defaults in inbuxa Admin first.") : locked ? t("This role carries permissions yours doesn't.") : null}
onDeleted={onDeleted}
/>
)}
@@ -112,7 +112,7 @@ describe("the Administration dashboard", () => {
});
});
describe("the pointer to INBUXA Admin", () => {
describe("the pointer to inbuxa Admin", () => {
let host: HTMLDivElement;
let root: Root;
beforeEach(() => {
@@ -136,7 +136,7 @@ describe("the pointer to INBUXA Admin", () => {
it("names it, and links it where the operator has said where it is", async () => {
await renderWith("https://admin.example.com");
const note = host.querySelector(".admin-dashboard-note")!;
expect(note.textContent).toContain("INBUXA Admin");
expect(note.textContent).toContain("inbuxa Admin");
const link = note.querySelector("a")!;
expect(link.getAttribute("href")).toBe("https://admin.example.com");
expect(link.getAttribute("rel")).toBe("noopener noreferrer");
@@ -144,7 +144,7 @@ describe("the pointer to INBUXA Admin", () => {
it("names it without a link where nobody has", async () => {
await renderWith(null);
expect(host.querySelector(".admin-dashboard-note")?.textContent).toContain("INBUXA Admin");
expect(host.querySelector(".admin-dashboard-note")?.textContent).toContain("inbuxa Admin");
expect(host.querySelector(".admin-dashboard-note a")).toBeNull();
});
});
+2 -2
View File
@@ -35,13 +35,13 @@ export function AboutSettings() {
<table className="sessions-table">
<tbody>
<tr><td>{t("Signed in as")}</td><td>{session?.username}</td></tr>
<tr><td>{t("Mail server")}</td><td className="notranslate" translate="no">INBUXA</td></tr>
<tr><td>{t("Mail server")}</td><td className="notranslate" translate="no">inbuxa</td></tr>
<tr><td>{t("Accounts")}</td><td>{Object.values(session?.accounts ?? {}).map((a) => a.name).join(", ")}</td></tr>
<tr><td>{t("Max upload")}</td><td>{t("{size} MB", { size: Math.round(client.maxSizeUpload / 1048576) })}</td></tr>
<tr><td>{t("Image privacy proxy")}</td><td>{session?.ihasmail?.imageProxy ? t("enabled") : t("disabled")}</td></tr>
</tbody>
</table>
<p className="hint" style={{ marginTop: 6 }}>{t("This webmail works with the INBUXA mail server, and sign-in refuses a server that doesn't offer what it needs.")}</p>
<p className="hint" style={{ marginTop: 6 }}>{t("This webmail works with the inbuxa mail server, and sign-in refuses a server that doesn't offer what it needs.")}</p>
<p className="hint">{tNode("{app}'s own version is the date of the commit it was built from, followed by where that commit came from: {example} was built from a commit dated the 30th of August 2026 that arrived through pull request 129. A commit that did not come through one carries its short SHA instead — {sha}. The version deliberately says nothing about the mail server; what this build needs from the server is the line above.", { example: <strong className="notranslate" translate="no">v2026.8.30+pr129</strong>, sha: <code>+g1fa6578</code> }, { app: appName })}</p>
<h2>{t("Server capabilities")}</h2>
<div className="row wrap gap-4">