Mail list: show who wrote, not everyone involved

The first column listed a thread's `participants`, which the threader builds from
from + to + cc — so every ordinary email read "Sender, You", and the +N badge
beside the avatar counted the user themselves.

`participants` cannot simply be narrowed: the subject-fallback join matches an
incoming message's recipients against it (threader._by_subject), so dropping
recipients would change how mail is threaded. Hence a separate `threads.senders`,
holding only from addresses, newest writer first — which is also the right thing
for a conversation where several people replied.

Migration 0019 backfills it, so existing threads do not wait to be touched again.
The list falls back to `participants` if a row somehow has no senders, rather
than rendering an empty column.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018SqJYt7jD7oUEkoY68sBZo
This commit is contained in:
2026-09-18 18:27:42 +02:00
co-authored by Claude Opus 5
parent e58a2f0ef4
commit 550b8cf503
7 changed files with 86 additions and 4 deletions
+1
View File
@@ -17,6 +17,7 @@ class ThreadSummary(BaseModel):
id: uuid.UUID
subject: str
snippet: str
senders: list[Address]
participants: list[Address]
account_ids: list[uuid.UUID]
message_count: int
+1
View File
@@ -38,6 +38,7 @@ def _summary(thread: Thread, message_count: int | None = None) -> ThreadSummary:
id=thread.id,
subject=thread.subject_norm or "(no subject)",
snippet=thread.snippet,
senders=_addresses(thread.senders),
participants=_addresses(thread.participants),
account_ids=list(thread.account_ids),
# Count only the messages this view actually shows (deleted/spam excluded