• Hey Guest. Check out your NeoGAF Wrapped 2025 results here!

GAF Keyboard Shortcuts - Yet another Chrome extension

Status
Not open for further replies.

Zeppu

Member
So this morning I woke up with a brilliant idea.

Going with the "Don't procrastinate" resolution which I invented a few seconds after I thought of the idea I started implementing it and here it is.

Get it here.

Might still be buggy and whatnot, but I'm all excited about it and want you guys to try it out (please) and tell me if you like, what's wrong with it and what you'd like to see.

As of v1.7.1 these are the shortcuts supported. (? for up to date on-screen command list)

yHptW.png


Anyway, try it out, let me know if you like it.

So, the reasoning behind my shortcuts:

a/s are the global prev/next shortcuts. The select prev/next thread/post. That remains the same everywhere. Reaching the end and pressing s again will take you to the next page automatically.
A/S are global prev/next page shortcuts. If available they will go to the next page.

Your fingers should be on a/s all the time. On QWERTY keyboards the buttons right above them are Q,W,E which I've assigned in a position relative to what you would click in the thread listings page:
fn7Fy.png


When reading threads it made more sense to have q for quote and r for reply.

Global goto shortcuts are simple.
g is for 'Go', o is for OT, g is for gaming, s is for subscriptions, etc...

Change List:
v1.7.1
- j to Jump directly to link (link numbers are show next to links, select the number to open in new tab)
- Bug fix: go to top (g then t) automatically subscribed to thread :S

v1.6
- t to Subscribe to Thread.

v1.5
- Added post highlight to follow user's posts. (thanks to Zombie James for idea and code for post highlight)

v1.2.1
- automatically selects next thread when opening link in background
- EASTER EGG!!

v1.2
- most commands can be opened in a new tab by holding shift!
- bug fixes
- commands window was borked on linux.

v1.1
- e to edit current post
- g then t - go to topmost item
- g then b - go to bottom item
- command list pops up every time there is an update with new shortcuts (so even if you forget the thread, you'll always know whats new :D)

v1.0.5
- f to focus on search
- X to eXpose spoilers in currently selected post
- when you load up the reply page, focus is given to the text area on load.

Todo List:
- On screen help - '?' - I was thinking of doing it like Google's on reader/gmail/everything when you press ?
- Go out of current thread into the current forum. I'm thinking 'w'.
- Edit post - 'e'?
- Focus on search box
- Go to first/last post/thread
- Options page
- Integrate with the GAF live updater.
- Integrate my NeoGAF post highlighter into it (soon).
- Autofocus on text area when loading the reply page.
- Not adding a New Thread shortcut. Posting of new threads should be made more difficult :P
- Options
- Select next thread when opening in new tab
- Enable/disable integration with other GAF plugins​
- Whatever you guys suggest which is doable.
 
Just replied using "r," now I just gotta remember the rest of the shortcuts :D
 
I want an extension like that dude made for firefox where highlight and
spoiler
tabs show up when you reply to a thread.
 
Hi guys! Thanks for the feedback. Let me know of any bugs please. Next item on the list is a shortcut to bring on screen the list of commands, so hopefully people will be able to get used to the commands quicker.

sprsk said:
Hmm, didn't work at all for me.

Hmm, strange, Do other NeoGAF extensions work? Also, what domain do you use to access GAF since as it is the script only executes itself on 'http://www.neogaf.com/*'. (ga-forum.com or stuff like that won't work).
 
Your directions are wrong. You have q as quoting and for next post.... it's actually s. Also I believe I ran into a bug early on (seems it hasn't repeated yet) where previous post (a) brought me back up to the first post.
 
Timedog said:
I want an extension like that dude made for firefox where highlight and
spoiler
tabs show up when you reply to a thread.

Install from here bro: http://userscripts.org/scripts/show/50489 - Works on chrome.

UltimaPooh said:
Your directions are wrong. You have q as quoting and for next post.... it's actually s. Also I believe I ran into a bug early on (seems it hasn't repeated yet) where previous post (a) brought me back up to the first post.

