diff --git a/channel/web/chat.html b/channel/web/chat.html index 5186a80..1b1111c 100644 --- a/channel/web/chat.html +++ b/channel/web/chat.html @@ -197,27 +197,54 @@ } .user-container { - width: 100%; - margin: 0; - padding: 20px; - border-bottom: 1px solid var(--border-color); + display: flex; + justify-content: flex-end; + margin: 10px 0; + padding: 0 15px; + } + + .user-container .message-container { + flex-direction: row-reverse; + text-align: right; + } + + .user-container .avatar { + margin-left: 15px; + margin-right: 0; + } + + .user-container .message-content { + align-items: flex-end; + } + + .user-container .message { + background-color: var(--bot-msg-bg); + border-radius: 10px; + margin-bottom: 8px; + } + + .bot-container .message { + background-color: var(--bot-msg-bg); + border-radius: 10px 10px 10px 0; + margin-bottom: 8px; } .avatar { - width: 30px; - height: 30px; - border-radius: 2px; + width: 36px; + height: 36px; + border-radius: 50%; + background-color: #e0e0e0; display: flex; align-items: center; justify-content: center; margin-right: 15px; flex-shrink: 0; - margin-top: 4px; } .bot-avatar { background-color: #10a37f; color: white; + margin-top: 4px; /* 微调头像位置,使其与文本更好地对齐 */ } .user-avatar { @@ -226,17 +253,24 @@ } .message-content { + display: flex; + flex-direction: column; flex: 1; - line-height: 1.6; - padding-top: 2px; - text-align: left; + padding-top: 0; /* 移除顶部内边距 */ + } + + .bot-container .message-content { + align-items: flex-start; + margin-top: 0; /* 确保没有顶部外边距 */ } .message { - width: 100%; + padding: 12px 16px; + border-radius: 10px; + margin-top: 0; /* 移除顶部外边距 */ + margin-bottom: 8px; word-wrap: break-word; - white-space: pre-wrap; - line-height: 1.3; + overflow-wrap: break-word; } .message p { @@ -300,7 +334,20 @@ .timestamp { font-size: 0.75rem; color: var(--text-light); - margin-top: 5px; + padding-left: 2px; + } + + /* 为机器人消息的时间戳添加左对齐 */ + .bot-container .timestamp { + align-self: flex-start; + margin-left: 15px; + } + + /* 为用户消息的时间戳添加右对齐 */ + .user-container .timestamp { + align-self: flex-end; + padding-right: 2px; + padding-left: 0; } #input-container { @@ -519,6 +566,8 @@ position: relative; top: -5px; left: -10px; + margin-top: 10px; + margin-bottom: 5px; } .typing-indicator span { @@ -571,6 +620,30 @@ background-color: rgba(255, 255, 255, 0.1); font-weight: bold; } + + /* 基础消息样式 */ + .message { + border-radius: 10px; + word-wrap: break-word; + overflow-wrap: break-word; + } + + /* 用户消息样式 */ + .user-container .message { + background-color: var(--bot-msg-bg); + border-radius: 10px; + margin-bottom: 8px; + padding: 12px 16px; + } + + /* 机器人消息样式 */ + .bot-container .message { + background-color: var(--bot-msg-bg); + border-radius: 10px 10px 10px 0; + margin-bottom: 8px; + padding: 0px 16px 12px 16px; + margin-top: 0; + } @@ -689,121 +762,10 @@ clearChat(); }); - // 清空聊天记录并显示欢迎屏幕 - function clearChat() { - // 清空消息区域 - messagesDiv.innerHTML = ''; - - // 创建欢迎屏幕 - const newWelcomeScreen = document.createElement('div'); - newWelcomeScreen.id = 'welcome-screen'; - newWelcomeScreen.innerHTML = ` -

AI 助手

-

我可以回答问题、提供信息或者帮助您完成各种任务

- -
-
-
解释复杂概念
-
用简单的语言解释量子计算
-
-
-
创意写作
-
写一个关于未来城市的短篇故事
-
-
-
编程帮助
-
如何用Python写一个简单的网络爬虫
-
-
- `; - - // 设置样式 - newWelcomeScreen.style.display = 'flex'; - newWelcomeScreen.style.flexDirection = 'column'; - newWelcomeScreen.style.alignItems = 'center'; - newWelcomeScreen.style.justifyContent = 'center'; - newWelcomeScreen.style.height = '100%'; - newWelcomeScreen.style.textAlign = 'center'; - newWelcomeScreen.style.padding = '20px'; - - // 添加到DOM - messagesDiv.appendChild(newWelcomeScreen); - - // 绑定示例卡片事件 - newWelcomeScreen.querySelectorAll('.example-card').forEach(card => { - card.addEventListener('click', function() { - const exampleText = this.querySelector('.example-text').textContent; - input.value = exampleText; - input.dispatchEvent(new Event('input')); - input.focus(); - }); - }); - - // 清空localStorage中的消息 - 使用用户ID作为键 - localStorage.setItem(`chatMessages_${userId}`, JSON.stringify([])); - - // 在移动设备上关闭侧边栏 - if (window.innerWidth <= 768) { - sidebar.classList.remove('active'); - } - } - - // 从localStorage加载消息 - 使用用户ID作为键 - function loadMessagesFromLocalStorage() { - try { - return JSON.parse(localStorage.getItem(`chatMessages_${userId}`) || '[]'); - } catch (error) { - console.error('Error loading messages from localStorage:', error); - return []; - } - } - - // 保存消息到localStorage - 使用用户ID作为键 - function saveMessageToLocalStorage(message) { - try { - const messages = loadMessagesFromLocalStorage(); - messages.push(message); - localStorage.setItem(`chatMessages_${userId}`, JSON.stringify(messages)); - } catch (error) { - console.error('Error saving message to localStorage:', error); - } - } - - // 初始化代码 - document.addEventListener('DOMContentLoaded', function() { - // 移除原始欢迎屏幕 - const originalWelcomeScreen = document.getElementById('welcome-screen'); - if (originalWelcomeScreen) { - originalWelcomeScreen.remove(); - } - - // 清空消息区域,确保不会重复显示消息 - messagesDiv.innerHTML = ''; - - // 加载消息 - const messages = loadMessagesFromLocalStorage(); - - if (messages.length === 0) { - // 如果没有消息,显示欢迎屏幕 - clearChat(); - } else { - // 显示现有消息 - messages.forEach(msg => { - if (msg.role === 'user') { - // 使用不保存到localStorage的版本显示消息 - displayUserMessage(msg.content, new Date(msg.timestamp)); - } else if (msg.role === 'assistant') { - // 使用不保存到localStorage的版本显示消息 - displayBotMessage(msg.content, new Date(msg.timestamp)); - } - }); - } - }); - // 发送按钮点击事件 - sendButton.onclick = function() { + sendButton.addEventListener('click', function() { sendMessage(); - }; + }); // 输入框按键事件 input.addEventListener('keydown', function(event) { @@ -843,6 +805,11 @@ // 添加一个等待中的机器人消息 const loadingContainer = addLoadingMessage(); + // 清空输入框并重置高度 - 移到这里,确保发送后立即清空 + input.value = ''; + input.style.height = '52px'; + sendButton.disabled = true; + // 发送到服务器并等待响应 fetch('/message', { method: 'POST', @@ -882,11 +849,6 @@ // 显示错误消息 addBotMessage("抱歉,发生了错误,请稍后再试。", new Date()); }); - - // 清空输入框并重置高度 - input.value = ''; - input.style.height = '52px'; - sendButton.disabled = true; } } @@ -1134,6 +1096,86 @@ // 初始化 input.focus(); + + // 清空聊天记录并显示欢迎屏幕 + function clearChat() { + // 清空消息区域 + messagesDiv.innerHTML = ''; + + // 创建欢迎屏幕 + const newWelcomeScreen = document.createElement('div'); + newWelcomeScreen.id = 'welcome-screen'; + newWelcomeScreen.innerHTML = ` +

AI 助手

+

我可以回答问题、提供信息或者帮助您完成各种任务

+ +
+
+
解释复杂概念
+
用简单的语言解释量子计算
+
+
+
创意写作
+
写一个关于未来城市的短篇故事
+
+
+
编程帮助
+
如何用Python写一个简单的网络爬虫
+
+
+ `; + + // 设置样式 + newWelcomeScreen.style.display = 'flex'; + newWelcomeScreen.style.flexDirection = 'column'; + newWelcomeScreen.style.alignItems = 'center'; + newWelcomeScreen.style.justifyContent = 'center'; + newWelcomeScreen.style.height = '100%'; + newWelcomeScreen.style.textAlign = 'center'; + newWelcomeScreen.style.padding = '20px'; + + // 添加到DOM + messagesDiv.appendChild(newWelcomeScreen); + + // 绑定示例卡片事件 + newWelcomeScreen.querySelectorAll('.example-card').forEach(card => { + card.addEventListener('click', function() { + const exampleText = this.querySelector('.example-text').textContent; + input.value = exampleText; + input.dispatchEvent(new Event('input')); + input.focus(); + }); + }); + + // 清空localStorage中的消息 - 使用用户ID作为键 + localStorage.setItem(`chatMessages_${userId}`, JSON.stringify([])); + + // 在移动设备上关闭侧边栏 + if (window.innerWidth <= 768) { + sidebar.classList.remove('active'); + } + } + + // 从localStorage加载消息 - 使用用户ID作为键 + function loadMessagesFromLocalStorage() { + try { + return JSON.parse(localStorage.getItem(`chatMessages_${userId}`) || '[]'); + } catch (error) { + console.error('Error loading messages from localStorage:', error); + return []; + } + } + + // 保存消息到localStorage - 使用用户ID作为键 + function saveMessageToLocalStorage(message) { + try { + const messages = loadMessagesFromLocalStorage(); + messages.push(message); + localStorage.setItem(`chatMessages_${userId}`, JSON.stringify(messages)); + } catch (error) { + console.error('Error saving message to localStorage:', error); + } + } \ No newline at end of file diff --git a/channel/web/web_channel.py b/channel/web/web_channel.py index c63571e..aac4f68 100644 --- a/channel/web/web_channel.py +++ b/channel/web/web_channel.py @@ -13,7 +13,6 @@ from config import conf import os import mimetypes # 添加这行来处理MIME类型 - class WebMessage(ChatMessage): def __init__( self, @@ -57,7 +56,7 @@ class WebChannel(ChatChannel): if reply.type in self.NOT_SUPPORT_REPLYTYPE: logger.warning(f"Web channel doesn't support {reply.type} yet") return - + # 获取用户ID user_id = context.get("receiver", None) if not user_id: