User:Nardog/RCMuter.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
['Recentchanges', 'Recentchangeslinked', 'Watchlist'].includes(mw.config.get('wgCanonicalSpecialPageName')) &&
$.when($.ready, mw.loader.using([
	'user.options', 'mediawiki.util', 'mediawiki.api'
])).then(function rcMuter() {
	let os = mw.user.options.get('userjs-rcmuter');
	let set = new Set(os && os.split('|'));
	let save = () => {
		let ns = [...set].join('|');
		if (ns === mw.user.options.get('userjs-rcmuter')) return;
		new mw.Api().saveOption('userjs-rcmuter', ns);
		mw.user.options.set('userjs-rcmuter', ns);
		$edit.attr('data-rcmuter', set.size);
	};
	mw.loader.addStyleTag('body:not(.rcmuter-disabled) .rcmuter-muted{display:none !important} .rcmuter-edit::after, .rcmuter-togglemuted::after{content:": " attr(data-rcmuter)}');
	let $edit = $('<a>').attr({
		class: 'rcmuter-edit',
		href: '#',
		'data-rcmuter': set.size
	}).text('Edit muted').on('click', e => {
		e.preventDefault();
		mw.loader.using([
			'oojs-ui-windows', 'mediawiki.widgets.UsersMultiselectWidget'
		]).then(() => OO.ui.getWindowManager().getWindow('message')).then(dialog => {
			let multiselect = new mw.widgets.UsersMultiselectWidget({
				$overlay: dialog.$overlay,
				ipAllowed: true,
				selected: [...set]
			}).connect(dialog, { change: 'updateSize', reorder: 'updateSize' });
			let instance = dialog.open({
				message: $([
					document.createTextNode('Muted users:'),
					multiselect.$element[0]
				]),
				size: 'medium'
			});
			instance.opened.then(() => {
				setTimeout(() => {
					multiselect.focus().menu.toggle(false);
				});
			});
			instance.closed.then(result => {
				if (!result || result.action !== 'accept') return;
				set = new Set(multiselect.getSelectedUsernames());
				save();
				mw.notify('Changes will take effect in next load.', {
					tag: 'rcmuter'
				});
			});
		});
	});
	let buttonsShown;
	let $toggleButtons = $('<a>').attr('href', '#').text('Show toggle buttons').on('click', function (e) {
		e.preventDefault();
		if (buttonsShown) {
			mw.hook('wikipage.content').remove(addButtons);
			$('.rcmuter-toggle').remove();
			this.textContent = 'Show toggle buttons';
		} else {
			mw.hook('wikipage.content').add(addButtons);
			this.textContent = 'Hide toggle buttons';
		}
		buttonsShown = !buttonsShown;
	});
	let $toggle = $('<a>').attr({
		class: 'rcmuter-togglemuted',
		href: '#'
	}).text('Show muted').on('click', function (e) {
		e.preventDefault();
		this.textContent = document.body.classList.toggle('rcmuter-disabled')
			? 'Hide muted'
			: 'Show muted';
	});
	let $toggleSpan = $('<span>').hide().append($toggle);
	mw.util.addSubtitle(' ');
	mw.util.addSubtitle(
		$('<span>').addClass('mw-changeslist-links').append(
			$('<span>').append($edit),
			$('<span>').append($toggleButtons),
			$toggleSpan
		)[0]
	);
	let toggle = function (e) {
		e.preventDefault();
		let user = $(this)
			.closest('.mw-userlink ~ .mw-usertoollinks, .mw-changeslist-line-inner-userLink ~ .mw-changeslist-line-inner-userTalkLink')
			.prevAll('.mw-userlink, .mw-changeslist-line-inner-userLink')
			.last().text().trim();
		if (!user) {
			mw.notify('Can\'t retrieve the username.', {
				tag: 'rcmuter',
				type: 'error'
			});
			return;
		}
		let muting = this.parentElement.classList.toggle('rcmuter-unmute');
		set[muting ? 'add' : 'delete'](user);
		save();
		this.textContent = muting ? 'unmute' : 'mute';
		mw.notify(`${muting ? 'Muting' : 'Unmuting'} ${user} from next load.`, {
			tag: 'rcmuter'
		});
	};
	let addButtons = $content => {
		if (!$content.is('#mw-content-text, .mw-changeslist')) {
			$content = $('#mw-content-text');
			if ($content.has('.rcmuter-toggle').length) return;
		}
		let $tools = $content.find('.mw-usertoollinks.mw-changeslist-links');
		let $muted = $tools.filter('.rcmuter-muted *');
		$tools.not($muted).append(
			$('<span>').addClass('rcmuter-toggle').append(
				$('<a>').attr('href', '#').text('mute').on('click', toggle)
			)
		);
		if (!$muted.length) return;
		$muted.append(
			$('<span>').addClass('rcmuter-toggle rcmuter-unmute').append(
				$('<a>').attr('href', '#').text('unmute').on('click', toggle)
			)
		);
	};
	let mutedCount;
	let filter = function () {
		let muted = set.has(this.textContent);
		if (muted) mutedCount++;
		return muted;
	};
	mw.hook('wikipage.content').add($content => {
		if (!$content.is('#mw-content-text, .mw-changeslist')) return;
		if (!set.size) {
			$toggleSpan.hide();
			return;
		}
		mutedCount = 0;
		$content.find('.changedby > .mw-userlink:only-child')
			.filter(filter).closest('table').addClass('rcmuter-muted');
		$content.find('.mw-userlink:not(.changedby > *, .rcmuter-muted *)')
			.filter(filter).closest('.mw-changeslist-line, table').addClass('rcmuter-muted')
			.closest('table.mw-enhanced-rc').find('.changedby > .mw-userlink').filter(filter).addClass('rcmuter-muted');
		$toggleSpan.toggle(!!mutedCount);
		$toggle.attr('data-rcmuter', mutedCount);
	});
});