Repository navigation
fix(uploads): say how many files a mixed pick, drop or paste skipped - #651
Conversation
A selection mixing a file the server takes with one it refuses dropped the refused one without a word, and the Compose and paste-dialog pickers never toasted even when every file was refused. Every pick, drop and paste filter now goes through one helper that counts what the classifier refused: a partial refusal toasts how many were skipped while the rest upload, a full one keeps the existing Unsupported file type toast, and a clipboard paste that falls back to its text stays quiet.
|
Thanks @JDProfresh, and thanks for following through on #622. This PR routes every pick, drop and paste through one helper, I traced every call site. Admission still comes only from One small thing, which I will do at merge time unless you want to push it first:
I will add the changeset and merge. Thanks again for closing the loop on this. |
…t in the docs CLAUDE.md (Prompt uploads) and architecture-invariants still named _promptAttachKind() as the filter every surface reads. That stays true, but the surfaces now admit through _admitPromptAttachments(), which is what says how many files a pick skipped. A new surface that filtered on the classifier directly would drop files silently. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…k, drop or paste skipped Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> # Conflicts: # CLAUDE.md
|
Merged and shipped in 1.43.0. Thanks @JDProfresh! I added the clause to CLAUDE.md and architecture-invariants saying new upload surfaces admit through |
When some files in a selection were refused, every upload surface just filtered them out. The
Unsupported file typetoast only came when nothing at all got through, and the Compose and paste-dialog pickers had no toast at all.This is the follow-up I offered at the end of #622, including the Compose and paste-dialog pickers.
Problem. Pick a photo, a
.shand a.pdftogether and the photo and the PDF upload while the script vanishes without a word. In the Compose dialog and the shell paste dialog it was worse: pick only an unsupported file and nothing happened at all. The paste dialog just stayed open with no explanation.Cause. Each filter (terminal drop, toolbar Attach, the Ctrl+V paste trap, the tile grid drop, and the Compose and paste-dialog pickers and paste handlers) ran
files.filter(_promptAttachKind)on its own. Only three of them toasted, and only when the filtered list came out empty.Fix. All of those now go through one helper,
_admitPromptAttachments()inimage-input.js, next to the classifier. It returns the admitted files and reports what it refused:1 file skipped: unsupported type(orN files skipped) as an info toast, and the rest still uploadUnsupported file typeerror toast, now on the Compose and paste-dialog pickers tooThe helper keys only on what
_promptAttachKind()refuses, so it does not care which kinds are admitted (it works the same before and after #621's documents). The two dialogs also reset their file input before handling a pick, the way the toolbar Attach input already does. Without that, picking the same refused file a second time fires nochangeevent and so no toast. The new string has a zh-CN pattern ini18n.jscovering singular and plural.Invariants touched: [Prompt uploads](CLAUDE.md, "Prompt uploads":
_promptAttachKind()stays the ONE classifier every pick and paste filter reads; the helper calls it and nothing else decides admission) and the frontend i18n rule insrc/web/CLAUDE.md.Tests.
test/toolbar-attach.test.ts: a mixed Attach pick uploads the photo and PDF and toasts the skip. A terminal drop goes through the same filter for both the partial toast and the full-refusal toast (the harness now mounts#terminalContainer). The helper is silent when it admits everything and quiet for a text paste with nothing admitted.test/image-paste-trap.test.ts: image plus refused file uploads the image and toasts. Text plus refused file pastes the text with no toast. A refused file with no text toasts.test/mobile-prompt-composer.test.ts: the Compose picker's mixed and fully-refused picks, the Compose paste with text plus a refused file, and the same three cases in the paste dialog. The harness binds the real helper fromimage-input.js, so these pin the shipped wording.test/tile-grid-file-drop.test.tsandtest/tile-grid-i18n.test.ts: the tile drop counts the skip, and the new string translates. The tile vm harness now loadsimage-input.js.I removed each branch of the helper and reverted each call site one at a time, and each change turned at least one of these tests red.
Verified. I ran a throwaway instance from #621 and #622 plus this commit, before they merged, with headless Chromium in an iPhone 13 profile and a desktop profile and a throwaway shell session. I picked photo.jpg + run.sh + notes.pdf through each surface. Observed:
1 file skipped: unsupported typeUnsupported file typerun.sh never reached the server in either column. Inferred, not observed: the input reset matters on a real device. In headless Chromium, Playwright's
setFilesfireschangeeven for the same file, so a repeated pick toasted twice there either way.Gate on this branch, rebased onto 1.42.0:
npm test11594 passed, 12 skipped. Typecheck, lint, format:check, check:frontend-syntax and check:browser-excludes are all green. The rebase only met the new worktree toasts ini18n.js, and both sets of entries are kept.