您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds a column showing comic type (Manga/Manhwa/Manhua).
当前为
// ==UserScript== // @name Comick Comic Type Column // @namespace https://github.com/GooglyBlox // @version 1.0 // @description Adds a column showing comic type (Manga/Manhwa/Manhua). // @author GooglyBlox // @match https://comick.io/user/*/list* // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; let comicCountryMap = new Map(); let isProcessing = false; function extractUserIdFromUrl() { const urlParts = window.location.pathname.split('/'); const userIndex = urlParts.indexOf('user'); return userIndex !== -1 && userIndex + 1 < urlParts.length ? urlParts[userIndex + 1] : null; } async function fetchUserFollows(userId) { try { const response = await fetch(`https://api.comick.io/user/${userId}/follows`); if (!response.ok) throw new Error(`HTTP ${response.status}`); return await response.json(); } catch (error) { console.error('Failed to fetch user follows:', error); return []; } } function getComicTypeFromCountry(country) { switch (country) { case 'kr': case 'gb': return 'Manhwa'; case 'cn': return 'Manhua'; case 'jp': return 'Manga'; default: return 'Unknown'; } } function buildComicCountryMap(followsData) { comicCountryMap.clear(); followsData.forEach(item => { if (item.md_comics) { const comic = item.md_comics; const key = comic.slug || comic.title; if (key) { comicCountryMap.set(key, comic.country); } } }); } function addTypeColumnHeader() { const headerRow = document.querySelector('.flex.w-full.items-center.min-w-0:first-child'); if (!headerRow || headerRow.querySelector('[data-comic-type-header]')) return; const typeHeader = document.createElement('div'); typeHeader.className = 'text-center pl-3 flex items-center h-12 w-20 lg:w-24 font-semibold flex-none text-sm'; typeHeader.setAttribute('data-comic-type-header', 'true'); typeHeader.innerHTML = '<div class="w-full text-center">Type</div>'; const lastReadColumn = headerRow.children[headerRow.children.length - 3]; headerRow.insertBefore(typeHeader, lastReadColumn); } function addTypeColumnToRow(row) { if (row.querySelector('[data-comic-type-cell]')) return; const titleLink = row.querySelector('a[href*="/comic/"]'); if (!titleLink) return; const href = titleLink.getAttribute('href'); const slug = href.split('/comic/')[1]; const country = comicCountryMap.get(slug); const comicType = country ? getComicTypeFromCountry(country) : 'Unknown'; const typeCell = document.createElement('div'); typeCell.className = 'flex justify-center text-sm md:text-base w-20 lg:w-24 flex-none'; typeCell.setAttribute('data-comic-type-cell', 'true'); typeCell.innerHTML = `<div class="w-full text-center">${comicType}</div>`; const lastReadColumn = row.children[row.children.length - 3]; row.insertBefore(typeCell, lastReadColumn); } function processTable() { if (isProcessing) return; const rows = document.querySelectorAll('.flex.w-full.items-center.min-w-0'); if (rows.length === 0) return; addTypeColumnHeader(); rows.forEach((row, index) => { if (index === 0) return; addTypeColumnToRow(row); }); } async function initializeScript() { if (isProcessing) return; isProcessing = true; const userId = extractUserIdFromUrl(); if (!userId) { isProcessing = false; return; } const followsData = await fetchUserFollows(userId); buildComicCountryMap(followsData); processTable(); isProcessing = false; } function observeChanges() { const observer = new MutationObserver((mutations) => { const hasRelevantChanges = mutations.some(mutation => mutation.type === 'childList' && Array.from(mutation.addedNodes).some(node => node.nodeType === 1 && (node.matches && node.matches('.flex.w-full.items-center.min-w-0') || node.querySelector && node.querySelector('.flex.w-full.items-center.min-w-0')) ) ); if (hasRelevantChanges) { setTimeout(processTable, 100); } }); observer.observe(document.body, { childList: true, subtree: true }); } function handleNavigation() { let currentUrl = window.location.href; const checkForNavigation = () => { if (window.location.href !== currentUrl) { currentUrl = window.location.href; if (currentUrl.includes('/user/') && currentUrl.includes('/list')) { setTimeout(initializeScript, 500); } } }; setInterval(checkForNavigation, 1000); } setTimeout(initializeScript, 1000); observeChanges(); handleNavigation(); })();