Suggested Feature: Ignore Thread

Grisu

Draghetto
Retired Moderator
Joined
Dec 20, 2001
Messages
10,531
Location
Switzerland
As we all know there's the Ignore List where we can put posters you have no wish to read again...But as of lately I've been wishing more and more that there was a feature 'Ignore Thread' (or similar)

At the moment OT looks a bit like this:
  • Obama blablabla
  • some thread
  • Palin nanananan
  • some other thread
  • McCain did thisandthat
  • etc
:cringe:

Every now and then some wave crashes over OT filling it with threads about the same issue (at the moment it's the Election, obviously). Rather than to deprive those that cherish those threads of them, a feature would be nice, so you'd have to only look once at a thread and then trash it (being the weak person that I am I usually end up in these threads despite better knowledge...)

Note: I have no idea if such a feature/plugin exists in vbulletin but if it does I herewith petition for its use :)
 
One suggested improvement on the excellent suggestion above is the capability to ignore threads with... say the words Palin, Obama, McCain etc in it. :)

I.e. auto-trash all thread titles with these words in them. :yeah:
 
:love:

now that would be spiffy (of course, OT would pretty much be empty) :)

btw, I found a Ignore Thread plugin for vbulletin: linky
 
It is in Outlook i.e. the 'rules' thingie, which is the inspiration for my improvement on your suggestion. Not sure if vb (the forum s/w, not the forum poster) has it.

The OT will not be empty - you'll just see older, probably better, threads. ;)
 
If it is not possible to implement this feature on server side, it shouldn't be that hard to write a Greasemonkey script to do it on the client side.
 
If it is not possible to implement this feature on server side, it shouldn't be that hard to write a Greasemonkey script to do it on the client side.
I take it to mean you'd volunteer for that task? :mischief:
 
With the traffic CFC gets, running such a filter will probably kill the server. Greasemonkey is the way to go.
 
I take it to mean you'd volunteer for that task? :mischief:

Why not...

The script bellow filters threads based on keywords in the OP tooltip (the little message you get when you hoover over a thread link for a while). It doesn't yet get threads which mention the keyword in the title but not in the OP, since that seems a little harder to do.

Spoiler :

Code:
// ==UserScript==
// @name           CFCfilter
// @description    Filter out threads by keywords
// @include        http://forums.civfanatics.com/*
// ==/UserScript==
var allElements, thisElement, replacements, regex, key, textnodes, node, s;


//############## EDIT THE VARIABLE BELLOW ############## 
//To match your preferences. It is the filter rule for the script.
//Any regular expression should work.
var filterregex = "[Pp]alin|[Oo]bama|[Mm][Cc]ain";


//############ Get rid of all threads with  OP previews machting the filter ############
allElements = document.evaluate(
    '//*[@title]',
    document,
    null,
    XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
    null);	

for (var i = 0; i < allElements.snapshotLength; i++) {
    thisElement = allElements.snapshotItem(i);
    if (thisElement.nodeName.toUpperCase() == 'TD')
	{
		for( var x = 0; x < thisElement.attributes.length; x++ ) 
		{
			if( thisElement.attributes[x].nodeName.toLowerCase() == 'title' ) 
			{
				s = thisElement.attributes[x].nodeValue;
				if( s.search(filterregex) != -1)
				{	
					node = thisElement.parentNode;
					node.parentNode.removeChild(node);
					//alert('Thread deleted');
				}
			}
		}				        
    }
}
// END FILE

Oh, and use at it your own risk. My coffee break isn't long enough to test this extensively..!
 
:lol: now that was fast...though it isn't really working for me :(

trying to find out what's the matter now...gosh I suck at JavaScript :cringe:
 
You might need to copy it again. I accidentally posted WIP code first.
If something is wrong Tools->Error Console should reveal what.
 
:worship: it's working now :)
 
How do I use that script, Till?

Also, I would freakin love a feature that could run a "rules" thing on the forum, so that I can make my own sub-forums! Pretty much a pipe-dream though... But it would be seriously Web 2.0 :)


EDIT: My god... just wiki'd this "greasemonkey" thing... How have I managed for so long without this?!?!?!?! :wow:
 
Glad it's working, Ovi! :D

Mise: You need to install the Greasemonkey extension, then save the script to a .js file and open it with Firefox. A prompt should appear, offering you to install it.

If you want to change the filter rule, you need to change the value of the
filterregex variable. Any Regular Expression should work.
 
