From 262611c736b9456e29cff0a963f82c2860527f2b Mon Sep 17 00:00:00 2001 From: Cola-Echo Date: Fri, 2 Jan 2026 16:10:57 +0800 Subject: [PATCH] Add files via upload --- chat.js | 15 ++++++++------- message-menu.js | 12 +++++++++--- multi-char-import.js | 4 ++-- phone-html.js | 2 +- style.css | 10 ++++++++-- 5 files changed, 28 insertions(+), 15 deletions(-) diff --git a/chat.js b/chat.js index d777cd7..4e88471 100644 --- a/chat.js +++ b/chat.js @@ -1476,7 +1476,8 @@ function getRealMsgIndexForVoice(container, msgElement) { let visualMsgCount = 1; const content = msg.content || ''; const isSpecial = msg.isVoice || msg.isSticker || msg.isPhoto || msg.isMusic; - if (!isSpecial && content.indexOf('|||') >= 0) { + // 只有 assistant 消息才会被 ||| 分割显示 + if (msg.role === 'assistant' && !isSpecial && content.indexOf('|||') >= 0) { const parts = content.split('|||').map(p => p.trim()).filter(p => p); visualMsgCount = parts.length || 1; } @@ -2022,14 +2023,14 @@ export async function sendMessage(messageText, isMultipleMessages = false, isVoi } } - const voiceMatch = aiMsg.match(/^\[语音[::]\s*(.+?)\]$/); + const voiceMatch = aiMsg.match(/^\s*\[语音[::]\s*(.+?)\]\s*$/); if (voiceMatch) { aiMsg = voiceMatch[1]; aiIsVoice = true; } // 解析AI照片格式 [照片:描述] - const photoMatch = aiMsg.match(/^\[照片[::]\s*(.+?)\]$/); + const photoMatch = aiMsg.match(/^\s*\[照片[::]\s*(.+?)\]\s*$/); if (photoMatch) { aiMsg = photoMatch[1]; aiIsPhoto = true; @@ -2602,14 +2603,14 @@ export async function sendStickerMessage(stickerUrl, description = '') { if (!aiMsg.trim()) continue; } - const voiceMatch = aiMsg.match(/^\[语音[::]\s*(.+?)\]$/); + const voiceMatch = aiMsg.match(/^\s*\[语音[::]\s*(.+?)\]\s*$/); if (voiceMatch) { aiMsg = voiceMatch[1]; aiIsVoice = true; } // 解析AI照片格式 [照片:描述] - const photoMatch = aiMsg.match(/^\[照片[::]\s*(.+?)\]$/); + const photoMatch = aiMsg.match(/^\s*\[照片[::]\s*(.+?)\]\s*$/); if (photoMatch) { aiMsg = photoMatch[1]; aiIsPhoto = true; @@ -3049,14 +3050,14 @@ export async function sendPhotoMessage(description) { if (!aiMsg.trim()) continue; } - const voiceMatch = aiMsg.match(/^\[语音[::]\s*(.+?)\]$/); + const voiceMatch = aiMsg.match(/^\s*\[语音[::]\s*(.+?)\]\s*$/); if (voiceMatch) { aiMsg = voiceMatch[1]; aiIsVoice = true; } // 解析AI照片格式 [照片:描述] - const photoMatch = aiMsg.match(/^\[照片[::]\s*(.+?)\]$/); + const photoMatch = aiMsg.match(/^\s*\[照片[::]\s*(.+?)\]\s*$/); if (photoMatch) { aiMsg = photoMatch[1]; aiIsPhoto = true; diff --git a/message-menu.js b/message-menu.js index 892f900..b7eeba1 100644 --- a/message-menu.js +++ b/message-menu.js @@ -7,7 +7,7 @@ import { requestSave } from './save-manager.js'; import { currentChatIndex, openChat, showTypingIndicator, hideTypingIndicator, appendMessage } from './chat.js'; import { showToast } from './toast.js'; import { getContext } from '../../../extensions.js'; -import { formatQuoteDate } from './utils.js'; +import { formatQuoteDate, sleep } from './utils.js'; import { isInGroupChat, getCurrentGroupIndex, openGroupChat } from './group-chat.js'; // 当前显示菜单的消息索引 @@ -504,12 +504,17 @@ async function regenerateMessage(msgIndex, contact) { if (!finalMsg) continue; let isVoice = false; - const voiceMatch = finalMsg.match(/^\[语音[::]\s*(.+?)\]$/); + const voiceMatch = finalMsg.match(/^\s*\[语音[::]\s*(.+?)\]\s*$/); if (voiceMatch) { finalMsg = voiceMatch[1]; isVoice = true; } + // 每条消息都要有typing效果和2-2.5秒延迟(与普通回复一致) + showTypingIndicator(contact); + await sleep(2000 + Math.random() * 500); + hideTypingIndicator(); + contact.chatHistory.push({ role: 'assistant', content: finalMsg, @@ -735,7 +740,8 @@ function getRealMsgIndex(container, msgElement) { const content = msg.content || ''; const isSpecial = msg.isVoice || msg.isSticker || msg.isPhoto || msg.isMusic; // 检查是否包含 ||| 或 标签(这些会导致消息被分割显示) - if (!isSpecial && (content.indexOf('|||') >= 0 || /<\s*meme\s*>/i.test(content))) { + // 注意:只有 assistant 消息才会被分割,用户消息不会分割 + if (msg.role === 'assistant' && !isSpecial && (content.indexOf('|||') >= 0 || /<\s*meme\s*>/i.test(content))) { // 使用 splitAIMessages 计算实际分割数量 const parts = splitAIMessages(content).filter(p => p && p.trim()); visualMsgCount = parts.length || 1; diff --git a/multi-char-import.js b/multi-char-import.js index 07a6a2e..4657a15 100644 --- a/multi-char-import.js +++ b/multi-char-import.js @@ -331,7 +331,7 @@ export function generateCharacterTablesHtml() { data-char-idx="${charIdx}" data-other="${escapeHtml(otherText)}" title="${hasOther ? '点击查看/编辑' : '点击添加'}" - style="width: 100%; font-size: 11px; padding: 3px 4px; ${hasOther ? 'background: var(--wechat-primary); color: white;' : ''}"> + style="width: 100%; font-size: 11px; padding: 3px 4px; ${hasOther ? 'background: var(--wechat-green); color: white;' : ''}"> ${hasOther ? '详情' : '+'} @@ -525,7 +525,7 @@ function saveCharOtherEdit() { const hasOther = newValue.length > 0; btn.textContent = hasOther ? '详情' : '+'; btn.title = hasOther ? '点击查看/编辑' : '点击添加'; - btn.style.background = hasOther ? 'var(--wechat-primary)' : ''; + btn.style.background = hasOther ? 'var(--wechat-green)' : ''; btn.style.color = hasOther ? 'white' : ''; } diff --git a/phone-html.js b/phone-html.js index db73ff3..239368a 100644 --- a/phone-html.js +++ b/phone-html.js @@ -1037,7 +1037,7 @@ function generateModalsHTML(settings) {
- 已选择 0 人 + 已选择 0
diff --git a/style.css b/style.css index 56a7b8e..1edb9e8 100644 --- a/style.css +++ b/style.css @@ -2379,9 +2379,15 @@ color: inherit; } -/* 用户消息的图标朝向左(水平翻转) */ +/* 用户消息的图标朝向左(水平翻转)+ 黑色 */ .wechat-voice-bubble.self .wechat-voice-waves-icon { transform: scaleX(-1); + color: #000; +} + +/* 用户消息的时长文字也是黑色 */ +.wechat-voice-bubble.self .wechat-voice-duration { + color: #000; } /* 对方消息的图标朝向右(默认方向) */ @@ -5306,7 +5312,7 @@ position: absolute; left: 0; right: 0; - bottom: 120px; + bottom: 165px; max-height: 250px; display: flex; flex-direction: column;