You're right, thanks for that - updated it. I'll check out what you described. The code for detecting what post you are currently looking at to start a/s is a little wonky, I know, let me know how to reproduce to tackle it asap ;)
 
josephdebono said:
You're right, thanks for that - updated it. I'll check out what you described. The code for detecting what post you are currently looking at to start a/s is a little wonky, I know, let me know how to reproduce to tackle it asap ;)

I can't repeat it. It was at the very beginning when I first used it but now it works fine. I guess don't worry about it unless other posters start popping up with it.

Anyway the app is pretty nice. It will be hard to give up my 10+ years of scrolling forums.
 
UltimaPooh said:
I can't repeat it. It was at the very beginning when I first used it but now it works fine. I guess don't worry about it unless other posters start popping up with it.

Anyway the app is pretty nice. It will be hard to give up my 10+ years of scrolling forums.

I did release a 1.0.1 a few minutes after I posted the article. You know how it is, one thing always slips by due to a last second change. It was highlighting the 3rd post first time you press 's' withing a thread. Maybe that also fixed whatever you observed.

1stStrike said:
so yeah it works. i wonder how long it'll take me to remember all the shortcuts though...

True, check updated OP for my reasoning behind the selected shortcuts.

Megadrive said:
how does it work out what the current post is supposed to be?

You navigate through posts/threads using a/s. A tiny arrow (») is shown on the far left to let you know which one is currently selected. Seems like people are not seeing it though. I'll look into what may be the problem.
 
josephdebono said:
You navigate through posts/threads using a/s. A tiny arrow (») is shown on the far left to let you know which one is currently selected. Seems like people are not seeing it though. I'll look into what may be the problem.

After navigating with a and s it works fine and I can see it. Great work! Any chance of releasing the source code? I'm interested in developing some extensions for Chrome.
 
What I need is a good stylish theme for neogaf. There used to be a pretty awesome one back in the day with a green coloring to it (actually looked great) but I can't find it now and the ones on stylish are mostly crap :|
 
Megadrive said:
After navigating with a and s it works fine and I can see it. Great work! Any chance of releasing the source code? I'm interested in developing some extensions for Chrome.

Extensions are basically .zip files. Download the crx (right click, save from the extension page), rename to .zip and extract. All source in there. Please pardon my inefficient/sloppy code, I was thinking more about getting it done than getting it done gracefully.
 
g then g - Go to Gaming
g then o - Go to OT
g then c - Go to Community
g then u - Go to User CP
g then s - Go to Subscriptions


best part
 
Hi again guys.

Updated again... :S

? - toggles on screen command list :D
w - in thread view takes you back to the parent board (so if you press it here you go back to the OT)
 
Awesome extension op, u have made Gaf have better browsing experience, thnx!

BTW I can't see this arrow thingy which tells you which bit your quoting.. anyone provide a screenie?
 
Sh1ner said:
Awesome extension op, u have made Gaf have better browsing experience, thnx!

BTW I can't see this arrow thingy which tells you which bit your quoting.. anyone provide a screenie?

Use a/s to navigate first, then you can use q.


Phantast2k said:
That's some hot shit. Thanks!
However I'd like to have a semi-transparent panel that I could toggle on and off to display all of the shortcuts.

Nonetheless: thank you very much!

press '?'.

Or do you mean to have it there all the time?
 
That's some hot shit. Thanks!
However I'd like to have a semi-transparent panel that I could toggle on and off to display all of the shortcuts.

Nonetheless: thank you very much!

/edit
FUUUUUUU
So far these are the shortcuts supported. (? for on-screen command list)

thanks ;(

/edit2
josephdebono said:
Or do you mean to have it there all the time?
Nah it's fine! Everything's lovely as it is :)
 
MOAR SHORTCUTS! YAAAY!

