jetman81 / Hide Forum Threads

// ==UserScript==
// @name Hide Forum Threads
// @namespace ThreadFilter
// @description Hides threads in Vbulletin boards.
// @require http://code.jquery.com/jquery-latest.min.js
// @require http://code.jquery.com/ui/1.11.2/jquery-ui.min.js
// @include http://www.neogaf.com/forum/forumdisplay.php?f=*
// ==/UserScript==

// Version 0.3 - 12/21/2014

var sThreadTitle;
nShownCount = 0;
nOriginalPageCount = GetNextPage();
nPageCount = nOriginalPageCount;
nAdditionalThreadCount = 0;

$(document).ready(function() {
    IgnoreList = localStorage.getItem('IgnoreList') ? JSON.parse(localStorage.getItem('IgnoreList')) : [];
    $("body").append("<link rel='stylesheet' href='//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css'>");
	$("body").append('<style>.threadbit > td > a[id^="RemoveThread"]:before {  content: "x";  font-size: 10pt;} .threadbit > td > a[id^="RemoveThread"] {  position: absolute !important;  margin-left: -11px;  margin-top: -38px;  font-size: 0pt;  visibility: hidden !important;} .threadbit > td:hover > a[id^="RemoveThread"] {  visibility: visible !important; }</style>');        
 	$('.large-button:first').parent().append("<select id='ThreadFilter'><option value='Unignored' selected='true'>Show Unignored Only</option><option value='Ignored'>Show Ignored Only</option><option value='All'>Show All</option></select>&nbsp;");
    $('#ThreadFilter').change(UpdateThreads); 
    
	var sWordFilter = CreateWordFilter();
    var sControlPanel = "<div id='tabs' style='display:none;'>";
  	sControlPanel += "<ul>";
  	sControlPanel += "<li><a href='#tabs-1'>Word Filter</a></li>";
    sControlPanel += "<li><a href='#tabs-3'>Ignored List</a></li>"; 
    sControlPanel += "<li><a href='#tabs-2'>Settings</a></li>";
    sControlPanel += "</ul>";
  	sControlPanel += "<div id='tabs-1'>";
    sControlPanel += sWordFilter;
    sControlPanel += "</div>";
    sControlPanel += "<div id='tabs-3'>";
    sControlPanel += "<div id='RecentlyIgnoredListing'></div>";
    sControlPanel += "</div>";
  	sControlPanel += "<div id='tabs-2'>";
    sControlPanel += CreateSettingsOptions();
    sControlPanel += "</div>";
	sControlPanel += "</div>";

	$('.large-button:first').parent().append(sControlPanel);
    $('.large-button:first').parent().append($('<a id="OpenFilterCP" class="large-button submit">Filter CP</a>'));
	$('#OpenFilterCP').click(OpenFilterCP);
	$('#AddWordButton').click(AddToWordFilter);
    $('#SearchAdditional').change(function() { localStorage.setItem('SearchAdditional', this.checked); }); 

  	$("td[id*='td_threadstatusicon_']").each(function( index,value ) { AddHideLink(this);});

    if (localStorage.getItem("ThreadFilter"))
    	$("#ThreadFilter").val(localStorage.getItem("ThreadFilter"));
    
    if (localStorage.getItem("SearchAdditional"))
        $("#SearchAdditional").attr("checked", localStorage.getItem("SearchAdditional") == "true" ? true : false);
    else
        localStorage.setItem("SearchAdditional", "true");
    
    UpdateThreads();

});


function containsObject(id, list) {
	    var i;
	    for (i = 0; i < list.length; i++) {
		    if (list[i].ID == id || list[i].Word == id) {
    			return i;
    			}
    		}

    	return -1;
	}

function IgnoreThread(event) { 
    var nThreadID = event.data.param1;
    var addThread = {};
    addThread.ID = nThreadID;
    addThread.Title = $('#thread_title_' + nThreadID).text();
    IgnoreList = localStorage.getItem('IgnoreList') ? JSON.parse(localStorage.getItem('IgnoreList')) : [];
    nThreadIndex = containsObject(nThreadID,IgnoreList);
            
    if (nThreadIndex == -1) 
    	{
            IgnoreList.push(addThread); 
            document.getElementById('RemoveThread' + nThreadID).innerHTML = 'Show';
        } 
    else 
    	{ 
            IgnoreList.splice(nThreadIndex,1); 
            document.getElementById('RemoveThread' + nThreadID).innerHTML = 'Hide';
        } 
    
	localStorage.setItem('IgnoreList', JSON.stringify(IgnoreList));
    UpdateThreads();
            

    
    }
    
    function UpdateThreads()
    {
        nShownCount = 0;
    	$('#ThreadFilter').blur();
    	localStorage.setItem('ThreadFilter',$('#ThreadFilter').val());
    	
    	$("td[id*=td_threadstatusicon_]").each(function(index) 
        	{
    		 nThreadID = $(this).attr('id').replace('td_threadstatusicon_','');
    		 sThreadTitle = $('#thread_title_' + nThreadID).text();
                
             if (CheckThreadHidden(nThreadID,sThreadTitle))
                 $(this).parent().hide();
             else
             {
                 nShownCount++;
                 $(this).parent().show();
             }
             
		});

    
        if (localStorage.getItem("SearchAdditional") == "true")
        {
            GetAdditionalThreads();
        }
        
    //    console.log(nShownCount + ' - ' + nAdditionalThreadCount);
    
    } 



