Mydealz User Profil Enhancer

Erweitert die Profilbuttons um zusätzliche Funktionen

当前为 2025-03-02 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name Mydealz User Profil Enhancer
// @namespace http://tampermonkey.net/
// @version 1.2
// @description Erweitert die Profilbuttons um zusätzliche Funktionen
// @author MD928835
// @license MIT
// @match https://www.mydealz.de/*
// @require https://update.greasyfork.org/scripts/528580/1545878/MyDealz%20Reactions%20Viewer%202025.js
// @grant GM_xmlhttpRequest
// ==/UserScript==

(function() {
    'use strict';

    // CSS zur sofortigen Ausblendung hinzufügen
    const style = document.createElement('style');
    style.textContent = `
      /* Originalen Button sofort ausblenden */
      .popover a.width--all-12.space--mt-2.button:not(.custom-button) {
        display: none !important;
      }

      /* Badges sofort ausblenden */
      .popover .flex.gap-1 {
        visibility: hidden !important;
      }

      /* Neue Buttons normal anzeigen */
      .popover .custom-buttons .button {
        display: flex !important;
      }
    `;
    document.head.appendChild(style);

    const observer = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
            const popover = document.querySelector('.popover--visible');
            if (popover) {
                setTimeout(() => modifyPopup(popover), 100);
            }
        });
    });

    async function modifyPopup(popover) {
        const profileBtn = popover.querySelector('a.width--all-12.space--mt-2.button');
        if (!profileBtn || popover.querySelector('.custom-buttons')) return;

        const username = profileBtn.href.split('/profile/')[1];
        const container = profileBtn.parentElement;
        container.classList.add('custom-buttons');

        // GraphQL Query für Online-Status und Beitrittsdatum
        const query = `query userProfile($username: String) {
            user(username: $username) {
                joinedAgo isOnline
            }
        }`;

        try {
            const response = await fetch('/graphql', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    query,
                    variables: {
                        username
                    }
                })
            });
            const data = await response.json();
            const {
                isOnline,
                joinedAgo
            } = data.data.user;

            // Mitgliedschaftsdauer aktualisieren
            const membershipElement = popover.querySelector('.overflow--wrap-off.size--all-s');
            if (membershipElement) {
                membershipElement.textContent = `Dabei seit ${joinedAgo}`;
            }

            // Zeitangabe von der Profilseite holen
            let lastActivityTime = 'unbekannt';
            try {
                const profileHtml = await fetch(`https://www.mydealz.de/profile/${username}`);
                const tempDiv = document.createElement('div');
                tempDiv.innerHTML = await profileHtml.text();
                const timeElement = tempDiv.querySelector('.userProfile-action-item .overflow--wrap-break .mute--text');
                if (timeElement) {
                    lastActivityTime = timeElement.textContent.trim();
                }
            } catch (error) {
                console.error('Fehler beim Abrufen der Profilseite:', error);
            }

            // Badge-Container durch Online-Status ersetzen
            const badgeContainer = popover.querySelector('.flex.gap-1');
            if (badgeContainer) {
                const statusContainer = document.createElement('div');
                // statusContainer.className = 'size--all-s color--text-TranslucentSecondary space--mt-2 space--mb-4';
                statusContainer.className = 'size--all-s space--mt-2 space--mb-4';
                const status = isOnline ? 'ON_line' : 'OFF_line';
                statusContainer.textContent = `${status}, zuletzt aktiv ${lastActivityTime}`;
                badgeContainer.replaceWith(statusContainer);
            }

            // Buttons Container erstellen
            const btnContainer = document.createElement('div');
            btnContainer.className = 'flex flex--grow-1 gap--all-2';
            btnContainer.style.gap = '5px';
            btnContainer.style.width = '100%';

            // Profil Button
            const profileButton = document.createElement('a');
            profileButton.href = `/profile/${username}`;
            profileButton.className = 'flex button button--shape-circle button--type-secondary button--mode-default';
            profileButton.style.flex = '1';
            profileButton.innerHTML = `<svg width="17" height="14" class="icon icon--mail"><use xlink:href="/assets/img/ico_632f5.svg#person"></use></svg><span class="space--ml-2"> Profil </span>`;

            // Nachricht Button
            const messageButton = document.createElement('button');
            messageButton.type = 'button';
            messageButton.className = 'flex button button--shape-circle button--type-secondary button--mode-default';
            messageButton.style.flex = '1';
            messageButton.innerHTML = `<svg width="17" height="14" class="icon icon--mail"><use xlink:href="/assets/img/ico_632f5.svg#mail"></use></svg><span class="space--ml-2"> Nachricht </span>`;

            messageButton.onclick = async () => {
                const username = document.querySelector('.popover--visible a[href^="/profile/"]')?.href.split('/profile/')[1];
                if (!username) return;

                try {
                    // GET-Request zur Prüfung des Inhalts
                    const response = await fetch(`/profile/messages/${username}`);
                    const html = await response.text();

                    // Prüfen, ob der Username im HTML vorkommt
                    const isSpecificMessagePage = html.includes(`<span class="size--all-l text--b space--mr-1">${username}</span>`);

                    if (isSpecificMessagePage) {
                        // Bei existierendem User direkt zur Nachrichtenseite
                        const win = window.open(`/profile/messages/${username}`, '_blank');

                        if (win) {
                            win.addEventListener('load', () => {
                                const observer = new MutationObserver((mutations, obs) => {
                                    const sendButton = win.document.querySelector('button[data-t="sendButton"]');
                                    if (sendButton) {
                                        sendButton.click();
                                        obs.disconnect();
                                    }
                                });

                                observer.observe(win.document.body, {
                                    childList: true,
                                    subtree: true
                                });

                                setTimeout(() => observer.disconnect(), 3000);
                            });
                        }
                    } else {
                        // Bei nicht-existierendem User zur Profilseite
                        const win = window.open(`/profile/${username}`, '_blank');

                        if (win) {
                            win.addEventListener('load', () => {
                                const observer = new MutationObserver((mutations, obs) => {
                                    const sendButton = win.document.querySelector('button[data-t="sendButton"]');
                                    if (sendButton) {
                                        sendButton.click();
                                        obs.disconnect();
                                    }
                                });

                                observer.observe(win.document.body, {
                                    childList: true,
                                    subtree: true
                                });

                                setTimeout(() => observer.disconnect(), 3000);
                            });
                        }
                    }
                } catch (error) {
                    console.error('Fehler beim Prüfen der Nachrichtenseite:', error);
                    window.open(`/profile/${username}`, '_blank');
                }
            };

            // Buttons hinzufügen
            btnContainer.appendChild(profileButton);
            btnContainer.appendChild(messageButton);

            // Alten Button ersetzen
            profileBtn.replaceWith(btnContainer);

            // Statistikbereich finden und "letzte anzeigen" Link hinzufügen
            setTimeout(() => {
                const kommentareElement = Array.from(popover.querySelectorAll('li.lbox--f.lbox--v-3 .size--all-s'))
                    .find(el => el.textContent.includes('Kommentare'));

                if (kommentareElement) {
                    // "letzte anzeigen" Link erstellen
                    const linkElement = document.createElement('span');
                    linkElement.className = 'showCommentsBtn';
                    linkElement.textContent = 'anzeigen';
                    linkElement.style.backgroundColor = '#e6f7e6';
                    linkElement.style.padding = '0 4px';
                    linkElement.style.borderRadius = '3px';
                    linkElement.style.cursor = 'pointer';
                    linkElement.style.marginLeft = '5px';
                    linkElement.style.fontSize = '14px';

                    // Funktionalität des ehemaligen Vote-Buttons übernehmen
                    linkElement.onclick = async () => {
                        const CONFIG = {
                            BATCH_SIZE: 5,
                            MAX_COMMENTS_PER_PAGE: 20
                        };

                        // Username aus dem PopUp holen
                        const p = document.querySelector('.popover--visible');
                        const username = p?.querySelector('a[href^="/profile/"]')?.getAttribute('href')?.split('/')[2];
                        if (!username) return;

                        // Progress Bar
                        const progress = document.createElement('div');
                        progress.style.cssText = 'position:fixed;top:0;left:0;height:3px;background:#4CAF50;z-index:9999;';
                        document.body.appendChild(progress);

                        try {
                            const response = await fetch(`https://www.mydealz.de/profile/${username}?page=1`);
                            if (!response.ok) throw new Error(`HTTP error! status:${response.status}`);
                            const html = await response.text();
                            const pattern = /href=https:\/\/www\.mydealz\.de\/.*?-(\d+)#(?:comment|reply)-(\d+)/g;
                            const matches_raw = [...html.matchAll(pattern)];

                            const tempDiv = document.createElement('div');
                            tempDiv.innerHTML = html;
                            const titles = [];
                            tempDiv.querySelectorAll('.userHtml').forEach(item => {
                                if (item.textContent.includes('kommentiert')) {
                                    const strongTag = item.querySelector('strong');
                                    if (strongTag) titles.push(strongTag.textContent);
                                }
                            });

                            const pageResults = [];
                            const commentPromises = matches_raw.map((match, index) =>
                                fetch("https://www.mydealz.de/graphql", {
                                    method: 'POST',
                                    headers: {
                                        'Content-Type': 'application/json'
                                    },
                                    body: JSON.stringify({
                                        query: 'query comment($id: ID!) { comment(id: $id) { preparedHtmlContent createdAt createdAtTs } }',
                                        variables: {
                                            id: match[2]
                                        }
                                    })
                                })
                                .then(res => res.json())
                                .then(data => {
                                    progress.style.width = `${(index / matches_raw.length) * 100}%`;
                                    if (!data?.data?.comment) return null;
                                    const comment = data.data.comment.preparedHtmlContent.replace(/<img[^>]*>/g, '');
                                    const date = new Date(data.data.comment.createdAtTs * 1000)
                                        .toLocaleString('de-DE', {
                                            day: '2-digit',
                                            month: '2-digit',
                                            year: '2-digit',
                                            hour: '2-digit',
                                            minute: '2-digit'
                                        })
                                        .replace(',', '');
                                    const result = {
                                        html: `<div class="comment-card" style="background-color:white;padding:1rem;margin:0.75rem 0;border-radius:8px;box-shadow:0 2px 4px rgba(0,0,0,0.1);"><span title="${date}">${data.data.comment.createdAt}</span> <b>${titles[index]}</b><br>${comment}<br><svg width="15px" height="16px" class="icon icon--comment" style="vertical-align: middle"><use xlink:href="/assets/img/ico_632f5.svg#comment"></use></svg> <a href='${match[0].replace('href=','')}'target='_blank'>Zum Kommentar</a></div>`,
                                        title: titles[index],
                                        comment: comment.replace(/<blockquote>.*?<\/blockquote>/g, ''),
                                        dealId: match[1],
                                        commentId: match[2]
                                    };
                                    pageResults.push(result);
                                    return result;
                                })
                                .catch(() => null)
                            );

                            await Promise.all(commentPromises);

                            const flatResults = pageResults.filter(r => r);
                            flatResults.sort((a, b) => b.commentId - a.commentId);

                            sessionStorage.setItem('mydealz_comments', JSON.stringify(flatResults));
                            let clipboardString = '$' + username + '$' + flatResults.map(r => `${r.title}|${r.comment}`).join('||').replace(/<[^>]*>/g, '').replace(/(\r\n|\n|\r)/gm, ' ').replace(/"/g, "'").trim();

                            const resultWindow = window.open("", "Results", "width=1000,height=700,location=no,menubar=no,toolbar=no,status=no,titlebar=no");
                            if (resultWindow) {
                                resultWindow.document.write(`<html><head><title>Schlechter Tag oder schlechter User?</title><script>function copyToClip(){navigator.clipboard.writeText(${JSON.stringify(clipboardString)}).then(()=>document.querySelector("button").textContent="Kopiert!").catch(e=>alert(e))}function sortComments(type){let comments=JSON.parse(sessionStorage.getItem('mydealz_comments'));if(type==='all'){comments.sort((a,b)=>b.commentId-a.commentId);}else{comments.sort((a,b)=>b.dealId===a.dealId?b.commentId-a.commentId:b.dealId-a.dealId);}document.getElementById('comments-container').innerHTML=comments.map(r=>r.html).join('');}</script></head><body style="margin:0;padding:0;background:#f5f5f5"><div style="background:#005293;height:56px;display:flex;align-items:center;color:white;font-size:24px;text-align:center"><img src="https://www.mydealz.de/assets/img/logo/default-light_d4b86.svg" style="height:40px;margin-left:20px"><div style="flex-grow:1;text-align:center"><a href="https://www.mydealz.de/profile/${username}" style="color:white;text-decoration:none" target="_blank">${username}s letzte ${flatResults.length} Kommentare</a></div></div><div style="text-align:center;padding:10px"><button style="padding:10px" onclick="copyToClip()">In Zwischenablage kopieren</button></div><div style="text-align:center;padding:10px">Kommentare sortieren nach <label><input type="radio" name="sort" checked onclick="sortComments('all')"> alle chronologisch</label> <label><input type="radio" name="sort" onclick="sortComments('deal')"> beitragschronologisch</label></div><div id="comments-container" style="margin:20px">${flatResults.map(r => r.html).join('')}</div></body></html>`);
                                resultWindow.document.close();
                                resultWindow.focus();
                            } else {
                                alert("Popup blockiert!");
                            }

                            progress.remove();
                        } catch (err) {
                            alert(`Fehler: ${err.message}`);
                            progress.remove();
                        }
                    };

                    // Link zum Kommentare-Element hinzufügen
                    kommentareElement.appendChild(document.createTextNode(' '));
                    kommentareElement.appendChild(linkElement);
                }
                const reactionsElement = Array.from(popover.querySelectorAll('li.lbox--f.lbox--v-3 .size--all-s'))
                    .find(el => el.textContent.includes('Reaktionen'));

                if (reactionsElement) {
                    const linkElement = document.createElement('span');
                    linkElement.className = 'showReactionsBtn';
                    linkElement.textContent = 'anzeigen';
                    linkElement.style.backgroundColor = '#e6f7e6';
                    linkElement.style.padding = '0 4px';
                    linkElement.style.borderRadius = '3px';
                    linkElement.style.cursor = 'pointer';
                    linkElement.style.marginLeft = '5px';
                    linkElement.style.fontSize = '14px';

                    linkElement.onclick = () => {
                        const p = document.querySelector('.popover--visible');
                        const username = p?.querySelector('a[href^="/profile/"]')?.getAttribute('href')?.split('/')[2];
                        if (!username) return;
                        viewReactions(username);
                    };

                    reactionsElement.appendChild(document.createTextNode(' '));
                    reactionsElement.appendChild(linkElement);
                }
            }, 500);
        } catch (error) {
            console.error('Fehler:', error);
        }
    }

    observer.observe(document.body, {
        childList: true,
        subtree: true,
        attributes: true,
        attributeFilter: ['class']
    });
})();