feat(chat): add one-click Plaza publish for HTML page messages.
Speed up the quick-plaza path with session snapshot reads, publish timeouts, and a modal fix so parent re-renders no longer abort in-flight requests. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+70
-52
@@ -1014,45 +1014,57 @@ export function useTKMindChat(
|
||||
setPendingTool(null);
|
||||
activeRequestId.current = null;
|
||||
|
||||
const knownSession = sessionsRef.current.find((s) => s.id === sessionId);
|
||||
const hints = knownSession
|
||||
? { messageCount: knownSession.message_count, updatedAt: knownSession.updated_at }
|
||||
: undefined;
|
||||
const detailPromise = withTransientConnectRetry(() =>
|
||||
loadSessionDetail(sessionId, hints, {
|
||||
before: 0,
|
||||
limit: appConfig.sessionMessagePageSize,
|
||||
}),
|
||||
);
|
||||
const resumedPromise =
|
||||
options?.skipResume || isDirectChatSessionId(sessionId)
|
||||
? Promise.resolve(options.seedSession ?? null)
|
||||
: withTransientConnectRetry(() =>
|
||||
resumeSession(sessionId, {
|
||||
skipReconcile: options?.skipReconcile ?? false,
|
||||
}),
|
||||
);
|
||||
const { session: detail, messages: history, page } = await detailPromise;
|
||||
if (token !== connectTokenRef.current) return;
|
||||
let completed = false;
|
||||
try {
|
||||
const knownSession = sessionsRef.current.find((s) => s.id === sessionId);
|
||||
const hints = knownSession
|
||||
? { messageCount: knownSession.message_count, updatedAt: knownSession.updated_at }
|
||||
: undefined;
|
||||
const detailPromise = withTransientConnectRetry(() =>
|
||||
loadSessionDetail(sessionId, hints, {
|
||||
before: 0,
|
||||
limit: appConfig.sessionMessagePageSize,
|
||||
}),
|
||||
);
|
||||
const resumedPromise =
|
||||
options?.skipResume || isDirectChatSessionId(sessionId)
|
||||
? Promise.resolve(options.seedSession ?? null)
|
||||
: withTransientConnectRetry(() =>
|
||||
resumeSession(sessionId, {
|
||||
skipReconcile: options?.skipReconcile ?? false,
|
||||
}),
|
||||
);
|
||||
const { session: detail, messages: history, page } = await detailPromise;
|
||||
if (token !== connectTokenRef.current) return;
|
||||
|
||||
writeStoredSessionId(userRef.current?.id, sessionId);
|
||||
setSession((current) => (current?.id === sessionId ? { ...detail, ...current, id: sessionId } : { ...detail, id: sessionId }));
|
||||
messagesRef.current = history;
|
||||
messageHistoryLoadedCountRef.current = history.length;
|
||||
messageHistoryTotalRef.current = Math.max(Number(page.total ?? history.length), history.length);
|
||||
messageHistoryHasMoreRef.current = history.length < messageHistoryTotalRef.current;
|
||||
setMessageHistoryHasMore(messageHistoryHasMoreRef.current);
|
||||
setMessageHistoryTotal(messageHistoryTotalRef.current);
|
||||
setMessages(history);
|
||||
const resumed = await resumedPromise;
|
||||
if (token !== connectTokenRef.current) return;
|
||||
setSession({ ...detail, ...(resumed ?? {}), id: sessionId });
|
||||
setChatState('idle');
|
||||
setSessions((prev) =>
|
||||
prependUnique(prev, toSessionSummary({ ...detail, ...(resumed ?? {}), id: sessionId })),
|
||||
);
|
||||
writeStoredSessionId(userRef.current?.id, sessionId);
|
||||
setSession((current) =>
|
||||
current?.id === sessionId ? { ...detail, ...current, id: sessionId } : { ...detail, id: sessionId },
|
||||
);
|
||||
messagesRef.current = history;
|
||||
messageHistoryLoadedCountRef.current = history.length;
|
||||
messageHistoryTotalRef.current = Math.max(Number(page.total ?? history.length), history.length);
|
||||
messageHistoryHasMoreRef.current = history.length < messageHistoryTotalRef.current;
|
||||
setMessageHistoryHasMore(messageHistoryHasMoreRef.current);
|
||||
setMessageHistoryTotal(messageHistoryTotalRef.current);
|
||||
setMessages(history);
|
||||
const resumed = await resumedPromise;
|
||||
if (token !== connectTokenRef.current) return;
|
||||
setSession({ ...detail, ...(resumed ?? {}), id: sessionId });
|
||||
setChatState('idle');
|
||||
completed = true;
|
||||
setSessions((prev) =>
|
||||
prependUnique(prev, toSessionSummary({ ...detail, ...(resumed ?? {}), id: sessionId })),
|
||||
);
|
||||
|
||||
subscribeToSession(sessionId);
|
||||
subscribeToSession(sessionId);
|
||||
} finally {
|
||||
if (!completed && token === connectTokenRef.current) {
|
||||
setChatState((current) =>
|
||||
current === 'connecting' || current === 'loading' ? 'idle' : current,
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
[clearActiveRequestMissingTimer, subscribeToSession],
|
||||
);
|
||||
@@ -1528,22 +1540,23 @@ export function useTKMindChat(
|
||||
setPendingTool(null);
|
||||
setChatState('connecting');
|
||||
|
||||
if (
|
||||
previousSessionId &&
|
||||
previousSession &&
|
||||
shouldShowNewChatTitle(toSessionSummary(previousSession))
|
||||
) {
|
||||
try {
|
||||
await deleteChatSession(previousSessionId);
|
||||
if (token === connectTokenRef.current) {
|
||||
setSessions((prev) => prev.filter((item) => item.id !== previousSessionId));
|
||||
}
|
||||
} catch {
|
||||
// Keep the abandoned empty session in history if cleanup fails.
|
||||
}
|
||||
}
|
||||
|
||||
let completed = false;
|
||||
try {
|
||||
if (
|
||||
previousSessionId &&
|
||||
previousSession &&
|
||||
shouldShowNewChatTitle(toSessionSummary(previousSession))
|
||||
) {
|
||||
try {
|
||||
await deleteChatSession(previousSessionId);
|
||||
if (token === connectTokenRef.current) {
|
||||
setSessions((prev) => prev.filter((item) => item.id !== previousSessionId));
|
||||
}
|
||||
} catch {
|
||||
// Keep the abandoned empty session in history if cleanup fails.
|
||||
}
|
||||
}
|
||||
|
||||
const started = await startSession();
|
||||
if (token !== connectTokenRef.current) return;
|
||||
|
||||
@@ -1560,12 +1573,17 @@ export function useTKMindChat(
|
||||
if (token !== connectTokenRef.current) return;
|
||||
subscribeToSession(nextSession.id);
|
||||
setChatState('idle');
|
||||
completed = true;
|
||||
void refreshSessions();
|
||||
} catch (err) {
|
||||
if (token !== connectTokenRef.current) return;
|
||||
setSession(null);
|
||||
setChatState('idle');
|
||||
setError(err instanceof Error ? err.message : String(err));
|
||||
} finally {
|
||||
if (!completed && token === connectTokenRef.current) {
|
||||
setChatState((current) => (current === 'connecting' ? 'idle' : current));
|
||||
}
|
||||
}
|
||||
}, [
|
||||
clearActiveRequestMissingTimer,
|
||||
|
||||
Reference in New Issue
Block a user