Skip to content

Comments

connect the draft to the thread#1381

Merged
ahmetskilinc merged 2 commits intostagingfrom
reply_drafts_loading_correctly
Jun 21, 2025
Merged

connect the draft to the thread#1381
ahmetskilinc merged 2 commits intostagingfrom
reply_drafts_loading_correctly

Conversation

@ahmetskilinc
Copy link
Contributor

@ahmetskilinc ahmetskilinc commented Jun 19, 2025

Add draft indicator and improve draft handling in mail threads

Description

This PR adds visual indicators for drafts in mail threads and improves draft handling throughout the mail application:

  1. Added a pencil icon indicator that appears next to threads containing drafts
  2. Improved the display of latest messages by filtering out drafts when showing thread previews
  3. Fixed draft handling in reply composer by properly parsing email addresses from drafts
  4. Added support for CC and BCC fields when reopening drafts
  5. Properly reset draft and reply state when navigating between threads
  6. Enhanced the Google Mail Manager to include CC and BCC information from drafts

Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 🎨 UI/UX improvement

Areas Affected

  • Email Integration (Gmail, IMAP, etc.)
  • User Interface/Experience

Summary by CodeRabbit

  • New Features

    • Draft status is now visually indicated in mail threads with a draft icon.
    • Draft emails now support CC and BCC recipient fields, which are populated when composing or editing drafts.
    • The draft data structure now includes an optional sender email address field.
  • Bug Fixes

    • Email recipient fields (To, CC, BCC) are consistently formatted and cleaned when initializing the email composer.
  • Improvements

    • Navigating between threads or moving emails clears any draft or reply state to prevent unintended carryover.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jun 19, 2025

Walkthrough

The changes introduce draft status indicators and handling in the mail UI, normalize email recipient fields for composing replies, and extend server-side draft parsing to include CC, BCC, and an optional sender email. State management for drafts and replies is improved during thread navigation, and relevant type definitions and schemas are updated accordingly.

Changes

File(s) Change Summary
apps/mail/components/mail/mail-list.tsx Added draft status display in thread list; updated to use latest non-draft message; imports draft icon.
apps/mail/components/mail/reply-composer.tsx Added ensureEmailArray utility; normalized To, Cc, and Bcc fields for email composer.
apps/mail/components/mail/thread-display.tsx Cleared draft/reply state on navigation and thread actions; included latestDraft from hook.
apps/server/src/lib/driver/google.ts Extracted and included CC/BCC fields from draft headers in parseDraft.
apps/server/src/lib/driver/types.ts Extended ParsedDraft interface with optional cc and bcc string arrays.
apps/server/src/lib/schemas.ts Added optional nullable fromEmail field to createDraftData schema.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant MailList
    participant ThreadDisplay
    participant ReplyComposer
    participant Server

    User->>MailList: View mail threads
    MailList->>Server: Fetch threads (including drafts)
    Server-->>MailList: Threads with latestDraft, cc, bcc, fromEmail
    MailList->>User: Show threads, display draft icon if hasDraft

    User->>ThreadDisplay: Open thread
    ThreadDisplay->>Server: Fetch thread details
    Server-->>ThreadDisplay: Thread data with latestDraft

    User->>ReplyComposer: Reply or edit draft
    ReplyComposer->>Server: Get draft data (to, cc, bcc)
    Server-->>ReplyComposer: Draft with normalized recipient arrays
    ReplyComposer->>User: Show composer with clean recipient fields

    User->>ThreadDisplay: Navigate threads or close
    ThreadDisplay->>ThreadDisplay: Clear draft/reply state
Loading

Possibly related PRs

  • Skeleton for drafts #1302: Adds skeleton loader placeholders for drafts in mail-list.tsx, complementing draft visualization changes in this PR.
  • thread action buttons #597: Modifies ThreadDisplay state management and action buttons, related to draft and reply state handling in this PR.

Suggested reviewers

  • MrgSub

Poem

In the warren of code, new drafts now appear,
With CCs and BCCs, all crystal clear.
A pencil icon twinkles—“Draft!” it proclaims,
Recipients tidy, no wild email names.
As threads hop along, old states disappear—
This bunny’s mailbox is ready, with nothing to fear!
🐇✉️


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c7e9d2c and eff4c09.

