├── CNAME ├── README.md ├── apple-touch-icon-114x114.png ├── apple-touch-icon-72x72.png ├── apple-touch-icon.png ├── favicon.ico ├── images ├── grey.gif ├── loading.gif ├── zoom-in-icon.png └── zoom-out-icon.png ├── index.html ├── javascripts ├── app.js ├── handlebars.1.0.0.beta.3.js ├── imagesLoaded.js ├── jquery-1.5.1.min.js ├── jquery.cookie.js ├── jquery.debounce.js ├── jquery.in-viewport.js └── spin.min.js ├── robots.txt └── stylesheets ├── base.css └── layout.css /CNAME: -------------------------------------------------------------------------------- 1 | redditate.com -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Redditate 2 | ================= 3 | 4 | Redditate is a simple Reddit reader that aims to make the browsing experience more pleasurable and easier for newbies :) 5 | 6 | 7 | Why am I making it? 8 | ----- 9 | 10 | I effin love browsing Reddit, but I wish I had a way to browse it that was a bit more friendly and beautiful. Reddit's design is functional, but I wanted to strip it down and make it my own. I've been noodling in my free time after everyone else is asleep, so don't expect rapid progress. 11 | 12 | 13 | Want to use it yourself? 14 | ----- 15 | 16 | Just go to [www.redditate.com](http://www.redditate.com). Are you a super nerd who wants their own copy?! Download the codebase here on Github, open the index.html file and enjoy (no server needed). 17 | 18 | 19 | What works right now? 20 | ----- 21 | 22 | + Browsing the front page or any subreddit - click the dropdown in the fixed header 23 | + Using fullview and listview - cookies your preference 24 | + Inline imgur and youtube - click them to play or zoom in 25 | + Click images to see max-size inline 26 | + Keyboard navigation 27 | + Endless scrolling 28 | + Check it out on any device (responsive media query goodness) 29 | 30 | 31 | What's coming next? 32 | ----------- 33 | 34 | Honestly not sure just yet. Going to wait to see what everyone thinks and go from there! 35 | 36 | 37 | Can haz feedback? 38 | ----------- 39 | 40 | I would love to hear if you have any feedback on Redditate - just drop me an email at hi@redditate.com. -------------------------------------------------------------------------------- /apple-touch-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhg/Redditate/9f1ac39e6521e0f638dc86797e391512ed054761/apple-touch-icon-114x114.png -------------------------------------------------------------------------------- /apple-touch-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhg/Redditate/9f1ac39e6521e0f638dc86797e391512ed054761/apple-touch-icon-72x72.png -------------------------------------------------------------------------------- /apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhg/Redditate/9f1ac39e6521e0f638dc86797e391512ed054761/apple-touch-icon.png -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhg/Redditate/9f1ac39e6521e0f638dc86797e391512ed054761/favicon.ico -------------------------------------------------------------------------------- /images/grey.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhg/Redditate/9f1ac39e6521e0f638dc86797e391512ed054761/images/grey.gif -------------------------------------------------------------------------------- /images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhg/Redditate/9f1ac39e6521e0f638dc86797e391512ed054761/images/loading.gif -------------------------------------------------------------------------------- /images/zoom-in-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhg/Redditate/9f1ac39e6521e0f638dc86797e391512ed054761/images/zoom-in-icon.png -------------------------------------------------------------------------------- /images/zoom-out-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhg/Redditate/9f1ac39e6521e0f638dc86797e391512ed054761/images/zoom-out-icon.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 19 | 20 | Redditate: Top News 21 | 22 | 23 | 26 | 27 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 37 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 56 | 81 | 98 | 99 | 100 | 101 | 102 | 103 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 116 | 131 | 132 |
133 |
134 |
135 |

keeping itFresh

136 | 142 |
143 |
144 |

it's all about theVisuals

145 | 151 |
152 |
153 |

I love being a Nerd

154 | 160 |
161 |
162 |

always keepLearning

163 | 169 |
170 |
171 |

Shortcuts: j = next post, k = previous post, z = zoom image,
enter = open post, c = comments, f = fullview, l = listview

172 |

Want to view another subreddit? Just use this fine equation:
www.redditate.com/?r=r/nameofthesubreddit

173 |

Created by Dave Gamache, © 2011.
davegamache.com / @dhg

174 |

Redditate proudly rocks the base CSS of Skeleton,
the responsive, grid & boilerplate

