Sleazy Fork is available in English.

ExVisited

Shows when a gallery was last visited and allows the hiding of individual galleries

  1. // ==UserScript==
  2. // @name ExVisited
  3. // @namespace Smoer
  4. // @description Shows when a gallery was last visited and allows the hiding of individual galleries
  5. // @include http://exhentai.org/*
  6. // @include https://exhentai.org/*
  7. // @include http://g.e-hentai.org/*
  8. // @include https://g.e-hentai.org/*
  9. // @version 2.1
  10. // @grant GM_setValue
  11. // @grant GM_getValue
  12. // @require http://code.jquery.com/jquery-1.11.0.min.js
  13. // ==/UserScript==
  14.  
  15. if(typeof(Storage) == "undefined"){
  16. alert("[ExVisited] Your browser does not support storage.");
  17. }
  18.  
  19. var url = document.URL;
  20. var sto = localStorage.getItem("exvisit3") ? localStorage.getItem("exvisit3") : '{"data":{}}';
  21. var vis = JSON.parse(sto);
  22. var spl = url.split("/");
  23. var d1 = spl[3]
  24. var d2 = spl[4];
  25. var d3 = spl[5];
  26. var css = GM_getValue("css") ? GM_getValue("css") : "background:#222 !important";
  27.  
  28. var hidden_raw = localStorage.getItem("exvisit3_h") ? localStorage.getItem("exvisit3_h") : '{"data":{}}';
  29. var hidden_tab = JSON.parse(hidden_raw);
  30.  
  31. vis["data"] = !vis["data"] ? Array() : vis["data"];
  32. hidden_tab["data"] = !hidden_tab["data"] ? Array() : hidden_tab["data"];
  33.  
  34. // Helper stuff
  35. if (!Date.now) {
  36. Date.now = function() { return new Date().getTime(); };
  37. }
  38.  
  39. Number.prototype.pad0 = function(length) {
  40. var result = this.toString();
  41. while(result.length<length) result = "0"+result;
  42. return result;
  43. }
  44.  
  45. Object.size = function(obj) {
  46. var size = 0, key;
  47. for (key in obj) {
  48. if (obj.hasOwnProperty(key)) size++;
  49. }
  50. return size;
  51. };
  52.  
  53. var old_storage = localStorage.getItem("exvisit");
  54. if(old_storage){
  55. console.log("Found old storage");
  56. var osj = JSON.parse(old_storage);
  57. console.log(osj);
  58. for(i=0;i<Object.size(osj["data"]);i++){
  59. vis["data"][ osj["data"][i] ] = Date.now();
  60. }
  61. console.log("Merged entries ("+Object.size(osj["data"])+")");
  62. localStorage.setItem("exvisit3",JSON.stringify(vis));
  63. localStorage.removeItem("exvisit"); // ;_;7
  64. }
  65.  
  66. function ExStore(){
  67. var c = d2+"."+d3;
  68. vis["data"][c] = Date.now();
  69. localStorage.setItem("exvisit3",JSON.stringify(vis));
  70. }
  71.  
  72. function timeDifference(current, previous) {
  73.  
  74. var msPerMinute = 60 * 1000;
  75. var msPerHour = msPerMinute * 60;
  76. var msPerDay = msPerHour * 24;
  77. var msPerMonth = msPerDay * 30;
  78. var msPerYear = msPerDay * 365;
  79.  
  80. var elapsed = current - previous;
  81.  
  82. if (elapsed < msPerMinute) {
  83. return Math.round(elapsed/1000) + ' seconds ago';
  84. }
  85.  
  86. else if (elapsed < msPerHour) {
  87. return Math.round(elapsed/msPerMinute) + ' minutes ago';
  88. }
  89.  
  90. else if (elapsed < msPerDay ) {
  91. return Math.round(elapsed/msPerHour ) + ' hours ago';
  92. }
  93.  
  94. else if (elapsed < msPerMonth) {
  95. return Math.round(elapsed/msPerDay) + ' days ago';
  96. }
  97.  
  98. else if (elapsed < msPerYear) {
  99. return Math.round(elapsed/msPerMonth) + ' months ago';
  100. }
  101.  
  102. else {
  103. return Math.round(elapsed/msPerYear ) + ' years ago';
  104. }
  105. }
  106.  
  107. var img_hide = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIhSURBVDjLlZPrThNRFIWJicmJz6BWiYbIkYDEG0JbBiitDQgm0PuFXqSAtKXtpE2hNuoPTXwSnwtExd6w0pl2OtPlrphKLSXhx07OZM769qy19wwAGLhM1ddC184+d18QMzoq3lfsD3LZ7Y3XbE5DL6Atzuyilc5Ciyd7IHVfgNcDYTQ2tvDr5crn6uLSvX+Av2Lk36FFpSVENDe3OxDZu8apO5rROJDLo30+Nlvj5RnTlVNAKs1aCVFr7b4BPn6Cls21AWgEQlz2+Dl1h7IdA+i97A/geP65WhbmrnZZ0GIJpr6OqZqYAd5/gJpKox4Mg7pD2YoC2b0/54rJQuJZdm6Izcgma4TW1WZ0h+y8BfbyJMwBmSxkjw+VObNanp5h/adwGhaTXF4NWbLj9gEONyCmUZmd10pGgf1/vwcgOT3tUQE0DdicwIod2EmSbwsKE1P8QoDkcHPJ5YESjgBJkYQpIEZ2KEB51Y6y3ojvY+P8XEDN7uKS0w0ltA7QGCWHCxSWWpwyaCeLy0BkA7UXyyg8fIzDoWHeBaDN4tQdSvAVdU1Aok+nsNTipIEVnkywo/FHatVkBoIhnFisOBoZxcGtQd4B0GYJNZsDSiAEadUBCkstPtN3Avs2Msa+Dt9XfxoFSNYF/Bh9gP0bOqHLAm2WUF1YQskwrVFYPWkf3h1iXwbvqGfFPSGW9Eah8HSS9fuZDnS32f71m8KFY7xs/QZyu6TH2+2+FAAAAABJRU5ErkJggg==";
  108.  
  109. console.log( Object.keys(hidden_tab["data"]).sort() );
  110.  
  111. function ExHide(){
  112.  
  113. var list = $(".it5");
  114. var thumb = $(".id1");
  115. var ids = [];
  116. // regular list
  117. if(list.length>0){
  118. $("table.itg tbody tr:first-child()").append("<th>Last viewed</th>");
  119. $("div.it5").css("max-width","570px");
  120. for(i=0;i<list.length;i++){
  121.  
  122. (function(tmp){
  123. var d = $(list[tmp]).find("a").attr("href").split("/");
  124. var galleryId = d[4]+"."+d[5];
  125.  
  126. if(hidden_tab["data"][ galleryId ] != undefined){
  127. console.log("Found hidden gallery: " + galleryId );
  128. $(list[tmp]).parent().parent().parent().slideUp(500).remove();
  129. }else{
  130.  
  131. console.log("Found gallery: " + galleryId );
  132.  
  133. $("<img src='" + img_hide + "' style='cursor:pointer !important; vertical-align:-4px; margin-right:1px; float:left' title='Hide gallery'>" ).prependTo( $(list[tmp]).find("a").first().parent().parent().parent() ).on( 'click', function(){
  134. ExHideGallery( galleryId );
  135. $(list[tmp]).parent().parent().parent().slideUp(500).remove();
  136. });
  137.  
  138. if(vis["data"][ galleryId ] != undefined){
  139. var d = new Date(vis["data"][ galleryId ]);
  140. $(list[tmp]).parent().parent().parent().addClass('gv');
  141. $(list[tmp]).parent().parent().parent().append("<td style='font-size:9px; text-align:left; width:80px'>"+timeDifference(Date.now(), vis["data"][ galleryId ]) + "<br>" + d.getHours().pad0(2) + ":" + d.getMinutes().pad0(2) + " " + d.getDate() + "/" + (d.getMonth()+1) + "</td>");
  142. }else{
  143. $(list[tmp]).parent().parent().parent().append("<td style='font-size:9px; text-align:left; width:80px'>Never</td>");
  144. }
  145.  
  146. }
  147. })(i);
  148.  
  149. }
  150. }
  151.  
  152. // thumbnails
  153. if(thumb.length>0){
  154. for(i=0;i<thumb.length;i++){
  155. var d = $(thumb[i]).find("a").attr("href").split("/");
  156. var c = d[4]+"."+d[5];
  157. $(thumb[i]).css('padding-bottom','25px');
  158. if(vis["data"][c] != undefined){
  159. var d = new Date(vis["data"][c]);
  160. $(thumb[i]).addClass('gv');
  161. $(thumb[i]).append("<br><div style='font-size:11px; margin-top:-5px; text-align:center'>"+timeDifference(Date.now(), vis["data"][c]) + " (" + d.getHours().pad0(2) + ":" + d.getMinutes().pad0(2) + " " + d.getDate() + "/" + (d.getMonth()+1) + ")</div>")
  162. }
  163. }
  164. }
  165. }
  166.  
  167. function ExHideGallery(id){
  168.  
  169. // clean slate
  170. var hidden_raw = localStorage.getItem("exvisit3_h") ? localStorage.getItem("exvisit3_h") : '{"data":{}}';
  171. var hidden_tab = JSON.parse(hidden_raw);
  172.  
  173. hidden_tab["data"][ id ] = 1;
  174. console.log("Hidden gallery: " + id );
  175. localStorage.setItem("exvisit3_h",JSON.stringify(hidden_tab));
  176. }
  177.  
  178. $(function(){
  179. $("head").append("<style>.gv { "+css+" }</style>");
  180. if(d1 == "g"){ ExStore(); }
  181. if(d1.substr(0,1) == "?" || d1.substr(0,1) == "#" || d1.substr(0,1) == "f" || d1.substr(0,1) == "t" || !d1){
  182. var len = Object.size(vis["data"]);
  183. $("#toppane").append('<div style="text-align:center">'+len+' visited galleries, ' + Object.size(hidden_tab["data"]) + ' hidden. <a href="javascript:;" id="ExImport">Import</a> / <a href="javascript:;" id="ExExport">Export</a> / <a href="javascript:;" id="ExCss">CSS</a></div>');
  184. $("#ExExport").click(function(){
  185. var e = "";
  186. for(d in vis["data"]){
  187. e += d + ":"+vis["data"][d]+";";
  188. }
  189. $("body").html('<div style="width:400px;height:400px;overflow:auto;padding:10px;margin:10px">'+e+'</div>');
  190. });
  191. $("#ExImport").click(function(){
  192. var c = prompt("Input data here:");
  193. if(c){
  194. var d = JSON.parse('{"data":{}}');
  195. var sp = c.split(";");
  196. for(k in sp){
  197. var s = sp[k].split(":");
  198. d["data"][s[0]] = parseInt(s[1]);
  199. }
  200. alert("Imported "+Object.size(d["data"])+" entries.");
  201. localStorage.setItem("exvisit3", JSON.stringify(d))
  202. location.reload();
  203. }
  204. });
  205. $("#ExCss").click(function(){
  206. var c = prompt("Input CSS here:", css);
  207. if(c){
  208. GM_setValue("css",c);
  209. location.reload();
  210. }
  211. });
  212.  
  213. ExHide();
  214. }
  215. });