mirror of
https://github.com/tiennm99/DocsGPT.git
synced 2026-10-11 03:12:55 +00:00
Fix a crash on the filtered agent routes, and two animation defects
AgentSection computed its folder breadcrumb in a useMemo placed below two early returns for the empty states. A hook after an early return is skipped on the render that takes it, which React rejects outright with "rendered fewer hooks than expected" — the page showed only the error boundary. Reachable now that each filter is its own route: landing straight on an empty one renders once while the data loads and again once it arrives empty, taking the early return the second time. The memo moves above them. Two problems in the chat's entrance animations, found while looking for the reported flicker: - .fade-in-bubble carried `opacity: 0` on the element and reached full opacity only by running `fadeInUp` to completion with `forwards`. The answer text was therefore visible *because* an animation had finished, so anything that stopped one running left it blank — including the obvious reduced-motion reset, which is presumably why the rule covers only .shimmer-text today. The start state moves into the keyframes, the element rests visible, and both entrances now honour prefers-reduced-motion. - The timings were long for their jobs. An expanded tool call reaches its full height at once, so fading its content over half a second read as the content lagging the layout rather than as a reveal; it is now 0.16s. The answer entrance goes to 0.26s with a 6px rise instead of 0.5s and 10px.
This commit is contained in:
1 parent
ac87430715
commit
2f6b2ee8dd
2 files changed
+33
-13
No files matched your search
@@ -400,6 +400,19 @@ function AgentSection({
|
||||
onCreateFolder(name, currentFolderId || undefined);
|
||||
};
|
||||
|
||||
// Must stay above the empty-state returns below: a hook after an early
|
||||
// return is skipped on the render that takes it, which React rejects with
|
||||
// "rendered fewer hooks than expected". Reachable now that each filter is
|
||||
// its own route — landing straight on an empty one renders once while the
|
||||
// data loads, then again once it arrives empty.
|
||||
const breadcrumbItems = useMemo(() => {
|
||||
if (!folders || folderPath.length === 0) return [];
|
||||
return folderPath.map((folderId) => {
|
||||
const folder = folders.find((f) => f.id === folderId);
|
||||
return { id: folderId, name: folder?.name || '' };
|
||||
});
|
||||
}, [folders, folderPath]);
|
||||
|
||||
const hasNoAgentsAtAll = !isLoading && totalAgents === 0;
|
||||
const isSearchingWithNoResults =
|
||||
!isLoading && searchQuery && filteredAgents.length === 0 && totalAgents > 0;
|
||||
@@ -433,15 +446,6 @@ function AgentSection({
|
||||
);
|
||||
}
|
||||
|
||||
// Build breadcrumb items from folder path
|
||||
const breadcrumbItems = useMemo(() => {
|
||||
if (!folders || folderPath.length === 0) return [];
|
||||
return folderPath.map((folderId) => {
|
||||
const folder = folders.find((f) => f.id === folderId);
|
||||
return { id: folderId, name: folder?.name || '' };
|
||||
});
|
||||
}, [folders, folderPath]);
|
||||
|
||||
return (
|
||||
<div className="mt-8 flex flex-col gap-4">
|
||||
<div className="flex w-full flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
|
||||
|
||||
+20
-4
@@ -690,8 +690,11 @@ Avoid over-scrolling in mobile browsers
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
/* Disclosure content, e.g. an expanded tool call. Short on purpose: the
|
||||
panel's height appears at once, so a long fade reads as the content
|
||||
lagging behind the layout rather than as a reveal. */
|
||||
.fade-in {
|
||||
animation: fadeIn 0.5s ease-in-out;
|
||||
animation: fadeIn 0.16s ease-out;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
@@ -703,10 +706,13 @@ Avoid over-scrolling in mobile browsers
|
||||
}
|
||||
}
|
||||
|
||||
/* The start state lives in the keyframes, not here: with `opacity: 0` on
|
||||
the element itself the content was only ever visible *because* an
|
||||
animation had run to completion, so anything that stopped it running —
|
||||
a cancelled animation, a reduced-motion reset — left the answer blank.
|
||||
The element now rests visible and the animation is purely additive. */
|
||||
.fade-in-bubble {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
animation: fadeInUp 0.5s forwards;
|
||||
animation: fadeInUp 0.26s ease-out;
|
||||
}
|
||||
|
||||
.shimmer-text {
|
||||
@@ -754,9 +760,19 @@ Avoid over-scrolling in mobile browsers
|
||||
.dark .shimmer-text {
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
/* Safe to drop outright now that both rest in their final state. */
|
||||
.fade-in,
|
||||
.fade-in-bubble {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(6px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
|
||||
Reference in new issue
Block a user