fix: 切换Agent时清空room并避免旧room拉取消息
parent
efd0ea5853
commit
3240155523
|
|
@ -15,6 +15,7 @@ import { useChatSender } from './hooks/useChatSender';
|
||||||
import { markdownToPlainText } from './utils/copy';
|
import { markdownToPlainText } from './utils/copy';
|
||||||
|
|
||||||
const lastRoomKey = (agentId: string) => `chat:lastRoom:${agentId}`;
|
const lastRoomKey = (agentId: string) => `chat:lastRoom:${agentId}`;
|
||||||
|
const isValidRoomId = (v: string | null): v is string => !!v && !String(v).startsWith('legacy_');
|
||||||
|
|
||||||
export default function ChatPage() {
|
export default function ChatPage() {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
|
|
@ -36,11 +37,14 @@ export default function ChatPage() {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!id) return;
|
if (!id) return;
|
||||||
|
abortRef.current?.abort();
|
||||||
|
setRoomId(null);
|
||||||
|
setHighlightId(null);
|
||||||
|
|
||||||
const s = searchParams.get('session');
|
const s = searchParams.get('session');
|
||||||
const m = searchParams.get('msg');
|
const m = searchParams.get('msg');
|
||||||
|
|
||||||
if (s) {
|
if (isValidRoomId(s)) {
|
||||||
setRoomId(s);
|
setRoomId(s);
|
||||||
try {
|
try {
|
||||||
localStorage.setItem(lastRoomKey(id), s);
|
localStorage.setItem(lastRoomKey(id), s);
|
||||||
|
|
@ -55,6 +59,12 @@ export default function ChatPage() {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (s && !isValidRoomId(s)) {
|
||||||
|
const next = new URLSearchParams(searchParams);
|
||||||
|
next.delete('session');
|
||||||
|
next.delete('msg');
|
||||||
|
setSearchParams(next, { replace: true });
|
||||||
|
}
|
||||||
|
|
||||||
const saved = (() => {
|
const saved = (() => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -63,10 +73,17 @@ export default function ChatPage() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
if (saved) {
|
if (isValidRoomId(saved)) {
|
||||||
setRoomId(saved);
|
setRoomId(saved);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (saved && !isValidRoomId(saved)) {
|
||||||
|
try {
|
||||||
|
localStorage.removeItem(lastRoomKey(id));
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import type { Agent, BranchInfo, ChatMessage, ModelOverrides } from '../../../api';
|
import type { Agent, BranchInfo, ChatMessage, ModelOverrides } from '../../../api';
|
||||||
import { AgentAPI, ChatAPI } from '../../../api';
|
import { AgentAPI, ChatAPI } from '../../../api';
|
||||||
import { parseAgentModels } from '../utils/agentModels';
|
import { parseAgentModels } from '../utils/agentModels';
|
||||||
|
|
@ -18,6 +18,7 @@ export function useChatData(args: {
|
||||||
const [agentList, setAgentList] = useState<Agent[]>([]);
|
const [agentList, setAgentList] = useState<Agent[]>([]);
|
||||||
const [messages, setMessages] = useState<ChatMessage[]>([]);
|
const [messages, setMessages] = useState<ChatMessage[]>([]);
|
||||||
const [branches, setBranches] = useState<Record<string, BranchInfo>>({});
|
const [branches, setBranches] = useState<Record<string, BranchInfo>>({});
|
||||||
|
const loadSeqRef = useRef(0);
|
||||||
|
|
||||||
const loadAgent = async () => {
|
const loadAgent = async () => {
|
||||||
if (!agentId) {
|
if (!agentId) {
|
||||||
|
|
@ -49,18 +50,14 @@ export function useChatData(args: {
|
||||||
|
|
||||||
const loadMessages = async () => {
|
const loadMessages = async () => {
|
||||||
if (!roomId) return;
|
if (!roomId) return;
|
||||||
const his = await ChatAPI.history(roomId);
|
const seq = ++loadSeqRef.current;
|
||||||
|
const rid = roomId;
|
||||||
|
const his = await ChatAPI.history(rid);
|
||||||
|
if (seq !== loadSeqRef.current) return;
|
||||||
|
if (rid !== roomId) return;
|
||||||
setMessages(Array.isArray(his.messages) ? his.messages : []);
|
setMessages(Array.isArray(his.messages) ? his.messages : []);
|
||||||
setBranches(his.branches || {});
|
setBranches(his.branches || {});
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
if (highlightId) {
|
|
||||||
const el = document.getElementById('msg-' + highlightId);
|
|
||||||
if (el) {
|
|
||||||
el.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
||||||
setTimeout(() => setHighlightId(null), 3000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!initialScrollDoneRef.current) {
|
if (!initialScrollDoneRef.current) {
|
||||||
scrollBottom(true);
|
scrollBottom(true);
|
||||||
initialScrollDoneRef.current = true;
|
initialScrollDoneRef.current = true;
|
||||||
|
|
@ -78,9 +75,12 @@ export function useChatData(args: {
|
||||||
if (!agentId) {
|
if (!agentId) {
|
||||||
setAgent(null);
|
setAgent(null);
|
||||||
setMessages([]);
|
setMessages([]);
|
||||||
|
setBranches({});
|
||||||
setOverrides(() => ({}));
|
setOverrides(() => ({}));
|
||||||
return abort;
|
return abort;
|
||||||
}
|
}
|
||||||
|
setMessages([]);
|
||||||
|
setBranches({});
|
||||||
loadAgent();
|
loadAgent();
|
||||||
setOverrides(() => ({}));
|
setOverrides(() => ({}));
|
||||||
return abort;
|
return abort;
|
||||||
|
|
@ -89,13 +89,22 @@ export function useChatData(args: {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
initialScrollDoneRef.current = false;
|
initialScrollDoneRef.current = false;
|
||||||
}, [agentId]);
|
}, [agentId, roomId]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!roomId) return;
|
if (!roomId) return;
|
||||||
loadMessages();
|
loadMessages();
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [roomId, highlightId, agentId]);
|
}, [roomId]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!highlightId) return;
|
||||||
|
const el = document.getElementById('msg-' + highlightId);
|
||||||
|
if (!el) return;
|
||||||
|
el.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||||
|
const t = setTimeout(() => setHighlightId(null), 3000);
|
||||||
|
return () => clearTimeout(t);
|
||||||
|
}, [highlightId, setHighlightId]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
agent,
|
agent,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue