fix(chat): speed up history switch

This commit is contained in:
john
2026-06-29 11:15:40 +08:00
parent 637b32515a
commit e0e03e95b1
3 changed files with 47 additions and 9 deletions
+27 -2
View File
@@ -59,11 +59,13 @@ export function HistorySidebar({
const bodyRef = useRef<HTMLDivElement>(null);
const [visibleCount, setVisibleCount] = useState(appConfig.sessionPageSize);
const [pendingDeleteId, setPendingDeleteId] = useState<string | null>(null);
const [pendingSelectId, setPendingSelectId] = useState<string | null>(null);
useEffect(() => {
if (open) {
setVisibleCount(appConfig.sessionPageSize);
setPendingDeleteId(null);
setPendingSelectId(null);
}
}, [open, sessions.length]);
@@ -77,6 +79,7 @@ export function HistorySidebar({
}, [visibleCount, sessions.length]);
const handleDeleteClick = useCallback((sessionId: string) => {
setPendingSelectId(null);
setPendingDeleteId(sessionId);
}, []);
@@ -92,6 +95,24 @@ export function HistorySidebar({
setPendingDeleteId(null);
}, []);
const handleSelectClick = useCallback(
(sessionId: string) => {
if (pendingDeleteId === sessionId) return;
if (activeSessionId === sessionId) {
setPendingSelectId(null);
onSelect(sessionId);
return;
}
if (pendingSelectId === sessionId) {
setPendingSelectId(null);
onSelect(sessionId);
return;
}
setPendingSelectId(sessionId);
},
[activeSessionId, onSelect, pendingDeleteId, pendingSelectId],
);
if (!open) return null;
const visibleSessions = sessions.slice(0, visibleCount);
@@ -130,17 +151,21 @@ export function HistorySidebar({
{group.sessions.map((item) => {
const label = getSessionListLabel(item);
const isPending = pendingDeleteId === item.id;
const isPendingSelect = pendingSelectId === item.id;
return (
<li key={item.id} className={`sidebar-item-wrap${isPending ? ' sidebar-item-confirming' : ''}`}>
<button
type="button"
className={`sidebar-item ${item.id === activeSessionId ? 'sidebar-item-active' : ''}`}
onClick={() => { if (!isPending) onSelect(item.id); }}
className={`sidebar-item ${item.id === activeSessionId ? 'sidebar-item-active' : ''}${isPendingSelect ? ' sidebar-item-pending' : ''}`}
onClick={() => handleSelectClick(item.id)}
>
<span className="sidebar-item-title">{label}</span>
<span className="sidebar-item-meta">
{formatSessionTime(item.updated_at ?? item.created_at)}
</span>
{isPendingSelect && item.id !== activeSessionId ? (
<span className="sidebar-item-hint"></span>
) : null}
</button>
{isPending ? (
<div className="sidebar-item-confirm">
+9 -7
View File
@@ -610,22 +610,24 @@ export function useTKMindChat(
setPendingTool(null);
activeRequestId.current = null;
const resumed = options?.skipResume
? (options.seedSession ?? null)
: await resumeSession(sessionId);
if (token !== connectTokenRef.current) return;
const knownSession = sessionsRef.current.find((s) => s.id === sessionId);
const hints = knownSession
? { messageCount: knownSession.message_count, updatedAt: knownSession.updated_at }
: undefined;
const { session: detail, messages: history } = await loadSessionDetail(sessionId, hints);
const detailPromise = loadSessionDetail(sessionId, hints);
const resumedPromise = options?.skipResume
? Promise.resolve(options.seedSession ?? null)
: resumeSession(sessionId);
const { session: detail, messages: history } = await detailPromise;
if (token !== connectTokenRef.current) return;
writeStoredSessionId(userRef.current?.id, sessionId);
setSession({ ...detail, ...(resumed ?? {}), id: sessionId });
setSession((current) => (current?.id === sessionId ? { ...detail, ...current, id: sessionId } : { ...detail, id: sessionId }));
messagesRef.current = history;
setMessages(history);
const resumed = await resumedPromise;
if (token !== connectTokenRef.current) return;
setSession({ ...detail, ...(resumed ?? {}), id: sessionId });
setChatState('idle');
setSessions((prev) => prependUnique(prev, { ...detail, ...resumed, id: sessionId }));
+11
View File
@@ -253,6 +253,10 @@ body,
color: var(--color-text-primary);
}
.sidebar-item-pending {
background: rgba(255, 255, 255, 0.06);
}
.sidebar-item-title {
display: block;
font-size: 14px;
@@ -269,6 +273,13 @@ body,
color: var(--color-text-faint);
}
.sidebar-item-hint {
display: block;
margin-top: 6px;
font-size: 11px;
color: var(--color-text-secondary);
}
.sidebar-item-confirming .sidebar-item {
pointer-events: none;
opacity: 0.6;