The anxiety behind a surprise duplicates count is "did I lose
something?" — a native title tooltip on the counter answers it:
these messages are already in the archive. Key added to all 18
locales.
duplicateCount existed only in en.json, so 17 locales fell back to
English inside an otherwise localized panel. The processed count,
percentage and progress bar computed success+failed+duplicates
inline three times; hoist it once so the three can never disagree.
success no longer includes dedup-skipped mail, so without a
duplicates field ImportPerformed consumers could not tell an
all-duplicates batch from one that silently lost everything. Also
documents that ExtractOutcome::Imported covers mail dropped by
archive rules, which has always counted as a success.
rustfmt +nightly (imports_granularity, group_imports per
.rustfmt.toml) over the five files the fix touched, plus trailing
whitespace cleanup. No behavior change.
Reapplies what c067655 reverted: the duplicates counter next to
success/failed and duplicates included in the processed count and
percentage. The server now reports real duplicate counts on every
upload-import path, so the display no longer renders dead zeros.
A BLAKE3 content-hash hit in extract_envelope_core returned the same
Ok(()) as a real import, so every import surface counted silently
skipped messages as successes and the documented duplicates field
stayed 0 forever.
Make the outcome explicit: extract_envelope_core now returns
ExtractOutcome::{Imported, Duplicate} and every import loop (batch
/import, upload EML, MBOX, PST) counts Duplicate into duplicates
instead of success. total = success + duplicates + failed holds on
every path; duplicates produce no failed_details entries and an
all-duplicates run reports Completed. The batch endpoint status check
treats duplicates as processed work so a duplicates-plus-failures run
keeps reporting Completed as before. The SMTP receiver and IMAP sync
ignore the outcome.
The upload-import path never increments duplicates (a dedup hit
returns Ok and counts as success), so the counter and the progress
math addition could only ever render dead zeros. The display returns
together with the server-side fix; the client-side aggregation of the
duplicates field stays, as issue #2 specifies.
The import footer showed 'Will import to: X' with no sign that the
whole selection lands in that one folder, and the detected-folder
badge never said which file the hint came from (only the first valid
file is consulted). Multi-file selections now show the file count in
the footer and the hint's source file in the badge.
The results card now renders the aggregated duplicates count and the
processed math includes it. The upload-import path currently always
reports duplicates as 0 (duplicates return Ok and count as success
server-side), so this only becomes visible once the server reports
them, but the aggregate and display are ready.
Header unfolding in extractFolderHint matched any whitespace-led line
in the remaining 64 KB, so body text could be glued onto the folder
name; it now stops at the first non-continuation line per RFC 5322.
The file picker allows multi-select but the import mutation only ever
uploaded files[0], silently dropping the rest. upload-import is
one-file-per-call and async: it returns Pending immediately and the
real counts only exist at /import-progress/:id, so summing upload
responses would aggregate zeros.
importFiles() loops the selection sequentially: upload, poll to a
terminal status, merge counts and failed_details into an aggregate.
A file that fails upload or polling becomes a synthetic failure entry
(labelled with the file name) instead of aborting the remaining
uploads; only when every upload transport-fails does it throw so the
existing toast-and-reset path still handles total failure. Upload
progress is byte-weighted across the whole selection so the bar never
resets between files. An AbortSignal wired to component unmount
replaces the deleted setInterval cleanup so polling cannot outlive
the page.
Fixes#2
- Add SyncFull trigger and configurable IMAP socket read timeout
- Replace streaming UID FETCH with UID SEARCH ALL + batched fetch so per-message progress stays responsive and throttling servers can retry with reconnection
- Finalize stale Running sessions on startup so interrupted syncs no longer show a phantom "syncing" state
- Show a live syncing pill on the account row; add elapsed time, current folder, and slow-server warning styling in the dialog