I edited the script a bit so that it also filters the thread if the word is in the thread title....but as I said above, I suck at js, so it's rather crude (and untested)

Spoiler :

Code:
// ==UserScript==
// @name           CFCFilter
// @namespace      CFC
// @include        http://forums.civfanatics.com/*
// ==/UserScript==

var allElements, thisElement, replacements, regex, key, textnodes, node, s;

var filterregex = "[Pp]alin|[Oo]bama|[Mm]c[Cc]ain|[Gg]affe";


//############ Get rid of all threads with  OP previews machting the filter ############
allElements = document.evaluate(
    '//*[@title]',
    document,
    null,
    XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
    null);	

for (var i = 0; i < allElements.snapshotLength; i++) {
    thisElement = allElements.snapshotItem(i);
    if (thisElement.nodeName.toUpperCase() == 'TD')
	{
		for( var x = 0; x < thisElement.attributes.length; x++ ) 
		{
			if( thisElement.attributes[x].nodeName.toLowerCase() == 'title' ) 
			{			
				s = thisElement.attributes[x].nodeValue;
				if( s.search(filterregex) != -1)
				{	
					node = thisElement.parentNode;
					node.parentNode.removeChild(node);
					//alert('Thread deleted');
				}
			}			
		}

		if( thisElement.childNodes[1].childNodes[3] != null)
			{
				p = thisElement.childNodes[1].childNodes[3].innerHTML;
				if (p != null && p.search(filterregex) != -1)
				{
					node = thisElement.parentNode;
					if (node.parentNode != null)
					node.parentNode.removeChild(node);
					//alert('Thread deleted');
				}
			}		
    }
}

// END FILE


edit: that doesn't work with Polls yet, though.
 
Now that's all pretty cool, but I don't really want a filter. I want a button on each thread that I can press and then I never have to see that stupid thread again.

I'll probably install your filter at home though. Thanks for doin' that. :)
 
That's pretty cool, Ovi!

I made a new version myself that now filters based on:

+ OP tool tip
+ Title
+ Thread starter

It also works on polls and deletes posts by people included in the filter in all threads.

Spoiler :
Code:
//CFCFilter v0.2
//=UserScript==
// @name           CFCFilter
// @namespace      CFC
// @include        http://forums.civfanatics.com/*
// ==/UserScript==

var allElements, thisElement, replacements, regex, key, textnodes, node, s;

//############## EDIT THE VARIABLE BELLOW ############## 
//To match your preferences. It is the filter rule for the script.
//Any regular expression should work.
var filterregex = "[Pp]alin|[Oo]bama|[Mm]c[Cc]ain|[Gg]affe";


//############ Get rid of all threads with  OP previews matching the filter ############
allElements = document.evaluate(
    '//*[@title]',
    document,
    null,
    XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
    null);	

for (var i = 0; i < allElements.snapshotLength; i++) {
    thisElement = allElements.snapshotItem(i);
    if (thisElement.nodeName.toUpperCase() == 'TD')
	{
		for( var x = 0; x < thisElement.attributes.length; x++ ) 
		{
			if( thisElement.attributes[x].nodeName.toLowerCase() == 'title' ) 
			{			
				s = thisElement.attributes[x].nodeValue;
				if( s.search(filterregex) != -1)
				{	
					node = thisElement.parentNode;
					node.parentNode.removeChild(node);
					//alert('Thread deleted');
				}
			}		
		}
    }
}

//############ Get rid of all threads with  titles  matching the filter ############
allElements = document.evaluate(
    '//a[@href]',
    document,
    null,
    XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
    null);	
	
for (var i=0; i<allElements.snapshotLength; i++) 
{
    thisElement = allElements.snapshotItem(i);
	for( var x = 0; x < thisElement.childNodes.length; x++ )
	{
		if( thisElement.childNodes[x].nodeValue != null)
		{
			s = thisElement.childNodes[x].nodeValue;			
			if( s.search(filterregex) != -1)
			{	
				node = thisElement;
				while( node.nodeName.toLowerCase() != 'tr')
				{
					node = node.parentNode;					
				}
				node.parentNode.removeChild(node);				
				//alert('Thread deleted');
			}
		}			
	}
}
// END FILE
 
