Mail list: name everyone who wrote in the thread, and call the user "me"
The sender column showed participants[0], and participants are rebuilt
newest message first — so replying to a thread put the user in that slot
and the list named them instead of the person who wrote in.
Thread summaries (list and search) now carry `senders`: the distinct From
addresses of the thread's visible messages, oldest first, with the same
Trash/Spam visibility as the message count. The list joins them and shows
the user's own account addresses as "me" ("me, Alice" for a thread the
user started), and the avatar prefers the other side of the conversation.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -102,6 +102,11 @@ export function MessageList({
|
||||
});
|
||||
const labelMap = labelsQuery.data ?? {};
|
||||
|
||||
// The user's own addresses, shown as "me" in the sender column.
|
||||
const accounts = useQuery({ queryKey: ["accounts"], queryFn: api.accounts });
|
||||
const myEmails = new Set((accounts.data ?? []).map((a) => a.email.toLowerCase()));
|
||||
const isMe = (a: Address) => myEmails.has(a.email.toLowerCase());
|
||||
|
||||
const virtualizer = useVirtualizer({
|
||||
count: threads.length,
|
||||
getScrollElement: () => parentRef.current,
|
||||
@@ -128,11 +133,15 @@ 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 = primary ? primary.name || primary.email : "(no one)";
|
||||
// The sender column lists everyone who wrote in the thread, oldest first,
|
||||
// with the user's own accounts shown as "me" — so a thread you started
|
||||
// and someone answered reads "me, Alice". Recipients are not listed.
|
||||
const senders = thread.senders.length ? thread.senders : thread.participants.slice(0, 1);
|
||||
const names = senders.length
|
||||
? senders.map((a) => (isMe(a) ? t("mail.me") : a.name || a.email)).join(", ")
|
||||
: "(no one)";
|
||||
// The avatar is the other side of the conversation where there is one.
|
||||
const primary = senders.find((a) => !isMe(a)) ?? senders[0];
|
||||
// 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);
|
||||
|
||||
Reference in New Issue
Block a user