|
// ==UserScript== |
|
// @name Blocked Tweet Hider |
|
// @namespace https://floris.debijl.xyz/ |
|
// @version 1.1 |
|
// @description Hide tweets that quote a tweet of a user that you muted or blocked (or that blocked/muted you). |
|
// @author Fdebijl |
|
// @match https://tweetdeck.twitter.com/ |
|
// @match https://twitter.com/* |
|
// @grant none |
|
// ==/UserScript== |
|
|
|
(() => { |
|
'use strict'; |
|
|
|
// De tijd in seconden tussen het checken voor geblokkeerde quotetweets (Getal) |
|
let INTERVAL = 30; |
|
// Of je wil dat een geblokkeerde tweet wordt vervangen door een screenshot, waar mogelijk (TRUE/FALSE) |
|
let SCREENSHOTS = true; |
|
|
|
// Alles hierna hoef je niet aan te passen |
|
const DECK_SELECTOR = { |
|
QUOTES: '.quoted-tweet > .txt-mute', |
|
CONTENTROOT: 'tweet-body', |
|
TWEETROOT: 'stream-item', |
|
LINK: '.js-tweet-text.tweet-text > a.url-ext' |
|
} |
|
const WEB_SELECTOR = { |
|
QUOTES: '.Tombstone > .Tombstone-label', |
|
CONTENTROOT: 'js-tweet-text-container', |
|
TWEETROOT: 'stream-item', |
|
LINK: '.js-tweet-text.tweet-text > a.twitter-timeline-link' |
|
} |
|
|
|
const SELECTOR = getSelector(); |
|
if (!SELECTOR) { |
|
return; |
|
} |
|
|
|
function makeRequest(url, method = 'GET') { |
|
return new Promise((resolve, reject) => { |
|
const xhr = new XMLHttpRequest(); |
|
xhr.open(method, url); |
|
xhr.onload = function() { |
|
if (this.status >= 200 && this.status < 300) { |
|
resolve(xhr.response); |
|
} else { |
|
reject({ |
|
status: this.status, |
|
statusText: xhr.statusText, |
|
}); |
|
} |
|
}; |
|
xhr.onerror = function() { |
|
reject({ |
|
status: this.status, |
|
statusText: xhr.statusText, |
|
}); |
|
}; |
|
xhr.send(); |
|
}); |
|
} |
|
|
|
function findAndReplaceBrokenTweets() { |
|
let quotes = document.querySelectorAll(SELECTOR.QUOTES); |
|
|
|
for(let i = 0; i < quotes.length; i++) { |
|
let parent = quotes[i].parentElement, link; |
|
let imgtarget = parent; |
|
while (!parent.classList.contains(SELECTOR.TWEETROOT)) { |
|
parent = parent.parentElement; |
|
} |
|
|
|
try { |
|
link = parent.querySelector(SELECTOR.LINK).dataset.fullUrl || parent.querySelector(SELECTOR.LINK).href; |
|
!SCREENSHOTS || makeRequest(`https://floris.amsterdam/ure/screenshot?url=${link}`).then((b64) => { |
|
imgtarget.innerHTML = `<img style="max-width: 100%;" src="data:image/jpeg;charset=utf-8;base64, ${b64}" alt="Screenshot of the quoted tweet" />`; |
|
}); |
|
} catch(e) { |
|
console.info('Could not find link in parent of quoted tweet, deleting without screenshot fallback.'); |
|
|
|
while (!parent.classList.contains(SELECTOR.TWEETROOT)) { |
|
parent = parent.parentElement; |
|
} |
|
|
|
parent.style.display = 'none'; |
|
continue; |
|
} |
|
} |
|
} |
|
|
|
function getSelector() { |
|
switch (window.location.hostname) { |
|
case 'tweetdeck.twitter.com': |
|
return DECK_SELECTOR; |
|
break; |
|
case 'twitter.com': |
|
// We kunnen toch geen screenshots maken op twitter.com vanwege de CSP |
|
SCREENSHOTS = false; |
|
return WEB_SELECTOR; |
|
break; |
|
default: |
|
return false; |
|
break; |
|
} |
|
} |
|
|
|
setInterval(findAndReplaceBrokenTweets, INTERVAL * 1000); |
|
})(); |