feat(frontend): better ui for long loading files#983
Conversation
097ce66 to
32cd128
Compare
There was a problem hiding this comment.
Pull request overview
Improves the chat file-upload UI to better communicate long-running uploads by adding delayed “waiting” messages to uploading file chips and refining the file-chip presentation.
Changes:
- Add two new i18n strings for “waiting” upload status and wire them into the
textshelper. - Update the file chip (
FileItemComponent) to show delayed waiting messages while uploading and display upload timestamps for completed files. - Refactor
ChatInputto render a unified, sorted list of uploading + uploaded files; add global CSS animations to support delayed/alternating status hints.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| services/reis/uv.lock | Bumps Python dependencies (appears unrelated to the frontend upload UI change). |
| frontend/src/texts/languages/en.ts | Adds English strings for the new long-upload waiting messages. |
| frontend/src/texts/languages/de.ts | Adds German strings for the new long-upload waiting messages. |
| frontend/src/texts/index.ts | Exposes the new files.waitingMessage1/2 translation keys through texts. |
| frontend/src/pages/chat/useChatDropzone.ts | Adjusts pending upload tracking (related to showing/allowing multiple pending uploads). |
| frontend/src/pages/chat/conversation/FileItem.tsx | Adds UI for delayed waiting hints during upload and shows uploaded timestamps; improves delete UX. |
| frontend/src/pages/chat/conversation/ChatInput.tsx | Renders uploading + uploaded files together with metadata/sorting logic. |
| frontend/src/index.css | Adds keyframes/classes used to delay and alternate the waiting hint text. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <div className="animate-show-after-7s relative h-5"> | ||
| <span className="animate-alternate-first absolute top-0 right-0 left-0 truncate text-sm font-medium text-orange-800 italic"> | ||
| {texts.files.waitingMessage1} | ||
| </span> | ||
| <span className="animate-alternate-second absolute top-0 right-0 left-0 truncate text-sm font-medium text-orange-800 italic"> | ||
| {texts.files.waitingMessage2} | ||
| </span> |
There was a problem hiding this comment.
The new long-upload hint text does not match the copy in #982 (“This may take a while...”), and the two-message alternation (‘processing...’ / ‘a few minutes more’) may not satisfy the requirement as written. If the issue expects the exact string, update the translation keys/copy accordingly (and ensure it’s only shown after the intended delay).
| {loading && ( | ||
| <div className="animate-show-after-7s relative h-5"> | ||
| <span className="animate-alternate-first absolute top-0 right-0 left-0 truncate text-sm font-medium text-orange-800 italic"> | ||
| {texts.files.waitingMessage1} | ||
| </span> | ||
| <span className="animate-alternate-second absolute top-0 right-0 left-0 truncate text-sm font-medium text-orange-800 italic"> | ||
| {texts.files.waitingMessage2} | ||
| </span> | ||
| </div> | ||
| )} |
There was a problem hiding this comment.
The new long-upload UI behavior (showing an additional hint after a delay) isn’t covered by existing frontend tests. Since this PR introduces user-visible behavior tied to timing/visibility, consider adding a unit test around the FileItemComponent/ChatInput rendering that asserts the hint elements/classes are present for loading items (and, if feasible, that they are delayed via the expected CSS class).
| .map((m, index) => ({ | ||
| fileName: m.variables?.file?.name || '', | ||
| isUploading: true, | ||
| originalFile: m.variables?.file, | ||
| uploadTime: new Date(), | ||
| uniqueKey: `${m.submittedAt}-${index}`, |
There was a problem hiding this comment.
uniqueKey includes the index from the filtered pending mutations list. When one pending upload settles, indices of the remaining items can shift, changing keys and remounting FileItemComponent (which will reset the “show after N seconds” animation/timer). Prefer a key derived only from stable mutation identity (e.g., submittedAt plus file name) rather than the array index.
| .map((m, index) => ({ | |
| fileName: m.variables?.file?.name || '', | |
| isUploading: true, | |
| originalFile: m.variables?.file, | |
| uploadTime: new Date(), | |
| uniqueKey: `${m.submittedAt}-${index}`, | |
| .map((m) => ({ | |
| fileName: m.variables?.file?.name || '', | |
| isUploading: true, | |
| originalFile: m.variables?.file, | |
| uploadTime: new Date(), | |
| uniqueKey: `${m.submittedAt}-${m.variables?.file?.name || ''}`, |
| } | ||
| } | ||
| .animate-show-after-7s { | ||
| animation: show-after-delay 5.5s forwards; |
There was a problem hiding this comment.
The CSS class name animate-show-after-7s implies a 7s delay, but it currently runs show-after-delay for 5.5s (with the element only becoming visible at the end). This will show the “long upload” hint earlier than intended and is likely out of sync with the 7s requirement; consider implementing an actual 7s delay (e.g., via animation-delay: 7s) and aligning the keyframes accordingly.
| animation: show-after-delay 5.5s forwards; | |
| animation: show-after-delay 7s forwards; |
| fileName: m.variables?.file?.name || '', | ||
| isUploading: true, | ||
| originalFile: m.variables?.file, | ||
| uploadTime: new Date(), |
There was a problem hiding this comment.
uploadTime is set to new Date() during render for each pending mutation, so it changes on every re-render. Because it participates in sorting, the ordering of file chips can become unstable/jittery; use a stable timestamp from the mutation (e.g., m.submittedAt) instead.
| uploadTime: new Date(), | |
| uploadTime: new Date(m.submittedAt || 0), |
| extensionFilesToUpload?.forEach(({ filesToUpload, extensionId }) => { | ||
| filesToUpload.forEach((file) => { | ||
| upload.mutate({ | ||
| file, | ||
| extensionId, | ||
| }); | ||
| }); |
There was a problem hiding this comment.
Issue #982 calls for prompting the user when they re-upload a file with the same name while the first upload is still in progress. handleUploadFile currently starts uploads immediately and there is no check for an existing pending upload with the same file.name nor any confirmation UI, so the second requirement in #982 does not appear to be implemented.
… when done loading
…or deleting a file
472817d to
25de073
Compare
Closes #982