mirror of
https://github.com/zhayujie/chatgpt-on-wechat.git
synced 2026-06-02 00:57:41 +08:00
fix: improve web UI stability and conversation history restore
- Fix dark mode FOUC: apply theme in <head> before first paint, defer transition-colors to post-init to avoid animated flash on load - Fix Safari IME Enter bug: defer compositionend reset via setTimeout(0) - Fix history scroll: use requestAnimationFrame before scrollChatToBottom - Limit restore turns to min(6, max_turns//3) on restart - Fix load_messages cutoff to start at turn boundary, preventing orphaned tool_use/tool_result pairs from being sent to the LLM - Merge all assistant messages within one user turn into a single bubble; render tool_calls in history using same CSS as live SSE view - Handle empty choices list in stream chunks
This commit is contained in:
@@ -43,8 +43,17 @@
|
||||
}
|
||||
</script>
|
||||
<link rel="stylesheet" href="assets/css/console.css">
|
||||
<!-- Apply theme/lang before first paint to avoid flash of unstyled content.
|
||||
This runs synchronously in <head> so the correct class is on <html>
|
||||
before any CSS or body rendering occurs. -->
|
||||
<script>
|
||||
(function() {
|
||||
var theme = localStorage.getItem('cow_theme') || 'dark';
|
||||
if (theme === 'dark') document.documentElement.classList.add('dark');
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body class="h-screen overflow-hidden bg-gray-50 dark:bg-[#111111] text-slate-800 dark:text-slate-200 font-sans transition-colors duration-200">
|
||||
<body class="h-screen overflow-hidden bg-gray-50 dark:bg-[#111111] text-slate-800 dark:text-slate-200 font-sans">
|
||||
<div id="app" class="flex h-screen">
|
||||
|
||||
<!-- ================================================================ -->
|
||||
|
||||
@@ -284,7 +284,11 @@ const sendBtn = document.getElementById('send-btn');
|
||||
const messagesDiv = document.getElementById('chat-messages');
|
||||
|
||||
chatInput.addEventListener('compositionstart', () => { isComposing = true; });
|
||||
chatInput.addEventListener('compositionend', () => { isComposing = false; });
|
||||
// Safari fires compositionend *before* the confirming keydown event, so if we
|
||||
// reset isComposing synchronously the keydown handler sees !isComposing and
|
||||
// sends the message prematurely. A setTimeout(0) defers the reset until after
|
||||
// keydown has been processed, fixing the Safari IME Enter-to-confirm bug.
|
||||
chatInput.addEventListener('compositionend', () => { setTimeout(() => { isComposing = false; }, 0); });
|
||||
|
||||
chatInput.addEventListener('input', function() {
|
||||
this.style.height = '42px';
|
||||
@@ -684,7 +688,9 @@ function loadHistory(page) {
|
||||
historyPage = page;
|
||||
|
||||
if (isFirstLoad) {
|
||||
scrollChatToBottom();
|
||||
// Use requestAnimationFrame to ensure the DOM has fully rendered
|
||||
// before scrolling, otherwise scrollHeight may not reflect new content.
|
||||
requestAnimationFrame(() => scrollChatToBottom());
|
||||
} else {
|
||||
// Restore scroll position so loading older messages doesn't jump the view
|
||||
messagesDiv.scrollTop = messagesDiv.scrollHeight - prevScrollHeight;
|
||||
@@ -1102,3 +1108,11 @@ applyTheme();
|
||||
applyI18n();
|
||||
document.getElementById('sidebar-version').textContent = `CowAgent ${APP_VERSION}`;
|
||||
chatInput.focus();
|
||||
|
||||
// Re-enable color transition AFTER first paint so the theme applied in <head>
|
||||
// doesn't produce an animated flash on load. The class is missing from the
|
||||
// body initially; adding it here means transitions only fire on user-triggered
|
||||
// theme toggles, not on page load.
|
||||
requestAnimationFrame(() => {
|
||||
document.body.classList.add('transition-colors', 'duration-200');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user