fix(compose): wait for in-flight attachment uploads before sending

Clicking Send while attachments were still uploading silently dropped
them from the outgoing message: every place that builds the outgoing
attachment list filters on att.blobId && !att.uploading, and the Send
button never accounted for uploads still in flight. Attach a few files,
hit Send right away, and the email could go out missing some of them
with no warning.

handleSend now detects pending uploads before validating:

- Send is disabled with an explanatory tooltip
  (validation.attachments_uploading) while it waits.
- Once uploads finish cleanly, the send proceeds automatically - no
  second click needed.
- If an upload FAILS while waiting, the send is aborted with an error
  toast (validation.attachment_upload_failed) instead of silently
  shipping the email without the failed attachment - the user may not
  be looking at the composer to notice the red error chip.
- If the draft is closed or discarded while waiting, the pending send
  is cancelled cleanly.

The wait/decision logic lives in waitForPendingUploads() in
lib/email-composer-utils.ts (returns completed | cancelled | failed)
with unit tests covering all three outcomes. Outgoing-attachment
call sites read the freshest state via attachmentsRef since the
render closure captured at click time won't reflect uploads that
finished during the wait.

Both new i18n keys added to all 20 locales under
email_composer.validation.
This commit is contained in:
KazNIISA IT
2026-07-04 14:54:41 +02:00
committed by Linus Rath
parent 9aef8bc393
commit 396f5f7d60
23 changed files with 210 additions and 24 deletions
+3 -1
View File
@@ -635,7 +635,9 @@
"validation": {
"recipient_required": "یک گیرنده اضافه کنید",
"subject_required": "یک موضوع اضافه کنید",
"body_required": "پیامی بنویسید یا فایلی پیوست کنید"
"body_required": "پیامی بنویسید یا فایلی پیوست کنید",
"attachments_uploading": "پیوست‌ها هنوز در حال بارگذاری هستند — پس از اتمام ارسال می‌شود",
"attachment_upload_failed": "ارسال نشد - بارگذاری یک پیوست ناموفق بود. آن را حذف کنید و دوباره تلاش کنید."
},
"upload_progress": "در حال بارگذاری {uploaded} / {total}",
"upload_cancel": "لغو بارگذاری",