X (upper case) shows (
eXposes?
) spoilers.
f focuses on searchbox.

I'm enjoying this too much...
 
1stStrike said:
I've got this on my laptop and desktop now, though unfortunately I primarily use firefox on my desktop :(

I'm sure someone more talent than myself would be able to convert it to a greasemonkey script for ya.

JS
Code:
var currentPage = null;
var prevKey;

const link_OT = "forumdisplay.php?f=3";
const link_GA = "forumdisplay.php?f=2";
const link_CO = "forumdisplay.php?f=8";
const link_CP = "usercp.php";
const link_SU = "subscription.php";

var _posts={
	$posts : null,
	count: 0,
	resetField: function() {
		$posts = $('#posts .page');
		if ($posts.length == 0) return;
		$pos = $($posts[this.count]).position();
		while (window.pageYOffset > $pos.top)
				$pos = $($posts[++this.count]).position();		
	},
	keyHandler: function(e) {
		switch(e.which)
		{
			case 97:	this.showPreviousPost();
						break;	
						
			case 115:	this.showNextPost();
						break;
						
			case 113:	this.quoteCurrentPost();
						break;		

			case 114:	this.gotoReply();
						break;
            
            		case 119: 	this.gotoBoard();
						break;

			case 88:	this.showSpoilers();
						break;
			
			default: return false;

		}
		return true;
	},
	showPreviousPost : function () {
		if ($posts.length == 0) return;
		
		if (this.count > 0) this.count--
		
		$pos = $($posts[this.count]).position();
		$('.arrow').remove();
		$($posts[this.count]).prepend('<span class="arrow" style="display: inline; position: absolute; left: 5px;" >»</span>');
		window.scroll(0,$pos.top);
	
	},
	showNextPost : function () {
		if ($posts.length == 0) return;
		
		if (this.count < $posts.length-1) this.count++;
		else {
			gotoNextPage();
		}
		
		$pos = $($posts[this.count]).position();		
		$('.arrow').remove();
		$($posts[this.count]).prepend('<span class="arrow" style="display: inline; position: absolute; left: 5px; ">»</span>');
		window.scroll(0,$pos.top);
	},
	quoteCurrentPost : function() {
		if ($posts.length == 0) return;
		redirect($($posts[this.count]).find('a:contains("Quote")').attr('href'));
	},
	gotoReply : function () {
		redirect($('img[title^="Reply"]').parent().attr('href'));
	},
	gotoBoard : function() {
		redirect($('.activetab > a').attr('href'));
	},
	showSpoilers : function() {
		if ($posts.length == 0) return;
		$($posts[this.count]).find('span.spoiler').toggleClass('spoilme');
	}
	
}

var _threads={
	$threads : null,
	count: -1,
	resetField: function() {
		$threads = $('td[id^="td_title"]').parent();
		if ($threads.length == 0) return;
	},
	keyHandler: function(e) {
		switch(e.which)
		{
			case 97:	this.selectPrevThread();
						break;	
						
			case 115:	this.selectNextThread();
						break;
						
			case 119: 	this.gotoFirstPage();
						break;

			case 113: 	this.gotoFirstUnread();
						break;
						
			case 101: 	this.gotoLastPage();
						break;
			
			default: return false;

		}
		return true;
	},
	selectPrevThread : function () {
		if ($threads.length == 0) return;
		
		if (this.count > 0) this.count--; else this.count = 0;
		
		$pos = $($threads[this.count]).position();
		$('.arrow').remove();
		$('.currentSelected').removeClass("currentSelected");
		$($threads[this.count]).addClass("currentSelected");
		$($($threads[this.count]).children()).first().prepend('<span class="arrow" style="display: inline; position: absolute; left: 5px; padding-top: 5px;" >»</span>');
		if (window.pageYOffset > $pos.top)
			window.scroll(0,$pos.top);
	
	},
	selectNextThread : function () {
		if ($threads.length == 0) return;
		
		if (this.count < $threads.length-1) this.count++;
		else {
			gotoNextPage();
		}
		
		$pos = $($threads[this.count]).position();		
		$('.arrow').remove();
		$('.currentSelected').removeClass("currentSelected");
		$($threads[this.count]).addClass("currentSelected");
		$($($threads[this.count]).children()).first().prepend('<span class="arrow" style="display: inline; position: absolute; left: 5px; padding-top: 5px;">»</span>');
		if (window.pageYOffset + (window.innerHeight / 2) < $pos.top)
			window.scroll(0,window.pageYOffset + $('.currentSelected').height());
	},
	gotoFirstPage : function() {
		redirect($(".currentSelected' [id^='thread_title_']").attr('href'));
	},
	gotoFirstUnread : function() {
		$link = $(".currentSelected [id^='td_status_'] > a");
		if ($link.length > 0)
			redirect($link.attr('href'));
	},
	gotoLastPage : function() {
		redirect($(".currentSelected [id^='td_title_'] a:last").attr('href'));
	}
}

