源码安装
1090197965 / 【云】XMXMKB关注作者管理

// ==UserScript==
// @name         【云】XMXMKB关注作者管理
// @namespace    http://tampermonkey.net/
// @version      1.5
// @description  为XMXMKB网站添加关注作者功能,可以管理关注的作者列表,显示每个作者的最新收藏内容,跟踪搜索时间和查看记录
// @author       AI
// @match        https://www.xmxmkb.com/search.php?mod=*
// @match        https://www.xmxmkb.com/forum.php?mod=viewthread&tid=*
// @grant        GM_setValue
// @grant        GM_getValue
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // 添加样式
    const style = document.createElement('style');
    style.textContent = `
        .follow-author-modal {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.5);
            z-index: 10000;
            display: none;
            justify-content: center;
            align-items: center;
        }

        .follow-author-content {
            background-color: white;
            border-radius: 8px;
            width: 90%;
            max-width: 800px;
            max-height: 80vh;
            overflow: hidden;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
        }

        .follow-author-header {
            background-color: #4caf50;
            color: white;
            padding: 15px 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .follow-author-title {
            font-size: 18px;
            font-weight: bold;
        }

        .follow-author-close {
            background: none;
            border: none;
            color: white;
            font-size: 24px;
            cursor: pointer;
            padding: 0;
            width: 30px;
            height: 30px;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .follow-author-close:hover {
            background-color: rgba(255, 255, 255, 0.2);
            border-radius: 50%;
        }

        .follow-author-add-section {
            padding: 15px 20px;
            border-bottom: 1px solid #eee;
            display: flex;
            gap: 10px;
            align-items: center;
        }

        .follow-author-input {
            flex: 1;
            padding: 8px 12px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 14px;
        }

        .follow-author-add-btn {
            background-color: #4caf50;
            color: white;
            border: none;
            padding: 8px 16px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
        }

        .follow-author-add-btn:hover {
            background-color: #45a049;
        }

        .follow-author-list {
            max-height: 400px;
            overflow-y: auto;
            padding: 0;
        }

        .follow-author-item {
            display: flex;
            align-items: flex-start;
            padding: 15px 20px;
            border-bottom: 1px solid #eee;
            transition: background-color 0.2s;
            gap: 15px;
        }

        .follow-author-item:hover {
            background-color: #f5f5f5;
        }

        .follow-author-item:last-child {
            border-bottom: none;
        }

        .follow-author-name {
            font-weight: bold;
            color: #333;
            cursor: pointer;
            min-width: 120px;
            display: flex;
            flex-direction: column;
            gap: 5px;
        }

        .follow-author-name:hover {
            color: #4caf50;
            text-decoration: underline;
        }

        .follow-author-content-wrapper {
            flex: 1;
            display: flex;
            gap: 15px;
            align-items: flex-start;
        }
        
        .follow-author-last-viewed {
            flex: 0 0 200px;
            display: flex;
            flex-direction: column;
            gap: 8px;
        }
        
        .follow-author-favorites {
            flex: 1;
            display: flex;
            gap: 10px;
            flex-wrap: wrap;
            max-width: 400px;
        }
        
        .follow-author-search-time {
            font-size: 11px;
            color: #999;
            font-weight: normal;
        }
        
        .follow-author-section-title {
            font-size: 12px;
            color: #666;
            font-weight: 500;
            margin-bottom: 5px;
        }

        .follow-author-favorite-item {
            background-color: #f0f0f0;
            padding: 8px;
            border-radius: 6px;
            font-size: 12px;
            color: #666;
            cursor: pointer;
            max-width: 180px;
            display: flex;
            flex-direction: column;
            gap: 6px;
            transition: all 0.2s;
        }
        
        .follow-author-last-viewed-item {
            background-color: #e3f2fd;
            padding: 8px;
            border-radius: 6px;
            font-size: 12px;
            color: #666;
            cursor: pointer;
            max-width: 200px;
            display: flex;
            flex-direction: column;
            gap: 6px;
            transition: all 0.2s;
            border: 1px solid #bbdefb;
        }
        
        .follow-author-last-viewed-item:hover {
            background-color: #d1c4e9;
            transform: translateY(-2px);
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
        }

        .follow-author-favorite-item:hover {
            background-color: #e0e0e0;
            transform: translateY(-2px);
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
        }

        .follow-author-favorite-title {
            font-weight: 500;
            color: #333;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            line-height: 1.3;
        }

        .follow-author-favorite-image {
            width: 100%;
            height: 80px;
            object-fit: cover;
            border-radius: 4px;
            background-color: #f5f5f5;
            border: 1px solid #eee;
        }

        .follow-author-favorite-time {
            font-size: 10px;
            color: #999;
            text-align: right;
        }

        .follow-author-unfollow {
            background-color: #f44336;
            color: white;
            border: none;
            padding: 4px 8px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 12px;
            margin-left: 10px;
        }

        .follow-author-unfollow:hover {
            background-color: #d32f2f;
        }

        .follow-author-empty {
            text-align: center;
            padding: 40px;
            color: #999;
            font-size: 14px;
        }

        .follow-author-stats {
            padding: 10px 20px;
            background-color: #f9f9f9;
            border-bottom: 1px solid #eee;
            font-size: 14px;
            color: #666;
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
        }

        @media (max-width: 600px) {
            .follow-author-content {
                width: 95%;
                margin: 10px;
            }
            
            .follow-author-add-section {
                flex-direction: column;
                gap: 8px;
            }
            
            .follow-author-add-btn {
                width: 100%;
            }
            
            .follow-author-stats {
                flex-direction: column;
                gap: 5px;
            }
            
            .follow-author-item {
                flex-direction: column;
                align-items: flex-start;
                gap: 10px;
            }
            
            .follow-author-content-wrapper {
                flex-direction: column;
                width: 100%;
            }
            
            .follow-author-last-viewed {
                flex: none;
                width: 100%;
            }
            
            .follow-author-name {
                min-width: auto;
                margin-right: 0;
            }
            
            .follow-author-favorites {
                width: 100%;
            }
        }
    `;
    document.head.appendChild(style);

    // 关注作者管理类
    class FollowAuthorManager {
        constructor() {
            this.followedAuthors = this.loadFollowedAuthors();
            this.init();
        }

        init() {
            this.createModal();
            this.bindEvents();
            console.log('关注作者管理器初始化完成');
        }

        // 从localStorage加载关注的作者列表
        loadFollowedAuthors() {
            try {
                const stored = localStorage.getItem('xmxmkb_followed_authors');
                const authors = stored ? JSON.parse(stored) : [];
                
                // 如果是旧格式(字符串数组),转换为新格式(对象数组)
                if (authors.length > 0 && typeof authors[0] === 'string') {
                    return authors.map(name => ({
                        name: name,
                        lastSearchTime: null,
                        lastViewedWork: null
                    }));
                }
                
                return authors;
            } catch (e) {
                console.error('加载关注作者列表失败:', e);
                return [];
            }
        }

        // 保存关注的作者列表到localStorage
        saveFollowedAuthors() {
            try {
                localStorage.setItem('xmxmkb_followed_authors', JSON.stringify(this.followedAuthors));
                console.log('关注作者列表已保存:', this.followedAuthors);
            } catch (e) {
                console.error('保存关注作者列表失败:', e);
            }
        }

        // 创建弹窗
        createModal() {
            this.modal = document.createElement('div');
            this.modal.className = 'follow-author-modal';
            this.modal.innerHTML = `
                <div class="follow-author-content">
                    <div class="follow-author-header">
                        <div class="follow-author-title">关注作者管理</div>
                        <button class="follow-author-close">×</button>
                    </div>
                    <div class="follow-author-stats">
                        <span>已关注作者: <strong id="followed-count">0</strong> 人</span>
                        <span style="margin-left: 20px;">收藏总数: <strong id="total-favorites">0</strong></span>
                        <span style="margin-left: 20px;">匹配收藏: <strong id="matched-favorites">0</strong></span>
                    </div>
                    <div class="follow-author-add-section">
                        <input type="text" class="follow-author-input" placeholder="输入作者名称" id="author-input">
                        <button class="follow-author-add-btn" id="add-author-btn">添加关注</button>
                        <button class="follow-author-add-btn" id="auto-extract-btn" style="background-color: #2196f3;">自动提取</button>
                        <button class="follow-author-add-btn" id="test-extract-btn" style="background-color: #ff9800; font-size: 12px;">测试提取</button>
                    </div>
                    <div class="follow-author-list" id="author-list">
                        <div class="follow-author-empty">暂无关注的作者</div>
                    </div>
                </div>
            `;
            document.body.appendChild(this.modal);
        }

        // 绑定事件
        bindEvents() {
            // 监听来自主脚本的事件
            document.addEventListener('followAuthorClick', () => {
                this.showModal();
            });

            // 关闭弹窗
            this.modal.querySelector('.follow-author-close').addEventListener('click', () => {
                this.hideModal();
            });

            // 点击背景关闭弹窗
            this.modal.addEventListener('click', (e) => {
                if (e.target === this.modal) {
                    this.hideModal();
                }
            });

            // 添加作者
            const addBtn = this.modal.querySelector('#add-author-btn');
            const authorInput = this.modal.querySelector('#author-input');
            const autoExtractBtn = this.modal.querySelector('#auto-extract-btn');
            
            addBtn.addEventListener('click', () => {
                this.addAuthor();
            });

            authorInput.addEventListener('keypress', (e) => {
                if (e.key === 'Enter') {
                    this.addAuthor();
                }
            });

            // 自动提取作者
            autoExtractBtn.addEventListener('click', () => {
                this.autoExtractAuthors();
            });

            // 测试提取功能
            const testExtractBtn = this.modal.querySelector('#test-extract-btn');
            testExtractBtn.addEventListener('click', () => {
                this.testExtractAuthors();
            });
        }

        // 显示弹窗
        showModal() {
            this.updateAuthorList();
            this.modal.style.display = 'flex';
        }

        // 隐藏弹窗
        hideModal() {
            this.modal.style.display = 'none';
        }

        // 添加关注作者
        addAuthor() {
            const input = this.modal.querySelector('#author-input');
            const authorName = input.value.trim();
            
            if (!authorName) {
                alert('请输入作者名称');
                return;
            }

            if (this.followedAuthors.some(author => 
                (typeof author === 'string' ? author : author.name).toLowerCase() === authorName.toLowerCase())) {
                alert('该作者已在关注列表中');
                return;
            }

            this.followedAuthors.push({
                name: authorName,
                lastSearchTime: null,
                lastViewedWork: null
            });
            this.saveFollowedAuthors();
            this.updateAuthorList();
            input.value = '';
        }

        // 取消关注作者
        unfollowAuthor(authorName) {
            const index = this.followedAuthors.findIndex(author => 
                (typeof author === 'string' ? author : author.name) === authorName);
            if (index > -1) {
                this.followedAuthors.splice(index, 1);
                this.saveFollowedAuthors();
                this.updateAuthorList();
            }
        }

        // 测试提取功能(仅显示结果,不添加)
        testExtractAuthors() {
            const favorites = this.getFavoritesData();
            if (favorites.length === 0) {
                alert('当前没有收藏数据');
                return;
            }

            const extractResults = [];
            favorites.slice(0, 10).forEach((fav, index) => {
                const author = this.extractAuthorFromTitle(fav.title);
                extractResults.push(`${index + 1}. "${fav.title}" → 作者: ${author || '无法提取'}`);
            });

            const message = `提取测试结果(前10条):\n\n${extractResults.join('\n')}\n\n这只是测试,未实际添加作者。`;
            alert(message);
        }

        // 自动从收藏中提取作者
        autoExtractAuthors() {
            const favorites = this.getFavoritesData();
            if (favorites.length === 0) {
                alert('当前没有收藏数据');
                return;
            }

            const extractedAuthors = new Set();
            let extractedCount = 0;

            favorites.forEach(fav => {
                const author = this.extractAuthorFromTitle(fav.title);
                if (author && !this.followedAuthors.some(followedAuthor => 
                    (typeof followedAuthor === 'string' ? followedAuthor : followedAuthor.name).toLowerCase() === author.toLowerCase())) {
                    extractedAuthors.add(author);
                    extractedCount++;
                }
            });

            if (extractedCount === 0) {
                alert('没有找到新的作者,可能已经全部关注或标题格式不支持自动提取');
                return;
            }

            const authorsArray = Array.from(extractedAuthors);
            const message = `找到 ${extractedCount} 个新作者:\n${authorsArray.slice(0, 10).join(', ')}${authorsArray.length > 10 ? '\n...' : ''}\n\n是否全部添加到关注列表?`;
            
            if (confirm(message)) {
                authorsArray.forEach(author => {
                    this.followedAuthors.push({
                        name: author,
                        lastSearchTime: null,
                        lastViewedWork: null
                    });
                });
                this.saveFollowedAuthors();
                this.updateAuthorList();
                alert(`成功添加 ${extractedCount} 个作者到关注列表`);
            }
        }

        // 从收藏数据中提取作者名称
        extractAuthorFromTitle(title) {
            // 格式7: 作者名_标题 或 作者名 标题(空格分隔)
            let match = title.match(/^([^_\s\[\]【】()()]+)[_\s]+/);
            if (match && match[1].length >= 2 && match[1].length <= 20) {
                return match[1].trim();
            }
            
            return null;
        }

        // 获取收藏数据
        getFavoritesData() {
            try {
                // 优先从localStorage获取(与主脚本保持一致)
                const stored = localStorage.getItem('xmxmkb_favorites');
                if (stored) {
                    const data = JSON.parse(stored);
                    console.log(`获取到 ${data.length} 条收藏数据`);
                    return data;
                }
                
                // 备用:尝试从GM_getValue获取
                if (typeof GM_getValue !== 'undefined') {
                    const data = GM_getValue('favorites', '[]');
                    return JSON.parse(data);
                }
                
                return [];
            } catch (e) {
                console.error('获取收藏数据失败:', e);
                return [];
            }
        }

        // 获取预加载数据
        getPreloadedData() {
            try {
                const stored = localStorage.getItem('fubiji_preloaded_images');
                if (stored) {
                    const data = JSON.parse(stored);
                    console.log(`获取到预加载数据,包含 ${Object.keys(data).length} 个URL`);
                    return data;
                }
                return {};
            } catch (e) {
                console.error('获取预加载数据失败:', e);
                return {};
            }
        }

        // 从预加载数据中获取作者的最近访问记录
        getAuthorRecentViews(authorName) {
            const preloadedData = this.getPreloadedData();
            const authorViews = [];
            
            Object.entries(preloadedData).forEach(([url, data]) => {
                if (data.title && data.loaded) {
                    // 简化匹配逻辑:只要标题中包含作者名称即可
                    if (data.title.toLowerCase().includes(authorName.toLowerCase())) {
                        authorViews.push({
                            title: data.title,
                            url: url,
                            timestamp: data.timestamp,
                            images: data.images || [],
                            firstImage: (data.images && data.images.length > 0) ? data.images[0] : null
                        });
                    }
                }
            });
            
            // 按时间戳降序排序,取最新的一条
            return authorViews
                .sort((a, b) => (b.timestamp || 0) - (a.timestamp || 0))
                .slice(0, 1);
        }

        // 获取指定作者的收藏数据(最新2条)
        getAuthorFavorites(authorName) {
            const favorites = this.getFavoritesData();
            const authorFavorites = favorites.filter(fav => {
                // 简化匹配逻辑:只要标题中包含作者名称即可
                return fav.title && fav.title.toLowerCase().includes(authorName.toLowerCase());
            });
            
            // 按时间戳降序排序,取最新2条
            return authorFavorites
                .sort((a, b) => (b.timestamp || 0) - (a.timestamp || 0))
                .slice(0, 2);
        }
        
        // 更新作者搜索时间
        updateAuthorSearchTime(authorName) {
            const author = this.followedAuthors.find(a => 
                (typeof a === 'string' ? a : a.name) === authorName);
            if (author && typeof author === 'object') {
                author.lastSearchTime = Date.now();
                this.saveFollowedAuthors();
            }
        }
        
        // 记录最后查看的作品
        recordLastViewedWork(authorName, workTitle, workUrl) {
            const author = this.followedAuthors.find(a => 
                (typeof a === 'string' ? a : a.name) === authorName);
            if (author && typeof author === 'object') {
                author.lastViewedWork = {
                    title: workTitle,
                    url: workUrl,
                    timestamp: Date.now()
                };
                this.saveFollowedAuthors();
            }
        }

        // 更新作者列表显示
        updateAuthorList() {
            const listContainer = this.modal.querySelector('#author-list');
            const countElement = this.modal.querySelector('#followed-count');
            const totalFavoritesElement = this.modal.querySelector('#total-favorites');
            const matchedFavoritesElement = this.modal.querySelector('#matched-favorites');
            
            const favorites = this.getFavoritesData();
            let matchedCount = 0;
            
            countElement.textContent = this.followedAuthors.length;
            totalFavoritesElement.textContent = favorites.length;

            if (this.followedAuthors.length === 0) {
                listContainer.innerHTML = '<div class="follow-author-empty">暂无关注的作者<br><small style="color: #999; margin-top: 10px; display: block;">可以手动添加作者名称,或点击"自动提取"从现有收藏中提取作者</small></div>';
                matchedFavoritesElement.textContent = 0;
                return;
            }

            listContainer.innerHTML = '';
            
            this.followedAuthors.forEach(authorData => {
                const authorName = typeof authorData === 'string' ? authorData : authorData.name;
                const authorObj = typeof authorData === 'object' ? authorData : { name: authorData, lastSearchTime: null, lastViewedWork: null };
                const authorFavorites = this.getAuthorFavorites(authorName);
                matchedCount += authorFavorites.length;
                const item = document.createElement('div');
                item.className = 'follow-author-item';
                
                const nameElement = document.createElement('div');
                nameElement.className = 'follow-author-name';
                
                const nameText = document.createElement('div');
                nameText.textContent = authorName;
                nameText.style.cursor = 'pointer';
                nameText.title = `点击搜索 ${authorName} 的作品`;
                nameText.addEventListener('click', () => {
                    this.searchAuthor(authorName);
                    this.updateAuthorSearchTime(authorName);
                });
                nameElement.appendChild(nameText);
                
                // 显示最近搜索时间
                if (authorObj.lastSearchTime) {
                    const searchTimeElement = document.createElement('div');
                    searchTimeElement.className = 'follow-author-search-time';
                    searchTimeElement.textContent = `搜索: ${this.formatTime(authorObj.lastSearchTime)}`;
                    nameElement.appendChild(searchTimeElement);
                }
                
                // 创建内容包装器
                const contentWrapper = document.createElement('div');
                contentWrapper.className = 'follow-author-content-wrapper';
                
                // 最后查看的作品(左边)- 优先从预加载数据获取
                const lastViewedContainer = document.createElement('div');
                lastViewedContainer.className = 'follow-author-last-viewed';
                
                const lastViewedTitle = document.createElement('div');
                lastViewedTitle.className = 'follow-author-section-title';
                lastViewedTitle.textContent = '最后查看';
                lastViewedContainer.appendChild(lastViewedTitle);
                
                // 优先从预加载数据获取最近访问记录
                const recentViews = this.getAuthorRecentViews(authorName);
                let lastViewedWork = null;
                
                if (recentViews.length > 0) {
                    lastViewedWork = recentViews[0];
                } else if (authorObj.lastViewedWork) {
                    lastViewedWork = authorObj.lastViewedWork;
                }
                
                if (lastViewedWork) {
                    const viewedItem = document.createElement('div');
                    viewedItem.className = 'follow-author-last-viewed-item';
                    viewedItem.title = lastViewedWork.title;
                    
                    const titleElement = document.createElement('div');
                    titleElement.className = 'follow-author-favorite-title';
                    titleElement.textContent = lastViewedWork.title;
                    viewedItem.appendChild(titleElement);
                    
                    // 添加图片显示(如果有的话)
                    if (lastViewedWork.firstImage || (lastViewedWork.images && lastViewedWork.images.length > 0)) {
                        const imageElement = document.createElement('img');
                        imageElement.className = 'follow-author-favorite-image';
                        imageElement.src = lastViewedWork.firstImage || lastViewedWork.images[0];
                        imageElement.alt = lastViewedWork.title;
                        imageElement.loading = 'lazy';
                        imageElement.onerror = function() {
                            this.style.display = 'none';
                        };
                        viewedItem.appendChild(imageElement);
                    }
                    
                    const timeElement = document.createElement('div');
                    timeElement.className = 'follow-author-favorite-time';
                    timeElement.textContent = this.formatTime(lastViewedWork.timestamp);
                    viewedItem.appendChild(timeElement);
                    
                    viewedItem.addEventListener('click', () => {
                        window.open(lastViewedWork.url, '_blank');
                    });
                    lastViewedContainer.appendChild(viewedItem);
                } else {
                    const emptyText = document.createElement('span');
                    emptyText.textContent = '暂无记录';
                    emptyText.style.color = '#999';
                    emptyText.style.fontSize = '12px';
                    lastViewedContainer.appendChild(emptyText);
                }
                
                // 最新收藏(右边)
                const favoritesContainer = document.createElement('div');
                favoritesContainer.className = 'follow-author-favorites';
                
                const favoritesTitle = document.createElement('div');
                favoritesTitle.className = 'follow-author-section-title';
                favoritesTitle.textContent = '最新收藏';
                favoritesTitle.style.width = '100%';
                favoritesContainer.appendChild(favoritesTitle);
                
                const favoritesWrapper = document.createElement('div');
                favoritesWrapper.style.display = 'flex';
                favoritesWrapper.style.gap = '10px';
                favoritesWrapper.style.flexWrap = 'wrap';
                favoritesWrapper.style.width = '100%';
                
                if (authorFavorites.length === 0) {
                    const emptyText = document.createElement('span');
                    emptyText.textContent = '暂无收藏';
                    emptyText.style.color = '#999';
                    emptyText.style.fontSize = '12px';
                    favoritesWrapper.appendChild(emptyText);
                } else {
                    authorFavorites.forEach(fav => {
                        const favItem = document.createElement('div');
                        favItem.className = 'follow-author-favorite-item';
                        favItem.title = fav.title;
                        
                        // 标题元素
                        const titleElement = document.createElement('div');
                        titleElement.className = 'follow-author-favorite-title';
                        titleElement.textContent = fav.title;
                        favItem.appendChild(titleElement);
                        
                        // 图片元素(优先显示收藏数据中的图片)
                        let imageToShow = null;
                        if (fav.firstImage) {
                            imageToShow = fav.firstImage;
                        } else if (fav.images && fav.images.length > 0) {
                            imageToShow = fav.images[0];
                        }
                        
                        if (imageToShow) {
                            const imageElement = document.createElement('img');
                            imageElement.className = 'follow-author-favorite-image';
                            imageElement.src = imageToShow;
                            imageElement.alt = fav.title;
                            imageElement.loading = 'lazy';
                            imageElement.onerror = function() {
                                this.style.display = 'none';
                            };
                            favItem.appendChild(imageElement);
                        }
                        
                        // 时间元素
                        if (fav.timestamp) {
                            const timeElement = document.createElement('div');
                            timeElement.className = 'follow-author-favorite-time';
                            timeElement.textContent = this.formatTime(fav.timestamp);
                            favItem.appendChild(timeElement);
                        }
                        
                        favItem.addEventListener('click', () => {
                            window.open(fav.url, '_blank');
                        });
                        favoritesWrapper.appendChild(favItem);
                    });
                }
                favoritesContainer.appendChild(favoritesWrapper);

                contentWrapper.appendChild(lastViewedContainer);
                contentWrapper.appendChild(favoritesContainer);
                
                const unfollowBtn = document.createElement('button');
                unfollowBtn.className = 'follow-author-unfollow';
                unfollowBtn.textContent = '取消关注';
                unfollowBtn.addEventListener('click', (e) => {
                    e.stopPropagation();
                    if (confirm(`确定要取消关注 ${authorName} 吗?`)) {
                        this.unfollowAuthor(authorName);
                    }
                });

                item.appendChild(nameElement);
                item.appendChild(contentWrapper);
                item.appendChild(unfollowBtn);
                listContainer.appendChild(item);
            });
            
            matchedFavoritesElement.textContent = matchedCount;
        }

        // 格式化时间戳
        formatTime(timestamp) {
            if (!timestamp) return '';
            
            const date = new Date(timestamp);
            const now = new Date();
            const diff = now - date;
            
            // 小于1分钟
            if (diff < 60000) {
                return '刚刚';
            }
            
            // 小于1小时
            if (diff < 3600000) {
                return `${Math.floor(diff / 60000)}分钟前`;
            }
            
            // 小于1天
            if (diff < 86400000) {
                return `${Math.floor(diff / 3600000)}小时前`;
            }
            
            // 小于7天
            if (diff < 604800000) {
                return `${Math.floor(diff / 86400000)}天前`;
            }
            
            // 超过7天显示具体日期
            return date.toLocaleDateString('zh-CN', {
                month: 'short',
                day: 'numeric'
            });
        }

        // 搜索作者
        searchAuthor(authorName) {
            const searchUrl = `https://www.xmxmkb.com/search.php?mod=forum&searchid=85&orderby=lastpost&ascdesc=desc&searchsubmit=yes&kw=${encodeURIComponent(authorName)}`;
            window.open(searchUrl, '_blank');
        }
        
        // 对外暴露的方法,供其他脚本调用
        recordAuthorView(authorName, workTitle, workUrl) {
            this.recordLastViewedWork(authorName, workTitle, workUrl);
            console.log(`记录作者 ${authorName} 的查看记录:`, workTitle);
        }
        
        // 获取关注的作者列表(供其他脚本使用)
        getFollowedAuthorNames() {
            return this.followedAuthors.map(author => 
                typeof author === 'string' ? author : author.name
            );
        }
    }

    // 全局实例
    let followAuthorManagerInstance = null;

    // 等待页面加载完成后初始化
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => {
            followAuthorManagerInstance = new FollowAuthorManager();
            // 将实例暴露到全局,供其他脚本使用
            window.followAuthorManager = followAuthorManagerInstance;
        });
    } else {
        followAuthorManagerInstance = new FollowAuthorManager();
        window.followAuthorManager = followAuthorManagerInstance;
    }

    console.log('关注作者管理脚本已加载');
})();