-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathModUserBoxHelper.user.js
155 lines (147 loc) · 6.82 KB
/
ModUserBoxHelper.user.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
143
144
145
146
147
148
149
150
151
152
153
154
155
// ==UserScript==
// @name Mod User Box helper
// @version 0.4.1
// @description Add some clarity to the mod boxes for ban statuses. Adds a clear button for edit ban
// @author Machavity
//
// @updateURL https://github.com/machavity/SO-Userscripts/raw/master/ModUserBoxHelper.user.js
// @downloadURL https://github.com/machavity/SO-Userscripts/raw/master/ModUserBoxHelper.user.js
// @include https://*stackoverflow.com/users*
// @include https://*serverfault.com/users*
// @include https://*superuser.com/users*
// @include https://*askubuntu.com/users*
// @include https://*mathoverflow.net/users*
// @include https://*.stackexchange.com/users*
// @exclude https://meta.stackoverflow.com/*
// @exclude https://meta.superuser.com/*
// @exclude https://meta.askubuntu.com/*
// @exclude https://meta.mathoverflow.net/*
// @exclude https://meta.*.stackexchange.com/*
// ==/UserScript==
(function() {
'use strict';
// SO classes for green and red. Pulled from the expanded up/down vote in Q&A CSS
const green = 'fc-green-600';
const red = 'fc-red-600';
const noEditBan = 'N/A';
let reputation = '1';
let url = window.location.href;
if(url.search(/\/account-info/) !== -1) loadUserModPage();
// Exclude Developer Story and profile edit
else if(url.search(/\/(story|edit)/) !== -1) return;
else loadUserProfilePage();
function loadUserProfilePage() {
let modCard = document.querySelector('div[class~="js-profile-mod-info"]');
if(!modCard) return; // No mod block so we're done
let reputation = loadUserProfileReputation();
let tds = document.querySelectorAll('td[class^="mod-label"]');
tds.forEach(function(elm) {
// Question and Answer Ban
if(elm.innerText.search(/blocked\sfrom\s(asking|answering)/i) !== -1) simpleBanNotice(elm.nextElementSibling);
else if(elm.innerText.includes('suspended from reviews')) simpleBanNotice(elm.nextElementSibling);
// Edit ban
else if(elm.innerText.includes('suggested edits') === true) {
if(reputation >= 2000) simpleBanNotice(elm.nextElementSibling, noEditBan);
else editBanNotice(elm.nextElementSibling);
}
});
}
function loadUserProfileReputation() {
// Profile Page
let div = document.getElementById('top-cards');
if(div) {
let header = div.querySelector('h4');
if(header) return parseReputation(header.innerText);
}
// Activity Page
div = document.getElementById('stats');
if(!div) return 1;
let list = div.querySelectorAll('.flex--item');
let rep;
Array.from(list).some(function(elm) {
if(elm.innerHTML.includes('reputation')) {
rep = elm.firstElementChild.innerText;
return true;
}
return false;
});
if(!rep) return 1;
return parseReputation(rep);
}
function loadUserModPage() {
const annotate = 'supernovabg';
const flags = 'hotbg';
let mod = document.getElementById('mod-content');
let divs = mod.querySelectorAll('div[class="col-2"]');
let nextDiv;
divs.forEach(function(elm) {
// Find user reputation. Neded for the edit ban section
if(elm.innerText.includes('Reputation') === true) reputation = parseReputation(elm.nextElementSibling.innerText);
// Question, Answer and Review Ban
if(elm.innerText.search(/(Question\sban|Answer\sban|Review\ssuspension)/i) !== -1) simpleBanNotice(elm.nextElementSibling);
// Edit ban
if(elm.innerText.includes('suggesting edits') === true) {
if(reputation >= 2000) simpleBanNotice(elm.nextElementSibling, noEditBan);
else editBanNotice(elm.nextElementSibling);
}
});
// style messages on the left side
let list = mod.querySelectorAll('span.bounty-indicator-tab');
if(list.length > 0) {
list[0].classList.add((list[0].nextElementSibling.innerText === 'flags for user' ? flags : annotate));
if(list.length > 1) list[1].classList.add(flags);
}
let cmElm = document.querySelector('a.coolbg');
if(!cmElm) return; // no CM messages so we don't need to add a link
let ul = document.querySelectorAll('ul.mod-quick-links li');
let flagLi = ul[4]; // grab the flag element
let newLi = document.createElement('li');
let span = document.createElement('span');
span.classList.add('bounty-indicator-tab', 'coolbg');
span.innerText = cmElm.innerText;
newLi.insertAdjacentElement('afterbegin', span);
let anchor = document.createElement('a');
anchor.href = cmElm.href;
anchor.innerText = ' Community Team message(s)';
newLi.insertAdjacentElement('beforeend', anchor);
flagLi.insertAdjacentElement('afterend', newLi);
}
function simpleBanNotice(elm, useText = null) {
let banned = elm.innerText.includes('yes');
let span = elm.querySelector('span[class^=blocked]');
if(!span) { // Review suspension omits the span if they are banned so we'll create it
span = document.createElement('span');
elm.insertAdjacentElement('afterbegin', span);
banned = true;
}
span.classList.add(((banned) ? red : green));
if(!useText) span.innerText = (banned ? 'Banned' : 'Not Banned');
else span.innerText = useText;
}
function editBanNotice(div) {
let banned = !div.innerText.includes('no');
let span = document.createElement('span');
span.classList.add(((banned) ? red : green));
span.innerText = (banned ? 'Banned' : 'Not Banned');
let eventSpan = div.querySelector('span[class="suggested-edit-ban"]');
if(eventSpan) {
div.appendChild(eventSpan);
div.querySelector('a').remove();
} else { // Banned users will not have the ban link. Unban is in a different element
eventSpan = div.querySelector('a[class="suggested-edit-unban"]');
if(!eventSpan) return; // Failsafe in case reputation check failed
eventSpan.nextSibling.remove();
eventSpan.previousSibling.remove();
}
let button = document.createElement('button');
button.classList.add('s-btn', 's-btn__primary', 's-btn__xs');
button.innerText = banned ? 'Remove Ban' : 'Add Ban';
eventSpan.innerHTML = '';
eventSpan.insertAdjacentElement('afterbegin', button);
div.insertAdjacentElement('afterbegin', span);
}
function parseReputation(reputation) {
reputation = reputation.replace(/\,/g,'');
return parseInt(reputation,10);
}
})();