- // ==UserScript==
- // @name Mydealz User Profil Enhancer
- // @namespace http://tampermonkey.net/
- // @version 1.1
- // @description Erweitert die Profilbuttons um zusätzliche Funktionen
- // @author MD928835
- // @license MIT
- // @match https://www.mydealz.de/*
- // @require https://update.gf.qytechs.cn/scripts/528391/1544983/MyDealz%20Reactions%20Viewer.js
- // @grant GM_xmlhttpRequest
- // ==/UserScript==
-
- (function() {
- 'use strict';
-
- 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 ? 'ONline' : 'OFFline';
- 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 (ehemals PN)
- 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']
- });
- })();