Mutes downvoted items. Hide specific merchants
当前为
// ==UserScript==
// @name HUDK - UX tweaks
// @namespace http://tampermonkey.net/
// @version 0.2.1
// @description Mutes downvoted items. Hide specific merchants
// @author thedrunkendev
// @match https://www.hotukdeals.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=hotukdeals.com
// @run-at document-start
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
/* global waitForKeyElements */
(function() {
'use strict';
console.log("Injecting Userscript")
let hiddenMerchants = GM_getValue("gm_hiddenmerchants") || [];
console.log("Found hiddent merchants:", hiddenMerchants)
// Hide downvoted
waitForKeyElements(".vote-box > .bg--color-grey .icon--minus", (el) => {
console.log(el)
el.closest(".threadGrid").style.opacity = 0.5;
}, false, 1_000);
// Add a hide merchant button
waitForKeyElements("button.cept-off", (el) => {
const merchant = el.closest(".threadGrid").querySelector(".cept-merchant-name");
const merchantIsHidden = hiddenMerchants.includes(merchant?.innerText);
if (merchant && merchantIsHidden){
hideMerchant(el, merchant.innerText)
}
else{
insert(el);
}
}, false, 1_000);
function insert(el) {
var textEl = document.createElement("button")
textEl.innerText = "hide merchant";
textEl.className = el.className.replace("cept-off", "btn btn--mode-boxSec");
textEl.onclick = (clickedEl) => {
const merchant = el.closest(".threadGrid").querySelector(".cept-merchant-name").innerText;
hiddenMerchants.push(merchant);
GM_setValue("gm_hiddenmerchants", hiddenMerchants);
// Hide button & thread
clickedEl.target.style.display="none";
hideMerchant(clickedEl.target, merchant);
};
el.insertAdjacentElement("beforebegin", textEl);
}
function hideMerchant(el, merchantName){
const thread = el.closest(".threadGrid");
thread.style.opacity = 0.8;
thread.style.justifyContent="space-between";
thread.style.display="flex";
thread.innerHTML = `<div><span class="cept-merchant-name">${merchantName}</span> is hidden.</div>`;
var textEl = document.createElement("button")
textEl.innerText = "Undo";
textEl.className = el.className="btn btn--mode-boxSec";
textEl.onclick = (clickedEl) => {
const merchant = thread.querySelector(".cept-merchant-name").innerText;
hiddenMerchants=hiddenMerchants.filter(x=> x!=merchant);
console.log(hiddenMerchants)
GM_setValue("gm_hiddenmerchants", hiddenMerchants);
// Hide button & thread
clickedEl.target.style.display="none";
// TODO - show the deal?
};
thread.appendChild(textEl);
}
})();
/**
* A utility function for userscripts that detects and handles AJAXed content.
*
* Usage example:
*
* function callback(domElement) {
* domElement.innerHTML = "This text inserted by waitForKeyElements().";
* }
*
* waitForKeyElements("div.comments", callback);
* // or
* waitForKeyElements(selectorFunction, callback);
*
* @param {(string|function)} selectorOrFunction - The selector string or function.
* @param {function} callback - The callback function; takes a single DOM element as parameter.
* If returns true, element will be processed again on subsequent iterations.
* @param {boolean} [waitOnce=true] - Whether to stop after the first elements are found.
* @param {number} [interval=300] - The time (ms) to wait between iterations.
* @param {number} [maxIntervals=-1] - The max number of intervals to run (negative number for unlimited).
*/
function waitForKeyElements(selectorOrFunction, callback, waitOnce, interval, maxIntervals) {
if (typeof waitOnce === "undefined") {
waitOnce = true;
}
if (typeof interval === "undefined") {
interval = 300;
}
if (typeof maxIntervals === "undefined") {
maxIntervals = -1;
}
var targetNodes = (typeof selectorOrFunction === "function")
? selectorOrFunction()
: document.querySelectorAll(selectorOrFunction);
var targetsFound = targetNodes && targetNodes.length > 0;
if (targetsFound) {
targetNodes.forEach(function(targetNode) {
var attrAlreadyFound = "data-userscript-alreadyFound";
var alreadyFound = targetNode.getAttribute(attrAlreadyFound) || false;
if (!alreadyFound) {
var cancelFound = callback(targetNode);
if (cancelFound) {
targetsFound = false;
}
else {
targetNode.setAttribute(attrAlreadyFound, true);
}
}
});
}
if (maxIntervals !== 0 && !(targetsFound && waitOnce)) {
maxIntervals -= 1;
setTimeout(function() {
waitForKeyElements(selectorOrFunction, callback, waitOnce, interval, maxIntervals);
}, interval);
}
}