NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Magic Wand and Uspeli v2.0 // @namespace http://tampermonkey.net/ // @icon https://shitcopikabu.strangled.net/icon.png // @version 2.0 // @description Разудаление комментариев и вызов "Успели" // @author Melhov Anton & v1z // @updateURL https://openuserjs.org/install/shitcopikabu/Pikabu_Magic_wand_userscript_edition.user.js // @homepage https://vk.com/id59967447 // @homepage https://vk.com/shitcopikabu // @homepage https://vk.com/klubnikapikabu // @include http://pikabu.ru/* // @include https://pikabu.ru/* // @include https://old.pikabu.ru/* // @connect https://shitcopikabu.strangled.net // @connect https://v25.name // @license MIT // @grant none // ==/UserScript== // ==OpenUserJS== // @author shitcopikabu & v1z // @collaborator AHTOH874 // ==/OpenUserJS== (function() { "use strict"; const VERSION = "2.0.0"; const DELETED_SPAN_COLOR = 'rgb(136, 136, 136)'; const TELEGRAM_BACKEND_URL = 'https://v25.name/'; const UNDELETE_BACKEND_URL = 'https://shitcopikabu.strangled.net/'; const JSON_HEADERS = { 'Accept': 'application/json', 'Content-Type': 'application/json' } function getUsername() { const username = document.querySelector('.user__nick.user__nick_big'); return username ? username.innerText : ''; } function getUrl(parentBlock) { const link = parentBlock.querySelector('[data-role="link"]'); return link ? link.href : ''; } function getImages(parentBlock) { const foundImages = parentBlock.querySelectorAll('.comment-image__content > a > img'); return Array.from(foundImages).map(image => image.dataset.largeImage); } function isNew(images) { const lsHistory = JSON.parse(localStorage.getItem('uspeli-images-sent')) || []; for (const image of images) { if (lsHistory.includes(image)) { return false; } lsHistory.push(image); } localStorage.setItem('uspeli-images-sent', JSON.stringify(lsHistory)); return true; } function postApi(url, data) { const composedUrl = TELEGRAM_BACKEND_URL + url; const result = fetch(composedUrl, { method: 'post', headers: JSON_HEADERS, body: JSON.stringify(data) }).then(function(response) { if (response.status == 200) { return true; } else if (response.status == 400) { alert('Эта версия расширения не поддерживается. Требуется обновление.'); return false; } else { alert('Не удалось - возможно, сервер сам не успевает.'); return false; } }); return result; } function postUndeleteApi(url, data) { const composedUrl = UNDELETE_BACKEND_URL + url; const result = fetch(composedUrl, { method: 'post', headers: JSON_HEADERS, body: JSON.stringify(data) }).then(function(response) { if (response.status == 200) { return response.json(); } else { throw new Error("Server error " + response.status); } }).then(function(data) { return data; }).catch(function(e) { alert("Ошибка.\n" + e); return false; }) return result; } function wandClick(button, data) { postUndeleteApi('ajax/undelete', data).then((response) => { if (response && response.comments && response.comments.length > 0) { const oldComment = button.closest(".comment__body").querySelector('.comment__content') oldComment.innerHTML = response.comments[0].content_html; button.remove(); } }); } function createUspeliButton() { const button = document.createElement('span'); button.className = 'uspeli comment__tool hint'; button.innerText = 'Успеть'; button.style.color = 'gray'; button.setAttribute('aria-label', 'Может быть, вы успеете?'); return button; } function createWandButton() { const button = document.createElement('span'); button.className = 'wand comment__tool hint'; button.innerText = '✨'; button.style.textDecoration = 'none'; button.setAttribute('aria-label', 'Вернуть как было'); return button; } function isRelated(element) { if (!element) { return false; } return element.classList.contains('comment-image') || element.classList.contains('comment__content') || element.classList.contains('comment__header') || element.classList.contains('comment__body') || element.classList.contains('comment__controls'); } function uspeliSuccess(uspeliButton) { const newButton = document.createElement('span'); newButton.innerText = "Вы успели!"; uspeliButton.replaceWith(newButton); } function checkImages(commentBody) { const images = getImages(commentBody); if (images.length > 0) { const nearest = commentBody.querySelector('.comment__tool[data-role="link"]'); const uspeliButton = nearest.parentElement.insertBefore(createUspeliButton(), nearest); const data = { images: images, commentUrl: getUrl(commentBody), username: getUsername(commentBody), version: VERSION } uspeliButton.addEventListener('click', () => { if (!isNew(images)) { return uspeliSuccess(uspeliButton); } postApi('pikabu/accept', data).then(function() { return uspeliSuccess(uspeliButton) }); }); } } function checkDeletedContent(commentBody) { const deletedCommentContent = commentBody.querySelector('.comment__content > span'); if (deletedCommentContent && deletedCommentContent.style.color == DELETED_SPAN_COLOR) { const nearest = commentBody.querySelector('.comment__tool[data-role="link"]'); const wandButton = nearest.parentElement.appendChild(createWandButton()); const data = { CommentID: parseInt(commentBody.parentElement.dataset.id) } wandButton.addEventListener('click', (button) => wandClick(button.target, data)) } } document.addEventListener('mouseover', (event) => { if (isRelated(event.target) || isRelated(event.relatedTarget)) { const commentBody = event.target.closest('.comment__body'); if (!commentBody || commentBody.dataset.parsed) { return false; } checkDeletedContent(commentBody); checkImages(commentBody); commentBody.dataset.parsed = true; return false; } }, false); })();