// ==UserScript== // @name MyDealz Kommentar Suche // @namespace http://tampermonkey.net/ // @version 1.0 // @description Suche nach Kommentaren auf den MyDealz-Angebotsseiten durch Drücken von alt+s // @author MyDealz Community // @match https://www.mydealz.de/deals/* // @icon https://www.google.com/s2/favicons?sz=64&domain=mydealz.de // @grant none // @downloadURL none // ==/UserScript== (function() { 'use strict'; const url = 'https://www.mydealz.de/graphql'; function extractThreadId() { const mainElement = document.getElementById('main'); if (mainElement) { const dataAttribute = mainElement.getAttribute('data-t-d'); if (dataAttribute) { const dataObject = JSON.parse(dataAttribute.replace(/"/g, '"')); return dataObject.threadId; } } return null; } const threadId = extractThreadId(); function cleanHTML(raw_html) { return raw_html.replace(/<.*?>/g, ''); } function createSearchForm(title) { return `

In den Kommentaren zu '${title}' suchen

`; } async function searchComments() { const searchTerm = this.document.getElementById('searchTerm').value; this.document.getElementById('results').innerHTML = '
Suche läuft...
'; try { const allData = await fetchDataAndReplies(); const filteredComments = allData.filter(comment => cleanHTML(comment.preparedHtmlContent).toLowerCase().includes(searchTerm.toLowerCase()) || (comment.replies && comment.replies.some(reply => cleanHTML(reply.preparedHtmlContent).toLowerCase().includes(searchTerm.toLowerCase()))) ); if (filteredComments.length === 0) { this.document.getElementById('results').innerHTML = '
Keine Kommentare gefunden, die den Suchbegriff enthalten.
'; return; } const commentsHTML = generateCommentsHTML(filteredComments, searchTerm); this.document.getElementById('results').innerHTML = `
${filteredComments.length} gefundene Kommentare mit '${searchTerm}'${commentsHTML}
`; } catch (error) { console.error('Error:', error); } } function generateCommentsHTML(comments, searchTerm) { let html = ''; function generateRepliesHTML(replies, searchTerm) { let repliesHTML = ''; for (const reply of replies) { const cleanContent = cleanHTML(reply.preparedHtmlContent); if (cleanContent.toLowerCase().includes(searchTerm.toLowerCase())) { const highlightedContent = cleanContent.replace(new RegExp(searchTerm, 'gi'), match => `${match}`); const usernameLink = `🔗 ${reply.user.username}`; repliesHTML += `
${usernameLink} ${reply.createdAt}: ${highlightedContent}
`; } } return repliesHTML; } for (const comment of comments) { const cleanContent = cleanHTML(comment.preparedHtmlContent); if (cleanContent.toLowerCase().includes(searchTerm.toLowerCase())) { const highlightedContent = cleanContent.replace(new RegExp(searchTerm, 'gi'), match => `${match}`); const usernameLink = `🔗 ${comment.user.username}`; html += `
${usernameLink} ${comment.createdAt}: ${highlightedContent}
`; } else if (comment.replies) { html += generateRepliesHTML(comment.replies, searchTerm); } } return html; } async function fetchGraphQLData(query, variables) { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query, variables }) }); if (response.status === 429) { console.log('Too many requests. Waiting 10 seconds.'); await new Promise(resolve => setTimeout(resolve, 10000)); return fetchGraphQLData(query, variables); } const responseData = await response.json(); if (responseData.errors) { throw new Error(responseData.errors[0].message); } return responseData.data.comments; } async function fetchReplies(commentId) { const graphqlQueryReplies = { query: `query comments($filter: CommentFilter!, $limit: Int, $page: Int) { comments(filter: $filter, limit: $limit, page: $page) { items { commentId preparedHtmlContent user { userId username } replyCount createdAt parentReply { user { username } } } pagination { current next } } }`, variables: { filter: { mainCommentId: commentId, threadId: { eq: threadId }, order: { direction: "Ascending" } }, page: 1, limit: 100 } }; return fetchAllPages(graphqlQueryReplies.query, graphqlQueryReplies.variables); } async function fetchAllPages(query, variables) { let currentPage = 1; let allData = []; while (true) { const data = await fetchGraphQLData(query, { ...variables, page: currentPage }); allData.push(...data.items); if (data.pagination.next) { currentPage++; } else { break; } } return allData; } async function fetchDataAndReplies() { const graphqlQuery = { query: `query comments($filter: CommentFilter!, $limit: Int, $page: Int) { comments(filter: $filter, limit: $limit, page: $page) { items { commentId preparedHtmlContent user { userId username } replyCount createdAt } pagination { current next } } }`, variables: { filter: { threadId: { eq: threadId }, order: { direction: "Ascending" } }, page: 1, limit: 100 } }; const allComments = await fetchAllPages(graphqlQuery.query, graphqlQuery.variables); for (const comment of allComments) { if (comment.replyCount !== 0) { const replies = await fetchReplies(comment.commentId); comment.replies = replies; } } return allComments; } function handleKeydown(e) { e = window.event ? event : e; if (e.keyCode == 83 && e.altKey) { console.log("Comment search opened"); const title = document.title.replace(" | mydealz", ""); const newWindow = window.open('', '_blank'); if (newWindow) { newWindow.document.write('Kommentar-Suche' + createSearchForm(title) + ''); newWindow.document.close(); newWindow.addEventListener('load', function() { newWindow.searchComments = searchComments.bind(newWindow); const searchTerm = prompt("Suchbegriff eingeben:"); if (!searchTerm) { alert("Kein Suchbegriff eingegeben. Das Skript wird beendet."); newWindow.close(); return; } newWindow.document.getElementById('searchTerm').value = searchTerm; newWindow.searchComments(); }); } } } document.addEventListener('keydown', handleKeydown, false); })();