Skip to content

[Thread] Thread-aware Actions + Optimistic UI UpdateΒ #4402

@dab246

Description

@dab246

Related

  • ADR-0072

Description

When a user performs an action (mark read, star, move, delete, etc.) on one or more threads in the email list, the system must:

  1. Expand ThreadId to List<EmailInThreadDetailInfo>
  2. Execute the action on all emails in the thread
  3. Update UI immediately before server response (optimistic UI)
  4. Handle rollback on failure

Tasks

Thread Expansion Service

  • Create ThreadExpansionService with in-memory cache, parallel execution, and error isolation
  • Create ThreadExpansionResult data model (emailThreadInfos + errors)
  • Implement expandThreads() reusing ThreadDetailRepository.getThreadById

Thread-aware Interactors

  • Create ThreadActionResult model (success, actionErrors, expansionErrors)
  • Create MarkAsThreadReadInteractor β€” expand threads, then delegate to existing email interactor
  • Create MoveThreadInteractor β€” expand threads, then delegate to existing move logic
  • Create other thread-aware interactors (star, delete, etc.) following the same pattern

Optimistic UI

  • Call updateEmailFlagByEmailIds() before interactor execution (optimistic update)
  • On failure: rollback via inverse operation (e.g., markAsRead to markAsUnread)
  • On partial success: rollback only failed email IDs
  • Sync thread detail UI via dispatchThreadDetailUIAction(UpdatedEmailKeywordsAction(...))

Cache Invalidation

  • Clear ThreadExpansionService cache in:
    • ThreadController.refreshAllEmail()
    • ThreadController.refreshChangeEmail()
    • collapseThreads toggle handler
    • After thread action completes

Acceptance Criteria

  • Action on a thread applies to all emails within that thread
  • UI updates instantly without waiting for server response
  • On failure: UI rolls back to previous state
  • On partial success: only failed emails are rolled back
  • One thread expansion failure does not block other threads

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions