漫画助手 Manga Assistant

移动端漫画收藏助手,按域名分组,底部可点翻页UI,支持全局导出导入。

目前為 2025-07-15 提交的版本,檢視 最新版本

// ==UserScript==
// @name         漫画助手 Manga Assistant
// @namespace    http://tampermonkey.net/
// @license MIT
// @version      3.0.0
// @description  移动端漫画收藏助手,按域名分组,底部可点翻页UI,支持全局导出导入。
// @author       おかゆ
// @match        *://*/*
// @grant        GM_registerMenuCommand
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @grant        GM_openInTab
// ==/UserScript==

(function() {
    'use strict';
    const domain = location.hostname;
    let allLists = {};
    let mangaList = [];
    let ui, itemsC, btns;

    function loadData() {
        allLists = GM_getValue('mangaLists', {});
        mangaList = allLists[domain] || [];
    }

    function saveData() {
        allLists[domain] = mangaList;
        GM_setValue('mangaLists', allLists);
    }

    function registerMenu() {
        loadData();
        const homepageDomain = GM_getValue('homepageDomain', '');
        const isHomepageDomain = (domain === homepageDomain);

        if (isHomepageDomain) {
            GM_registerMenuCommand('➕ 添加漫画', addCurrentManga);
            GM_registerMenuCommand('➖ 删除主页', deleteHomepage);
            GM_registerMenuCommand('📤 导出全部', exportAllData);
            GM_registerMenuCommand('📥 导入全部', importAllData);
            GM_registerMenuCommand('🔄 刷新', () => location.reload());
        } else {
            GM_registerMenuCommand('⚙️ 设置主页', setHomepage);
            GM_registerMenuCommand('🔄 刷新', () => location.reload());
        }
    }

    function deleteHomepage() {
        if (confirm("确定要删除当前主页设置吗?这将删除所有该域名下的漫画记录。")) {
            GM_deleteValue('homepageDomain');
            loadData();
            delete allLists[domain];
            GM_setValue('mangaLists', allLists);
            alert('主页设置及漫画记录已清除');
            if (ui && ui.parentNode) ui.parentNode.removeChild(ui);
            location.reload();
        }
    }

    function addCurrentManga() {
        loadData();
        let def = document.title.replace(/ -.*$/, '').slice(0, 16);
        let name = prompt('漫画名(最多18字符)', def);
        if (!name) return;
        mangaList.unshift({
            id: Date.now() + '',
            name: name.slice(0, 18),
            url: location.href,
            added: new Date().toISOString()
        });
        saveData();
        alert(`已添加: ${name}`);
        renderUI();
    }

    function setHomepage() {
        GM_setValue('homepageDomain', domain);
        alert(`主页域: ${domain}`);
        location.reload();
    }

    function exportAllData() {
        allLists = GM_getValue('mangaLists', {});
        if (!Object.keys(allLists).length) return alert('没有收藏数据');

        const b = new Blob([JSON.stringify(allLists, null, 2)], { type: 'application/json' });
        GM_openInTab(URL.createObjectURL(b));
    }

    function importAllData() {
        let txt = prompt('粘贴JSON(全局数据)');
        if (!txt) return;
        try {
            let a = JSON.parse(txt);
            if (typeof a !== 'object' || Array.isArray(a)) throw 0;

            GM_setValue('mangaLists', a);
            alert(`成功导入 ${Object.keys(a).length} 个域名的数据`);
            location.reload();
        } catch {
            alert('导入失败,格式错误');
        }
    }

    function renderUI() {
        const isHomepage = domain === GM_getValue('homepageDomain', '');
        if (!isHomepage) {
            if (ui && ui.parentNode) ui.parentNode.removeChild(ui);
            return;
        }

        loadData();

        if (!ui) {
            ui = document.createElement('div');
            ui.id = 'gm-ui';
            ui.style.cssText = 'position:fixed;bottom:0;left:0;right:0;height:50px;display:flex;align-items:center;background:#fff;border-top:1px solid #ccc;z-index:9999;font-family:sans-serif;';
            itemsC = document.createElement('div');
            itemsC.style.cssText = 'flex:1;overflow:hidden;white-space:nowrap;';
            ui.appendChild(itemsC);
            btns = document.createElement('div');
            ui.appendChild(btns);
            document.body.appendChild(ui);
        }

        itemsC.innerHTML = '';
        btns.innerHTML = '';

        if (mangaList.length === 0) {
            const emptyMsg = document.createElement('div');
            emptyMsg.textContent = '📭 暂无收藏漫画';
            emptyMsg.style.cssText = 'color:#999;font-size:14px;margin-left:10px;';
            itemsC.appendChild(emptyMsg);
            return;
        }

        mangaList.forEach((m, index) => {
            const itemDiv = document.createElement('div');
            itemDiv.style.cssText = 'display:inline-block;margin:0 6px;align-items:center;';

            const a = document.createElement('a');
            a.textContent = m.name;
            a.href = m.url;
            a.target = '_blank';
            a.style.cssText = 'font-size:14px;color:#06c;text-decoration:none;';
            itemDiv.appendChild(a);

            const renameBtn = document.createElement('button');
            renameBtn.textContent = '✏️';
            renameBtn.style.cssText = 'margin-left:4px;font-size:12px;border:none;background:none;cursor:pointer;';
            renameBtn.onclick = () => {
                const newName = prompt('输入新名称(最多18字符)', m.name);
                if (newName) {
                    const oldName = m.name;
                    mangaList[index].name = newName.slice(0, 18);
                    saveData();
                    alert(`"${oldName}" 改为 "${mangaList[index].name}"`);
                    renderUI();
                }
            };
            itemDiv.appendChild(renameBtn);

            const deleteBtn = document.createElement('button');
            deleteBtn.textContent = '❌';
            deleteBtn.style.cssText = 'margin-left:4px;font-size:12px;border:none;background:none;cursor:pointer;';
            deleteBtn.onclick = () => {
                if (confirm(`确定删除 "${m.name}" 吗?`)) {
                    mangaList.splice(index, 1);
                    saveData();
                    alert(`已删除 "${m.name}"`);
                    renderUI();
                }
            };
            itemDiv.appendChild(deleteBtn);

            itemsC.appendChild(itemDiv);
        });

        const l = document.createElement('button');
        l.textContent = '◀';
        l.style.cssText = 'font-size:20px;padding:8px 12px;margin-left:4px;';
        l.onclick = () => { itemsC.scrollBy({ left: -100, behavior: 'smooth' }) };

        const r = document.createElement('button');
        r.textContent = '▶';
        r.style.cssText = 'font-size:20px;padding:8px 12px;margin-left:4px;';
        r.onclick = () => { itemsC.scrollBy({ left: 100, behavior: 'smooth' }) };

        btns.appendChild(l);
        btns.appendChild(r);
    }

    loadData();
    registerMenu();
    renderUI();
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址