add feature nickname
This commit is contained in:
		| @ -2,6 +2,10 @@ const ipc = window.electronAPI; | ||||
| let userInfo = {}; | ||||
| let trcConfig = {} | ||||
|  | ||||
| // 会话状态跟踪 - 用于控制滚动行为 | ||||
| let sessionStates = new Map(); // 存储会话状态 {userId: {isFirstOpen: boolean, scrollPosition: number}} | ||||
| let isAppFirstLoad = true; // 标记应用是否首次加载 | ||||
|  | ||||
| // 安全的 localStorage 访问工具 | ||||
| const safeLocalStorage = { | ||||
|   getItem: (key) => { | ||||
| @ -50,7 +54,8 @@ const getCurrentUserId = (item) => { | ||||
|     return peerId; | ||||
| } | ||||
| const onlineStatusCheck = ()=> { | ||||
|     setInterval(async () => { | ||||
|     // 定义检测函数 | ||||
|     const checkStatus = async () => { | ||||
|         // 安全地检查 localStorage | ||||
|         const element = safeLocalStorage.getItem('dc1_auth_key'); | ||||
|  | ||||
| @ -82,7 +87,13 @@ const onlineStatusCheck = ()=> { | ||||
|             ipc.loginNotify(args); | ||||
|             userInfo = args; | ||||
|         } | ||||
|     }, 60000); // 每隔5000毫秒(3秒)调用一次 | ||||
|     }; | ||||
|  | ||||
|     // 立即执行一次检测 | ||||
|     checkStatus(); | ||||
|  | ||||
|     // 然后每5秒检测一次(更快速地检测登录状态) | ||||
|     setInterval(checkStatus, 5000); | ||||
| } | ||||
| const getUserInfo = () => { | ||||
|     return new Promise((resolve, reject) => { | ||||
| @ -589,18 +600,189 @@ const updateConfigInfo = async () => { | ||||
|     } | ||||
| } | ||||
|  | ||||
| // 滚动到聊天底部的函数 | ||||
| const scrollToBottom = (force = false) => { | ||||
|     try { | ||||
|         console.log('Telegram: 开始执行滚动到底部操作'); | ||||
|  | ||||
|         // Telegram 聊天消息容器选择器 | ||||
|         const possibleSelectors = [ | ||||
|             '#MiddleColumn .messages-container', | ||||
|             '#MiddleColumn [class*="messages-container"]', | ||||
|             '#MiddleColumn .Transition', | ||||
|             '#MiddleColumn [class*="Transition"]', | ||||
|             '#MiddleColumn > div > div', | ||||
|             '.MessageList', | ||||
|             '[class*="MessageList"]' | ||||
|         ]; | ||||
|  | ||||
|         let chatContainer = null; | ||||
|         for (const selector of possibleSelectors) { | ||||
|             const element = document.querySelector(selector); | ||||
|             if (element) { | ||||
|                 // 检查元素是否真的可以滚动 | ||||
|                 const style = window.getComputedStyle(element); | ||||
|                 if (style.overflowY === 'auto' || style.overflowY === 'scroll' || | ||||
|                     element.scrollHeight > element.clientHeight) { | ||||
|                     chatContainer = element; | ||||
|                     console.log(`Telegram: 找到可滚动聊天容器,使用选择器: ${selector}`); | ||||
|                     console.log(`Telegram: 容器信息 - scrollHeight: ${element.scrollHeight}, clientHeight: ${element.clientHeight}, scrollTop: ${element.scrollTop}`); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // 如果没找到特定容器,尝试查找包含消息的父容器 | ||||
|         if (!chatContainer) { | ||||
|             console.log('Telegram: 未找到预定义容器,尝试通过消息元素查找'); | ||||
|             const messageElements = document.querySelectorAll('.Message, [class*="Message"]'); | ||||
|             console.log(`Telegram: 找到 ${messageElements.length} 个消息元素`); | ||||
|  | ||||
|             if (messageElements.length > 0) { | ||||
|                 // 从最后一个消息元素开始向上查找可滚动容器 | ||||
|                 const lastMessage = messageElements[messageElements.length - 1]; | ||||
|                 let parent = lastMessage.parentElement; | ||||
|  | ||||
|                 while (parent && parent !== document.body) { | ||||
|                     const style = window.getComputedStyle(parent); | ||||
|                     if (style.overflowY === 'auto' || style.overflowY === 'scroll' || | ||||
|                         parent.scrollHeight > parent.clientHeight) { | ||||
|                         chatContainer = parent; | ||||
|                         console.log('Telegram: 通过消息元素找到滚动容器'); | ||||
|                         console.log(`Telegram: 容器信息 - scrollHeight: ${parent.scrollHeight}, clientHeight: ${parent.clientHeight}, scrollTop: ${parent.scrollTop}`); | ||||
|                         break; | ||||
|                     } | ||||
|                     parent = parent.parentElement; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (chatContainer) { | ||||
|             // 记录滚动前的状态 | ||||
|             const beforeScrollTop = chatContainer.scrollTop; | ||||
|             const maxScrollTop = chatContainer.scrollHeight - chatContainer.clientHeight; | ||||
|             console.log(`Telegram: 滚动前状态 - scrollTop: ${beforeScrollTop}, maxScrollTop: ${maxScrollTop}`); | ||||
|  | ||||
|             // 使用最可靠的滚动方法 | ||||
|             const scrollMethods = [ | ||||
|                 () => { | ||||
|                     // 方法1: 直接设置为最大滚动值 | ||||
|                     chatContainer.scrollTop = chatContainer.scrollHeight; | ||||
|                     console.log(`Telegram: 方法1执行后 scrollTop: ${chatContainer.scrollTop}`); | ||||
|                 }, | ||||
|                 () => { | ||||
|                     // 方法2: 使用scrollTo方法滚动到底部 | ||||
|                     chatContainer.scrollTo({ | ||||
|                         top: chatContainer.scrollHeight, | ||||
|                         behavior: 'auto' | ||||
|                     }); | ||||
|                     console.log(`Telegram: 方法2执行后 scrollTop: ${chatContainer.scrollTop}`); | ||||
|                 }, | ||||
|                 () => { | ||||
|                     // 方法3: 查找最后一条消息并滚动到它 | ||||
|                     const lastMessage = chatContainer.querySelector('.Message:last-child, [class*="Message"]:last-child'); | ||||
|                     if (lastMessage) { | ||||
|                         lastMessage.scrollIntoView({ | ||||
|                             behavior: 'auto', | ||||
|                             block: 'end', | ||||
|                             inline: 'nearest' | ||||
|                         }); | ||||
|                         console.log(`Telegram: 方法3执行后 scrollTop: ${chatContainer.scrollTop}`); | ||||
|                     } | ||||
|                 } | ||||
|             ]; | ||||
|  | ||||
|             // 执行滚动方法 | ||||
|             scrollMethods.forEach((method, index) => { | ||||
|                 try { | ||||
|                     method(); | ||||
|                     console.log(`Telegram: 执行滚动方法 ${index + 1} 完成`); | ||||
|                 } catch (error) { | ||||
|                     console.warn(`Telegram: 滚动方法 ${index + 1} 失败:`, error); | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             // 最终验证和强制滚动 | ||||
|             setTimeout(() => { | ||||
|                 const finalScrollTop = chatContainer.scrollTop; | ||||
|                 const finalMaxScrollTop = chatContainer.scrollHeight - chatContainer.clientHeight; | ||||
|                 const isAtBottom = finalScrollTop >= (finalMaxScrollTop - 10); | ||||
|  | ||||
|                 console.log(`Telegram: 滚动完成验证 - scrollTop: ${finalScrollTop}, maxScrollTop: ${finalMaxScrollTop}, 是否在底部: ${isAtBottom}`); | ||||
|  | ||||
|                 // 如果还没到底部,执行最终强制滚动 | ||||
|                 if (!isAtBottom) { | ||||
|                     chatContainer.scrollTop = chatContainer.scrollHeight; | ||||
|                     console.log(`Telegram: 执行最终强制滚动,新scrollTop: ${chatContainer.scrollTop}`); | ||||
|                 } | ||||
|             }, 200); | ||||
|  | ||||
|             console.log('Telegram: 滚动到聊天底部操作执行完成'); | ||||
|             return true; | ||||
|         } else { | ||||
|             console.warn('Telegram: 未找到聊天容器,无法滚动'); | ||||
|             return false; | ||||
|         } | ||||
|     } catch (error) { | ||||
|         console.error('Telegram: 滚动到底部时出错:', error); | ||||
|         return false; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| //会话列表切换触发函数 | ||||
| const sessionChange = async () => { | ||||
|     const currentUserId = getCurrentUserId(); | ||||
|     const args = {platform: 'Telegram', userId: currentUserId}; | ||||
|     console.log('会话切换 sessionChange args', args); | ||||
|  | ||||
|     // 检查是否为新打开的会话 | ||||
|     const isNewSession = isAppFirstLoad || !sessionStates.has(currentUserId); | ||||
|  | ||||
|     // 先更新配置信息 | ||||
|     ipc.infoUpdate(args) | ||||
|     await updateConfigInfo() | ||||
|  | ||||
|     const myNode = document.getElementById('custom-translate-textarea') | ||||
|     if (!myNode) { | ||||
|         addTranslatePreview(); | ||||
|         addTranslateListener(); | ||||
|     } | ||||
|     styledTextarea.initData() | ||||
|  | ||||
|     // 处理滚动逻辑 | ||||
|     if (isNewSession) { | ||||
|         console.log(`Telegram: 新打开会话 ${currentUserId},将滚动到底部`); | ||||
|         // 新打开的会话,滚动到底部 - 使用多次延迟确保完全加载 | ||||
|  | ||||
|         // 第一次滚动 - 早期尝试 | ||||
|         setTimeout(() => { | ||||
|             scrollToBottom(); | ||||
|         }, 300); | ||||
|  | ||||
|         // 第二次滚动 - 确保DOM完全加载 | ||||
|         setTimeout(() => { | ||||
|             scrollToBottom(); | ||||
|         }, 800); | ||||
|  | ||||
|         // 第三次滚动 - 最终确保 | ||||
|         setTimeout(() => { | ||||
|             scrollToBottom(); | ||||
|         }, 1500); | ||||
|  | ||||
|         // 标记会话已打开 | ||||
|         sessionStates.set(currentUserId, { | ||||
|             isFirstOpen: false, | ||||
|             scrollPosition: 0 | ||||
|         }); | ||||
|  | ||||
|         // 标记应用不再是首次加载 | ||||
|         if (isAppFirstLoad) { | ||||
|             isAppFirstLoad = false; | ||||
|         } | ||||
|     } else { | ||||
|         console.log(`Telegram: 切换到已打开的会话 ${currentUserId},保持原滚动位置`); | ||||
|         // 已打开的会话切换,不进行滚动操作,保持原位置 | ||||
|     } | ||||
| } | ||||
| const debouncedSessionChange = debounce(sessionChange,500); | ||||
|  | ||||
| @ -726,7 +908,37 @@ const monitorMainNode = ()=> { | ||||
|  | ||||
|             if (res.status && res.data) { | ||||
|                 // 找到了缓存的翻译结果,显示它 | ||||
|                 leftDiv.innerHTML = res.data; | ||||
|                 const translatedText = res.data; | ||||
|                 if (translatedText.length > 300) { | ||||
|                     // 创建折叠的翻译结果 | ||||
|                     const shortText = translatedText.substring(0, 300) + "..."; | ||||
|                     leftDiv.innerHTML = ` | ||||
|                         <div class="translate-content"> | ||||
|                             <div class="translate-short">${shortText}</div> | ||||
|                             <div class="translate-full" style="display: none;">${translatedText}</div> | ||||
|                             <span class="translate-toggle" style="color: #007bff; cursor: pointer; text-decoration: underline; font-size: 12px;">查看更多</span> | ||||
|                         </div> | ||||
|                     `; | ||||
|  | ||||
|                     // 添加展开/折叠功能 | ||||
|                     const toggleBtn = leftDiv.querySelector(".translate-toggle"); | ||||
|                     const shortDiv = leftDiv.querySelector(".translate-short"); | ||||
|                     const fullDiv = leftDiv.querySelector(".translate-full"); | ||||
|  | ||||
|                     toggleBtn.addEventListener("click", () => { | ||||
|                         if (fullDiv.style.display === "none") { | ||||
|                             shortDiv.style.display = "none"; | ||||
|                             fullDiv.style.display = "block"; | ||||
|                             toggleBtn.textContent = "收起"; | ||||
|                         } else { | ||||
|                             shortDiv.style.display = "block"; | ||||
|                             fullDiv.style.display = "none"; | ||||
|                             toggleBtn.textContent = "查看更多"; | ||||
|                         } | ||||
|                     }); | ||||
|                 } else { | ||||
|                     leftDiv.innerHTML = translatedText; | ||||
|                 } | ||||
|                 leftDiv.style.color = 'var(--color-text)'; | ||||
|                 // 缓存存在时,刷新按钮正常显示 | ||||
|                 rightDiv.style.display = ''; | ||||
| @ -784,7 +996,38 @@ const monitorMainNode = ()=> { | ||||
|             // 修复:刷新按钮不自动清理缓存,保留翻译历史 | ||||
|             const res = await ipc.translateText({route: route, text: text,from:from, to: to,refresh:'false',mode:mode}); | ||||
|             if (res.status) { | ||||
|                 leftDiv.innerHTML = res.data; | ||||
|                 // 处理长翻译结果的折叠显示 | ||||
|                 const translatedText = res.data; | ||||
|                 if (translatedText.length > 300) { | ||||
|                     // 创建折叠的翻译结果 | ||||
|                     const shortText = translatedText.substring(0, 300) + "..."; | ||||
|                     leftDiv.innerHTML = ` | ||||
|                         <div class="translate-content"> | ||||
|                             <div class="translate-short">${shortText}</div> | ||||
|                             <div class="translate-full" style="display: none;">${translatedText}</div> | ||||
|                             <span class="translate-toggle" style="color: #007bff; cursor: pointer; text-decoration: underline; font-size: 12px;">查看更多</span> | ||||
|                         </div> | ||||
|                     `; | ||||
|  | ||||
|                     // 添加展开/折叠功能 | ||||
|                     const toggleBtn = leftDiv.querySelector(".translate-toggle"); | ||||
|                     const shortDiv = leftDiv.querySelector(".translate-short"); | ||||
|                     const fullDiv = leftDiv.querySelector(".translate-full"); | ||||
|  | ||||
|                     toggleBtn.addEventListener("click", () => { | ||||
|                         if (fullDiv.style.display === "none") { | ||||
|                             shortDiv.style.display = "none"; | ||||
|                             fullDiv.style.display = "block"; | ||||
|                             toggleBtn.textContent = "收起"; | ||||
|                         } else { | ||||
|                             shortDiv.style.display = "block"; | ||||
|                             fullDiv.style.display = "none"; | ||||
|                             toggleBtn.textContent = "查看更多"; | ||||
|                         } | ||||
|                     }); | ||||
|                 } else { | ||||
|                     leftDiv.innerHTML = translatedText; | ||||
|                 } | ||||
|                 rightDiv.style.display = ''; | ||||
|             }else { | ||||
|                 leftDiv.style.color = 'red'; | ||||
| @ -818,7 +1061,38 @@ const monitorMainNode = ()=> { | ||||
|             const mode = trcConfig.mode; | ||||
|             const res = await ipc.translateText({route: route, text: text,from:from, to: to,mode:mode}); | ||||
|             if (res.status) { | ||||
|                 leftDiv.innerHTML = res.data; | ||||
|                 // 处理长翻译结果的折叠显示 | ||||
|                 const translatedText = res.data; | ||||
|                 if (translatedText.length > 300) { | ||||
|                     // 创建折叠的翻译结果 | ||||
|                     const shortText = translatedText.substring(0, 300) + "..."; | ||||
|                     leftDiv.innerHTML = ` | ||||
|                         <div class="translate-content"> | ||||
|                             <div class="translate-short">${shortText}</div> | ||||
|                             <div class="translate-full" style="display: none;">${translatedText}</div> | ||||
|                             <span class="translate-toggle" style="color: #007bff; cursor: pointer; text-decoration: underline; font-size: 12px;">查看更多</span> | ||||
|                         </div> | ||||
|                     `; | ||||
|  | ||||
|                     // 添加展开/折叠功能 | ||||
|                     const toggleBtn = leftDiv.querySelector(".translate-toggle"); | ||||
|                     const shortDiv = leftDiv.querySelector(".translate-short"); | ||||
|                     const fullDiv = leftDiv.querySelector(".translate-full"); | ||||
|  | ||||
|                     toggleBtn.addEventListener("click", () => { | ||||
|                         if (fullDiv.style.display === "none") { | ||||
|                             shortDiv.style.display = "none"; | ||||
|                             fullDiv.style.display = "block"; | ||||
|                             toggleBtn.textContent = "收起"; | ||||
|                         } else { | ||||
|                             shortDiv.style.display = "block"; | ||||
|                             fullDiv.style.display = "none"; | ||||
|                             toggleBtn.textContent = "查看更多"; | ||||
|                         } | ||||
|                     }); | ||||
|                 } else { | ||||
|                     leftDiv.innerHTML = translatedText; | ||||
|                 } | ||||
|                 rightDiv.style.display = ''; | ||||
|             }else { | ||||
|                 leftDiv.style.color = 'red'; | ||||
| @ -1061,4 +1335,11 @@ const initTgObserver = () => { | ||||
| }; | ||||
|  | ||||
| // 监听tg消息 | ||||
| initTgObserver(); | ||||
| initTgObserver(); | ||||
|  | ||||
| // 监听页面加载完成,确保首次打开时滚动到底部 | ||||
| window.addEventListener('load', () => { | ||||
|     console.log('Telegram: 页面加载完成,标记为首次加载状态'); | ||||
|     isAppFirstLoad = true; | ||||
|     sessionStates.clear(); | ||||
| }); | ||||
| @ -110,7 +110,8 @@ let lastProfileName = ""; | ||||
| let lastAboutText = ""; | ||||
|  | ||||
| const onlineStatusCheck = () => { | ||||
|   setInterval(async () => { | ||||
|   // 定义检测函数 | ||||
|   const checkStatus = async () => { | ||||
|     const element = localStorage["last-wid-md"]; | ||||
|     if (element) { | ||||
|       const phoneNumber = element.split(":")[0].replace(/"/g, ""); | ||||
| @ -169,7 +170,13 @@ const onlineStatusCheck = () => { | ||||
|       ipc.loginNotify(args); | ||||
|       userInfo = args; | ||||
|     } | ||||
|   }, 60000); // 每隔60秒调用一次 | ||||
|   }; | ||||
|  | ||||
|   // 立即执行一次检测 | ||||
|   checkStatus(); | ||||
|  | ||||
|   // 然后每5秒检测一次(更快速地检测登录状态) | ||||
|   setInterval(checkStatus, 5000); | ||||
| }; | ||||
|  | ||||
| /** | ||||
| @ -1315,6 +1322,9 @@ let currentNode = null; | ||||
| let sessionStates = new Map(); // 存储会话状态 {userId: {isFirstOpen: boolean, scrollPosition: number}} | ||||
| let isAppFirstLoad = true; // 标记应用是否首次加载 | ||||
|  | ||||
| // 全局 MutationObserver 实例,避免重复创建 | ||||
| let chatObserver = null; | ||||
|  | ||||
| // 滚动到聊天底部的函数 | ||||
| const scrollToBottom = (force = false) => { | ||||
|   try { | ||||
| @ -1508,20 +1518,34 @@ const monitorMainNode = () => { | ||||
|   // 每次切换会话后重新获取监听消息列表处理消息翻译 | ||||
|   const observeChatChanges = () => { | ||||
|     const chatContainer = document.querySelector("#app"); | ||||
|     if (chatContainer) { | ||||
|       const observer = new MutationObserver((mutations) => { | ||||
|         observer.disconnect(); // 暂时断开观察器以避免循环触发 | ||||
|         debouncedAddTranslateButtonToAllMessages(); | ||||
|         observer.observe(chatContainer, { | ||||
|           childList: true, | ||||
|           subtree: true, | ||||
|         }); | ||||
|       }); | ||||
|       observer.observe(chatContainer, { | ||||
|     if (!chatContainer) { | ||||
|       console.warn('WhatsApp: 未找到聊天容器 #app'); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     // 如果已经存在 observer,先断开连接 | ||||
|     if (chatObserver) { | ||||
|       console.log('WhatsApp: 断开旧的 MutationObserver'); | ||||
|       chatObserver.disconnect(); | ||||
|       chatObserver = null; | ||||
|     } | ||||
|  | ||||
|     // 创建新的 observer | ||||
|     console.log('WhatsApp: 创建新的 MutationObserver 监听聊天变化'); | ||||
|     chatObserver = new MutationObserver((mutations) => { | ||||
|       chatObserver.disconnect(); // 暂时断开观察器以避免循环触发 | ||||
|       debouncedAddTranslateButtonToAllMessages(); | ||||
|       chatObserver.observe(chatContainer, { | ||||
|         childList: true, | ||||
|         subtree: true, | ||||
|       }); | ||||
|     } | ||||
|     }); | ||||
|  | ||||
|     // 开始监听 | ||||
|     chatObserver.observe(chatContainer, { | ||||
|       childList: true, | ||||
|       subtree: true, | ||||
|     }); | ||||
|   }; | ||||
|   /** | ||||
|    * 为所有消息添加翻译按钮 | ||||
| @ -2969,22 +2993,53 @@ ipc.onMessageFromMain((newNickName) => { | ||||
|     const currentUserId = getCurrentUserId(); | ||||
|     console.log(`🔄 收到昵称更新消息: ${newNickName} for ${currentUserId}`); | ||||
|  | ||||
|     // 只更新当前选中的联系人在列表中的显示 | ||||
|     // 1. 更新 whatsappNickname 的内存缓存(关键修复) | ||||
|     if (window.whatsappNickname && currentUserId) { | ||||
|       console.log(`💾 更新内存缓存: ${currentUserId} -> ${newNickName}`); | ||||
|  | ||||
|       // 保存多种格式的 ID,确保能匹配到 | ||||
|       window.whatsappNickname.nicknames.set(currentUserId, newNickName); | ||||
|  | ||||
|       // 如果是手机号格式,也保存聊天ID格式 | ||||
|       if (currentUserId.match(/^\+?\d+$/)) { | ||||
|         const chatId = currentUserId.replace(/^\+/, '') + '@c.us'; | ||||
|         window.whatsappNickname.nicknames.set(chatId, newNickName); | ||||
|         console.log(`💾 同时更新聊天ID格式: ${chatId} -> ${newNickName}`); | ||||
|       } | ||||
|  | ||||
|       // 如果是聊天ID格式,也保存手机号格式 | ||||
|       if (currentUserId.includes('@c.us')) { | ||||
|         const phoneNumber = currentUserId.replace('@c.us', ''); | ||||
|         window.whatsappNickname.nicknames.set(phoneNumber, newNickName); | ||||
|         window.whatsappNickname.nicknames.set('+' + phoneNumber, newNickName); | ||||
|         console.log(`💾 同时更新手机号格式: ${phoneNumber} -> ${newNickName}`); | ||||
|       } | ||||
|  | ||||
|       console.log(`✅ 内存缓存已更新,当前缓存大小: ${window.whatsappNickname.nicknames.size}`); | ||||
|     } | ||||
|  | ||||
|     // 2. 更新当前选中的联系人在列表中的显示 | ||||
|     const listName = currentNode.querySelector('div[role="gridcell"] span[title]'); | ||||
|     if (listName) { | ||||
|       const originalTitle = listName.getAttribute("title") || listName.innerText; | ||||
|       const originalTitle = listName.dataset.originalName || listName.getAttribute("title") || listName.innerText; | ||||
|  | ||||
|       // 保存原始名称(如果还没保存) | ||||
|       if (!listName.dataset.originalName) { | ||||
|         listName.dataset.originalName = originalTitle; | ||||
|       } | ||||
|  | ||||
|       listName.innerText = newNickName; | ||||
|       listName.title = newNickName; | ||||
|       listName.style.fontWeight = "bold"; | ||||
|       listName.style.color = "#1976d2"; | ||||
|       // 保存完整的昵称信息 | ||||
|       listName.setAttribute("data-remark", newNickName); | ||||
|       listName.setAttribute("data-user-id", currentUserId); | ||||
|       listName.setAttribute("data-original-name", originalTitle); | ||||
|       listName.setAttribute("data-manual-update", "true"); | ||||
|       console.log(`✅ 精确更新列表昵称: "${originalTitle}" -> "${newNickName}" for ${currentUserId}`); | ||||
|     } | ||||
|  | ||||
|     // 更新顶部聊天窗口的昵称 | ||||
|     // 3. 更新顶部聊天窗口的昵称 | ||||
|     const cardName = document.querySelector('#main header span[dir="auto"]'); | ||||
|     if (cardName) { | ||||
|       cardName.innerText = newNickName; | ||||
| @ -3212,20 +3267,30 @@ class WhatsAppNickname { | ||||
|   } | ||||
|  | ||||
|   setupObserver() { | ||||
|     let debounceTimer = null; | ||||
|     const observer = new MutationObserver(() => { | ||||
|       if (!this.isProcessing) { | ||||
|         this.isProcessing = true; | ||||
|         setTimeout(() => { | ||||
|           this.syncContactList(); | ||||
|           this.isProcessing = false; | ||||
|         }, 100); | ||||
|       // 使用防抖,避免频繁触发 | ||||
|       if (debounceTimer) { | ||||
|         clearTimeout(debounceTimer); | ||||
|       } | ||||
|  | ||||
|       debounceTimer = setTimeout(() => { | ||||
|         if (!this.isProcessing) { | ||||
|           this.isProcessing = true; | ||||
|           console.log('🔄 MutationObserver 触发同步...'); | ||||
|           this.syncContactList().finally(() => { | ||||
|             this.isProcessing = false; | ||||
|           }); | ||||
|         } | ||||
|       }, 500); // 增加防抖时间到500ms | ||||
|     }); | ||||
|  | ||||
|     observer.observe(document.body, { | ||||
|       childList: true, | ||||
|       subtree: true | ||||
|     }); | ||||
|  | ||||
|     console.log('✅ MutationObserver 已设置'); | ||||
|   } | ||||
|  | ||||
|   setupNicknameListener() { | ||||
| @ -3319,8 +3384,24 @@ class WhatsAppNickname { | ||||
|       console.log(`🆔 聊天ID: "${chatId}"`); | ||||
|       this.chatIdMap.set(originalName, chatId); | ||||
|  | ||||
|       // 先检查内存中的昵称 | ||||
|       // 先检查内存中的昵称(尝试多种格式) | ||||
|       let nickname = this.nicknames.get(chatId); | ||||
|  | ||||
|       // 如果没找到,尝试其他格式 | ||||
|       if (!nickname && chatId.includes('@c.us')) { | ||||
|         const phoneNumber = chatId.replace('@c.us', ''); | ||||
|         nickname = this.nicknames.get(phoneNumber) || this.nicknames.get('+' + phoneNumber); | ||||
|         if (nickname) { | ||||
|           console.log(`💭 通过手机号格式找到昵称: ${phoneNumber} -> ${nickname}`); | ||||
|         } | ||||
|       } else if (!nickname && chatId.match(/^\+?\d+$/)) { | ||||
|         const chatIdFormat = chatId.replace(/^\+/, '') + '@c.us'; | ||||
|         nickname = this.nicknames.get(chatIdFormat); | ||||
|         if (nickname) { | ||||
|           console.log(`💭 通过聊天ID格式找到昵称: ${chatIdFormat} -> ${nickname}`); | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       console.log(`💭 内存中的昵称: ${nickname || '无'}`); | ||||
|  | ||||
|       // 如果内存中没有昵称,就保持原名(不再查询数据库) | ||||
|  | ||||
| @ -278,13 +278,13 @@ class WindowService { | ||||
|           windowStatus: "true", | ||||
|           windowId: view.webContents.id, | ||||
|           userAgent: userAgent, | ||||
|           onlineStatus: "true", // 会话启动时立即设置为在线状态 | ||||
|           // 移除启动时自动设置 onlineStatus,等待平台脚本检测真实登录状态 | ||||
|         }, | ||||
|         { platform: platform, partitionId: inputPartitionId } | ||||
|       ); | ||||
|       sessionObj.windowStatus = "true"; | ||||
|       sessionObj.windowId = view.webContents.id; | ||||
|       sessionObj.onlineStatus = "true"; // 同步更新内存中的对象 | ||||
|       // 移除启动时自动设置 onlineStatus,等待平台脚本检测真实登录状态 | ||||
|  | ||||
|       return { status: true, message: "启动成功", data: sessionObj }; | ||||
|     } catch (err) { | ||||
|  | ||||
| @ -110,9 +110,9 @@ | ||||
|                 </div> | ||||
|                 <div class="child-menu-item-line" /> | ||||
|                 <div class="child-menu-item-img" :class="{ 'margin-top-10': !isEmpty(child.avatarUrl) }"> | ||||
|                   <!-- 修复后的状态显示逻辑: | ||||
|                        状态0:未启动/未登录 → 灰色dot | ||||
|                        状态1:已启动/已登录无消息 → 绿色dot | ||||
|                   <!-- 修复后的状态显示逻辑(只依赖真实登录状态): | ||||
|                        状态0:未登录 → 灰色dot | ||||
|                        状态1:已登录无消息 → 绿色dot | ||||
|                        状态2:有消息 → 红色badge(带数字) --> | ||||
|                   <el-badge :offset="[-38, 15]" | ||||
|                     :is-dot="getStatusValue(child) === ''" | ||||
| @ -151,9 +151,9 @@ | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div v-if="isCollapse" class="child-menu-item-icon margin-top-10"> | ||||
|                   <!-- 折叠状态下的修复状态显示: | ||||
|                        状态0:未启动/未登录 → 灰色dot | ||||
|                        状态1:已启动/已登录无消息 → 绿色dot | ||||
|                   <!-- 折叠状态下的修复状态显示(只依赖真实登录状态): | ||||
|                        状态0:未登录 → 灰色dot | ||||
|                        状态1:已登录无消息 → 绿色dot | ||||
|                        状态2:有消息 → 红色badge(带数字) --> | ||||
|                   <el-badge :offset="[-15, 0]" | ||||
|                     :is-dot="getStatusValue(child) === ''" | ||||
| @ -333,11 +333,10 @@ const isEmpty = (value) => { | ||||
|   return false | ||||
| } | ||||
|  | ||||
| // 修复后的状态计算逻辑 - 使用响应式函数 | ||||
| // 修复后的状态计算逻辑 - 只依赖真实登录状态 | ||||
| const getStatusType = (child) => { | ||||
|   // 修复:使用Number()确保数据类型一致性 | ||||
|   const msgCount = Number(child?.msgCount) || 0 | ||||
|   const isStarted = child.windowStatus === 'true' | ||||
|   const isOnline = child.onlineStatus === 'true' | ||||
|  | ||||
|   console.log(`🎨 状态计算 [${child.partitionId}]:`, { | ||||
| @ -346,7 +345,6 @@ const getStatusType = (child) => { | ||||
|     数据类型: typeof child?.msgCount, | ||||
|     windowStatus: child.windowStatus, | ||||
|     onlineStatus: child.onlineStatus, | ||||
|     isStarted, | ||||
|     isOnline, | ||||
|     时间戳: new Date().toLocaleTimeString() | ||||
|   }) | ||||
| @ -357,14 +355,14 @@ const getStatusType = (child) => { | ||||
|     return 'error' | ||||
|   } | ||||
|  | ||||
|   // 状态1:已启动/已登录无消息 → 绿色dot | ||||
|   if (isStarted || isOnline) { | ||||
|     console.log(`🟢 ${child.partitionId} → 绿色 (已启动或在线)`) | ||||
|   // 状态1:已登录无消息 → 绿色dot(只依赖真实登录状态) | ||||
|   if (isOnline) { | ||||
|     console.log(`🟢 ${child.partitionId} → 绿色 (已登录)`) | ||||
|     return 'success' | ||||
|   } | ||||
|  | ||||
|   // 状态0:未启动/未登录 → 灰色dot | ||||
|   console.log(`⚪ ${child.partitionId} → 灰色 (未启动且离线)`) | ||||
|   console.log(`⚪ ${child.partitionId} → 灰色 (未登录)`) | ||||
|   return 'info' | ||||
| } | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 unknown
					unknown