📒 Files selected for processing (6)
  • apps/mail/components/mail/mail-list.tsx (4 hunks)
  • apps/mail/components/mail/reply-composer.tsx (2 hunks)
  • apps/mail/components/mail/thread-display.tsx (4 hunks)
  • apps/server/src/lib/driver/google.ts (1 hunks)
  • apps/server/src/lib/driver/types.ts (1 hunks)
  • apps/server/src/lib/schemas.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • apps/server/src/lib/schemas.ts
  • apps/server/src/lib/driver/types.ts
  • apps/mail/components/mail/thread-display.tsx
  • apps/server/src/lib/driver/google.ts
  • apps/mail/components/mail/reply-composer.tsx
  • apps/mail/components/mail/mail-list.tsx
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Analyze (javascript-typescript)
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@ahmetskilinc ahmetskilinc force-pushed the reply_drafts_loading_correctly branch 3 times, most recently from 057d10e to 11d2388 Compare June 20, 2025 15:24
@ahmetskilinc ahmetskilinc marked this pull request as ready for review June 20, 2025 15:27
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
apps/mail/components/mail/mail-list.tsx (2)

81-94: Consider optimizing the filtering and sorting logic.

The implementation correctly filters out drafts and finds the latest received message. However, the sorting operation runs on every render despite memoization.

Consider this optimization to reduce unnecessary sorting:

 const latestReceivedMessage = useMemo(() => {
   if (!getThreadData?.messages) return getThreadData?.latest;

   const nonDraftMessages = getThreadData.messages.filter((msg) => !msg.isDraft);
   if (nonDraftMessages.length === 0) return getThreadData?.latest;

-  return (
-    nonDraftMessages.sort((a, b) => {
-      const dateA = new Date(a.receivedOn).getTime();
-      const dateB = new Date(b.receivedOn).getTime();
-      return dateB - dateA;
-    })[0] || getThreadData?.latest
-  );
+  return nonDraftMessages.reduce((latest, current) => {
+    const latestTime = new Date(latest.receivedOn).getTime();
+    const currentTime = new Date(current.receivedOn).getTime();
+    return currentTime > latestTime ? current : latest;
+  }) || getThreadData?.latest;
 }, [getThreadData?.messages, getThreadData?.latest]);

505-514: Consider using the translation system for consistency.

The draft icon implementation is well-structured with proper conditional rendering and tooltip. However, the tooltip text is hardcoded while other parts of the codebase use the translation system.

Apply this diff to use the translation system:

-                          <TooltipContent className="p-1 text-xs">Draft</TooltipContent>
+                          <TooltipContent className="p-1 text-xs">
+                            {t('common.draft')}
+                          </TooltipContent>

Note: Ensure the translation key common.draft exists in your translation files.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7db4b08 and 11d2388.

📒 Files selected for processing (6)
  • apps/mail/components/mail/mail-list.tsx (4 hunks)
  • apps/mail/components/mail/reply-composer.tsx (2 hunks)
  • apps/mail/components/mail/thread-display.tsx (4 hunks)
  • apps/server/src/lib/driver/google.ts (1 hunks)
  • apps/server/src/lib/driver/types.ts (1 hunks)
  • apps/server/src/lib/schemas.ts (1 hunks)
🔇 Additional comments (13)
apps/server/src/lib/schemas.ts (1)

34-34: LGTM: Schema extension for draft sender email.

The addition of the optional nullable fromEmail field is consistent with the existing schema pattern and supports the enhanced draft functionality.

apps/server/src/lib/driver/types.ts (1)

19-20: LGTM: Interface extension for CC/BCC recipients.

The addition of optional cc and bcc string arrays properly extends the ParsedDraft interface to support complete recipient information.

apps/server/src/lib/driver/google.ts (2)

1107-1110: LGTM: CC/BCC extraction from draft headers.

The header parsing correctly extracts CC and BCC recipients from the draft message. The simple comma-splitting approach should handle most common cases effectively.


1118-1119: LGTM: Including parsed CC/BCC in draft object.

The parsed CC and BCC arrays are properly included in the returned draft object, completing the integration with the extended ParsedDraft interface.

apps/mail/components/mail/reply-composer.tsx (2)

232-245: LGTM: Robust email array normalization utility.

The ensureEmailArray function properly handles multiple input types (undefined, null, string, array) and normalizes them into clean email arrays. The logic for trimming, filtering empty values, and removing angle brackets is appropriate.


261-263: LGTM: Consistent initialization of recipient fields.

The use of ensureEmailArray for initialTo, initialCc, and initialBcc ensures consistent handling of recipient data from drafts, regardless of the input format.

apps/mail/components/mail/thread-display.tsx (3)

175-175: LGTM: Adding latestDraft to thread data.

The addition of latestDraft from the useThread hook aligns with the enhanced draft handling features, even though it's not used in the visible code segment.


211-214: LGTM: Proper state cleanup during navigation.

The consistent clearing of mode, activeReplyId, and draftId when navigating between threads or performing actions prevents stale state issues and ensures clean transitions.

Also applies to: 238-240, 269-271, 280-282


219-228: LGTM: Updated dependency arrays for state setters.

The dependency arrays are properly updated to include the new state setter functions, ensuring correct effect tracking and preventing stale closures.

Also applies to: 245-254, 272-272, 287-287

apps/mail/components/mail/mail-list.tsx (4)

9-16: LGTM: Import changes look correct.

The addition of PencilCompose icon to the imports is properly placed and aligns with the draft indicator functionality.


72-76: LGTM: Thread hook enhancement is well-structured.

The destructuring of latestDraft from the useThread hook is cleanly implemented and follows the existing pattern.


96-96: LGTM: Clean assignment pattern.

The assignment of latestMessage using the computed latestReceivedMessage is straightforward and maintains code readability.


264-267: LGTM: Draft detection logic is correct.

The hasDraft computation properly checks for the existence of latestDraft with appropriate memoization.

@ahmetskilinc ahmetskilinc force-pushed the reply_drafts_loading_correctly branch from 11d2388 to c7e9d2c Compare June 21, 2025 19:51
Copy link
Contributor Author

ahmetskilinc commented Jun 21, 2025

Merge activity

  • Jun 21, 7:51 PM UTC: Graphite rebased this pull request as part of a merge.
  • Jun 21, 7:52 PM UTC: Graphite rebased this pull request as part of a merge.
  • Jun 21, 7:54 PM UTC: @ahmetskilinc merged this pull request with Graphite.

@ahmetskilinc ahmetskilinc force-pushed the reply_drafts_loading_correctly branch from c7e9d2c to eff4c09 Compare June 21, 2025 19:52
@ahmetskilinc ahmetskilinc merged commit 275443f into staging Jun 21, 2025
6 checks passed
@ahmetskilinc ahmetskilinc deleted the reply_drafts_loading_correctly branch June 21, 2025 19:54
krakenftw pushed a commit to krakenftw/Zero that referenced this pull request Jun 24, 2025
# Add draft indicator and improve draft handling in mail threads

## Description

This PR adds visual indicators for drafts in mail threads and improves draft handling throughout the mail application:

1. Added a pencil icon indicator that appears next to threads containing drafts
2. Improved the display of latest messages by filtering out drafts when showing thread previews
3. Fixed draft handling in reply composer by properly parsing email addresses from drafts
4. Added support for CC and BCC fields when reopening drafts
5. Properly reset draft and reply state when navigating between threads
6. Enhanced the Google Mail Manager to include CC and BCC information from drafts

## Type of Change

- [x] 🐛 Bug fix (non-breaking change which fixes an issue)
- [x] ✨ New feature (non-breaking change which adds functionality)
- [x] 🎨 UI/UX improvement

## Areas Affected

- [x] Email Integration (Gmail, IMAP, etc.)
- [x] User Interface/Experience

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Draft status is now visually indicated in mail threads with a draft icon.
  - Draft emails now support CC and BCC recipient fields, which are populated when composing or editing drafts.
  - The draft data structure now includes an optional sender email address field.

- **Bug Fixes**
  - Email recipient fields (To, CC, BCC) are consistently formatted and cleaned when initializing the email composer.

- **Improvements**
  - Navigating between threads or moving emails clears any draft or reply state to prevent unintended carryover.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
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.

2 participants