diff --git a/application/single_app/config.py b/application/single_app/config.py index b3419b568..30cb1b95f 100644 --- a/application/single_app/config.py +++ b/application/single_app/config.py @@ -94,7 +94,7 @@ EXECUTOR_TYPE = 'thread' EXECUTOR_MAX_WORKERS = 30 SESSION_TYPE = 'filesystem' -VERSION = "0.241.008" +VERSION = "0.241.007" SECRET_KEY = os.getenv('SECRET_KEY', 'dev-secret-key-change-in-production') diff --git a/application/single_app/static/js/chat/chat-global.js b/application/single_app/static/js/chat/chat-global.js index 7ea874a46..0cb42f724 100644 --- a/application/single_app/static/js/chat/chat-global.js +++ b/application/single_app/static/js/chat/chat-global.js @@ -9,71 +9,9 @@ let groupPrompts = []; let publicPrompts = []; let currentlyEditingId = null; -function getChatScrollContainer() { - return ( - document.getElementById("chat-messages-container") || - document.getElementById("chatbox") || - null - ); -} - -function isChatNearBottom(threshold = 40) { - const container = getChatScrollContainer(); - if (!container) return true; - - const distanceFromBottom = - container.scrollHeight - (container.scrollTop + container.clientHeight); - return distanceFromBottom <= threshold; -} - function scrollChatToBottom() { - const container = getChatScrollContainer(); - if (container) { - container.scrollTop = container.scrollHeight; + const chatbox = document.getElementById("chatbox"); + if (chatbox) { + chatbox.scrollTop = chatbox.scrollHeight; } -} - -function showScrollToBottomButton() { - const btn = document.getElementById("scroll-to-bottom-btn"); - if (!btn) return; - btn.classList.remove("d-none"); -} - -function hideScrollToBottomButton() { - const btn = document.getElementById("scroll-to-bottom-btn"); - if (!btn) return; - btn.classList.add("d-none"); -} - -function initializeChatScrollBehavior() { - const container = getChatScrollContainer(); - const btn = document.getElementById("scroll-to-bottom-btn"); - - if (!container) return; - - // Initial state - if (isChatNearBottom()) { - hideScrollToBottomButton(); - } else { - showScrollToBottomButton(); - } - - container.addEventListener("scroll", () => { - if (isChatNearBottom()) { - hideScrollToBottomButton(); - } else { - showScrollToBottomButton(); - } - }); - - if (btn) { - btn.addEventListener("click", () => { - scrollChatToBottom(); - hideScrollToBottomButton(); - }); - } -} - -window.addEventListener("load", () => { - initializeChatScrollBehavior(); -}); \ No newline at end of file +} \ No newline at end of file diff --git a/application/single_app/static/js/chat/chat-messages.js b/application/single_app/static/js/chat/chat-messages.js index 7a6bb7586..c904639d6 100644 --- a/application/single_app/static/js/chat/chat-messages.js +++ b/application/single_app/static/js/chat/chat-messages.js @@ -1036,14 +1036,7 @@ export function appendMessage( }); } - // For AI messages, only auto-scroll if the user is currently near - // the bottom. This prevents a final jump after a long answer if - // the user has scrolled up to read earlier content. - if (typeof isChatNearBottom === 'function' && typeof scrollChatToBottom === 'function') { - if (isChatNearBottom()) { - scrollChatToBottom(); - } - } + scrollChatToBottom(); return; // <<< EXIT EARLY FOR AI MESSAGES // --- Handle ALL OTHER message types --- @@ -1113,10 +1106,7 @@ export function appendMessage( // Validate image URL before creating img tag if (messageContent && messageContent !== 'null' && messageContent.trim() !== '') { - // Use a placeholder container; the actual element will be - // created with DOM APIs after insertion to avoid string-based - // attribute interpolation in src/data-*. - messageContentHtml = ''; + messageContentHtml = `${isUserUpload ? 'Uploaded' : 'Generated'} Image`; } else { messageContentHtml = `
Failed to ${isUserUpload ? 'load' : 'generate'} image - invalid response from image service
`; } @@ -1266,28 +1256,6 @@ export function appendMessage( // Append and scroll (common actions for non-AI) chatbox.appendChild(messageDiv); - // Attach safe image element and error handler for generated/uploaded images - if (sender === "image") { - const placeholder = messageDiv.querySelector('.generated-image-placeholder'); - if (placeholder && messageContent && messageContent !== 'null' && messageContent.trim() !== '') { - const imgEl = document.createElement('img'); - imgEl.className = 'generated-image'; - imgEl.style.width = '170px'; - imgEl.style.height = '170px'; - imgEl.style.cursor = 'pointer'; - imgEl.src = messageContent; - imgEl.alt = isUserUpload ? 'Uploaded Image' : 'Generated Image'; - imgEl.dataset.imageSrc = messageContent; - - imgEl.addEventListener('error', () => { - imgEl.src = '/static/images/image-error.png'; - imgEl.alt = 'Failed to load image'; - }); - - placeholder.replaceWith(imgEl); - } - } - // Highlight code blocks in the messages messageDiv.querySelectorAll('pre code[class^="language-"]').forEach((block) => { const match = block.className.match(/language-([a-zA-Z0-9]+)/); @@ -1410,16 +1378,7 @@ export function appendMessage( } } - // For new user/file/image messages, scroll to bottom once so the - // user sees what they just sent. For history loads, only scroll - // if they are already near the bottom. - if (isNewMessage && typeof scrollChatToBottom === 'function') { - scrollChatToBottom(); - } else if (typeof isChatNearBottom === 'function' && typeof scrollChatToBottom === 'function') { - if (isChatNearBottom()) { - scrollChatToBottom(); - } - } + scrollChatToBottom(); } // End of the large 'else' block for non-AI messages } @@ -1477,7 +1436,7 @@ export function actuallySendMessage(finalMessageToSend) { const tempUserMessageId = `temp_user_${Date.now()}`; // Append user message first with temporary ID - appendMessage("You", finalMessageToSend, null, tempUserMessageId, false, [], [], [], null, null, null, true); + appendMessage("You", finalMessageToSend, null, tempUserMessageId); userInput.value = ""; userInput.style.height = ""; // Update send button visibility after clearing input diff --git a/application/single_app/templates/chats.html b/application/single_app/templates/chats.html index fd4ac4d3e..dfcb11385 100644 --- a/application/single_app/templates/chats.html +++ b/application/single_app/templates/chats.html @@ -267,20 +267,8 @@
-
-
- -
- +
+
diff --git a/docs/explanation/release_notes.md b/docs/explanation/release_notes.md index 89e611245..5a6834fc3 100644 --- a/docs/explanation/release_notes.md +++ b/docs/explanation/release_notes.md @@ -4,16 +4,6 @@ This page tracks notable Simple Chat releases and organizes the detailed change For feature-focused and fix-focused drill-downs by version, see [Features by Version](/explanation/features/) and [Fixes by Version](/explanation/fixes/). -### **(v0.241.008)** - -#### User Interface Enhancements - -* **Chat Scroll Behavior and 508 Usability** - * Updated chat message rendering so the viewport no longer jumps to the very bottom of long assistant responses when they finish loading while the user is reading near the top. - * Auto-scroll now only occurs when the user is already near the bottom of the conversation, and a floating "scroll to latest message" button appears when new content arrives below the current view. - * This aligns the chat experience more closely with other AI chat tools and reduces unexpected motion for 508 testers and keyboard users. - * (Ref: `chats.html`, `chat-global.js`, `chat-messages.js`) - ### **(v0.241.007)** ## New Feature