// Fade out the post const post = link.closest('shreddit-post, article, .thing, [data-testid="post-container"]'); if (post) { post.style.transition = 'opacity 0.3s'; post.style.opacity = '0.3'; } } else { throw new Error('Block request failed'); } } catch (err) { console.error('Reddit Quick Block error:', err); link.textContent = 'block'; link.style.color = '#ff4500'; link.style.backgroundColor = 'rgba(255, 69, 0, 0.1)'; link.style.borderColor = 'rgba(255, 69, 0, 0.2)'; window.open(`https://www.reddit.com/user/${username}`, '_blank'); alert('Could not block directly. Opening profile page - use the "More Options" menu to block.'); } });
return link; }
async function getModhash() { try { // Try to get from the page first const existing = document.querySelector('input[name="uh"]')?.value; if (existing) return existing;
// Fetch from API const response = await fetch('https://www.reddit.com/api/me.json', { credentials: 'include' }); const data = await response.json(); return data?.data?.modhash; } catch { return null; } }
function addBlockLinksOldReddit() { const posts = document.querySelectorAll('.thing.link:not([data-quick-block])');
// Look for the author link/element in various places const authorSelectors = [ `a[href="/user/${username}/"]`, `a[href="/user/${username}"]`, '[slot="authorName"]', 'faceplate-hovercard a', '.author-name', `a[href*="/user/${username}"]` ];
let authorEl = null; for (const selector of authorSelectors) { authorEl = post.querySelector(selector); if (authorEl) break; }
// If we found an author element, add the block link if (authorEl && !authorEl.parentNode.querySelector('.quick-block-link')) { const blockLink = createBlockLink(username); authorEl.insertAdjacentElement('afterend', blockLink); return; }
// Fallback: look for any element containing the username text const walker = document.createTreeWalker(post, NodeFilter.SHOW_ELEMENT); while (walker.nextNode()) { const el = walker.currentNode; if (el.tagName === 'A' && el.textContent.trim() === `u/${username}`) { if (!el.parentNode.querySelector('.quick-block-link')) { const blockLink = createBlockLink(username); el.insertAdjacentElement('afterend', blockLink); } return; } }
// Last resort: add to the post's credit bar area const creditBar = post.querySelector('[slot="credit-bar"]'); if (creditBar && !creditBar.querySelector('.quick-block-link')) { const blockLink = createBlockLink(username); blockLink.style.marginLeft = '10px'; creditBar.appendChild(blockLink); } });
I used gemini to improve the button look which is very much needed. Thank you for making this btw:
// ==UserScript==
// @name Reddit Quick Block
// @namespace http://tampermonkey.net/
// @version 1.2
// @description Add a "block" button to posts in the Reddit feed for quick blocking
// @match https://www.reddit.com/*
// @match https://old.reddit.com/*
// @match https://sh.reddit.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
const isOldReddit = window.location.hostname === 'old.reddit.com';
function createBlockLink(username) {
const link = document.createElement('a');
link.href = '#';
link.textContent = 'block';
link.className = 'quick-block-link';
// Updated styles to transform the link into a sleek pill button
link.style.cssText = `
margin-left: 8px;
display: inline-flex;
align-items: center;
justify-content: center;
background-color: rgba(255, 69, 0, 0.1);
color: #ff4500;
font-size: 11px;
font-family: inherit;
font-weight: 700;
cursor: pointer;
text-decoration: none;
padding: 2px 8px;
border-radius: 9999px;
border: 1px solid rgba(255, 69, 0, 0.2);
transition: background-color 0.2s ease, border-color 0.2s ease;
vertical-align: middle;
`;
link.title = `Block u/${username}`;
// Hover effects adapted for a button style
link.addEventListener('mouseenter', () => {
link.style.backgroundColor = 'rgba(255, 69, 0, 0.2)';
link.style.borderColor = 'rgba(255, 69, 0, 0.4)';
});
link.addEventListener('mouseleave', () => {
link.style.backgroundColor = 'rgba(255, 69, 0, 0.1)';
link.style.borderColor = 'rgba(255, 69, 0, 0.2)';
});
link.addEventListener('click', async (e) => {
e.preventDefault();
e.stopPropagation();
if (!confirm(`Block u/${username}?\n\nYou won't see their posts or comments anymore.`)) {
return;
}
link.textContent = 'blocking...';
link.style.color = '#888';
link.style.backgroundColor = 'rgba(0, 0, 0, 0.05)';
link.style.borderColor = 'rgba(0, 0, 0, 0.1)';
try {
const modhash = await getModhash();
if (!modhash) {
throw new Error('Could not get auth token');
}
const response = await fetch('https://www.reddit.com/api/block_user', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `name=${encodeURIComponent(username)}&uh=${modhash}`,
credentials: 'include'
});
if (response.ok) {
link.textContent = 'blocked ✓';
link.style.color = '#228b22';
link.style.backgroundColor = 'rgba(34, 139, 34, 0.1)';
link.style.borderColor = 'rgba(34, 139, 34, 0.2)';
link.style.pointerEvents = 'none';
// Fade out the post
const post = link.closest('shreddit-post, article, .thing, [data-testid="post-container"]');
if (post) {
post.style.transition = 'opacity 0.3s';
post.style.opacity = '0.3';
}
} else {
throw new Error('Block request failed');
}
} catch (err) {
console.error('Reddit Quick Block error:', err);
link.textContent = 'block';
link.style.color = '#ff4500';
link.style.backgroundColor = 'rgba(255, 69, 0, 0.1)';
link.style.borderColor = 'rgba(255, 69, 0, 0.2)';
window.open(`https://www.reddit.com/user/${username}`, '_blank');
alert('Could not block directly. Opening profile page - use the "More Options" menu to block.');
}
});
return link;
}
async function getModhash() {
try {
// Try to get from the page first
const existing = document.querySelector('input[name="uh"]')?.value;
if (existing) return existing;
// Fetch from API
const response = await fetch('https://www.reddit.com/api/me.json', { credentials: 'include' });
const data = await response.json();
return data?.data?.modhash;
} catch {
return null;
}
}
function addBlockLinksOldReddit() {
const posts = document.querySelectorAll('.thing.link:not([data-quick-block])');
posts.forEach(post => {
post.setAttribute('data-quick-block', 'true');
const authorLink = post.querySelector('a.author');
if (!authorLink) return;
const username = authorLink.textContent;
if (!username || username === '[deleted]') return;
const tagline = post.querySelector('.tagline');
if (tagline) {
const blockLink = createBlockLink(username);
tagline.appendChild(document.createTextNode(' '));
tagline.appendChild(blockLink);
}
});
}
function addBlockLinksNewReddit() {
// Method 1: shreddit-post elements (main feed)
document.querySelectorAll('shreddit-post:not([data-quick-block])').forEach(post => {
post.setAttribute('data-quick-block', 'true');
const username = post.getAttribute('author');
if (!username || username === '[deleted]') return;
// Look for the author link/element in various places
const authorSelectors = [
`a[href="/user/${username}/"]`,
`a[href="/user/${username}"]`,
'[slot="authorName"]',
'faceplate-hovercard a',
'.author-name',
`a[href*="/user/${username}"]`
];
let authorEl = null;
for (const selector of authorSelectors) {
authorEl = post.querySelector(selector);
if (authorEl) break;
}
// If we found an author element, add the block link
if (authorEl && !authorEl.parentNode.querySelector('.quick-block-link')) {
const blockLink = createBlockLink(username);
authorEl.insertAdjacentElement('afterend', blockLink);
return;
}
// Fallback: look for any element containing the username text
const walker = document.createTreeWalker(post, NodeFilter.SHOW_ELEMENT);
while (walker.nextNode()) {
const el = walker.currentNode;
if (el.tagName === 'A' && el.textContent.trim() === `u/${username}`) {
if (!el.parentNode.querySelector('.quick-block-link')) {
const blockLink = createBlockLink(username);
el.insertAdjacentElement('afterend', blockLink);
}
return;
}
}
// Last resort: add to the post's credit bar area
const creditBar = post.querySelector('[slot="credit-bar"]');
if (creditBar && !creditBar.querySelector('.quick-block-link')) {
const blockLink = createBlockLink(username);
blockLink.style.marginLeft = '10px';
creditBar.appendChild(blockLink);
}
});
// Method 2: Regular divs with data-testid (some Reddit views)
document.querySelectorAll('[data-testid="post-container"]:not([data-quick-block])').forEach(post => {
post.setAttribute('data-quick-block', 'true');
const authorLink = post.querySelector('a[href*="/user/"]');
if (!authorLink) return;
const usernameMatch = authorLink.href.match(/\/user\/([^/?]+)/);
if (!usernameMatch) return;
const username = usernameMatch[1];
if (username === '[deleted]' || authorLink.parentNode.querySelector('.quick-block-link')) return;
const blockLink = createBlockLink(username);
authorLink.insertAdjacentElement('afterend', blockLink);
});
// Method 3: Article elements
document.querySelectorAll('article:not([data-quick-block])').forEach(article => {
article.setAttribute('data-quick-block', 'true');
const authorLink = article.querySelector('a[href*="/user/"]');
if (!authorLink) return;
const usernameMatch = authorLink.href.match(/\/user\/([^/?]+)/);
if (!usernameMatch) return;
const username = usernameMatch[1];
if (username === '[deleted]' || authorLink.parentNode.querySelector('.quick-block-link')) return;
const blockLink = createBlockLink(username);
authorLink.insertAdjacentElement('afterend', blockLink);
});
}
function addBlockLinks() {
if (isOldReddit) {
addBlockLinksOldReddit();
} else {
addBlockLinksNewReddit();
}
}
// Run on load
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', addBlockLinks);
} else {
addBlockLinks();
}
// Periodic check for new content (handles infinite scroll and dynamic loading)
setInterval(addBlockLinks, 1000);
// Also watch for mutations
const observer = new MutationObserver(() => {
clearTimeout(window.quickBlockDebounce);
window.quickBlockDebounce = setTimeout(addBlockLinks, 150);
});
observer.observe(document.body, {
childList: true,
subtree: true
});
console.log('Reddit Quick Block v1.2 loaded with button UI');
})();