Greasy Fork

MyDealz Comment Viewer

Zeigt die letzten Kommentare eines Benutzers an

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.greasyfork.cloud/scripts/528796/1547271/MyDealz%20Comment%20Viewer.js

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

(function() {
    'use strict';
    
    // Globale Funktion definieren
    window.viewUserComments = async function(username) {
        const CONFIG = {
            BATCH_SIZE: 5,
            MAX_COMMENTS_PER_PAGE: 20
        };

        // 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);
                }
            });

            // Mutable und isMuted Status abfragen
            const query = `query userProfile($username: String) {
                user(username: $username) {
                    mutable isMuted
                }
            }`;
            
            const userDataResponse = await fetch('/graphql', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    query,
                    variables: { username }
                })
            });
            
            const userData = await userDataResponse.json();
            const { mutable, isMuted } = userData.data.user;

            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));

            // Kommentarfenster
            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>Schnorrer oder Nassauer?</title>
  <style>
    body { margin: 0; padding: 0; background: #f5f5f5; font-family: Arial, sans-serif; }
    .header { background: #005293; height: 56px; display: flex; align-items: center; justify-content: center; color: white; font-size: 24px; position: relative; }
    .logo { height: 40px; position: absolute; left: 20px; }
    .sort-options { text-align: center; padding: 10px; }
    .comments-container { margin: 20px; }
    .comment-card { background-color: white; padding: 1rem; margin: 0.75rem 0; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
    .mute-container { display: flex; justify-content: center; margin: 10px 0; }
    .mute-btn {
      display: inline-flex;
      align-items: center;
      padding: 8px 16px;
      border-radius: 4px;
      cursor: pointer;
      background-color: #fff;
      border: 1px solid #ccc;
      font-size: 14px;
      color: #666;
      box-shadow: 0 1px 3px rgba(0,0,0,0.1);
    }
    .mute-btn:hover {
      background-color: #f8f8f8;
    }
  </style>
  <script>
    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>
  <div class="header">
    <img src="https://www.mydealz.de/assets/img/logo/default-light_d4b86.svg" class="logo">
    <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 class="sort-options">
    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 class="mute-container">
    <button id="muteBtn" class="mute-btn" style="display: ${mutable ? 'inline-flex' : 'none'}">
      <svg width="20" height="20" class="icon" style="margin-right: 8px;">
        <use id="muteIcon" xlink:href="/assets/img/ico_632f5.svg#${isMuted ? 'mute' : 'unmute'}"></use>
      </svg>
      <span id="muteText">${username} ${isMuted ? 'nicht mehr stumm schalten' : 'stumm schalten'}</span>
    </button>
  </div>

  <div id="comments-container" class="comments-container">${flatResults.map(r => r.html).join('')}</div>

  <script>
    // Mute-Funktionalität
    let mutable = ${mutable};
    let isMuted = ${isMuted};
    const username = "${username}";
    const muteBtn = document.getElementById('muteBtn');
    const muteText = document.getElementById('muteText');
    const muteIcon = document.getElementById('muteIcon');

    muteBtn.addEventListener('click', function() {
      const endpoint = isMuted ? "/profile/" + username + "/unmute" : "/profile/" + username + "/mute";
      
      fetch(endpoint, {
        method: 'POST',
        headers: {
          'X-Request-Type': 'application/vnd.pepper.v1+json',
          'X-Requested-With': 'XMLHttpRequest',
          'X-Pepper-Txn': 'user.profile.overview',
          'X-XSRF-TOKEN': document.cookie.split('xsrf_t=')[1]?.split(';')[0]?.replace(/"/g, '')
        }
      })
      .then(response => response.json())
      .then(data => {
        if (data.status === 'success') {
          isMuted = !isMuted;
          muteText.textContent = username + ' ' + (isMuted ? 'nicht mehr stumm schalten' : 'stumm schalten');
          muteIcon.setAttribute('xlink:href', '/assets/img/ico_632f5.svg#' + (isMuted ? 'mute' : 'unmute'));
        }
      })
      .catch(error => console.error('Fehler:', error));
    });
  </script>
</body>
</html>`);
                resultWindow.document.close();
                resultWindow.focus();
            } else {
                alert("Popup blockiert!");
            }

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