Skip to content

fix: resolve blank email content via on-demand detail fetching and real-time cache - #565

Open
cmlung wants to merge 1 commit into
maillab:mainfrom
cmlung:fix/email-detail-on-demand-loading
Open

cmlung wants to merge 1 commit into
maillab:mainfrom
cmlung:fix/email-detail-on-demand-loading

Conversation

@cmlung

@cmlung cmlung commented Sep 3, 2026

Copy link
Copy Markdown

Summary of Changes

When a user clicks on a newly arrived email (polled via emailLatest) or navigates to an email before the background list full=1 fetch completes, the email body (content) is empty (""), rendering a completely blank screen below the header until the user manually refreshes the page.

Root Causes

  1. Real-time Polling stripped content without caching:
    In emailService.latest, the query used emailBriefColumns and called applyListText(list), explicitly deleting item.content. The frontend latest() loop added the email item to the scroll list without populating detailMap.
  2. Missing Single Email Detail API:
    The backend previously had no dedicated /email/detail endpoint to retrieve a single email's full body on demand.
  3. No Fallback / Self-Healing in content/index.vue:
    content/index.vue only rendered whatever was in emailStore.contentData.email. If content was empty, it rendered an empty block indefinitely without attempting to fetch the details.

Solutions Applied

  1. Backend (mail-worker):
    • Added GET /email/detail?emailId=:emailId in email-api.js and emailService.detail to fetch complete content and attachments for a specific email with permission checks.
    • Updated emailService.latest and allEmailLatest to query full columns and load attachments (emailAddAtt). Real-time polling typically returns only 1–2 items, so returning complete content introduces no performance penalty while eliminating race conditions.
  2. Frontend Store & Poller (mail-vue):
    • In views/email/index.vue and views/all-email/index.vue, newly polled emails are immediately cached into emailStore.detailMap[email.emailId] = email.
    • In store/email.js, toContentEmail retains content and text if already present in the passed object.
  3. Frontend Content View (views/content/index.vue):
    • Added on-demand self-healing (loadMissingDetail()): If content is missing when opening an email, it displays an animated skeleton and immediately fetches the full email via emailDetail(emailId), populating detailMap and rendering seamlessly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant