-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
bcc cc #646
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bcc cc #646
Conversation
Update navbar component layout for mobile view
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThis pull request updates several modules in the mail application. In the API driver, a new Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant ThreadDisplay
participant ReplyCompose
participant MailAPI
User->>ThreadDisplay: Click "ReplyAll" button
ThreadDisplay->>ThreadDisplay: Set replyAllComposerOpen true<br>Reset other composer states
ThreadDisplay->>ReplyCompose: Render composer in "replyAll" mode
User->>ReplyCompose: Compose reply with multiple recipients
ReplyCompose->>MailAPI: Send email request
MailAPI->>MailAPI: Parse request, extract replyTo and handle recipients
MailAPI-->>ReplyCompose: Return send confirmation
Poem
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this 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
🔭 Outside diff range comments (1)
apps/mail/components/mail/reply-composer.tsx (1)
846-876
:⚠️ Potential issuePotential mismatch when saving drafts.
For non-forward modes, line 854 enforcesoriginalEmail.sender.email
instead of the current form array forto
. This risks losing additional recipients the user typed if they save the draft.Proposed fix to store the actual recipient array in non-forward modes:
- to: mode === 'forward' ? getValues('to').join(', ') : originalEmail.sender.email, + to: getValues('to').join(', '),Ensure that the entire array of manually entered addresses is preserved in the draft.
🧹 Nitpick comments (6)
apps/mail/app/api/driver/google.ts (2)
189-191
: Consider using structured logging in productionAdded debug logs provide helpful information during development but could be noisy in production.
Consider using a logging level system to conditionally output these debug statements:
-console.log('Debug - From email:', fromEmail); -console.log('Debug - Original to recipients:', JSON.stringify(to, null, 2)); +if (process.env.DEBUG_EMAIL === 'true') { + console.log('Debug - From email:', fromEmail); + console.log('Debug - Original to recipients:', JSON.stringify(to, null, 2)); +}
215-229
: Consider reducing log verbosity for recipient processingThe recipient processing logs for each email address may generate excessive output in production.
Consider condensing the logs or making them conditional:
-console.log('Debug - Processing recipient:', { - originalEmail: recipient.email, - normalizedEmail: email, - fromEmail, - isDuplicate: uniqueRecipients.has(email), - isSelf: email === fromEmail -}); +if (process.env.DEBUG_EMAIL === 'true') { + console.log('Debug - Processing recipient:', { + originalEmail: recipient.email, + normalizedEmail: email, + fromEmail, + isDuplicate: uniqueRecipients.has(email), + isSelf: email === fromEmail + }); +}apps/mail/components/mail/reply-composer.tsx (4)
54-62
: Consider expanding or externalizing the noreply check.
isNoReplyAddress
currently only checks for a few patterns (e.g.noreply
,no-reply
,notifications@github.com
). If you need more control or future-proofing, consider externalizing these checks or broadening them to align with project needs.
334-345
: handleAttachment with drag-n-drop synergy.
Asynchronous file handling with a brief simulated wait is straightforward. Consider adding user feedback if a specific file fails to be attached or processed to improve the UX.
382-386
: Email format check.
isValidEmail
is a simple pattern-based validator. If advanced validation is ever required, consider more robust solutions or library usage.
752-815
: RecipientInput components.
The logic to add emails on comma, Enter, or space is a convenient user experience. As a minor nitpick, consider whether adding an email on space might cause accidental additions. Otherwise, the approach is well-structured.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
apps/mail/app/api/driver/google.ts
(4 hunks)apps/mail/components/mail/reply-composer.tsx
(18 hunks)apps/mail/components/mail/thread-display.tsx
(4 hunks)apps/mail/components/mail/use-mail.ts
(1 hunks)apps/mail/types/index.ts
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
apps/mail/components/mail/thread-display.tsx (1)
apps/mail/lib/utils.ts (1)
cn
(51-51)
apps/mail/components/mail/reply-composer.tsx (2)
apps/mail/types/index.ts (1)
Sender
(32-35)apps/mail/lib/utils.ts (1)
constructReplyBody
(379-404)
🔇 Additional comments (42)
apps/mail/types/index.ts (1)
57-57
: LGTM - Added optional replyTo field to ParsedMessage interfaceThe addition of the optional
replyTo
field aligns well with the extraction of the reply-to header implemented in the API driver.apps/mail/components/mail/use-mail.ts (1)
9-9
: LGTM - Added replyAllComposerOpen stateThe addition of the
replyAllComposerOpen
boolean state properly extends the mail configuration model to support the new reply-all functionality. It's correctly initialized tofalse
in the configAtom, maintaining consistency with the other composer states.Also applies to: 17-17
apps/mail/components/mail/thread-display.tsx (5)
8-8
: LGTM - Added ReplyAll icon importThe ReplyAll icon from lucide-react is properly imported to support the new reply-all functionality.
368-374
: LGTM - Updated Reply button handlerThe onClick handler for the Reply button now properly ensures that only the reply composer is open by setting
replyComposerOpen
to true while explicitly settingreplyAllComposerOpen
andforwardComposerOpen
to false.
376-388
: LGTM - Added ReplyAll buttonThe new ReplyAll button is correctly implemented with appropriate icon, translation label, and state management. The active state styling is properly applied using the
cn
utility whenmail.replyAllComposerOpen
is true.
396-401
: LGTM - Updated Forward button handlerThe Forward button handler now properly manages the state of all three composer types, ensuring only one composer is open at a time.
434-434
: LGTM - Updated ReplyCompose mode logicThe mode passed to the ReplyCompose component now correctly handles the new replyAll state with proper precedence logic.
apps/mail/app/api/driver/google.ts (5)
136-137
: LGTM - Added replyTo field extractionThe code now properly extracts the reply-to header from email messages and includes it in the parsed message data structure, which matches the updated interface.
Also applies to: 173-173
194-205
: LGTM - Improved input validationThe added validation logic correctly ensures that the "to" field is a non-empty array before proceeding, improving error handling.
207-247
: LGTM - Enhanced recipient handlingThe implementation now properly handles recipients with robust filtering, deduplication using a Set, and appropriate error handling when no valid recipients remain after filtering.
249-289
: LGTM - Added CC and BCC recipient handlingThe code now properly processes CC and BCC recipients with appropriate filtering and deduplication logic, consistent with the handling of primary recipients.
299-310
: LGTM - Improved header handlingThe code now uses
Object.entries()
instead ofObject.keys()
for header processing, which is more appropriate as it provides access to both keys and values. The special handling for the References header ensures proper email threading.apps/mail/components/mail/reply-composer.tsx (30)
4-10
: Imports look good.
These imports from@/lib/utils
consolidate needed utilities such ascleanEmailAddress
andconvertJSONToHTML
without any apparent issues.
24-31
: React hooks import.
The addition ofuseRef
,useState
,useEffect
,useCallback
, anduseReducer
is consistent with modern React patterns.
34-34
: Using react-hook-form.
LeveraginguseForm
anduseWatch
is a solid approach for form state management.
37-38
: Custom hooks usage.
useMail
anduseSettings
are properly imported, no concerns here.
41-41
: Thread hook import.
useThread
fetches the email thread data. This is consistent with the rest of the codebase usage.
48-48
: Toast library addition.
Importingtoast
fromsonner
is straightforward and used for user notifications.
49-49
: Zod type reference.
Declaring a type import fromzod
suggests potential schema validations, though it does not appear used here.
82-87
: Expanded MailState is clear.
IntroducingreplyComposerOpen
,replyAllComposerOpen
, andforwardComposerOpen
ensures each composer mode is managed distinctly.
145-146
: New mode option for replyAll.
Adding'replyAll'
toReplyComposeProps
is consistent with the rest of the logic in the file.
151-157
: Extended form data structure.
Storing recipients in arrays forto
,cc
,bcc
aligns with multi-address handling.toInput
,ccInput
, andbccInput
keys help manage user input neatly.
167-169
: State toggles for editing recipients.
isEditingRecipients
,showCc
, andshowBcc
provide flexible control over UI toggles without any apparent issues.
172-177
: Conditional composer display.
Usingmode
to pick which composer is open is well-structured for managing different reply scenarios.
182-182
: Selective composer open state.
Exclusively assigningreplyAllComposerOpen
fits the approach to toggling only the relevant composer.
208-217
: Form initialization.
Default values for arrays and string inputs are clearly defined, which prevents undefined states in the form fields.
229-233
: Watching to, cc, and bcc arrays.
Automatically tracking recipient changes is essential for dynamic UI updates and ensures re-renders happen as needed.
234-241
: handleAddEmail function.
The trimming logic and duplication check look sound. UsingisValidEmail
helps maintain minimal validation.
243-328
: handleSendEmail logic.
This function properly constructsto
,cc
, andbcc
recipients, sets email subject lines, and callssendEmail
. The flow forreply
,replyAll
, andforward
is coherent, and the error handling withtoast
user feedback is appropriate for a typical UI.
346-380
: Drag events.
The dragOver, dragLeave, and drop handlers handle state updates to maintain correct UI feedback. Implementation is consistent.
387-403
: CloseButton component.
Abstracting this logic is clean and consistent with the rest of the code. It neatly prevents accidental clicks throughonMouseDown
usage.
404-423
: toggleComposer resets relevant states.
All composers are closed, and recipient states are reset, preventing leftover data from reuse.
467-476
: Keyboard shortcut for send.
Supporting Cmd/Ctrl + Enter is a nice UX feature. CheckingisFormValid
is important to avoid empty sends.
478-480
: Editor content update.
Storing editor content in form state usingsetValue
ensures everything remains in sync with other inputs.
592-652
: initializeRecipients for reply modes.
Conditionally populatingto
andcc
forreply
vs.replyAll
is sound. Skipping BCC in replies is standard. The checks for not including the current user help avoid self-address duplication.
654-662
: Auto-setup recipients on composer open.
Synchronizing form values with the latestEmail data upon opening the composer ensures the user sees correct default addresses.
663-748
: renderHeaderContent approach.
Toggling between a compact view and expanded recipient editing is a solid pattern. Implementation for cc/bcc toggles is intuitive.
835-835
: Form reset on composer close.
Thisreset()
call keeps the form state clean when the composer is not in use.
880-965
: Reply, replyAll, and forward buttons.
The logic for toggling each composer’s open state is well-organized. Checking participant counts before enabling “ReplyAll” is a practical approach.
983-983
: onSubmit -> handleSubmit bridging.
CallinghandleSubmit
directly in a custom callback keeps the code consistent withreact-hook-form
best practices.
990-1021
: Dynamic recipient controls in header.
Allowing the user to add cc/bcc on the fly is user-friendly. The ghost button style is a nice UI touch.
1183-1208
: Save draft and send button.
Both actions handle enabling/disabling states properly.saveDraft
is triggered via an explicit button, andsendEmail
is triggered via the arrow button or shortcuts.
READ CAREFULLY THEN REMOVE
Remove bullet points that are not relevant.
PLEASE REFRAIN FROM USING AI TO WRITE YOUR CODE AND PR DESCRIPTION. IF YOU DO USE AI TO WRITE YOUR CODE PLEASE PROVIDE A DESCRIPTION AND REVIEW IT CAREFULLY. MAKE SURE YOU UNDERSTAND THE CODE YOU ARE SUBMITTING USING AI.
Description
Please provide a clear description of your changes.
Type of Change
Please delete options that are not relevant.
Areas Affected
Please check all that apply:
Testing Done
Describe the tests you've done:
Security Considerations
For changes involving data or authentication:
Checklist
Additional Notes
Add any other context about the pull request here.
Screenshots/Recordings
Add screenshots or recordings here if applicable.
By submitting this pull request, I confirm that my contribution is made under the terms of the project's license.
Summary by CodeRabbit
New Features
Bug Fixes