Files
workavia-mail-front/docs/adr/0071-collapse-threads-in-email-query.md
Dat H. Pham 93c96a2b83 ADR-71 CollapseThread (#4380)
* ADR-71 CollapseThread

* fixup! ADR-71 CollapseThread

* docs(ADR-0072): Add thread-aware bulk actions for collapseThreads in EmailList

* fixup! docs(ADR-0072): Add thread-aware bulk actions for collapseThreads in EmailList

* fixup! fixup! docs(ADR-0072): Add thread-aware bulk actions for collapseThreads in EmailList

* fixup! fixup! fixup! docs(ADR-0072): Add thread-aware bulk actions for collapseThreads in EmailList

* fixup! fixup! fixup! fixup! docs(ADR-0072): Add thread-aware bulk actions for collapseThreads in EmailList

* fixup! fixup! fixup! fixup! fixup! docs(ADR-0072): Add thread-aware bulk actions for collapseThreads in EmailList

* fixup! fixup! fixup! fixup! fixup! fixup! docs(ADR-0072): Add thread-aware bulk actions for collapseThreads in EmailList

* fixup! fixup! fixup! fixup! fixup! fixup! fixup! docs(ADR-0072): Add thread-aware bulk actions for collapseThreads in EmailList

---------

Co-authored-by: dab246 <tdvu@linagora.com>
2026-03-27 09:44:45 +07:00

2.7 KiB

0071 - Enable collapseThreads in Email/query

Date: 2026-03-12

Status

Proposed

Context

JMAP Email/query supports collapseThreads (RFC 8621 §4.4). When true, server returns only the latest email per thread, avoiding duplicate rows in the mail list.

Currently, our app does not set collapseThreads. When thread is enabled, users see multiple emails from the same thread as separate rows.

Two Query Paths (see ADR-0070)

Path FORCE_EMAIL_QUERY Method Cache
Force query true forceQueryAllEmailsForWeb() No local cache — server only
Cache-first false getAllEmail() Local DB first, then sync

Problem: Cache Inconsistency on Toggle

On the cache-first path, the local DB reflects the collapseThreads mode it was built under. When thread mode changes:

  • OFF → ON: Cache has individual emails (5 rows) but server now returns collapsed (3 rows) → stale first yield
  • ON → OFF: Cache has collapsed emails (3 rows) but server now returns all individuals (5 rows) → missing emails in first yield

Force-query path has no problem — always queries server directly.

Decision

1. Set collapseThreads: true in Email/query When Thread Is Enabled

In MailAPIMixin.fetchAllEmail() and ThreadAPI.searchEmails(), pass collapseThreads: true when thread is enabled.

2. Clear Email Cache on Thread Setting Toggle

Reuse the existing thread-enabled setting. No new flag needed. When thread is toggled (enable ↔ disable), clear email cache immediately in the toggle handler. Next getAllEmail() will rebuild cache under correct mode.

3. No Change for Force-Query Path

Already server-only. Just pass collapseThreads: true in the query.

Consequences

Positive: Correct thread display, reduced data per page, spec-compliant.

Negative: One-time full reload on each toggle; toggle handler coupled with cache management.

Implementation Steps

  1. Add collapseThreads to QueryEmailMethod in MailAPIMixin.fetchAllEmail() and ThreadAPI.searchEmails()
  2. Pass thread-enabled status from Settings to query builder
  3. Clear email cache in thread setting toggle handler
  4. Update GetEmailsInMailboxInteractor and related interactors to propagate thread status

References

  • RFC 8621 §4.4
  • ADR-0070
  • lib/features/base/mixin/mail_api_mixin.dartfetchAllEmail()
  • lib/features/thread/data/repository/thread_repository_impl.dartgetAllEmail()
  • lib/features/thread/domain/usecases/get_emails_in_mailbox_interactor.dart