MyDealz Price and Savings Highlighter with Tooltips and Keyword Exclusion

in den Einstellungen kannst du festlegen was du angezeigt haben möchtest

// ==UserScript==
// @name         MyDealz Price and Savings Highlighter with Tooltips and Keyword Exclusion
// @namespace    http://tampermonkey.net/
// @version      1.0-2024.01.08
// @description  in den Einstellungen kannst du festlegen was du angezeigt haben möchtest
// @author       Moritz
// @license MIT
// @match        https://www.mydealz.de/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=mydealz.de
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
// Konfiguration der Skripteinstellungen

    const Geizfaktor = 6; // Hier trägst du die Mindestersparniss ein die du haben möchtest, alle deals darunter kannst du entweder einfärben oder mit Geizfaktorvisible ganz ausblenden
    const Geizfaktorghost = '0.5'; // hier kannst du einstellen wie "durchsichtig" eingefäbt wird. 0.2 - 0.5 sind hier brauchbare werte
    const Geizfaktorvisible ='yes'; // 'yes' oder 'none' --> bei none werden deals unterhalb des Geizfaktor ausgeblendet

    const Maximalpreis = 160; // Maximal akzeptierter Preis für Deals
    const Maximalpreisghost = '0.5'; //hier kannst du einstellen wie "durchsichtig" eingefäbt wird. 0.2 - 0.5 sind hier brauchbare werte
    const Maximalpreisvisible ='yes'; // 'yes' oder 'none' --> bei none werden deals überhalb des Maximalpreis ausgeblendet

    //const Hotness = 50; // Mindest-Hotness-Wert
    const Hotnessghost = '0.5'; // hier kannst du einstellen wie "durchsichtig" eingefäbt wird. 0.2 - 0.5 sind hier brauchbare werte
    const Hotnessvisible ='yes'; // 'yes' oder 'none' --> bei none werden deals unterhalb einer Hotness ausgeblendet

    const excludeWords = ['Amazon', 'Film', 'Ps4', 'PlayStation', 'Xbox']; // Wörter, aus dem Titel die ausgeschlossen werden sollen
   // const excludeMerchant =['Amazon', 'dm', 'ebay']; // Händler, die ausgeschlossen werden sollen

    // Ende der Einstellungen

    // Konvertiert Preis-Strings in numerische Werte
    function convertPriceToNumber(priceString) {
        let numberString = priceString.replace('€', '').trim();
        numberString = numberString.replace(/\./g, '').replace(',', '.');
        return parseFloat(numberString);
    }
    // Überprüft, ob ein Artikel basierend auf dem Titel ausgeschlossen werden soll
    function shouldExcludeArticle(article) {
        const titleElement = article.querySelector('.thread-title');
        if (titleElement) {
            return excludeWords.some(word => titleElement.textContent.toLowerCase().includes(word.toLowerCase()));
        }
        return false;
    }
    // Hauptfunktion zur Hervorhebung und ggf. Ausblendung von Artikeln exclude words
    function highlightDeals(article) {
        if (shouldExcludeArticle(article)) {
            article.style.display = 'none'; // Artikel ausblenden
            return;
        }
    // Elemente für Originalpreis, reduzierten Preis und Warm-Vote finden
        const originalPriceElement = article.querySelector('.mute--text.text--lineThrough');
        const reducedPriceElement = article.querySelector('.thread-price');
        const warmVoteElement = article.querySelector('.vote-temp--warm'); // könnte man in Zukunft mal abändern das die Temperatur als wert erfasst wird...

        if (warmVoteElement) {
            article.style = `background-color: rgba(0, 0, 255, 0.1); opacity: ${Hotnessghost};`;
            article.title = 'Nur "warm" gevoted';
            article.style.display = `${Hotnessvisible}`; // Artikel ausblenden über konstanten

        } else if (originalPriceElement && reducedPriceElement) {
            const originalPrice = convertPriceToNumber(originalPriceElement.textContent);
            const reducedPrice = convertPriceToNumber(reducedPriceElement.textContent);
            const savings = originalPrice - reducedPrice;

            if (savings < Geizfaktor) {
                article.style = `background-color: rgba(255, 121, 0, 0.2); opacity: ${Geizfaktorghost};`;
                article.title = `Ersparniss ist weniger als ${Geizfaktor}€`;
                article.style.display = `${Geizfaktorvisible}`; // Artikel ausblenden über konstanten
            }
        }

        if (reducedPriceElement && !warmVoteElement) {
            const priceValue = convertPriceToNumber(reducedPriceElement.textContent);
            if (priceValue > Maximalpreis) {
                article.style = `background-color: rgba(255, 34, 34, 0.1); opacity: ${Maximalpreisghost};`;
                article.title = `Preis ist über Limit von ${Maximalpreis}€`;
               article.style.display = `${Maximalpreisvisible}`; // Artikel ausblenden über konstanten
            }
        }
    }
// Verarbeitet alle Artikel auf der Seite
    function processArticles() {
        const articles = document.querySelectorAll('article');
        articles.forEach(highlightDeals);
    }
// MutationObserver zur Überwachung von Änderungen im DOM und Ausführung von processArticles bei Änderungen
    const observer = new MutationObserver(mutations => {
        mutations.forEach(mutation => {
            if (mutation.addedNodes && mutation.addedNodes.length > 0) {
                processArticles();
            }
        });
    });
// Konfiguration und Start des MutationObservers
    const config = { childList: true, subtree: true };
    observer.observe(document.body, config);

// Erstmalige Ausführung von processArticles
    processArticles();
})();