Now that's all pretty cool, but I don't really want a filter. I want a button on each thread that I can press and then I never have to see that stupid thread again.
I had started to adapt a existing script to do just that before Till posted the solution...it even worked but was very user-unfriendly (you have to manually enter the thread-id in the ignore list)....if I have excessive time tomorrow I might try to make a spiffy link to kill a specific thread :)

That's pretty cool, Ovi!

I made a new version myself that now filters based on:

+ OP tool tip
+ Title
+ Thread starter

It also works on polls and deletes posts by people included in the filter in all threads.

Spoiler :
Code:
//CFCFilter v0.2
//=UserScript==
// @name           CFCFilter
// @namespace      CFC
// @include        http://forums.civfanatics.com/*
// ==/UserScript==

var allElements, thisElement, replacements, regex, key, textnodes, node, s;

//############## EDIT THE VARIABLE BELLOW ############## 
//To match your preferences. It is the filter rule for the script.
//Any regular expression should work.
var filterregex = "[Pp]alin|[Oo]bama|[Mm]c[Cc]ain|[Gg]affe";


//############ Get rid of all threads with  OP previews matching the filter ############
allElements = document.evaluate(
    '//*[@title]',
    document,
    null,
    XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
    null);    

for (var i = 0; i < allElements.snapshotLength; i++) {
    thisElement = allElements.snapshotItem(i);
    if (thisElement.nodeName.toUpperCase() == 'TD')
    {
        for( var x = 0; x < thisElement.attributes.length; x++ ) 
        {
            if( thisElement.attributes[x].nodeName.toLowerCase() == 'title' ) 
            {            
                s = thisElement.attributes[x].nodeValue;
                if( s.search(filterregex) != -1)
                {    
                    node = thisElement.parentNode;
                    node.parentNode.removeChild(node);
                    //alert('Thread deleted');
                }
            }        
        }
    }
}

//############ Get rid of all threads with  titles  matching the filter ############
allElements = document.evaluate(
    '//a[@href]',
    document,
    null,
    XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
    null);    
    
for (var i=0; i<allElements.snapshotLength; i++) 
{
    thisElement = allElements.snapshotItem(i);
    for( var x = 0; x < thisElement.childNodes.length; x++ )
    {
        if( thisElement.childNodes[x].nodeValue != null)
        {
            s = thisElement.childNodes[x].nodeValue;            
            if( s.search(filterregex) != -1)
            {    
                node = thisElement;
                while( node.nodeName.toLowerCase() != 'tr')
                {
                    node = node.parentNode;                    
                }
                node.parentNode.removeChild(node);                
                //alert('Thread deleted');
            }
        }            
    }
}
// END FILE

nice to see that you've adopted 'Gaffe' to your default ignore list ;) I've come to hate that word :ack:
 
That would be a very useful addition! This filter is more suited for general policies, i.e. filter out the irredeemable threads and posters.

And yeah, gaffe encompasses everything that is wrong with politics...
 
I completed a early working version of my adaption of Till's script. This one won't filter threads containing keywords. What it does is create a link for every thread to put it on a ignore List.
As I said it's still a rather early version (and dirty too, there's just too many nested loops :cringe: ) ) so use at your own risk :)

Spoiler :

Code:
// ==UserScript==
// @name           ThreadBlocker
// @namespace      CFC
// @include        http://forums.civfanatics.com/*
// ==/UserScript==

var allElements, thisElement, replacements, regex, key, textnodes, node, s, threadid;
var splitCh = String.fromCharCode(255);


unsafeWindow._blockThread = function(threadid) {	
	window.setTimeout(SetKillFile, 0, threadid);
}

function updateKillFile(list) {
  var splitCh = String.fromCharCode(255);
  data = list.join(splitCh);
  window.setTimeout(GM_setValue, 0, "ThreadBlockerKillFile", escape(data));
 }



//adds a Thread to the Killfile 
function SetKillFile(killspec)
{
  var row = document.getElementById("td_threadtitle_"+killspec)
  row.parentNode.parentNode.removeChild(row.parentNode);
  var splitCh = String.fromCharCode(255);
  var data = "";
  var list = new Array();

  // initialize variables

  //killspec = prompt("Add to KillFile", killspec);
  data = unescape(GM_getValue("ThreadBlockerKillFile", "-----"));
  list = data.split(splitCh);
  list.push(killspec);

  updateKillFile(list);
  alert("Thread " + killspec + ' has been added to the KillFile.\n');
  // re-save new list with names added or removed
}



