链滴聊天页面优化

链滴聊天页面优化

支持按日期增加分割符和右侧生成日期菜单,点击滚动到对应位置。

动态添加的聊天内容也支持,但仅支持当前页的日期,超出当前页的需要翻页。

(()=>{
    // 聊天界面添加分割线和右侧按日期跳转列表
    if (location.href.indexOf("ld246.com/chats/")!==-1) {
        // 生成日期列表
        generateDateList();

        // 监控新聊天消息生成
        const chatsList = document.querySelector('.chats__list');
        const observer = new MutationObserver((mutations) => {
            mutations.forEach(mutation => {
                // 遍历新增的节点
                mutation.addedNodes.forEach(node => {
                    //if (node.nodeType === 1) console.log(node)
                    // 确保是元素节点且符合选择器
                    if (node.nodeType === 1 && node.matches('.chats__item')) {
                        generateDateList();
                    }
                });
            });
        });
        // 开始观察 body 的子元素变化
        observer.observe(chatsList, {
            childList: true,  // 监听直接子元素变化
            subtree: false    // 不监听深层子元素
        });
    }

    // 生成日期列表
    function generateDateList() {
        // ================= 原有分割线功能 =================
        addStyle(`
            /* 聊天页面字体大小 */
            .chats__content .ft-13{font-size: 16px;}.chats__content .ft__fade{font-size:14px;}
            /* 分隔符样式 */
            .new-day-separator {
                border-top: 2px solid #ccc;
                padding-top: 10px;
                position: relative;
            }

            /* 新增悬浮列表样式 */
            #date-floating-list {
                position: fixed;
                right: 41px;
                top: 50%;
                transform: translateY(-50%);
                background-color: var(--background-color); /*rgba(255, 255, 255, 0.95);*/
                /*border: 1px solid #ddd;*/
                border: 1px solid var(--layer-border-color);
                border-radius: 3px;
                padding: 12px 16px;
                box-shadow: 0 2px 8px rgba(0,0,0,0.1);
                max-height: 80vh;
                overflow-y: auto;
                z-index: 9999;
                font-family: Arial, sans-serif;
            }

            .date-item {
                padding: 6px 12px;
                margin: 4px 0;
                border-radius: 4px;
                cursor: pointer;
                transition: all 0.2s;
                font-size: 14px;
                color: var(--layer-color); /*#666;*/
                white-space: nowrap;
            }

            .date-item:hover {
                /*background: #f0f0f0;
                color: #333;*/
                background-color: var(--background-secondary-color);
                color: var(--toc-hover-color);
                transform: translateX(-4px);
            }

            .highlight {
                animation: highlight-fade 1s ease-out;
            }

            @keyframes highlight-fade {
                0% { background: rgba(255,235,59,0.3); }
                100% { background: transparent; }
            }
        `);

        // ================= 原有分割线逻辑 + 新增悬浮列表数据收集 =================
        const chatItems = document.querySelectorAll('.chats__list .chats__item');
        const dateMap = new Map();
        let previousDate = null;

        chatItems.forEach((item, index) => {
            // 原有分割线逻辑
            const timeElement = item.querySelector('.ft__smaller.ft__fade.fn__right');
            if (!timeElement) return;

            const timeString = timeElement.textContent.trim();
            const currentDate = new Date(timeString);
            currentDate.setHours(0, 0, 0, 0);

            // 收集日期数据用于悬浮列表
            const dateKey = currentDate.toISOString().split('T')[0];
            if (!dateMap.has(dateKey)) {
                dateMap.set(dateKey, {
                    element: item,
                    dateStr: timeString.split(' ')[0]
                });
            }

            // 原有日期比较逻辑
            if (index > 0 && !isSameDay(currentDate, previousDate)) {
                item.classList.add('new-day-separator');
            }
            previousDate = currentDate;
        });

        // ================= 新增悬浮列表功能 =================
        const dateList = document.createElement('div');
        dateList.id = 'date-floating-list';

        // 按日期排序(从新到旧)
        const sortedDates = [...dateMap.entries()].sort((a, b) => new Date(b[0]) - new Date(a[0]));

        sortedDates.forEach(([dateKey, data]) => {
            const dateItem = document.createElement('div');
            dateItem.className = 'date-item';
            dateItem.textContent = data.dateStr;

            dateItem.addEventListener('click', () => {
                data.element.scrollIntoView({
                    behavior: 'smooth',
                    block: 'start'
                });
                data.element.classList.add('highlight');
                setTimeout(() => data.element.classList.remove('highlight'), 1000);
            });

            dateList.appendChild(dateItem);
        });

        document.body.appendChild(dateList);

        // ================= 原有辅助函数 =================
        function isSameDay(date1, date2) {
            if (!date1 || !date2) return false;
            return (
                date1.getFullYear() === date2.getFullYear() &&
                date1.getMonth() === date2.getMonth() &&
                date1.getDate() === date2.getDate()
            );
        }
    }

    function addStyle(cssRules) {
        const styleId = 'ld246-user-chats-style'; // 定义一个固定的 id 标记

        // 如果存在上一次添加的 <style> 元素,则移除它
        const existingStyle = document.getElementById(styleId);
        if (existingStyle && existingStyle.parentNode) {
            existingStyle.parentNode.removeChild(existingStyle);
        }

        // 创建一个新的 <style> 元素
        const styleElement = document.createElement('style');
        styleElement.id = styleId; // 设置 id
        styleElement.type = 'text/css';

        // 将 CSS 规则写入 <style> 元素
        if (styleElement.styleSheet) {
            // 针对旧版 IE 浏览器
            styleElement.styleSheet.cssText = cssRules;
        } else {
            // 现代浏览器
            styleElement.appendChild(document.createTextNode(cssRules));
        }

        // 将 <style> 元素添加到 <head> 中
        document.head.appendChild(styleElement);
    }
})();

已封装为油猴脚本,访问地址 https://greasyfork.org/zh-CN/scripts/533009

国内镜像站 https://gf.qytechs.cn/zh-CN/scripts/533009

image.png

留下你的脚步
推荐阅读