function GetAdditionalThreads()
{
    //console.log('Page ' + nPageCount + ' begins');
    //console.log(window.location.href + "&order=desc&page=" + nPageCount);
    
    if (nShownCount < 40 && nPageCount <= nOriginalPageCount + 5)
    {
        var jqxhr = $.get(window.location.href + "&order=desc&page=" + nPageCount, ProcessAdditionalThread)
    	.done(function() {
        nPageCount ++;
        
        GetAdditionalThreads();
  		});
    }
}

function ProcessAdditionalThread(data)
{
    //console.log('page ' + nPageCount + ' length - ' + data.length);

    var lastThread = $("td[id*='td_threadstatusicon_']").last();
    
        $(data).find("td[id*='td_threadstatusicon_']").each(function(index, value) 
       	{
            nThreadID = $(this).attr('id').replace('td_threadstatusicon_','');
        	sThreadTitle = $(data).find('#thread_title_' + nThreadID).text();
        	
        	nAdditionalThreadCount = nAdditionalThreadCount + 1;
        	
        	if (!CheckThreadHidden(nThreadID, sThreadTitle) && nShownCount < 40)
            	{
    	            console.log(nThreadID);
	                $(lastThread).parent().after($(this).parent().clone().wrap('<p>').parent().html());
    	    		AddHideLink($("td[id*=td_threadstatusicon_" + nThreadID + "]"));    	
            		nShownCount++;
            	}
           
    	});
}

function AddHideLink(currentThread)
{
    	nThreadID = $(currentThread).attr('id').replace('td_threadstatusicon_','');
                         
        if (containsObject(nThreadID,IgnoreList) == -1)
            sIgnoreText = "Hide";
        else
            sIgnoreText = "Show";
    
    
    	if ($(currentThread).has("a[id*='RemoveThread" + nThreadID + "']").length == 0);
    {
        $('<a></a>', {
  		text: sIgnoreText,
        id: "RemoveThread" + nThreadID
		}).appendTo(currentThread);
        
        $('#RemoveThread' + nThreadID).click({param1: nThreadID}, IgnoreThread); 
    }
}


function CheckThreadHidden(nThreadID, sThreadTitle)
{
    		var sThreadFilterVal = $('#ThreadFilter').val();
    		var bWordFilterApplies = false;
    
    		IgnoreList = JSON.parse(localStorage.getItem('IgnoreList'));
    		nThreadIndex = containsObject(nThreadID,IgnoreList);
    		
    		var bThreadIgnored = (nThreadIndex == -1) ? false : true;
    
             if (bThreadIgnored && sThreadFilterVal == 'Unignored' )
             {
                 return true;
             }
             else
             {
                 bWordFilterApplies = WordFilterApplies(sThreadTitle);
                 
                 if (bWordFilterApplies && sThreadFilterVal == 'Unignored')
             		{
                 		return true;
             		}
             	else if (!bThreadIgnored && !bWordFilterApplies && sThreadFilterVal == 'Ignored')
             		{
                 		return true;
             		}
             }
    
    return false;
}

function WordFilterApplies(sThreadTitle)
{
    var bFilterApplies = false;
	WordList = localStorage.getItem('WordList') ? JSON.parse(localStorage.getItem('WordList')) : [];
            
    jQuery.each(WordList,function (index)
	{
        if (this.Type == 'plaintext')
		{
			sFragments = this.Word.split('*');
		
			bMatchesPattern = true;
			jQuery.each(sFragments, function(index)
			{
				if (sThreadTitle.toLowerCase().indexOf(this.toLowerCase()) == -1)
				{
					bMatchesPattern = false;
				}
			});
		
			if (bMatchesPattern == true)
            	{
                    bFilterApplies = true;
					return 0;
            	}
		}
		else if (this.Type == 'regularexpression')
		{
			sRegExMatches = sThreadTitle.match(this.Word);
			
			if (sRegExMatches)
            {
                bFilterApplies = true;
                return 0;;
            }
		}
    });
	
    return bFilterApplies;
 }   
 