function run()
{
    allElements = document.evaluate(
        '//*[@title]',
        document,
        null,
        XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
        null);

    for (var i = 0; i < allElements.snapshotLength; i++) {
        thisElement = allElements.snapshotItem(i);
        if (thisElement.nodeName.toUpperCase() == 'TD')
        {
			for( var x = 0; x < thisElement.attributes.length; x++ )
            {
                if( thisElement.attributes[x].nodeName.toLowerCase() == 'title' )
                {
                    threadid = thisElement.getAttribute('id');
					if(threadid != null)
					{
						// Adding the Ignore-Link
						threadid = threadid.substring(15);
						var link = document.createElement('a');
						link.setAttribute('href', 'javascript:_blockThread("'+threadid+'")');
                        link.setAttribute('style', 'float:right;font-size:xx-small;');
						link.innerHTML = "Ignore";
                        thisElement.childNodes[1].appendChild(link);
						
						//Filtering Threads
						var data = unescape(GM_getValue("ThreadBlockerKillFile", "-----"));
						var list = data.split(splitCh);
						for (var j=0; j<list.length; j++) {		
							//var tid = threadid.substring(13);
							if (list[j] == threadid)
							{
								node = thisElement.parentNode;
								if (node.parentNode != null)
								{
									node.parentNode.removeChild(node);
									//alert('Thread deleted');
								}
							}
						}
					}
                }				
            }
        }
    }
}

run();


// END FILE
 
woops just noticed a bug...apparantly it filters some links that it shouldn't :blush:

edit: ok, should be fixed now:

Spoiler :
Code:
// ==UserScript==
// @name           ThreadBlocker
// @namespace      CFC
// @include        http://forums.civfanatics.com/*
// ==/UserScript==

var allElements, thisElement, replacements, regex, key, textnodes, node, s, threadid;
var splitCh = String.fromCharCode(255);


unsafeWindow._blockThread = function(threadid) {	
	window.setTimeout(SetKillFile, 0, threadid);
}

function updateKillFile(list) {
  var splitCh = String.fromCharCode(255);
  data = list.join(splitCh);
  window.setTimeout(GM_setValue, 0, "ThreadBlockerKillFile", escape(data));
 }



//adds a Thread to the Killfile 
function SetKillFile(killspec)
{
  var row = document.getElementById("td_threadtitle_"+killspec)
  row.parentNode.parentNode.removeChild(row.parentNode);
  var splitCh = String.fromCharCode(255);
  var data = "";
  var list = new Array();

  // initialize variables

  //killspec = prompt("Add to KillFile", killspec);
  data = unescape(GM_getValue("ThreadBlockerKillFile", "-----"));
  list = data.split(splitCh);
  list.push(killspec);

  updateKillFile(list);
  //alert("Thread " + killspec + ' has been added to the KillFile.\n');
  // re-save new list with names added or removed
}



function run()
{
    allElements = document.evaluate(
        '//*[@title]',
        document,
        null,
        XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
        null);

    for (var i = 0; i < allElements.snapshotLength; i++) {
        thisElement = allElements.snapshotItem(i);
        if (thisElement.nodeName.toUpperCase() == 'TD')
        {
			for( var x = 0; x < thisElement.attributes.length; x++ )
            {
                if( thisElement.attributes[x].nodeName.toLowerCase() == 'title' )
                {
                    threadid = thisElement.getAttribute('id');
					if(threadid != null)
					{
						// Adding the Ignore-Link
						threadid = threadid.substring(15);
						var link = document.createElement('a');
						link.setAttribute('href', 'javascript:_blockThread("'+threadid+'")');
                        link.setAttribute('style', 'float:right;font-size:xx-small;');
						link.innerHTML = "Ignore";
                        thisElement.childNodes[1].appendChild(link);
						
						//Filtering Threads
						var data = unescape(GM_getValue("ThreadBlockerKillFile", "-----"));
						var list = data.split(splitCh);
						for (var j=0; j<list.length; j++) {		
							//var tid = threadid.substring(13);
							if (list[j] == threadid && list[j] != "" && threadid != "")
							{
								node = thisElement.parentNode;
								if (node.parentNode != null)
								{									
									node.parentNode.removeChild(node);
									//alert('Thread deleted' + node.innerHTML);
									
								}
							}
						}
					}
                }				
            }
        }
    }
}

run();


// END FILE
 
Back
Top Bottom