// ==UserScript== // @name Ci-en Comment Mute // @name:en Ci-en Comment Mute // @namespace https://github.com/riyonasan/Cien-Comment-Mute // @version 1.2 // @description Ci-en(DLsite)で特定ユーザーのコメントを非表示にする // @description:en Hides comments from specific users on Ci-en(DLsite) // @match https://ci-en.dlsite.com/creator/*/article/* // @icon https://www.google.com/s2/favicons?sz=64&domain=ci-en.dlsite.com // @grant GM_setValue // @grant GM_getValue // @grant GM_listValues // @grant GM_deleteValue // @require https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/js/all.min.js // @license MIT // @downloadURL https://update.greasyfork.icu/scripts/549208/Ci-en%20Comment%20Mute.user.js // @updateURL https://update.greasyfork.icu/scripts/549208/Ci-en%20Comment%20Mute.meta.js // ==/UserScript== (function () { "use strict"; let cachedMuted = new Map(); // { id -> {id, name?} } let showMuted = false; function getMutedUsers() { return GM_listValues() .filter((k) => k.startsWith("mute_")) .map((k) => GM_getValue(k)); } function updateCache() { cachedMuted.clear(); getMutedUsers().forEach((entry) => { if (typeof entry === "string") { // 旧形式(idだけ) cachedMuted.set(entry, { id: entry }); } else if (entry && typeof entry === "object") { cachedMuted.set(entry.id, entry); } }); } function muteUser(id, name) { GM_setValue("mute_" + id, { id, name }); updateCache(); } function unmuteUser(id) { GM_deleteValue("mute_" + id); updateCache(); } // コメント処理 function processComment(li) { if (li.dataset.muteProcessed) return; li.dataset.muteProcessed = "1"; const userLink = li.querySelector("a[href*='/profile/']"); if (!userLink) return; const match = userLink.href.match(/\/profile\/(\d+)/); if (!match) return; const userId = match[1]; li.dataset.userid = userId; // ミュート済みなら非表示 if (cachedMuted.has(userId)) { li.dataset.muted = "1"; if (!showMuted) li.style.display = "none"; } // ミュートボタン追加 attachMuteBtnToLi(li, userId, userLink); } function scanComments() { const commentList = document.querySelector("#comment > div:nth-child(3) > div > ul"); if (!commentList) return; commentList.querySelectorAll("li").forEach(processComment); } function attachMuteBtnToLi(li, userId, userLink) { if (li.querySelector(".ci-mute-btn")) return; const btn = document.createElement("button"); btn.className = "ci-mute-btn"; btn.dataset.userid = userId; btn.title = "ミュート"; btn.style.marginLeft = "6px"; btn.style.border = "none"; btn.style.background = "transparent"; btn.style.cursor = "pointer"; btn.innerHTML = ''; btn.onclick = () => { const userName = userLink.textContent.trim(); muteUser(userId, userName); li.dataset.muted = "1"; if (!showMuted) li.style.display = "none"; renderPanel(); }; userLink.insertAdjacentElement("afterend", btn); } // ウィジェット作成 function buildWidget() { if (document.getElementById("ciMuteWidget")) return; const w = document.createElement("div"); w.id = "ciMuteWidget"; w.style.position = "fixed"; w.style.bottom = "10px"; w.style.right = "10px"; w.style.zIndex = "9999"; w.style.fontSize = "13px"; w.style.background = "#fff"; w.style.border = "1px solid #ccc"; w.style.padding = "6px"; w.style.boxShadow = "0 2px 6px rgba(0,0,0,0.2)"; w.innerHTML = `