function AddToWordFilter(event)
{
	newWord = $('#AddWordText').val();

var addWord= {};
addWord.Word = newWord;
addWord.Type = $('input[name*=AddWordType]:checked').val();

WordList = localStorage.getItem('WordList') ? JSON.parse(localStorage.getItem('WordList')) : [];
nWordIndex = containsObject(addWord.Word,WordList);

if (nWordIndex == -1) 
{

WordList.push(addWord); 
} 
    
localStorage.setItem('WordList', JSON.stringify(WordList));
$('#AddWordText').val('');
UpdateWordListing();
}

function RemoveFromWordFilter(event)
{
    var index = event.data.param1;
    
	WordList = localStorage.getItem('WordList') ? JSON.parse(localStorage.getItem('WordList')) : [];
	WordList.splice(index,1); 
	localStorage.setItem('WordList', JSON.stringify(WordList));
	UpdateWordListing();
}

function UpdateWordListing()
{
	$('#WordListing').empty();
  WordList = localStorage.getItem('WordList') ? JSON.parse(localStorage.getItem('WordList')) : [];
    
    var sWordListing;
    
    sWordListing = '<table width="100%"><tr><td align="center" width="200px"><strong>Word</strong></td><td align="center" width="200px"><strong>Type</strong></td><td>&nbsp;</td></tr>';
		
  jQuery.each(WordList,function (index) 
	{	
        sWordListing += '<tr><td align="center"><div style="word-wrap:break-word;width:200px">' + this.Word + '</div></td><td align="center">' + this.Type + '</td><td><input type=button id="RemoveWord' + index + '" value=Remove /></td></tr>';
        
	});
    
    sWordListing += '</table>';
    
    $('#WordListing').append(sWordListing);
        
    jQuery.each(WordList,function (index) 
                {
    $('#RemoveWord' + index).click({param1: index}, RemoveFromWordFilter);
                });
        
}

function CreateWordFilter()
{
    sWordFilter = "<div id='WordFilter'>";
    sWordFilter += "<strong>Add New Word:</strong>&nbsp;<input id='AddWordText'><input type='button' id='AddWordButton' value='Add'><br /><input type='radio' name='AddWordType' value='plaintext' checked>Plain Text (* supported)<input type='radio' name='AddWordType' value='regularexpression'>Regular Expression<br /><br /><hr width='100%' color='black'><div id='WordListing'></div>";
    sWordFilter += "</div>";
    
    return sWordFilter;
}

function CreateSettingsOptions()
{
    sCreateSettings = "<input type='checkbox' id='SearchAdditional' checked='true'>Search additional pages for threads</input>";
    return sCreateSettings;
}

function OpenFilterCP()
    {
    	UpdateWordListing();
        UpdateRecentlyIgnoredListing();
        $('#tabs').tabs();
        $('#tabs').dialog();
        $('#tabs').bind('dialogclose', function(event) { UpdateThreads();});
    	$('#tabs').dialog({ title: "Filter Control Panel"});
        $("#tabs").dialog("option", "width", $("#tabs").dialog( "option", "width" ) + 200);
    }

function UpdateRecentlyIgnoredListing()
{
	$('#RecentlyIgnoredListing').empty();
    IgnoreList = localStorage.getItem('IgnoreList') ? JSON.parse(localStorage.getItem('IgnoreList')) : [];
    IgnoreList.reverse();
    var sRecentlyIgnoredListing;
    
    sRecentlyIgnoredListing = '<table width="100%"><tr><td align="center" width="300px"><strong>Title</strong></td></td><td>&nbsp;</td></tr>';
		
  jQuery.each(IgnoreList,function (index) 
	{	
        sRecentlyIgnoredListing += '<tr><td align="center"><div style="word-wrap:break-word;width:300px"><a href="http://www.neogaf.com/forum/showthread.php?t=' + this.ID + '" target="_blank">' + this.Title + '</a></div></td><td><input type=button id="RemoveRecentlyIgnored' + this.ID + '" value=Unignore /></td></tr>';
        
	});
    
    sRecentlyIgnoredListing += '</table>';
    
    $('#RecentlyIgnoredListing').append(sRecentlyIgnoredListing);
        
    jQuery.each(IgnoreList,function (index) 
                {
                    $('#RemoveRecentlyIgnored' + this.ID).click({param1: index, param2: IgnoreList}, RemoveRecentlyIgnored);
                });
        
    
}


function RemoveRecentlyIgnored(event) { 
    event.data.param2.splice(event.data.param1,1); 
    event.data.param2.reverse();
    localStorage.setItem('IgnoreList', JSON.stringify(event.data.param2));
    UpdateRecentlyIgnoredListing();
}

function GetNextPage()
{
    var str = window.location.href; 
	var res = str.match("page=[0-9]+");
    
    if (res)
        	return parseInt(res[0].replace("page=","")) + 1;
    else
            return 2;
                        
}