Skip to content

[_]: fix: update draft handling in compose message component and hooks#70

Open
jzunigax2 wants to merge 2 commits into
masterfrom
fix/draft-handling
Open

[_]: fix: update draft handling in compose message component and hooks#70
jzunigax2 wants to merge 2 commits into
masterfrom
fix/draft-handling

Conversation

@jzunigax2

Copy link
Copy Markdown
Contributor
  • Introduced flushPendingDraftSave to manage draft saving more effectively.
  • Replaced draftId with resolveDraftId in useComposeSend for better draft resolution.
  • Enhanced saveDraft logic to prevent duplicate saves during concurrent operations.
  • Updated tests to reflect changes in draft handling and ensure correct functionality.

- Introduced `flushPendingDraftSave` to manage draft saving more effectively.
- Replaced `draftId` with `resolveDraftId` in `useComposeSend` for better draft resolution.
- Enhanced `saveDraft` logic to prevent duplicate saves during concurrent operations.
- Updated tests to reflect changes in draft handling and ensure correct functionality.
@jzunigax2 jzunigax2 requested a review from xabg2 as a code owner July 8, 2026 23:48
@jzunigax2 jzunigax2 added the enhancement New feature or request label Jul 8, 2026
@jzunigax2 jzunigax2 self-assigned this Jul 8, 2026
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Draft autosave logic in useDraftMessage is refactored to queue concurrent saves and expose resolveDraftId. useComposeSend now awaits that resolver instead of reading a static draft id. ComposeMessageDialog wires the resolver through, and tests cover the new async flow.

Changes

Draft save coordination and send integration

Layer / File(s) Summary
Draft save coordination
src/components/compose-message/hooks/useDraftMessage.ts
Adds queued save state, refactors autosave execution and rescheduling, and returns resolveDraftId from the hook.
Draft save and autosave tests
src/components/compose-message/hooks/useDraftMessage.test.ts
Adds editor event handlers and covers concurrent saves, resolveDraftId waiting, and update-triggered autosave re-arming.
Async draft resolution in send
src/components/compose-message/hooks/useComposeSend.ts, src/components/compose-message/hooks/useComposeSend.test.ts
Replaces draftId with resolveDraftId, awaits it during send, updates callback dependencies, and verifies resolved and missing draft ids.
Compose message wiring
src/components/compose-message/index.tsx
Removes draftId from useDraftMessage output and passes resolveDraftId into useComposeSend.

Estimated code review effort: 3 (Moderate) | ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: updating draft handling in compose message hooks and component.
Description check ✅ Passed The description is clearly related to the draft-handling refactor and the updated tests.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/draft-handling

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

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Warning

CodeRabbit couldn't request changes on this pull request because it doesn't have sufficient GitHub permissions.

Please grant CodeRabbit Pull requests: Read and write permission and re-run the review.

