fix(chat): export the complete conversation across PDF pages (#6921)

This commit is contained in:
red person
2026-11-03 00:30:07 +00:00
committed by GitHub
parent 596e1421e4
commit 1e34f938cc
4 changed files with 118 additions and 16 deletions
+44 -15
View File
@@ -353,36 +353,38 @@ function _installHistoryPager(id, pageInfo, modelName) {
handler: null,
};
const loadOlder = async () => {
if (!_historyPager || _historyPager.loading || _historyPager.done) return;
if (_historyPager.sessionId !== currentSessionId) return;
if (box.scrollTop > 90) return;
const loadOlder = async (force = false) => {
const pager = _historyPager;
if (!pager || pager.loading || pager.done) return;
if (pager.sessionId !== currentSessionId) return;
if (!force && box.scrollTop > 90) return;
const nextOffset = Math.max(0, _historyPager.offset - _historyPager.limit);
const nextLimit = _historyPager.offset - nextOffset;
const nextOffset = Math.max(0, pager.offset - pager.limit);
const nextLimit = pager.offset - nextOffset;
if (nextLimit <= 0) {
_historyPager.done = true;
pager.done = true;
return;
}
_historyPager.loading = true;
pager.loading = true;
const anchor = box.querySelector('.msg, .agent-thread, .gallery-bubble');
const beforeHeight = box.scrollHeight;
try {
const res = await fetch(_historyUrl(_historyPager.sessionId, { limit: nextLimit, offset: nextOffset }));
const res = await fetch(_historyUrl(pager.sessionId, { limit: nextLimit, offset: nextOffset }));
if (!res.ok) throw new Error(`Chat history request failed (HTTP ${res.status})`);
const data = await res.json();
if (!_historyPager || _historyPager.sessionId !== currentSessionId) return;
if (_historyPager !== pager || pager.sessionId !== currentSessionId) return;
const newEls = [];
for (const msg of data.history || []) {
if (msg.role !== 'user' && msg.role !== 'assistant') continue;
const els = _renderHistoryMessage(msg, _historyPager.modelName);
const els = _renderHistoryMessage(msg, pager.modelName);
if (Array.isArray(els)) newEls.push(...els);
}
for (const el of newEls) {
box.insertBefore(el, anchor || box.firstChild);
}
_historyPager.offset = Number(data.offset || nextOffset);
_historyPager.done = !data.has_more_before;
pager.offset = Number(data.offset || nextOffset);
pager.done = !data.has_more_before;
if (window.hljs) {
newEls.forEach(el => el.querySelectorAll('pre code:not(.hljs)').forEach(block => window.hljs.highlightElement(block)));
}
@@ -391,16 +393,42 @@ function _installHistoryPager(id, pageInfo, modelName) {
} catch (e) {
console.warn('Failed to load older chat history:', e);
} finally {
if (_historyPager) _historyPager.loading = false;
pager.loading = false;
}
};
_historyPager.loadOlder = loadOlder;
_historyPager.handler = () => {
if (box.scrollTop <= 90) loadOlder();
if (box.scrollTop <= 90 && _historyPager && !_historyPager.loading) {
_historyPager.pending = loadOlder();
}
};
box.addEventListener('scroll', _historyPager.handler, { passive: true });
}
export async function prepareHistoryForPrint() {
const pager = _historyPager;
if (!pager) return;
const ensureCurrentChat = () => {
if (_historyPager !== pager || currentSessionId !== pager.sessionId) {
throw new Error('Chat changed while preparing the PDF. Export again from the intended chat.');
}
};
while (!pager.done) {
await pager.pending;
ensureCurrentChat();
if (pager.done) break;
const previousOffset = pager.offset;
pager.pending = pager.loadOlder(true);
await pager.pending;
ensureCurrentChat();
if (!pager.done && pager.offset >= previousOffset) {
throw new Error('Could not load the complete chat for PDF export. Please try again.');
}
}
ensureCurrentChat();
}
function _getIncognitoIds() {
try { return JSON.parse(sessionStorage.getItem(_INCOGNITO_SESSIONS_KEY) || '[]'); } catch { return []; }
}
@@ -4061,6 +4089,7 @@ const sessionModule = {
renderSessionList,
loadSessions,
selectSession,
prepareHistoryForPrint,
createDirectChat,
materializePendingSession,
preMaterializePendingSession,