Greasy Fork

MyDealz Comment Viewer

Zeigt die letzten Kommentare eines Benutzers an

当前为 2025-05-10 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/528796/1586404/MyDealz%20Comment%20Viewer.js

// ==UserScript==
// @name MyDealz Comment Viewer
// @namespace http://tampermonkey.net/
// @version 2.3
// @description Zeigt die letzten Kommentare eines Benutzers an
// @author MD928835
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // Globale Funktion definieren
    window.viewUserComments = async function(username) {
        // SessionStorage für Kommentare leeren
        sessionStorage.removeItem('mydealz_comments');

        const fetchDealTitle = async (threadId) => {
            const query = `
                query getThread($filter: IDFilter!) {
                    thread(threadId: $filter) {
                        title
                    }
                }`;
            try {
                const response = await fetch("https://www.mydealz.de/graphql", {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        query,
                        variables: { filter: { eq: threadId } }
                    })
                });
                const result = await response.json();
                return result.data.thread.title || "Titel nicht verfügbar";
            } catch (error) {
                console.error(`Fehler beim Abrufen des Titels für threadId ${threadId}:`, error);
                return "Titel nicht verfügbar";
            }
        };

        try {
            // Profilseite abrufen
            const response = await fetch(`https://www.mydealz.de/profile/${username}?page=1`);
            if (!response.ok) throw new Error(`HTTP Fehler! Status: ${response.status}`);
            const html = await response.text();

            // Kommentar- und Thread-IDs extrahieren
            const pattern = /href=https:\/\/www\.mydealz\.de\/.*?-(\d+)#(?:comment|reply)-(\d+)/g;
            const matches_raw = [...html.matchAll(pattern)];
            const ids = matches_raw.map(match => ({
                threadId: match[1],
                commentId: match[2],
                url: match[0].replace('href=', '')
            }));

            // Parallelisierte Anfragen für Kommentare und Titel
            const fetchPromises = ids.map(async ({ threadId, commentId, url }) => {
                const commentQuery = `
                    query comment($id: ID!) {
                        comment(id: $id) {
                            preparedHtmlContent
                            createdAt
                            createdAtTs
                        }
                    }`;
                try {
                    const [commentResponse, title] = await Promise.all([
                        fetch("https://www.mydealz.de/graphql", {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json'
                            },
                            body: JSON.stringify({
                                query: commentQuery,
                                variables: { id: commentId }
                            })
                        }).then(res => res.json()),
                        fetchDealTitle(threadId)
                    ]);

                    const commentData = commentResponse?.data?.comment;
                    if (commentData) {
                        const comment = commentData.preparedHtmlContent.replace(/]*>/g, '');
                        const date = new Date(commentData.createdAtTs * 1000)
                            .toLocaleString('de-DE', {
                                day: '2-digit',
                                month: '2-digit',
                                year: '2-digit',
                                hour: '2-digit',
                                minute: '2-digit'
                            })
                            .replace(',', '');

                        return {
                            html: `<div class="comment-item">
                                <div class="comment-header">
                                    <a href="${url}" target="_blank" class="comment-title">${title}</a>
                                    <span class="comment-date">${date}</span>
                                </div>
                                <div class="comment-content">${comment}</div>
                                <div class="comment-footer">
                                    <a href="${url}" target="_blank" class="comment-link">Zum Kommentar</a>
                                </div>
                            </div>`,
                            date: commentData.createdAtTs
                        };
                    }
                    return null;
                } catch (error) {
                    console.error(`Fehler beim Abrufen des Kommentars ${commentId}:`, error);
                    return null;
                }
            });

            // Alle Kommentare abrufen und sortieren
            const comments = (await Promise.all(fetchPromises))
                .filter(Boolean)
                .sort((a, b) => b.date - a.date);

            // Popup erstellen und anzeigen
            const popup = document.createElement('div');
            popup.id = 'comment-popup';
            popup.style.cssText = `
                position: fixed;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                width: 80%;
                max-width: 800px;
                max-height: 80vh;
                background: white;
                border-radius: 8px;
                box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
                z-index: 10000;
                display: flex;
                flex-direction: column;
                overflow: hidden;
            `;

            // Header
            const header = document.createElement('div');
            header.className = 'bubble-button-background';
            header.style.cssText = `
                padding: 15px;
                background: #0277bd;
                color: white;
                font-weight: bold;
                display: flex;
                justify-content: space-between;
                align-items: center;
            `;
            header.innerHTML = `
                <span>Kommentare von ${username}</span>
                <button id="close-popup" style="background: none; border: none; color: white; cursor: pointer; font-size: 20px;">×</button>
            `;

            // Sortieroptionen
            const sortOptions = document.createElement('div');
            sortOptions.className = 'comment-sorting-options';
            sortOptions.style.cssText = `
                padding: 10px 15px;
                border-bottom: 1px solid #eee;
                display: flex;
                gap: 10px;
            `;
            sortOptions.innerHTML = `
                <span>Kommentare sortieren nach</span>
                <label>
                    <input type="radio" name="sort" value="all" checked> alle
                </label>
                <label>
                    <input type="radio" name="sort" value="chrono"> chronologisch
                </label>
                <label>
                    <input type="radio" name="sort" value="thread"> beitragschronologisch
                </label>
            `;

            // Kommentare Container
            const commentsContainer = document.createElement('div');
            commentsContainer.style.cssText = `
                padding: 15px;
                overflow-y: auto;
                flex-grow: 1;
            `;

            // Kommentare anzeigen
            commentsContainer.innerHTML = comments.map(comment => comment.html).join('<hr style="margin: 15px 0; border: 0; border-top: 1px solid #eee;">');

            // Komponenten zusammenfügen
            popup.appendChild(header);
            popup.appendChild(sortOptions);
            popup.appendChild(commentsContainer);
            document.body.appendChild(popup);

            // Event-Listener für Schließen-Button
            document.getElementById('close-popup').addEventListener('click', () => {
                document.body.removeChild(popup);
            });

            // Event-Listener für Sortierung
            const sortRadios = sortOptions.querySelectorAll('input[name="sort"]');
            sortRadios.forEach(radio => {
                radio.addEventListener('change', () => {
                    const sortValue = radio.value;
                    let sortedComments;

                    if (sortValue === 'chrono') {
                        sortedComments = [...comments].sort((a, b) => b.date - a.date);
                    } else if (sortValue === 'thread') {
                        // Hier müsste eine threadbasierte Sortierung implementiert werden
                        sortedComments = [...comments];
                    } else {
                        sortedComments = [...comments];
                    }

                    commentsContainer.innerHTML = sortedComments.map(comment => comment.html).join('<hr style="margin: 15px 0; border: 0; border-top: 1px solid #eee;">');
                });
            });

            // Schließen bei Klick außerhalb
            document.addEventListener('click', function closePopup(e) {
                if (!popup.contains(e.target) && e.target.id !== 'view-comments-btn') {
                    document.body.removeChild(popup);
                    document.removeEventListener('click', closePopup);
                }
            });

            // Escape-Taste zum Schließen
            document.addEventListener('keydown', function escapeClose(e) {
                if (e.key === 'Escape') {
                    document.body.removeChild(popup);
                    document.removeEventListener('keydown', escapeClose);
                }
            });

        } catch (error) {
            console.error('Fehler beim Abrufen der Kommentare:', error);
            alert('Fehler beim Abrufen der Kommentare: ' + error.message);
        }
    };

    // Button zu Benutzerprofilen hinzufügen
    const addViewCommentsButton = () => {
        const userProfileHeader = document.querySelector('.userProfile-header');
        if (userProfileHeader) {
            const username = window.location.pathname.split('/').pop();
            const buttonContainer = document.createElement('div');
            buttonContainer.style.marginTop = '10px';
            buttonContainer.innerHTML = `
                <button id="view-comments-btn" class="userProfile-actionButton" style="margin-right: 10px;">
                    Kommentare anzeigen
                </button>
            `;
            userProfileHeader.appendChild(buttonContainer);

            document.getElementById('view-comments-btn').addEventListener('click', (e) => {
                e.stopPropagation();
                viewUserComments(username);
            });
        }
    };

    // MutationObserver für dynamisch geladene Inhalte
    const observer = new MutationObserver((mutations) => {
        if (window.location.pathname.includes('/profile/')) {
            addViewCommentsButton();
            observer.disconnect();
        }
    });

    // Beobachtung starten
    observer.observe(document.body, { childList: true, subtree: true });

    // Initiale Prüfung
    if (window.location.pathname.includes('/profile/')) {
        addViewCommentsButton();
    }
})();