// ==UserScript==
// @name Wanikani Forums: Hide Users
// @namespace Wanikani Forums: Hide Users
// @version 2.0.7.
// @description Makes it possible to remove people from the forums.
// @author Kumirei
// @include https://community.wanikani.com*
// @require https://greasyfork.org/scripts/5392-waitforkeyelements/code/WaitForKeyElements.js
// @grant none
// ==/UserScript==
/*jshint esversion: 8 */
var userList;
(function() {
getList(); // Get list of users to hide
setTriggers(); // Set triggers for when the script should fire
hideUsers(); // Hide anything which happens to be on the page
// Do stuff when entering a new thread
waitForKeyElements('.post-stream', function(){
makeObserver(observerFunction, "post-stream"); // Set up mutation observer for new posts
hideUsers(); // Hide users when using slider to jump
});
// Hide user in "who liked" dropdown
waitForKeyElements('.who-liked', hideWhoLiked);
// Detect embedded replies
waitForKeyElements('.embedded-posts', hideEmbedded);
// Add the hide button to usercards
waitForKeyElements('.card-content .name-username-wrapper', function(){
var userName = $('.name-username-wrapper')[0].innerText;
var userID = $('.trigger-user-card[href="/u/'+userName+'"]').closest('article').attr('data-user-id');
var li = document.createElement('li');
var btn = document.createElement('button');
btn.onclick = ()=>{addUser(userName, userID);};
btn.className = 'btn addUserButton';
btn.title = 'Hide or unhide everything about this person on the forums';
btn.innerText = 'Hide User';
li.appendChild(btn);
$('.usercard-controls').append(li);
});
// Add manage button in menu
waitForKeyElements('.menu-container-footer-links .menu-links', function(e) {
var li = document.createElement('li');
var a = document.createElement('a');
a.className = 'widget-link WKFhideUsersMenu';
a.title = 'Manage Hidden Users';
a.onclick = openMenu;
var span = document.createElement('span');
span.class = 'd-label';
span.innerText = 'Hidden Users';
a.appendChild(span);
li.appendChild(a);
e[0].appendChild(li);
});
// Get list of hidden users from storage
function getList() {
userList = localStorage.getItem('WKFhideUsersList');
if (userList === null || userList === "") {
userList = [];
}
else {
userList = $.parseJSON(userList);
}
console.log("Hidden Users: ", userList);
}
// Create a new observer
function makeObserver(func, targetClass) {
var target = document.getElementsByClassName(targetClass)[0];
if (target !== undefined) {
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
func(mutation);
});
});
var config = {childList: true};
observer.observe(target, config);
}
}
// Call the hideUsers function if there are new nodes of the relevant classes
function observerFunction(mutation) {
if ((mutation.addedNodes[0] !== undefined) && (mutation.addedNodes !== undefined)) {
if (mutation.addedNodes[0].className.includes("topic-post")) {
hideUsers();
}
}
}
// Do the magical hiding stuff
function hideUsers() {
$(userList).each(function(i, user) {
hideUser(user);
});
}
// Set the triggers for when the script should fire
function setTriggers() {
// Loading the window
window.addEventListener('load', hideUsers);
// Using back and forth buttons
window.addEventListener('popstate', function() {setTimeout(hideUsers, 1000);});
// Navigating
(function(history){
var pushState = history.pushState;
history.pushState = function(state) {
hideUsers();
return pushState.apply(history, arguments);
};
})(window.history);
// Scrolling
var i = 0;
window.onscroll = function() {
if (i % 50 == 0) {
hideUsers();
}
i++;
};
}
// Hide users in who-liked dropdown
function hideWhoLiked(e) {
var elem = e[0];
var likeCountElem = $(elem).siblings('.post-controls').find('.like-count')[0];
hidePostMeta(elem, 'a', 'a', '', '', likeCountElem, 'width: 64px; height: 30px;', 'this post has been liked by hidden users', likeCountElem);
}
// Hide users in embedded replies
function hideEmbedded(e) {
var elem = e[0];
var replyCountElem = $(elem).siblings('.post-menu-area').find('.show-replies')[0];
hidePostMeta(elem, '.trigger-user-card', 'div .reply', ' Replies', ' Reply', replyCountElem, 'width: 40px; height: 30px;', 'this post has been replied to by hidden users', replyCountElem.children[0]);
replyCountElem.children[1].style = 'margin-left: 0;';
}
// Edit the elements of the above two functions
function hidePostMeta(elem, target, countTarget, texts, text, countElem, countStyle, countEmptyText, textElem) {
for (var i = 0; i < userList.length; i++) {
var e = $(elem).find(target+'[data-user-card="'+userList[i].split(':')[0]+'"]');
if (e.length) {
e.closest('.reply').closest('div').remove();
e.remove();
}
}
var count = $(elem).find(countTarget).length;
var countText = texts;
if (count == 1) {countText = text;}
else if (count == 0) {
count = '';
countText = '';
$(countElem).attr('style', countStyle);
$(countElem).attr('title', '');
elem.style = 'border: 0;';
elem.innerText = countEmptyText;
}
textElem.innerText = count + countText;
}
// Hide the user's stuffsies
function hideUser(user, unhide) {
var userName = user.split(':')[0];
var userID = user.split(':')[1];
var display = "display: none;";
if (unhide) {display = "display: initial;";}
// Posts
$("[data-user-id='" + userID + "']").closest($('.topic-post')).attr('style', display);
// Replies
$('.reply-to-tab img[title="'+userName+'"]').closest('.reply-to-tab').attr('style', display);
// Quotes
$('.quote .title').each(function() {if(this.innerText.includes(userName)) {$(this).closest('.quote').attr('style', display + '!important');}});
// Css stuff
hideWithCSS(userName, userID);
}
// Hides things with css, which is much easier
function hideWithCSS(userName, userID) {
if ($('head .WKFhideUsers[user-id="'+userID+'"]').length == 0) {
$('head').append(
'<style class="WKFhideUsers" user-id="'+userID+'">'+
' .trigger-user-card[data-user-card="'+userName+'"],'+
' a[data-user-card="'+userName+'"] {'+
' display: none;'+
' }'+
''+
'.WKFhideUsersListItem:hover {background-color: #ffffa6;}'+
'</style>'
);
}
}
// Adds a user to the userlist or removes a user if it is already on the list
addUser = function(userName, userID) {
if (userID === undefined) {alert('No user ID found; try opening the user card from a post instead');}
else {
var userStr = userName+':'+userID;
if (userList.includes(userStr)) {
userList.splice(userList.indexOf(userStr), 1);
hideUser(userStr, true);
$('#WKFhideUsersMenu .WKFhideUsersListItem[user-id="'+userID+'"]').remove();
$('head .WKFhideUsers[user-id="'+userID+'"]').remove();
alert('You may have to refresh to unhide some items');
}
else {
userList.push(userStr);
//hide usercard
$('#user-card').hide();
hideUser(userStr);
alert('You may have to refresh for user to be completely hidden');
}
localStorage.setItem("WKFhideUsersList",JSON.stringify(userList));
}
};
// Opens up the menu for managing hidden users
openMenu = function() {
var div = $('<div class="menu-panel" id="WKFhideUsersMenu" height="100px !important" width="100px" style="left: 0; bottom: -10px; position: absolute; transform: translate(0, 100%);">'+
'<div style="border-bottom: 1px solid black;"><span style="padding-left: 0.5em;"><b>Click name to stop hiding</b></span></div><ul>')[0];
for (var i = 0; i < userList.length; i++) {
var userInfo = userList[i].split(':');
var li = document.createElement('li');
li.className = 'WKFhideUsersListItem';
li.setAttribute('user-id', userInfo[1]);
li.onclick = ()=>{addUser(userInfo[0], userInfo[1])};
var a = document.createElement('a');
a.className = 'widget-link';
a.style = "display: inline-block; padding: 0.25em 0.5em;";
a.innerText = userInfo[0];
li.appendChild(a);
div.appendChild(li);
}
if (!$('#WKFhideUsersMenu').length) {$('.menu-panel').append(div);}
else {$('#WKFhideUsersMenu').remove();}
};
})();