GGBases | Thumbnails

Add images as thumbnails to the row items (on the end)

  1. // ==UserScript==
  2. // @name GGBases | Thumbnails
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0.2
  5. // @description Add images as thumbnails to the row items (on the end)
  6. // @author extra.lewd
  7. // @match https://www.ggbases.com/*
  8. // @match https://ggbases.dlgal.com/*
  9. // @exclude https://www.ggbases.com/view.so*
  10. // @exclude https://ggbases.dlgal.com/view.so*
  11. // @icon https://www.ggbases.com/favicon.ico
  12. // @run-at document-end
  13. // @license CC BY-NC-ND 4.0
  14. // @license-url https://creativecommons.org/licenses/by-nc-nd/4.0/
  15. // @homepage https://discord.gg/TcWrM6pXWD
  16. // @homepageURL https://discord.gg/TcWrM6pXWD
  17. // @website https://discord.gg/TcWrM6pXWD
  18. // @source https://discord.gg/TcWrM6pXWD
  19. // @compatible firefox
  20. // @compatible chrome
  21. // @compatible opera
  22. // @compatible safari
  23. // @compatible edge
  24. // @grant GM.getValue
  25. // @grant GM.setValue
  26. // @grant GM.registerMenuCommand
  27. // ==/UserScript==
  28. (function () {
  29. 'use strict';
  30. const observer = new MutationObserver(boostrap);
  31. observer.observe(document.querySelector("body"), {
  32. childList: true,
  33. subtree: true,
  34. });
  35. async function boostrap() {
  36. const elements = document.querySelectorAll("a[name='title']:not(.gay)");
  37. const [width, height] = await Promise.all([GM.getValue("img.width", 600), GM.getValue("img.height", 450)]);
  38. elements.forEach(e => {
  39. e.classList.add("gay"); // skip from adding img again
  40. const img = document.createElement("img");
  41. const src = parseSource(e.getAttribute("c"));
  42. if (!src)
  43. return;
  44. img.src = src;
  45. img.width = width;
  46. img.height = height;
  47. // todo: try use fragmentDocument somehow instead?
  48. // probably it has low performance due re-render on each append...
  49. e.parentElement.parentElement.append(img);
  50. });
  51. }
  52. // stealed from ggbases.com
  53. const r1 = new RegExp("^http"), r2 = new RegExp("^//");
  54. // init
  55. boostrap();
  56. registerCommands();
  57. function parseSource(src) {
  58. if (!src || src === "" || src === " ")
  59. return;
  60. if (/^d[0-9]{6,8}$/.test(src)) {
  61. // @ts-expect-error optional argument
  62. src = gendlcover(src.substr(1, src.length));
  63. }
  64. else if (/^RJ[0-9]{6,8}$/.test(src)) {
  65. // @ts-expect-error optional argument
  66. src = gendlcover(src.substr(2, src.length));
  67. }
  68. else if (/^v[0-9]{6,8}$/.test(src)) {
  69. src = gendlcover(src.substr(1, src.length), 1);
  70. }
  71. else if (/^VJ[0-9]{6,8}$/.test(src)) {
  72. src = gendlcover(src.substr(2, src.length), 1);
  73. }
  74. else if (/^g[0-9]{6,7}$/.test(src)) {
  75. src = gengccover(src.substr(1, src.length));
  76. }
  77. else if (/^gc[0-9]{6,7}$/.test(src)) {
  78. src = gengccover(src.substr(2, src.length));
  79. }
  80. else if (!r1.test(src) && !r2.test(src)) {
  81. src = coverurl(src);
  82. }
  83. return src;
  84. }
  85. // stealed from ggbases.com
  86. function gendlcover(did, type) {
  87. let pre0 = null, dpre0 = null, npre = null;
  88. if (did.indexOf('0') == 0 && did.length == 8)
  89. npre = '0';
  90. did = parseInt(did);
  91. let rid = Math.ceil(did / 1000) * 1000;
  92. if (did < 10) {
  93. pre0 = "00000";
  94. }
  95. else if (did < 100) {
  96. pre0 = "0000";
  97. }
  98. else if (did < 1000) {
  99. pre0 = "000";
  100. }
  101. else if (did < 10000) {
  102. pre0 = "00";
  103. }
  104. else if (did < 100000) {
  105. pre0 = "0";
  106. }
  107. if (rid < 10000) {
  108. dpre0 = "00";
  109. }
  110. else if (rid < 100000) {
  111. dpre0 = "0";
  112. }
  113. if (pre0) {
  114. did = pre0 + did;
  115. }
  116. if (dpre0) {
  117. rid = dpre0 + rid;
  118. }
  119. if (npre) {
  120. did = npre + did;
  121. rid = npre + rid;
  122. }
  123. let usecoverproxy = false;
  124. if (typeof Storage !== "undefined") {
  125. // @ts-expect-error Developer (I mean myself) is 🤡. Using already loaded on website lib of dayjs
  126. usecoverproxy = localStorage.getItem("usecoverproxy" + dayjs().format("YYYY-MM-DD"));
  127. }
  128. return (usecoverproxy ? "//cover.ydgal.com/_200_cover/".replace("/_200_cover/", "") : "//img.dlsite.jp") + "/modpub/images2/work/" + (!type ? "doujin/RJ" : "professional/VJ") + rid + "/" + (!type ? "RJ" : "VJ") + did + "_img_main.jpg";
  129. }
  130. // stealed from ggbases.com
  131. function gengccover(did) {
  132. return "//cover.ydgal.com/_200_cover/".replace("/_200_cover/", "/_300_cover/") + "/getchu/gc" + did + ".jpg";
  133. //return "//cover.ydgal.com/_200_cover/".replace("/_200_cover/", "") + "/brandnew/" + did + "/c" + did + "package_s.jpg";
  134. }
  135. // stealed from ggbases.com
  136. function coverurl(tid) {
  137. const num = tid.split("_")[0];
  138. const coverUrl = "//cover.ydgal.com/_200_cover/";
  139. if (parseInt(num) > 1360000) {
  140. return coverUrl + "new/" + tid;
  141. }
  142. else {
  143. return coverUrl + "old/" + tid;
  144. }
  145. }
  146. function registerCommands() {
  147. GM.registerMenuCommand("Set image width", () => {
  148. const value = parseInt(prompt("Input image width", "600"));
  149. if (!isNaN(value) && value > 0) {
  150. GM.setValue("img.width", value);
  151. alert("Success! Reload page to apply changes");
  152. }
  153. });
  154. GM.registerMenuCommand("Set image height", () => {
  155. const value = parseInt(prompt("Input image height", "450"));
  156. if (!isNaN(value) && value > 0) {
  157. GM.setValue("img.height", value);
  158. alert("Success! Reload page to apply changes");
  159. }
  160. });
  161. }
  162. })();