mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-29 19:12:27 +08:00
refactor(llm): optimize chat UI updates by checking for new content and preserving scroll position
This commit is contained in:
parent
7b498cf384
commit
0d305cd22c
@ -362,16 +362,52 @@ export default class LlmChatPanel extends BasicWidget {
|
|||||||
const savedData = await this.onGetData() as ChatData;
|
const savedData = await this.onGetData() as ChatData;
|
||||||
|
|
||||||
if (savedData?.messages?.length > 0) {
|
if (savedData?.messages?.length > 0) {
|
||||||
|
// Check if we actually have new content to avoid unnecessary UI rebuilds
|
||||||
|
const currentMessageCount = this.messages.length;
|
||||||
|
const savedMessageCount = savedData.messages.length;
|
||||||
|
|
||||||
|
// If message counts are the same, check if content is different
|
||||||
|
const hasNewContent = savedMessageCount > currentMessageCount ||
|
||||||
|
JSON.stringify(this.messages) !== JSON.stringify(savedData.messages);
|
||||||
|
|
||||||
|
if (!hasNewContent) {
|
||||||
|
console.log("No new content detected, skipping UI rebuild");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Loading saved data: ${currentMessageCount} -> ${savedMessageCount} messages`);
|
||||||
|
|
||||||
|
// Store current scroll position if we need to preserve it
|
||||||
|
const shouldPreserveScroll = savedMessageCount > currentMessageCount && currentMessageCount > 0;
|
||||||
|
const currentScrollTop = shouldPreserveScroll ? this.chatContainer.scrollTop : 0;
|
||||||
|
const currentScrollHeight = shouldPreserveScroll ? this.chatContainer.scrollHeight : 0;
|
||||||
|
|
||||||
// Load messages
|
// Load messages
|
||||||
|
const oldMessages = [...this.messages];
|
||||||
this.messages = savedData.messages;
|
this.messages = savedData.messages;
|
||||||
|
|
||||||
// Clear and rebuild the chat UI
|
// Only rebuild UI if we have significantly different content
|
||||||
this.noteContextChatMessages.innerHTML = '';
|
if (savedMessageCount > currentMessageCount) {
|
||||||
|
// We have new messages - just add the new ones instead of rebuilding everything
|
||||||
|
const newMessages = savedData.messages.slice(currentMessageCount);
|
||||||
|
console.log(`Adding ${newMessages.length} new messages to UI`);
|
||||||
|
|
||||||
this.messages.forEach(message => {
|
newMessages.forEach(message => {
|
||||||
const role = message.role as 'user' | 'assistant';
|
const role = message.role as 'user' | 'assistant';
|
||||||
this.addMessageToChat(role, message.content);
|
this.addMessageToChat(role, message.content);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
// Content changed but count is same - need to rebuild
|
||||||
|
console.log("Message content changed, rebuilding UI");
|
||||||
|
|
||||||
|
// Clear and rebuild the chat UI
|
||||||
|
this.noteContextChatMessages.innerHTML = '';
|
||||||
|
|
||||||
|
this.messages.forEach(message => {
|
||||||
|
const role = message.role as 'user' | 'assistant';
|
||||||
|
this.addMessageToChat(role, message.content);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Restore tool execution steps if they exist
|
// Restore tool execution steps if they exist
|
||||||
if (savedData.toolSteps && Array.isArray(savedData.toolSteps) && savedData.toolSteps.length > 0) {
|
if (savedData.toolSteps && Array.isArray(savedData.toolSteps) && savedData.toolSteps.length > 0) {
|
||||||
@ -421,6 +457,27 @@ export default class LlmChatPanel extends BasicWidget {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restore scroll position if we were preserving it
|
||||||
|
if (shouldPreserveScroll) {
|
||||||
|
// Calculate the new scroll position to maintain relative position
|
||||||
|
const newScrollHeight = this.chatContainer.scrollHeight;
|
||||||
|
const scrollDifference = newScrollHeight - currentScrollHeight;
|
||||||
|
const newScrollTop = currentScrollTop + scrollDifference;
|
||||||
|
|
||||||
|
// Only scroll down if we're near the bottom, otherwise preserve exact position
|
||||||
|
const wasNearBottom = (currentScrollTop + this.chatContainer.clientHeight) >= (currentScrollHeight - 50);
|
||||||
|
|
||||||
|
if (wasNearBottom) {
|
||||||
|
// User was at bottom, scroll to new bottom
|
||||||
|
this.chatContainer.scrollTop = newScrollHeight;
|
||||||
|
console.log("User was at bottom, scrolling to new bottom");
|
||||||
|
} else {
|
||||||
|
// User was not at bottom, try to preserve their position
|
||||||
|
this.chatContainer.scrollTop = newScrollTop;
|
||||||
|
console.log(`Preserving scroll position: ${currentScrollTop} -> ${newScrollTop}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -1105,7 +1162,7 @@ export default class LlmChatPanel extends BasicWidget {
|
|||||||
console.error("Failed to save assistant response to note:", err);
|
console.error("Failed to save assistant response to note:", err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, 3000); // Wait 3 seconds for server to complete its save
|
}, 1500); // Wait 1.5 seconds for server to complete its save
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scroll to bottom
|
// Scroll to bottom
|
||||||
|
Loading…
x
Reference in New Issue
Block a user