Robin Enhancement Script

Highlight mentions, auto link links & automatically remove spam

Versión del día 3/4/2016. Echa un vistazo a la versión más reciente.

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Necesitará instalar una extensión como Tampermonkey para instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name         Robin Enhancement Script
// @namespace    https://www.reddit.com/
// @version      1.7
// @description  Highlight mentions, auto link links & automatically remove spam
// @author       mr_bag
// @match        https://www.reddit.com/robin/
// @grant        none
// ==/UserScript==
(function() {

	// Grab users username + play nice with RES
	var robin_user = $("#header-bottom-right .user a").first().text();
	var ignored_users = {};

	/**
	 * Check if a message is "spam"
	 */
	var is_spam = function(line){
		return (
			// Hide auto vote messages
			(/^voted to (grow|stay|abandon)/.test(line)) ||
			// random unicode?
			(/[\u0080-\uFFFF]/.test(line)) ||
			// hide any auto voter messages
			(/\[.*autovoter.*\]/.test(line)) ||
			// Common bots
			(/^(\[binbot\]|\[robin-grow\])/.test(line)) ||
			// repeating chars in line (more than 5). e.g. aaaaaaa !!!!!!!!
			(/(.)\1{5,}/.test(line)) ||
			// Some common messages
			(/(voting will end in approximately|\[i spam the most used phrase\]|\[message from creator\])/.test(line)) ||
			// no spaces = spam if its longer than 25 chars (dont filter links)
			(line.indexOf(" ") === -1 && line.length > 25 && line.indexOf("http") === -1) ||
			// repeating same word
			/(\b\S+\b)\s+\b\1\b/i.test(line)
		);
	};

	/**
	 * Check if a message is from an ignored user
	 *
	 */
	var is_ignored = function($usr, $ele){
		// no user name, go looking for when said it
		if($usr.length === 0){
			while($usr.length === 0){
				$ele = $ele.prev();
				$usr = $ele.find(".robin--username");
			}
		}
		// are they ignored?
		return (ignored_users[$usr.text()]);
	};

	/**
	 * Make links clickable
	 *
	 */
	var auto_link = function($msg){
		var text = $msg.html(); // read as html so stuff stays escaped
		// normal links
		text = text.replace(/\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|]/gim, '<a target="blank" href="$&">$&</a>');
		// reddit subreddit links
		text = text.replace(/ \/r\/(\w+)/gim, ' <a target="blank" href="https://reddit.com/r/$1">/r/$1</a>');
		// update text
		$msg.html(text);
	};

	/**
	 * Mute a user
	 */
	var _mute_user = function(usr){
		// Add to ignore list
		ignored_users[usr] = true;
		_render_muted_list();
	};

	/**
	 * un-mute a user
	 */
	var _unmute_user = function(usr){
		// Add to ignore list
		delete ignored_users[usr];
		_render_muted_list();
	};

	// Render list of ignored users
	var _render_muted_list = function(){
		var html = "<strong>Ignored users</strong><br>";
		for(var u in ignored_users){
			html += "<div data-usr='"+ u + "'>" + u + " - [unmute]</div>";
		}
		$("#muted_users").html(html);
	};

	// Scroll chat back to bottom
	var _scroll_to_bottom = function(){
		$("#robinChatWindow").scrollTop($("#robinChatMessageList").height());
	};

	/**
	 * Parse a link and apply changes
	 */
	var parse_line = function($ele){
		var $msg = $ele.find(".robin-message--message");
		var $usr = $ele.find(".robin--username");

		var line = $msg.text().toLowerCase();

		// If user is ignored or message looks like "Spam". hide it
		if (is_ignored($usr, $ele) || is_spam(line)) {
			$ele.addClass("spam-hidden");
		}

		// Highlight mentions
		if(line.indexOf(robin_user) !== -1){
			$ele.css("font-weight", "bold");
		}

		// Make links clickable
		if(line.indexOf("http") !== -1){
			auto_link($msg);
		}

		// Add mute button to users
		if(!$ele.hasClass("robin--user-class--system") && $usr.text() != robin_user){
			$("<span style='font-size:.8em;cursor:pointer'> [mute] </span>").insertBefore($usr).click(function(){
				_mute_user($usr.text());
			});
		}

		// Add filter support
		if(line.indexOf("%") === 0){ $ele.addClass("filter-percent");}
		if(line.indexOf("$") === 0){ $ele.addClass("filter-dollar");}
		if(line.indexOf("#") === 0){ $ele.addClass("filter-hash"); }
	};

	// Detect changes, are parse the new message
	$("#robinChatWindow").on('DOMNodeInserted', function(e) {
		if ($(e.target).is('div.robin-message')) {
			// Apply changes to line
			parse_line($(e.target));
		}
	});

	// When everything is ready
	$(document).ready(function(){
		// Set default spam filter type
		$("#robinChatWindow").addClass("hide-spam");

		// Add checkbox to toggle "hide" behaviors
		$("#robinDesktopNotifier").append("<label><input type='checkbox' checked='checked'>Hide spam completely</label>").click(function(){
			if($(this).find("input").is(':checked')){
				$("#robinChatWindow").removeClass("mute-spam").addClass("hide-spam");
			}else{
				$("#robinChatWindow").removeClass("hide-spam").addClass("mute-spam");
			}
			// correct scroll after spam filter change
			_scroll_to_bottom();
		});

		// Add Muted list & hook up unmute logic
		$('<div id="muted_users" class="robin-chat--sidebar-widget robin-chat--notification-widget"><strong>Ignored users</strong></div>').insertAfter($("#robinDesktopNotifier"));
		$('#muted_users').click(function(e){
			var user = $(e.target).data("usr");
			if(user) _unmute_user(user);
		});

		// Hook up toggles for filters
		$('<div id="filter_mode">Filter: <span data-filter="*">Show all</span> | <span data-filter="%">% Only</span> | <span data-filter="$">$ Only</span> | <span data-filter="#"># Only</span> | <span data-filter="hide">No channels</span></div>').insertAfter("#robinSendMessage").click(function(e){
			var filter = $(e.target).data("filter");
			if(filter === '*'){
				$("#robinChatWindow").removeClass("filter_on").removeAttr("data-filter").removeClass("filter_all_channels");
			}else if(filter === 'hide'){
				$("#robinChatWindow").removeClass("filter_on").removeAttr("data-filter").addClass("filter_all_channels");
			}else{
				$("#robinChatWindow").addClass("filter_on").attr("data-filter", filter);
			}
			// correct scroll after filter change
			_scroll_to_bottom();
		});
		// Auto append % when in filtered mode
		$("#robinSendMessage").submit(function(){
			if($("#robinChatWindow").hasClass("filter_on")){
				if($(".text-counter-input").val().indexOf("/") !== 0){ // /commands should work as normal
					$(".text-counter-input").val($("#robinChatWindow").attr("data-filter") + " " + $(".text-counter-input").val());
				}
			}
		});
	});


	// filter styles
	document.styleSheets[0].insertRule("#robinChatWindow.filter_on div.robin-message { display:none; }", 0);
	document.styleSheets[0].insertRule("#robinChatWindow.filter_on[data-filter='$'] div.robin-message.filter-dollar,#robinChatWindow.filter_on[data-filter='%'] div.robin-message.filter-percent,#robinChatWindow.filter_on[data-filter='#'] div.robin-message.filter-hash,#robinChatWindow.filter_on div.robin-message.robin--user-class--system  { display:block; }", 0);
	document.styleSheets[0].insertRule("#robinChatWindow.filter_all_channels div.robin-message.filter-dollar,#robinChatWindow.filter_all_channels  div.robin-message.filter-hash, #robinChatWindow.filter_all_channels div.robin-message.filter-percent { display:none; }", 0);

	document.styleSheets[0].insertRule("#filter_mode span { cursor: pointer;}", 0);

	// Add initial styles for "spam" messages
	document.styleSheets[0].insertRule("#robinChat #robinChatWindow.hide-spam div.robin-message.spam-hidden { display:none; }", 0);
	document.styleSheets[0].insertRule("#robinChat #robinChatWindow.mute-spam div.robin-message.spam-hidden { opacity:0.3; font-size:1.2em; }", 0);

	// muted user box
	document.styleSheets[0].insertRule("#muted_users { font-size:1.2em; }", 0);
	document.styleSheets[0].insertRule("#muted_users div { padding: 2px 0; }", 0);
	document.styleSheets[0].insertRule("#muted_users strong { font-weight:bold; }", 0);

	// FIX RES nightmode (ish)
	document.styleSheets[0].insertRule(".res-nightmode #robinChatWindow div.robin-message { color: #ccc; }", 0);
})();