175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 | Load Next 25 185 |
186 |
187 |
188 | 189 |
190 |
191 |
192 | 193 |
194 |
195 | 196 | 197 |
198 |
199 | 200 | 213 | 214 | 227 | 228 | 229 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 243 | -------------------------------------------------------------------------------- /javascripts/app.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Redditate 3 | * Copyright 2011, Dave Gamache 4 | * www.redditate.com 5 | * Free to use under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 10/01/2011 8 | */ 9 | 10 | $(document).ready(function() { 11 | 12 | 13 | //Global Vars ----------------------------------------------------- 14 | 15 | var posts = $('.posts'), 16 | afterString, 17 | subdomain = readParams('r'), 18 | loader = $('.wash'), 19 | loadMore = $('.loadmore-button'), 20 | activePost = 0, 21 | post, 22 | subredditHint = $('.subreddit-hint p'), 23 | hintIndex = 0, 24 | lock = false, 25 | commandDown = false, 26 | subredditShortcutJustLaunched = false, 27 | loadedPosts = []; 28 | isTouchDevice = 'ontouchstart' in document.documentElement; 29 | 30 | 31 | //Initial Load ------------------------------------------------------------------------------- 32 | 33 | window.scrollTo(0,0); 34 | 35 | // If viewType cookied, set it 36 | if($.cookie("viewtype")) { 37 | $('body') 38 | .removeClass('fullview') 39 | .removeClass('listview') 40 | .addClass($.cookie("viewtype")); 41 | } 42 | 43 | //Initial JSON load 44 | loadJSON(); 45 | 46 | //JSON ------------------------------------------------------------------------------- 47 | 48 | // Load data 49 | function loadJSON() { 50 | $.getJSON("https://www.reddit.com/"+subdomain+".json?limit=25&after="+afterString+"&jsonp=?", null, function(data) { 51 | $.each(data.data.children, function(i, post) { 52 | //If the post wasn't loaded before, render it. 53 | if(loadedPosts.indexOf(post.data.id) < 0) renderPost(post.data); 54 | afterString = post.data.name; 55 | //Save the post id. 56 | loadedPosts.push(post.data.id); 57 | }); 58 | }).complete(function() { 59 | post = $('.post'); 60 | classifyImages(); 61 | loader.fadeOut(100); 62 | loadMore.removeClass('loading'); 63 | lock = false; 64 | playVisibleVideos(); 65 | gfyCollection.init(); 66 | }); 67 | } 68 | 69 | function playVisibleVideos() { 70 | // $('video').each(function(){ 71 | // this.pause(); 72 | // }); 73 | 74 | if (!isTouchDevice) { 75 | $('video:in-viewport').each(function(){ 76 | this.play(); 77 | }) 78 | } 79 | } 80 | 81 | function throttle(fn, threshhold, scope) { 82 | threshhold || (threshhold = 250); 83 | var last, 84 | deferTimer; 85 | return function () { 86 | var context = scope || this; 87 | 88 | var now = +new Date, 89 | args = arguments; 90 | if (last && now < last + threshhold) { 91 | // hold on to it 92 | clearTimeout(deferTimer); 93 | deferTimer = setTimeout(function () { 94 | last = now; 95 | fn.apply(context, args); 96 | }, threshhold); 97 | } else { 98 | last = now; 99 | fn.apply(context, args); 100 | } 101 | }; 102 | } 103 | 104 | throttledVideo = throttle(playVisibleVideos, 100) 105 | 106 | $(window).scroll(function(){ 107 | 108 | // Load more JSON from scroll 109 | if ($(window).scrollTop() >= $(document).height() - $(window).height() - 10){ 110 | if (isTouchDevice) { 111 | 112 | } else { 113 | if(lock == false) { 114 | lock = true; 115 | loader.fadeIn(100); 116 | loadJSON(); 117 | } 118 | } 119 | } 120 | //Control activePost value based on scroll position 121 | if($(document).scrollTop() > (post.eq(activePost).offset().top-90)) { 122 | activePost++ 123 | } 124 | if($(document).scrollTop() < (post.eq(activePost-1).offset().top-90)) { 125 | if(activePost-1 > 0) { 126 | activePost-- 127 | } 128 | } 129 | throttledVideo(); 130 | // console.log("activePost: "+activePost+", documentScrollTop: "+$(document).scrollTop()+", activePost offset top: "+(post.eq(activePost).offset().top-90)) 131 | 132 | }); 133 | 134 | // Load more JSON from click (tablet/mobile) 135 | $('.loadmore-button').click(function() { 136 | if(lock == false) { 137 | loadMore.addClass('loading') 138 | loadJSON(); 139 | } 140 | }); 141 | 142 | 143 | 144 | //Rendering ------------------------------------------------------------------------------- 145 | 146 | // Render Post with Handlebars 147 | function renderPost(postData) { 148 | var templateSource = $("#postTemplate").html(), 149 | postTemplate = Handlebars.compile(templateSource); 150 | postHTML = postTemplate(postData); 151 | 152 | // If it's an imgur album make a request to the imgur API 153 | if (postData.url.indexOf('imgur.com/a/') >= 0) { 154 | fetchImgurAlbum(postData); 155 | } 156 | 157 | posts.append(postHTML); 158 | 159 | } 160 | 161 | // hit the imgur API for some sweet json 162 | function fetchImgurAlbum(postData) { 163 | var pathArray = postData.url.split( '/' ), 164 | hash = pathArray[4], 165 | albumUrl = 'http://api.imgur.com/2/album/' + hash + '.json'; 166 | 167 | $.getJSON(albumUrl, function(json, textStatus) { 168 | 169 | renderAlbum(postData, json); 170 | 171 | }); 172 | 173 | } 174 | 175 | // render first image as a preview and store rest of src tags as data attributes 176 | function renderAlbum(postData, imgurAlbumData) { 177 | var albumTemplateSource = $("#imgurAlbumTemplate").html(), 178 | albumTemplate = Handlebars.compile(albumTemplateSource), 179 | albumHTML = albumTemplate(imgurAlbumData.album); 180 | 181 | 182 | $('#' + postData.name).find('.image-embed').html(albumHTML); 183 | 184 | var $previewImage = $('#album-' + imgurAlbumData.album.cover).find('li:first-of-type img'), 185 | previewImageSrc = $previewImage.data('src'); 186 | 187 | $previewImage.attr('src', previewImageSrc); 188 | 189 | // bind click event to first image to load rest of album 190 | $('#album-' + imgurAlbumData.album.cover).find('.open-album').bind('click', function(event) { 191 | 192 | event.preventDefault(); 193 | 194 | $(this).parent('.open-album-wrapper').siblings('li').find('img').each(function(index) { 195 | 196 | $(this).attr('src', $(this).data('src')); 197 | 198 | }); 199 | 200 | $(this).parents('.imgur-album').addClass('show-album'); 201 | 202 | }); 203 | } 204 | 205 | //Create readable title from ?r= subdomain value 206 | if(!subdomain == "") { 207 | var readableSubdomain = subdomain.replace("r/", "") 208 | $('.logo .subreddit .title').text(readableSubdomain); 209 | document.title = "Redditate: "+readableSubdomain; 210 | } 211 | 212 | 213 | // Template Helpers ------------------------------------------------------------------------------- 214 | 215 | // IMAGE: Rendering fullsize images 216 | Handlebars.registerHelper('hasImage', function(url, fn) { 217 | var isImgur = (/imgur*/).test(url); 218 | var isGifv = (/https?:\/\/i\.imgur\.com\/([A-Za-z0-9]+)\.gifv/).exec(url); 219 | var isGfycat = (/https?:\/\/gfycat\.com\/([A-Za-z0-9]+)/).exec(url); 220 | var isWebm = (/\.webm$/).test(url); 221 | 222 | if(isImgur) { 223 | 224 | if(isImage(url)) { 225 | // do nothing 226 | } else { 227 | url += ".jpg" 228 | } 229 | } else { 230 | var isQuickMeme = (/(?:qkme\.me|quickmeme\.com\/meme)\/(\w*)/).exec(url); 231 | if (isQuickMeme !== null) { 232 | url = "http://i.qkme.me/" + isQuickMeme[1] + ".jpg"; 233 | } 234 | 235 | var isLiveMeme = (/(?:livememe\.com)\/(\w*)/).exec(url); 236 | if (isLiveMeme !== null) { 237 | url = "http://ai1.livememe.com/" +isLiveMeme[1] + ".gif"; 238 | } 239 | } 240 | 241 | if (isGifv !== null) { 242 | return '
' + 243 | '' + 247 | '
'; 248 | } else if (isGfycat !== null) { 249 | return ''; 250 | } else if (isWebm) { 251 | return '
' + 252 | '