Wanikani Forums: Hide Users

Makes it possible to remove people from the forums.

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

You will need to install an extension such as Tampermonkey to install this script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==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();}
		};
})();