E-H Visited

Marks visited galleries.

ของเมื่อวันที่ 23-03-2019 ดู เวอร์ชันล่าสุด

  1. // ==UserScript==
  2. // @name E-H Visited
  3. // @description Marks visited galleries.
  4. // @author Hen Tie
  5. // @homepage https://hen-tie.tumblr.com/
  6. // @namespace https://greasyfork.org/en/users/8336
  7. // @include /https?:\/\/(e-|ex)hentai\.org\/.*/
  8. // @require https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js
  9. // @grant GM_setValue
  10. // @grant GM_getValue
  11. // @run-at document-start
  12. // @icon https://i.imgur.com/pMMVGRx.png
  13. // @version 2.4
  14. // ==/UserScript==
  15. // 2019 fork of exvisited: sleazyfork.org/en/scripts/22270
  16.  
  17. /*═════════════════════════╦═════════════════════════════╦════════════════════════╗
  18. ║ IMPORT ║ EXPORT ║ CSS ║
  19. ╠══════════════════════════╬═════════════════════════════╬════════════════════════╣
  20. ║ data format is unchanged ║ localstorage is impermanent ║ you can set custom css ║
  21. ║ should import from any ║ but exporting is simple ║ for marking viewed ║
  22. ║ old exvisited scripts ║ one click gives plain text ║ galleries ║
  23. ╚══════════════════════════╩═════════════════════════════╩═══════════════════════*/
  24.  
  25. var storageName = "ehVisited"; //name of object, to avoid clash with old installs
  26. var url = document.URL;
  27. var sto = localStorage.getItem(storageName) ? localStorage.getItem(storageName) : '{"data":{}}';
  28. var vis = JSON.parse(sto);
  29. var spl = url.split("/");
  30. var d1 = spl[3]
  31. var d2 = spl[4];
  32. var d3 = spl[5];
  33. var css = GM_getValue("css") ? GM_getValue("css") : "background:rgba(2, 129, 255, .2)"; //default highlight colour
  34. if (css === "initial") {
  35. css = "background:rgba(2, 129, 255, .2)";
  36. } else if (css === "none") {
  37. css = "";
  38. }
  39.  
  40. vis["data"] = !vis["data"] ? Array() : vis["data"];
  41.  
  42. if (typeof (Storage) == "undefined") {
  43. alert("E-H Visited:\nYour browser does not support localStorage :(");
  44. }
  45.  
  46. // date.now shim (probably unnecessary)
  47. if (!Date.now) {
  48. Date.now = function () {
  49. return new Date().getTime();
  50. };
  51. }
  52.  
  53. Number.prototype.pad0 = function (length) {
  54. var result = this.toString();
  55. while (result.length < length) result = "0" + result;
  56. return result;
  57. }
  58.  
  59. Object.size = function (obj) {
  60. var size = 0,
  61. key;
  62. for (key in obj) {
  63. if (obj.hasOwnProperty(key)) size++;
  64. }
  65. return size;
  66. };
  67.  
  68. function ehvStore() {
  69. var c = d2 + "." + d3;
  70. vis["data"][c] = Date.now();
  71. localStorage.setItem(storageName, JSON.stringify(vis));
  72. }
  73.  
  74. function timeDifference(current, previous) {
  75. var msPerMinute = 60 * 1000;
  76. var msPerHour = msPerMinute * 60;
  77. var msPerDay = msPerHour * 24;
  78. var msPerMonth = msPerDay * 30;
  79. var msPerYear = msPerDay * 365;
  80. var elapsed = current - previous;
  81.  
  82. if (elapsed < msPerMinute) {
  83. return Math.round(elapsed / 1000) + " seconds ago";
  84. } else if (elapsed < msPerHour) {
  85. return Math.round(elapsed / msPerMinute) + " minutes ago";
  86. } else if (elapsed < msPerDay) {
  87. return Math.round(elapsed / msPerHour) + " hours ago";
  88. } else if (elapsed < msPerMonth) {
  89. return Math.round(elapsed / msPerDay) + " days ago";
  90. } else if (elapsed < msPerYear) {
  91. return Math.round(elapsed / msPerMonth) + " months ago";
  92. } else {
  93. return Math.round(elapsed / msPerYear) + " years ago";
  94. }
  95. }
  96.  
  97. function ehvHide() {
  98. var list = $("table.itg>tbody>tr"); //present only in list views
  99. var thumb = $(".itg .gl1t"); //present only in thumbnail view
  100. var gid;
  101. var d;
  102. var galleryId;
  103.  
  104. // check current view
  105. if (list.length > 0) {
  106. if ($('.gl1e').length) { //extended
  107. for (i = 0; i < list.length; i++) {
  108. gid = $(list[i]).find(".glname a").attr("href").split("/");
  109. galleryId = gid[4] + "." + gid[5];
  110. if (vis["data"][galleryId] != undefined) {
  111. d = new Date(vis["data"][galleryId]);
  112. $(list[i]).addClass("ehv-visited");
  113. $(list[i]).find('.gldown').prepend("<ehv class='ehv-extended'>" + timeDifference(Date.now(), vis["data"][galleryId]) + "<br>(" + d.getHours().pad0(2) + ":" + d.getMinutes().pad0(2) + " " + d.getDate() + "/" + (d.getMonth() + 1) + ")</div>")
  114. }
  115. }
  116. } else if ($('.gl1c').length) { //compact
  117. var borderColour = $('.gl1c').first().css('border-top-color'); //border colour different between domains
  118. $('table.itg tbody>tr:first-child').append('<th>Visited</th>');
  119. for (i = 1; i < list.length; i++) {
  120. gid = $(list[i]).find(".glname a").attr("href").split("/");
  121. galleryId = gid[4] + "." + gid[5];
  122. if (vis["data"][galleryId] != undefined) {
  123. d = new Date(vis["data"][galleryId]);
  124. $(list[i]).addClass("ehv-visited");
  125. $(list[i]).append('<td class="ehv-compact" style="border-color:' + borderColour + ';"><ehv title="' + timeDifference(Date.now(), vis["data"][galleryId]) + "\n" + d.getHours().pad0(2) + ":" + d.getMinutes().pad0(2) + " " + d.getDate() + "/" + (d.getMonth() + 1) + '">&#128065Yes</ehv></td>');
  126. } else {
  127. $(list[i]).append('<td class="ehv-compact" style="border-color:' + borderColour + ';"></td>');
  128. }
  129. }
  130. } else { //minimal
  131. for (i = 1; i < list.length; i++) {
  132. gid = $(list[i]).find(".glname a").attr("href").split("/");
  133. galleryId = gid[4] + "." + gid[5];
  134. if (vis["data"][galleryId] != undefined) {
  135. d = new Date(vis["data"][galleryId]);
  136. $(list[i]).addClass("ehv-visited");
  137. $(list[i]).find('.gl2m').append('<ehv class="ehv-minimal" title="' + timeDifference(Date.now(), vis["data"][galleryId]) + "\n" + d.getHours().pad0(2) + ":" + d.getMinutes().pad0(2) + " " + d.getDate() + "/" + (d.getMonth() + 1) + '">&#128065</ehv>')
  138. }
  139. }
  140. }
  141. } else if (thumb.length > 0) { //thumbnail
  142. for (var i = 0; i < thumb.length; i++) {
  143. gid = $(thumb[i]).find(".glname a").attr("href").split("/");
  144. var c = gid[4] + "." + gid[5];
  145. if (vis["data"][c] != undefined) {
  146. d = new Date(vis["data"][c]);
  147. $(thumb[i]).addClass("ehv-visited");
  148. $(thumb[i]).children('.gl5t').after("<ehv class='ehv-thumbnail'>" + timeDifference(Date.now(), vis["data"][c]) + " (" + d.getHours().pad0(2) + ":" + d.getMinutes().pad0(2) + " " + d.getDate() + "/" + (d.getMonth() + 1) + ")</div>")
  149. }
  150. }
  151. } else {
  152. console.log("E-H Visited\nI don't know what view mode this is!");
  153. }
  154. }
  155.  
  156. //script body
  157. $("<style>.gl3e>div:nth-child(6){left:unset;width:100%;text-align:center;} .gl2m{width:144px;} .gl2m>div:nth-child(3){left:unset;right:4px;top:7px;}" + //overrides
  158. ".ehv-minimal{position:absolute;top:7px;right:23px;width:1em;line-height:1;font-size:15px;}" + //icon only
  159. ".ehv-compact{border-style:solid;border-width:1px 0;}" + //td with icon
  160. ".ehv-extended,.ehv-thumbnail{display:block;text-align:center;margin-bottom:1em;}" + //full text timestamp
  161. "table.itg>tbody>tr.ehv-visited, .gl1t.ehv-visited{" + css + "}" + //style visited galleries
  162. ".ehv-controls{text-align:center;display:block;}" +
  163. "</style>").appendTo("head");
  164.  
  165. if (d1 == "g") {
  166. ehvStore();
  167. }
  168.  
  169. if (d1.substr(0, 1) == "?" || d1.substr(0, 1) == "#" || d1.substr(0, 1) == "f" || d1.substr(0, 1) == "t" || !d1) {
  170. var len = Object.size(vis["data"]);
  171. $("#toppane").append("<ehv class='ehv-controls'>Galleries visited: " + len + " (<a href='javascript:;' class='ehv-import'>Import</a> / <a href='javascript:;' class='ehv-export'>Export</a> / <a href='javascript:;' class='ehv-css'>CSS</a>)</ehv>");
  172.  
  173. $(".ehv-export").click(function () {
  174. var e = "";
  175. for (var d in vis["data"]) {
  176. e += d + ":" + vis["data"][d] + ";";
  177. }
  178. prompt("E-H Visited:\nYour data has been exported.", e);
  179. });
  180.  
  181.  
  182. $(".ehv-import").click(function () {
  183. var c = prompt("E-H Visited:\nPaste here to import, and overwrite current data.");
  184. if (c) {
  185. var d = JSON.parse('{"data":{}}');
  186. var sp = c.split(";");
  187. for (var k in sp) {
  188. var s = sp[k].split(":");
  189. d["data"][s[0]] = parseInt(s[1]);
  190. }
  191.  
  192. alert("Imported " + Object.size(d["data"]) + " entries.");
  193. localStorage.setItem(storageName, JSON.stringify(d))
  194. location.reload();
  195.  
  196. }
  197. });
  198.  
  199. $(".ehv-css").click(function () {
  200. var c = prompt("E-H Visited:\nThis CSS is applied to visited galleries.\n('initial' to reset, or 'none' for no styling)", css);
  201. if (c) {
  202. GM_setValue("css", c);
  203. location.reload();
  204. }
  205. });
  206.  
  207. ehvHide();
  208. }