fix(chat): add history loading skeletons
Build Push and Deploy / docker-image (push) Successful in 1m2s
Build Push and Deploy / deploy-fallback-log (push) Has been skipped

This commit is contained in:
2026-06-10 17:51:28 +08:00
parent ab9e2a0420
commit 9c0a7a2864
6 changed files with 254 additions and 57 deletions
+62 -11
View File
@@ -13,6 +13,7 @@ import {
Divider,
IconButton,
Paper,
Skeleton,
Stack,
TextField,
Tooltip,
@@ -34,9 +35,11 @@ type AgentHistoryPanelProps = {
sessions: ChatSessionSummary[];
activeSessionId?: string;
isHydrating?: boolean;
isLoadingSessions?: boolean;
loadingSessionId?: string;
onNewSession: () => void;
onRenameSession: (sessionId: string, title: string) => void;
onSelectSession: (sessionId: string) => void;
onSelectSession: (sessionId: string, title: string) => void;
onDeleteSession: (sessionId: string) => void;
};
@@ -76,6 +79,8 @@ export const AgentHistoryPanel = ({
sessions,
activeSessionId,
isHydrating = false,
isLoadingSessions = false,
loadingSessionId,
onNewSession,
onRenameSession,
onSelectSession,
@@ -127,6 +132,30 @@ export const AgentHistoryPanel = ({
(session) => session.id === pendingDeleteSessionId,
);
const renderSessionListSkeleton = () => (
<Stack spacing={1} aria-label="正在加载历史会话">
{Array.from({ length: 6 }, (_, index) => (
<Paper
key={index}
elevation={0}
sx={{
px: 1.25,
py: 1,
borderRadius: 3,
bgcolor: alpha("#fff", 0.48),
border: `1px solid ${alpha("#fff", 0.68)}`,
boxShadow: `0 4px 12px ${alpha("#000", 0.025)}`,
}}
>
<Stack spacing={0.75} sx={{ minHeight: 46, justifyContent: "center" }}>
<Skeleton variant="text" width={`${72 - (index % 3) * 12}%`} height={18} />
<Skeleton variant="text" width="32%" height={14} />
</Stack>
</Paper>
))}
</Stack>
);
const handleStartRename = (sessionId: string, title: string) => {
setEditingSessionId(sessionId);
setDraftTitle(title);
@@ -215,7 +244,9 @@ export const AgentHistoryPanel = ({
<Divider sx={{ borderColor: alpha("#fff", 0.6) }} />
<Box sx={{ flex: 1, overflowY: "auto", px: 1.25, py: 1.25 }}>
{sessions.length === 0 ? (
{isLoadingSessions ? (
renderSessionListSkeleton()
) : sessions.length === 0 ? (
<Stack
alignItems="center"
justifyContent="center"
@@ -271,27 +302,42 @@ export const AgentHistoryPanel = ({
<Stack spacing={1}>
{groupSessions.map((session) => {
const isActive = session.id === activeSessionId;
const isLoading = session.id === loadingSessionId;
return (
<Paper
key={session.id}
elevation={0}
aria-label={isLoading ? `正在加载会话 ${session.title}` : undefined}
onClick={() => {
if (editingSessionId === session.id) return;
onSelectSession(session.id);
if (editingSessionId === session.id || isLoading) return;
onSelectSession(session.id, session.title);
}}
sx={{
px: 1.25,
py: 1,
borderRadius: 3,
cursor: isHydrating ? "default" : "pointer",
bgcolor: isActive ? alpha("#00acc1", 0.12) : alpha("#fff", 0.56),
border: `1px solid ${isActive ? alpha("#00acc1", 0.25) : alpha("#fff", 0.72)}`,
boxShadow: isActive ? `0 8px 20px ${alpha("#00acc1", 0.12)}` : `0 4px 12px ${alpha("#000", 0.03)}`,
cursor: isHydrating || isLoading ? "default" : "pointer",
bgcolor:
isActive || isLoading
? alpha("#00acc1", 0.12)
: alpha("#fff", 0.56),
border: `1px solid ${
isActive || isLoading
? alpha("#00acc1", 0.25)
: alpha("#fff", 0.72)
}`,
boxShadow:
isActive || isLoading
? `0 8px 20px ${alpha("#00acc1", 0.12)}`
: `0 4px 12px ${alpha("#000", 0.03)}`,
transition: "all 0.2s ease",
pointerEvents: isHydrating ? "none" : "auto",
pointerEvents: isHydrating || isLoading ? "none" : "auto",
"&:hover": {
bgcolor: isActive ? alpha("#00acc1", 0.14) : alpha("#fff", 0.86),
bgcolor:
isActive || isLoading
? alpha("#00acc1", 0.14)
: alpha("#fff", 0.86),
borderColor: alpha("#00acc1", 0.2),
},
}}
@@ -382,6 +428,11 @@ export const AgentHistoryPanel = ({
<CloseRounded sx={{ fontSize: 16 }} />
</IconButton>
</Stack>
) : isLoading ? (
<Box sx={{ minHeight: 46, display: "flex", flexDirection: "column", justifyContent: "center" }}>
<Skeleton variant="text" width="74%" height={18} />
<Skeleton variant="text" width="34%" height={14} sx={{ mt: 0.5 }} />
</Box>
) : pendingDeleteSessionId === session.id ? (
<Stack direction="row" spacing={0.75} alignItems="center" sx={{ minHeight: 46 }}>
<Box
@@ -437,7 +488,7 @@ export const AgentHistoryPanel = ({
)}
</Box>
{!(editingSessionId === session.id || pendingDeleteSessionId === session.id) && (
{!(editingSessionId === session.id || pendingDeleteSessionId === session.id || isLoading) && (
<Stack direction="row" spacing={0.25}>
<Tooltip title="修改会话标题">
<span>