From c5742f19da4eaabd85b4d73eafe7cba3bf716feb Mon Sep 17 00:00:00 2001 From: Lukas Remis Date: Fri, 18 Sep 2026 18:35:05 +0200 Subject: [PATCH] Mail list: show the sender only, keep the participant count MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first column listed every participant, so an ordinary email read "Sender, You". It now shows the sender — `participants[0]`, which is the newest message's from address because the threader adds each message's sender ahead of its recipients. The +N badge beside the avatar stays: the name is narrowed, the "how many people are in this" signal is not. Nine lines in one component. An earlier attempt at this added a denormalized `threads.senders` column and a backfill migration so that a thread with several writers could list them all; that was more machinery than the request warranted and is reverted. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_018SqJYt7jD7oUEkoY68sBZo --- frontend/src/components/list/MessageList.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/list/MessageList.tsx b/frontend/src/components/list/MessageList.tsx index 0bd6233..cc094fe 100644 --- a/frontend/src/components/list/MessageList.tsx +++ b/frontend/src/components/list/MessageList.tsx @@ -119,9 +119,13 @@ export function MessageList({ const selected = selectedId === thread.id; const checked = checkedIds.has(thread.id); const dimmed = dimmedIds?.has(thread.id) ?? false; + // `participants` is from + to + cc, newest message first — so the first + // entry is the sender and the rest are recipients (usually just you). + // The list shows the sender only. const primary = thread.participants[0]; - const names = - thread.participants.map((p) => p.name || p.email).join(", ") || "(no one)"; + const names = primary ? primary.name || primary.email : "(no one)"; + // The badge still counts everyone involved — the name is narrowed, the + // "how many people are in this" signal is not. const extra = Math.max(0, thread.participants.length - 1); const avatarBg = `hsl(${hue(primary?.email || primary?.name || "?")} 45% 45%)`; const stop = (fn: () => void) => (e: React.MouseEvent) => {