function gotoPrevPage() {
	if ($('a[title^="Prev Page"]').length != 0)
	{
		redirect($('a[title^="Prev Page"]').attr('href'));
	}
}

function gotoNextPage() {
	if ($('a[title^="Next Page"]').length != 0)
	{
		redirect($('a[title^="Next Page"]').attr('href'));
	}
}

function detectPageType(e) {
	if (document.location.href.search(/forumdisplay.php|usercp.php|subscription.php/i) != -1) {
		currentPage = _threads;
		currentPage.resetField();
		return;
	}
	
	if (document.location.href.search(/showthread.php/i) != -1) {
		currentPage = _posts;
		currentPage.resetField();
		return;
	}
	
	currentPage = -1;
	
}

function focusOnSearch(e) {
	$('input[name="q"]').focus();
}

function redirect(url) {

if (url != null)
	window.location = url;

}

function globalKeyHandler(e) {
	switch (e.which) {
		case 65:	gotoPrevPage();
					break;
		
		case 83:	gotoNextPage();
					break;

		case 103:	prevKey = true;
					break;
		
		case 63:	showHelp();
					break;
		
		case 102:	focusOnSearch() 
					return false;
					

	}
}

function redirectHandler(e) {
	switch (e.which) {
		case 111:	redirect(link_OT);
					break;
		
		case 103:	redirect(link_GA);
					break;
					
		case 99:	redirect(link_CO);
					break;
		
		case 117:	redirect(link_CP);
					break;
					
		case 115 : 	redirect(link_SU);
					break;
	}
}

function showHelp() {
	if ($("#helpBox").length == 0) {
		$("body").prepend(helpHTML);
		$("#hideHelp").click(function() { $("#helpBox").hide(); });
	} else {
		$("#helpBox").toggle();
	}
}

$(document).keypress(function(e)
	{	
		if (e.target.nodeName == 'INPUT' || e.target.nodeName == 'TEXTAREA') return;
		if (currentPage == null)
			detectPageType();
		
		if (prevKey) {
			prevKey = false;
			redirectHandler(e);
		}
	
		if (currentPage != null && currentPage != -1) {
			if (!currentPage.keyHandler(e))
				return globalKeyHandler(e);
		}
		else return globalKeyHandler(e);
		
	});

$(document).ready(function() 
{
	if (document.location.href.search(/newthread.php/i) != -1) {
		$('input[name="subject"]').focus();	
	}

	if (document.location.href.search(/newreply.php/i) != -1) {
		$('textarea[name="message"]').focus();	
	}	
});

var helpHTML = "<div id='helpBox'>" +
        "<h2>Keyboard Shortcuts</h2>" +
        "<div id='hideHelp'>close</div>" +
        "<table class='listing'>" +
	"<tr><td class='w10'>&nbsp;</td><td class='w40 action'>Global</td><td class='w10'>&nbsp;</td><td class='w40 action'>Thread List</td></tr>" +
	"<tr><td class='w10 action'>A</td><td class='w40'>Previous page</td><td class='w10 action'>a</td><td class='w40'>Select previous thread</td></tr>" +
	"<tr><td class='w10 action'>S</td><td class='w40'>Next page</td><td class='w10 action'>s</td><td class='w40'>Select next thread</td></tr>" +
    "<tr><td class='w10 action'>g <span class='tiny'>then</span> g</td><td class='w40'>Go to Gaming board</td><td class='w10 action'>q</td><td class='w40'>Go to first unread post</td></tr>" +
    "<tr><td class='w10 action'>g <span class='tiny'>then</span> o</td><td class='w40'>Go to Off-Topic board</td><td class='w10 action'>w</td><td class='w40'>Go to first page of selected thread</td></tr>" +
    "<tr><td class='w10 action'>g <span class='tiny'>then</span> c</td><td class='w40'>Go to Community board</td><td class='w10 action'>e</td><td class='w40'>Go to last page of selected thread</td></tr>" +
    "<tr><td class='w10 action'>g <span class='tiny'>then</span> s</td><td class='w40'>Go to Subscriptions</td><td class='w10'>&nbsp;</td><td class='w40'>&nbsp;</td></tr>" +
    "<tr><td class='w10 action'>g <span class='tiny'>then</span> u</td><td class='w40'>Go to User CP</td><td class='w10'>&nbsp;</td><td class='w40 action'>Thread View</td></tr>" +
    "<tr><td class='w10 action'>f</td><td class='w40'>Focus on search</td><td class='w10 action'>a</td><td class='w40'>Select previous post</td></tr>" +
    "<tr><td class='w10 action'>?</td><td class='w40'>Command list (toggle)</td><td class='w10 action'>s</td><td class='w40'>Select next post</td></tr>" +
    "<tr><td class='w10 action'>&nbsp;</td><td class='w40'>&nbsp;</td><td class='w10 action'>q</td><td class='w40'>Quote selected post</td></tr>" +
    "<tr><td class='w10 action'>&nbsp;</td><td class='w40'>&nbsp;</td><td class='w10 action'>X</td><td class='w40'>Expose spoilers in selected post (toggle)</td></tr>" +
    "<tr><td class='w10 action'>&nbsp;</td><td class='w40'>&nbsp;</td><td class='w10 action'>r</td><td class='w40'>Reply to thread</td></tr>" +
    "<tr><td class='w10 action'>&nbsp;</td><td class='w40'>&nbsp;</td><td class='w10 action'>w</td><td class='w40'>Go to parent forum</td></tr>" +
"</table>" + 

        "</div>";

CSS:
Code:
.currentSelected a[id^="thread_title"] {
	font-weight: bolder;
}

#helpBox {
	z-index: 999;
	position: fixed;
	padding: 1em;
	background-color: black;
	opacity: 0.7;
	margin: 2em;
	width: 800px;	
	margin-left: auto;
	margin-right: auto;
	right: 0;
	left: 0;
	-webkit-border-radius: 10px;
	color: white;
	font-size: 1.2em;
}

#helpBox h2 {
	border-bottom: 1px solid white;
	width: 100%;
	text-align: center;
	margin-top: 0;
}

#hideHelp {
	top: 1em;
	right: 1em;
	position: absolute;
	cursor: pointer;
}

td.w10 { 
	width: 10%; 
	text-align: right;
	padding-right: 5px;
}
td.w40 { width: 40%; } 
td.action { 
color: #DD0;
font-weight: bold; 
}
table.listing { width: 100%; }

td.w10.action {
	font-family: monospace;
}

span.tiny {
	color: white;
	font-size: 0.8em;
}
span.spoiler.spoilme {
	color : white;
}

Requires jquery. Sorry about the mess at the end of the end of the js but the help was done quick and dirty since it seemed useful to have it up ASAP.
 
Status
Not open for further replies.
Top Bottom