Mail list: cut a lone long sender name at 21 characters plus "..."

A single sender showed in full (or, past 25 characters, as a first word).
Past 22 characters it now shows the first 21 and "...". Several senders
keep the full-names / first-words presentation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-25 20:45:28 +02:00
co-authored by Claude Opus 5.5
parent 02011f23f6
commit cfc89e78b3
2 changed files with 22 additions and 3 deletions
+11 -3
View File
@@ -35,15 +35,23 @@ function initials(p: Address | undefined): string {
// Past this many characters the sender column switches to first names only. // Past this many characters the sender column switches to first names only.
const SENDERS_FULL_MAX = 25; const SENDERS_FULL_MAX = 25;
// A lone sender's name longer than this is cut to one character less plus "...".
const SINGLE_SENDER_MAX = 22;
// The sender column's text: full names joined, or — when that would run past // The sender column's text. A single sender shows in full, or cut at
// SENDERS_FULL_MAX — each sender's first word ("Alice Smith" -> "Alice", a bare // SINGLE_SENDER_MAX. Several show as full names joined, or — when that would run
// address -> its local part). The user's own accounts are always `me`. // past SENDERS_FULL_MAX — each sender's first word ("Alice Smith" -> "Alice", a
// bare address -> its local part). The user's own accounts are always `me`.
export function senderNames( export function senderNames(
senders: Address[], senders: Address[],
isMe: (a: Address) => boolean, isMe: (a: Address) => boolean,
me: string, me: string,
): string { ): string {
if (senders.length === 1) {
const [a] = senders;
const name = isMe(a) ? me : a.name || a.email;
return name.length > SINGLE_SENDER_MAX ? `${name.slice(0, SINGLE_SENDER_MAX - 1)}...` : name;
}
const full = senders.map((a) => (isMe(a) ? me : a.name || a.email)).join(", "); const full = senders.map((a) => (isMe(a) ? me : a.name || a.email)).join(", ");
if (full.length <= SENDERS_FULL_MAX) return full; if (full.length <= SENDERS_FULL_MAX) return full;
return senders return senders
+11
View File
@@ -29,4 +29,15 @@ describe("senderNames", () => {
); );
expect(out).toBe("Alice, me, Bob, carol.jones"); expect(out).toBe("Alice, me, Bob, carol.jones");
}); });
it("cuts a lone sender past 22 characters to 21 plus three dots", () => {
expect(
senderNames([addr("Global Entertainment News", "n@x.com")], me, "me"),
).toBe("Global Entertainment ...");
// exactly 22 stays whole
expect(
senderNames([addr("Twenty-two chars long!", "n@x.com")], me, "me"),
).toBe("Twenty-two chars long!");
expect(senderNames([addr("", "me@example.com")], me, "me")).toBe("me");
});
}); });