👉 Steps to fix this

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/compose-message/hooks/useComposeSend.test.ts`:
- Around line 314-315: The affected test descriptions in useComposeSend.test
should be rewritten to follow the “When…then…” style without naming
implementation details like sendEmail or draftId. Update the descriptions for
the related tests in the useComposeSend test suite to describe the behavior in
user-facing terms, while keeping the assertions and setup unchanged.

In `@src/components/compose-message/hooks/useDraftMessage.ts`:
- Around line 130-164: Extract the repeated autosave timer cleanup in
useDraftMessage into a shared helper (for example a clearAutosaveTimer-style
function) and reuse it in saveDraft, flushPendingDraftSave, clearDraftRef, and
scheduleAutosave. Make sure the helper still nulls timerRef.current after
clearTimeout, and update each useCallback’s dependency array to include the new
helper so the teardown logic stays consistent and DRY.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 680672d6-f875-4472-8563-a33674b6e4d6

📥 Commits

Reviewing files that changed from the base of the PR and between a01ab37 and 5f5c841.

📒 Files selected for processing (5)
  • src/components/compose-message/hooks/useComposeSend.test.ts
  • src/components/compose-message/hooks/useComposeSend.ts
  • src/components/compose-message/hooks/useDraftMessage.test.ts
  • src/components/compose-message/hooks/useDraftMessage.ts
  • src/components/compose-message/index.tsx

Comment thread src/components/compose-message/hooks/useComposeSend.test.ts Outdated
Comment thread src/components/compose-message/hooks/useDraftMessage.ts Outdated
toRecipients,
inReplyTo: inReplyItemId,
draftId: draftId ?? undefined,
resolveDraftId: flushPendingDraftSave,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would be better resolvePendingDrafts or smth like that. What do you think?

… clarity

- Updated the draft handling logic in the ComposeMessage component and related hooks.
- Replaced `flushPendingDraftSave` with `resolveDraftId` to better reflect its purpose.
- Adjusted tests to align with the new draft resolution approach and ensure accurate functionality.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 9, 2026

Copy link
Copy Markdown

Deploying mail-web with  Cloudflare Pages  Cloudflare Pages

Latest commit: d319bea
Status: ✅  Deploy successful!
Preview URL: https://4171a68b.mail-web-ea0.pages.dev
Branch Preview URL: https://fix-draft-handling.mail-web-ea0.pages.dev

View logs

@sonarqubecloud

sonarqubecloud Bot commented Jul 9, 2026

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Warning

CodeRabbit couldn't request changes on this pull request because it doesn't have sufficient GitHub permissions.

Please grant CodeRabbit Pull requests: Read and write permission and re-run the review.

👉 Steps to fix this

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/compose-message/hooks/useDraftMessage.ts`:
- Around line 167-170: Cancel the autosave timer in handleDraftDiscard before
the draft deletion request is awaited, so a pending autosave cannot race with
discardDraft and call updateDraft on the same draft; update useDraftMessage to
invoke clearAutosaveTimer() at the start of handleDraftDiscard, before
discardDraft({ draftId: draftIdRef.current }).unwrap(), and keep the guard on
draftIdRef.current intact.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 18d0b740-5dfb-44bf-8e7c-7f4785c4b5a6

📥 Commits

Reviewing files that changed from the base of the PR and between 5f5c841 and d319bea.

📒 Files selected for processing (4)
  • src/components/compose-message/hooks/useComposeSend.test.ts
  • src/components/compose-message/hooks/useDraftMessage.test.ts
  • src/components/compose-message/hooks/useDraftMessage.ts
  • src/components/compose-message/index.tsx

Comment on lines 167 to 170
const handleDraftDiscard = useCallback(async () => {
if (!draftIdRef.current) return;
await discardDraft({ draftId: draftIdRef.current }).unwrap();
}, [discardDraft]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -nP 'handleDraftDiscard|clearDraftRef|scheduleAutosave' -C3 src/components/compose-message

Repository: internxt/mail-web

Length of output: 7967


🏁 Script executed:

#!/bin/bash
set -euo pipefail

ast-grep outline src/components/compose-message/hooks/useDraftMessage.ts --view expanded
printf '\n--- FILE (relevant sections) ---\n'
sed -n '1,260p' src/components/compose-message/hooks/useDraftMessage.ts
printf '\n--- TESTS / USAGE ---\n'
rg -n "useDraftMessage|handleDraftDiscard|clearAutosaveTimer|discardDraft|scheduleAutosave|saveDraft\(" src/components/compose-message -g '!**/node_modules/**'

Repository: internxt/mail-web

Length of output: 13183


Cancel the autosave timer before discarding the draft. handleDraftDiscard() should call clearAutosaveTimer() before awaiting discardDraft(...).unwrap(). Otherwise a pending autosave can fire while draftIdRef.current still points at the draft and issue updateDraft({ draftId }) against a draft that is being deleted.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/compose-message/hooks/useDraftMessage.ts` around lines 167 -
170, Cancel the autosave timer in handleDraftDiscard before the draft deletion
request is awaited, so a pending autosave cannot race with discardDraft and call
updateDraft on the same draft; update useDraftMessage to invoke
clearAutosaveTimer() at the start of handleDraftDiscard, before discardDraft({
draftId: draftIdRef.current }).unwrap(), and keep the guard on
draftIdRef.current intact.

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

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants