-
Notifications
You must be signed in to change notification settings - Fork 0
/
ban-hn.js
142 lines (122 loc) · 3.79 KB
/
ban-hn.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// ==UserScript==
// @author dylanarmstrong
// @description Ban people I dislike on HN
// @grant none
// @match https://news.ycombinator.com/*
// @name ban-hn
// @namespace https://github.com/dylanarmstrong/userscripts/
// @supportURL https://github.com/dylanarmstrong/userscripts/issues
// @updateURL https://raw.githubusercontent.com/dylanarmstrong/userscripts/main/ban-hn.js
// @version 1
// ==/UserScript==
/**
* HN has really bad moderation, so it's easier to just block the people who are cancer.
*/
(function () {
'use strict';
// Store the version # in localStorage
// this will be useful for possible breaking changes
// How many ? can you fit on one line?
const version =
typeof GM_info === 'object' ? GM_info?.script?.version ?? 0 : 0;
const keys = {
users: 'filter.users',
version: 'filter.version',
};
// Make sure all keys are initialized
Object.keys(keys).forEach((key) => {
const value = keys[key];
const item = localStorage.getItem(value);
if (item === null) {
localStorage.setItem(value, '');
}
});
// This is in case changes are ever breaking
localStorage.setItem(keys.version, version);
// Make a (x) button next to subhn
let button = document.createElement('button');
button.classList.add('hn-filter-block');
let nodes = null;
const updateNodes = () => {
nodes = Array.from(
document.querySelectorAll('.comment-tree .comhead'),
).filter((node) => node !== null && typeof node !== 'undefined');
};
const getUser = (node) =>
node.parentNode.parentNode
.querySelector('.hnuser')
.textContent.toLowerCase();
const isBanned = (user) =>
localStorage.getItem(keys.users).split(',').includes(user);
// Remove all blocked subhns
const hide = () => {
for (let i = 0, len = nodes.length; i < len; i++) {
const node = nodes[i];
const user = getUser(node);
if (isBanned(user)) {
// Check if already hidden
if (
!node.parentNode.parentNode.parentNode.parentNode.querySelector(
'.noshow',
)
) {
node.parentNode.parentNode.querySelector('a.togg.clicky').click();
}
}
}
};
const click = (e) => {
e.preventDefault();
e.stopPropagation();
const { target } = e;
const key = keys.users;
const user = getUser(target);
const banned = isBanned(user);
if (
confirm(
`Are you sure you want to ${banned ? 'unblock' : 'block'} '${user}'?`,
)
) {
let blocked = localStorage.getItem(key).split(',');
// Already in here, how'd the user block it twice?
if (blocked.includes(user)) {
blocked.splice(blocked.indexOf(user), 1);
} else {
blocked.push(user);
}
localStorage.setItem(key, blocked.join(','));
hide();
updateButtons();
}
};
const updateButtons = () => {
for (let i = 0, len = nodes.length; i < len; i++) {
const node = nodes[i];
const a = node.querySelector('.hn-filter-span a');
const user = getUser(node);
a.textContent = isBanned(user) ? 'unban' : 'ban';
}
};
const addButtons = () => {
for (let i = 0, len = nodes.length; i < len; i++) {
const node = nodes[i];
if (!node.querySelector('.hn-filter-span')) {
const span = document.createElement('span');
span.classList.add('hn-filter-span');
const a = document.createElement('a');
const user = getUser(node);
a.textContent = isBanned(user) ? 'unban' : 'ban';
a.addEventListener('click', click);
span.insertAdjacentText('afterbegin', ' | ');
span.appendChild(a);
node.appendChild(span);
}
}
};
const run = () => {
updateNodes();
hide();
addButtons();
};
run();
})();