mirror of
https://github.com/temetro/temetro.git
synced 2026-07-26 11:58:14 +00:00
frontend: fix file attach dropping the picked file (live FileList race)
The file pickers read event.target.files but reset event.target.value = "" before the file was actually used: in the AI composer the value reset ran before React's deferred setState updater read the (now-empty) live FileList, so no chip appeared; in Messages the reset ran before the length check, so it returned early. Snapshot the files into a plain array synchronously, before the reset. This is why attaching seemed to fail (no badge) — especially while typing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -85,12 +85,17 @@ export function ChatInput({
|
||||
|
||||
const handleFilesSelected = useCallback(
|
||||
(event: ChangeEvent<HTMLInputElement>) => {
|
||||
const selected = event.target.files;
|
||||
if (selected && selected.length > 0) {
|
||||
setFiles((prev) => [...prev, ...Array.from(selected)]);
|
||||
}
|
||||
// Copy the files out NOW: `event.target.files` is a live FileList, and the
|
||||
// `event.target.value = ""` reset below empties it. React runs the
|
||||
// functional setState updater during a later render, so reading the
|
||||
// FileList inside the updater would see it already cleared (no file added,
|
||||
// no chip). Snapshot to a plain array first.
|
||||
const picked = Array.from(event.target.files ?? []);
|
||||
// Reset so picking the same file again still fires onChange.
|
||||
event.target.value = "";
|
||||
if (picked.length > 0) {
|
||||
setFiles((prev) => [...prev, ...picked]);
|
||||
}
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
@@ -283,12 +283,15 @@ export function MessagesView() {
|
||||
|
||||
// Open the file picker; on select, upload each and stage it.
|
||||
const onPickFiles = async (event: ChangeEvent<HTMLInputElement>) => {
|
||||
const files = event.target.files;
|
||||
// Snapshot before resetting: `event.target.files` is a live FileList that
|
||||
// `event.target.value = ""` empties, so reading it afterwards (or in a later
|
||||
// tick) yields nothing.
|
||||
const picked = Array.from(event.target.files ?? []);
|
||||
event.target.value = "";
|
||||
if (!files?.length) return;
|
||||
if (picked.length === 0) return;
|
||||
setUploading(true);
|
||||
try {
|
||||
for (const file of Array.from(files)) {
|
||||
for (const file of picked) {
|
||||
if (file.size > MAX_ATTACHMENT_BYTES) {
|
||||
notify.error(
|
||||
t("messages.attach.tooLargeTitle"),
|
||||
|
||||
Reference in New Issue
Block a user