您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Färbt den Dealbilderhintergrund anhand der erfolgten Updates ein
// ==UserScript== // @name mydealz Deal Update Indicator // @namespace http://tampermonkey.net/ // @version 1.0 // @description Färbt den Dealbilderhintergrund anhand der erfolgten Updates ein // @author MD928835 // @license MIT // @match https://www.mydealz.de/profile/*/deals* // @grant GM_xmlhttpRequest // ==/UserScript== (function() { 'use strict'; // GraphQL query to fetch thread updates const UPDATE_QUERY = `query getThread($filter: IDFilter!) { thread(threadId: $filter) { threadUpdates { createdAt } } }`; // Function to fetch updates for a thread async function fetchThreadUpdates(threadId) { return new Promise((resolve) => { GM_xmlhttpRequest({ method: 'POST', url: 'https://www.mydealz.de/graphql', headers: { 'Content-Type': 'application/json' }, data: JSON.stringify({ query: UPDATE_QUERY, variables: { filter: { eq: threadId } } }), onload: function(response) { try { const result = JSON.parse(response.responseText); resolve(result.data?.thread?.threadUpdates || []); } catch (e) { console.error('Error parsing response', e); resolve([]); } }, onerror: function(error) { console.error('Error fetching updates', error); resolve([]); } }); }); } // Format date for display function formatUpdateDate(timestamp) { const date = new Date(timestamp * 1000); return date.toLocaleDateString('de-DE') + ' ' + date.toLocaleTimeString('de-DE', {hour: '2-digit', minute: '2-digit'}); } // Process each thread card async function processCard(card) { const article = card.closest('article'); if (!article) return; const threadIdMatch = article.id.match(/thread_(\d+)/); if (!threadIdMatch) return; const threadId = threadIdMatch[1]; const imageContainer = card.querySelector('.threadListCard-image'); if (!imageContainer) return; // Fetch updates for this thread const updates = await fetchThreadUpdates(threadId); const updateCount = updates.length; // Sort updates by date (newest first) const sortedUpdates = [...updates].sort((a, b) => b.createdAt - a.createdAt); // Remove existing classes imageContainer.classList.remove( 'update-0', 'update-1', 'update-2', 'update-3' ); // Add appropriate class based on update count if (updateCount > 0 && updateCount <= 3) { imageContainer.classList.add(`update-${updateCount}`); // Add tooltip with update dates if (updateCount > 0) { const tooltipText = sortedUpdates.map(update => formatUpdateDate(update.createdAt) ).join('\n'); imageContainer.setAttribute('title', `Updates:\n${tooltipText}`); } } } // Add CSS styles const style = document.createElement('style'); style.textContent = ` .threadListCard-image.update-1 { background-color: #e8f5e9 !important; /* Light green */ } .threadListCard-image.update-2 { background-color: #fff9c4 !important; /* Light yellow */ } .threadListCard-image.update-3 { background-color: #ffcdd2 !important; /* Light red */ } .threadListCard-image[title] { cursor: help; } `; document.head.appendChild(style); // Process all cards on page load async function processAllCards() { const cards = document.querySelectorAll('.threadListCard'); for (const card of cards) { await processCard(card); } } // Run initially processAllCards(); // Observe DOM changes for dynamic content const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { mutation.addedNodes.forEach((node) => { if (node.nodeType === 1) { // Element node const cards = node.querySelectorAll ? node.querySelectorAll('.threadListCard') : []; cards.forEach(processCard); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })();