feat(messaging-ui): Gmail-style uploading chip while an attachment uploads (0.1.2)

Picking a file now shows an immediate chip with the filename + a spinner while
the bytes upload (mail compose, mail reply, and the messenger composer), instead
of only appearing once upload finishes. Respects prefers-reduced-motion.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-23 01:04:52 +05:30
parent 8878ee8c54
commit 22eaf0f654
4 changed files with 45 additions and 4 deletions
@@ -38,6 +38,7 @@ export function Composer({
const [sending, setSending] = useState(false);
const [staged, setStaged] = useState<Attachment | null>(null);
const [uploading, setUploading] = useState(false);
const [uploadingName, setUploadingName] = useState<string | null>(null);
const fileRef = useRef<HTMLInputElement>(null);
const query = trailingMentionQuery(draft);
@@ -59,12 +60,14 @@ export function Composer({
e.target.value = '';
if (!file) return;
setUploading(true);
setUploadingName(file.name);
try {
setStaged(await upload(file));
} catch {
/* host surfaces upload errors */
} finally {
setUploading(false);
setUploadingName(null);
}
}
@@ -110,7 +113,11 @@ export function Composer({
))}
</ul>
) : null}
{staged ? (
{uploading && uploadingName ? (
<div className="miu-staged is-uploading">
<span className="miu-spinner" aria-hidden="true" /> {uploadingName} · uploading
</div>
) : staged ? (
<div className="miu-staged">
📎 {staged.name}
<button type="button" className="miu-staged-x" onClick={() => setStaged(null)} aria-label="Remove attachment">