guard stale init effects
This commit is contained in:
@@ -136,6 +136,8 @@ function AiChatPage() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!token || authLoading) return;
|
if (!token || authLoading) return;
|
||||||
|
|
||||||
|
let stale = false;
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
setLoadingConv(true);
|
setLoadingConv(true);
|
||||||
setError(null);
|
setError(null);
|
||||||
@@ -147,6 +149,7 @@ function AiChatPage() {
|
|||||||
const res = await fetch(`${API_BASE}/api/v1/chat/conversations`, {
|
const res = await fetch(`${API_BASE}/api/v1/chat/conversations`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
});
|
});
|
||||||
|
if (stale) return;
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
const list = await res.json();
|
const list = await res.json();
|
||||||
const openAi = Array.isArray(list)
|
const openAi = Array.isArray(list)
|
||||||
@@ -155,12 +158,12 @@ function AiChatPage() {
|
|||||||
if (openAi) convId = openAi.id;
|
if (openAi) convId = openAi.id;
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
if (stale) return;
|
||||||
setError("Failed to load conversations.");
|
setError("Failed to load conversations.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!convId) {
|
if (!convId) {
|
||||||
// Auto-create a new AI conversation
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`${API_BASE}/api/v1/chat/conversations`, {
|
const res = await fetch(`${API_BASE}/api/v1/chat/conversations`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -170,17 +173,19 @@ function AiChatPage() {
|
|||||||
},
|
},
|
||||||
body: JSON.stringify({ message: "Hello! I'd like to chat with the AI assistant." }),
|
body: JSON.stringify({ message: "Hello! I'd like to chat with the AI assistant." }),
|
||||||
});
|
});
|
||||||
|
if (stale) return;
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
const conv = await res.json();
|
const conv = await res.json();
|
||||||
convId = conv.id;
|
convId = conv.id;
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// silent
|
if (stale) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!convId) {
|
if (!convId) {
|
||||||
await fetchConversations();
|
await fetchConversations();
|
||||||
|
if (stale) return;
|
||||||
setLoadingConv(false);
|
setLoadingConv(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -190,6 +195,7 @@ function AiChatPage() {
|
|||||||
fetchMessages(convId),
|
fetchMessages(convId),
|
||||||
fetchConversations(),
|
fetchConversations(),
|
||||||
]);
|
]);
|
||||||
|
if (stale) return;
|
||||||
setLoadingConv(false);
|
setLoadingConv(false);
|
||||||
startPolling(convId);
|
startPolling(convId);
|
||||||
router.replace(`/ai-chat?id=${convId}`, { scroll: false });
|
router.replace(`/ai-chat?id=${convId}`, { scroll: false });
|
||||||
@@ -198,6 +204,7 @@ function AiChatPage() {
|
|||||||
init();
|
init();
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
stale = true;
|
||||||
if (pollRef.current) clearInterval(pollRef.current);
|
if (pollRef.current) clearInterval(pollRef.current);
|
||||||
};
|
};
|
||||||
}, [token, authLoading, conversationIdParam, fetchConversation, fetchMessages, startPolling, fetchConversations, router]);
|
}, [token, authLoading, conversationIdParam, fetchConversation, fetchMessages, startPolling, fetchConversations, router]);
|
||||||
|
|||||||
@@ -152,6 +152,8 @@ function ChatPage() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!token || authLoading) return;
|
if (!token || authLoading) return;
|
||||||
|
|
||||||
|
let stale = false;
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
setLoadingConv(true);
|
setLoadingConv(true);
|
||||||
setError(null);
|
setError(null);
|
||||||
@@ -163,6 +165,7 @@ function ChatPage() {
|
|||||||
const res = await fetch(`${API_BASE}/api/v1/chat/conversations`, {
|
const res = await fetch(`${API_BASE}/api/v1/chat/conversations`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
});
|
});
|
||||||
|
if (stale) return;
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
const list = await res.json();
|
const list = await res.json();
|
||||||
const open = Array.isArray(list)
|
const open = Array.isArray(list)
|
||||||
@@ -171,12 +174,14 @@ function ChatPage() {
|
|||||||
if (open) convId = open.id;
|
if (open) convId = open.id;
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
if (stale) return;
|
||||||
setError("Failed to load conversations.");
|
setError("Failed to load conversations.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!convId) {
|
if (!convId) {
|
||||||
await fetchConversations();
|
await fetchConversations();
|
||||||
|
if (stale) return;
|
||||||
setLoadingConv(false);
|
setLoadingConv(false);
|
||||||
setConversation(null);
|
setConversation(null);
|
||||||
return;
|
return;
|
||||||
@@ -187,6 +192,7 @@ function ChatPage() {
|
|||||||
fetchMessages(convId),
|
fetchMessages(convId),
|
||||||
fetchConversations(),
|
fetchConversations(),
|
||||||
]);
|
]);
|
||||||
|
if (stale) return;
|
||||||
setLoadingConv(false);
|
setLoadingConv(false);
|
||||||
startPolling(convId);
|
startPolling(convId);
|
||||||
}
|
}
|
||||||
@@ -194,6 +200,7 @@ function ChatPage() {
|
|||||||
init();
|
init();
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
stale = true;
|
||||||
if (pollRef.current) clearInterval(pollRef.current);
|
if (pollRef.current) clearInterval(pollRef.current);
|
||||||
};
|
};
|
||||||
}, [token, authLoading, conversationIdParam, fetchConversation, fetchMessages, startPolling, fetchConversations]);
|
}, [token, authLoading, conversationIdParam, fetchConversation, fetchMessages, startPolling, fetchConversations]);
|
||||||
|
|||||||
Reference in New Issue
Block a user