Milkie Thumbnails

Hover torrent link to preview thumbnails

  1. // ==UserScript==
  2. // @name Milkie Thumbnails
  3. // @namespace dumpsterbaby.lol
  4. // @version 0.0.0
  5. // @description Hover torrent link to preview thumbnails
  6. // @author egore
  7. // @license MIT
  8. // @match https://milkie.cc/browse*
  9. // @icon https://milkie.cc/assets/icons/logo.svg
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. (function () {
  14.  
  15. function newElement(tagName, attributes, content) {
  16. var tag = document.createElement(tagName);
  17. for (var key in attributes || {}) {
  18. if (attributes[key] !== undefined && attributes[key] !== null) {
  19. tag.setAttribute(key, attributes[key]);
  20. }
  21. }
  22. tag.innerHTML = content || "";
  23. return tag;
  24. }
  25.  
  26. function findLinksByHref(urlFragment) {
  27. const links = Array.from(document.querySelectorAll('a')).filter(link => {
  28. return link.href.includes(urlFragment);
  29. });
  30. return links;
  31. }
  32.  
  33. function iterateNodeList(nodeList, callback) {
  34. if (!(nodeList instanceof NodeList)) {
  35. throw new TypeError("Invalid NodeList provided.");
  36. }
  37. if (typeof callback !== "function") {
  38. throw new TypeError("Callback must be a function.");
  39. }
  40. for (let i = 0; i < nodeList.length; i++) {
  41. if (callback(nodeList[i]) === false) {
  42. break; //Stop iteration if callback returns false
  43. }
  44. }
  45. }
  46.  
  47. function init() {
  48. const uls = document.querySelectorAll('.adult');
  49.  
  50. const btns = document.querySelectorAll('.mat-icon.notranslate.download.material-icons.mat-icon-no-color');
  51. btns.forEach(btn => { btn.style.display = 'none' });
  52.  
  53. if (interval) {
  54. clearInterval(interval);
  55. interval = undefined;
  56. window.setInterval(init, 5000);
  57. }
  58.  
  59. iterateNodeList(uls, (node) => {
  60. const context = node.__ngContext__[115]
  61.  
  62. const ln = findLinksByHref(`/browse/${context}`);
  63. const link = ln[0];
  64.  
  65. const previewContainer = newElement("div", {
  66. style: `
  67. position: absolute;
  68. `
  69. });
  70.  
  71. const previewContainer2 = newElement("div", {
  72. style: `
  73. position: absolute;
  74. `
  75. });
  76.  
  77. const previewContainer3 = newElement("div", {
  78. style: `
  79. position: absolute;
  80. `
  81. });
  82.  
  83. for (let i = 0; i < 2; i++) {
  84. const img = newElement("img", {
  85. src: `https://cdn.milkie.cc/t/${context}/o_${i}.jpg`,
  86. style: `
  87. display: none;
  88. position: absolute;
  89. left: ${0 + i * 452}px;
  90. top: 22px;
  91. max-width: 450px;
  92. `,
  93. loading: "lazy"
  94. });
  95. previewContainer.appendChild(img);
  96. link.parentNode.insertBefore(previewContainer, link.nextSibling);
  97.  
  98. link.addEventListener('mouseover', () => {
  99. img.style.display = "block";
  100. });
  101. link.addEventListener('mouseout', () => {
  102. img.style.display = "none";
  103. });
  104. }
  105.  
  106. for (let i = 2; i < 4; i++) {
  107. const img = newElement("img", {
  108. src: `https://cdn.milkie.cc/t/${context}/o_${i}.jpg`,
  109. style: `
  110. display: none;
  111. position: absolute;
  112. left: ${0 + (i - 2) * 452}px;
  113. top: 277px;
  114. max-width: 450px;
  115. `,
  116. loading: "lazy"
  117. });
  118. previewContainer2.appendChild(img);
  119. link.parentNode.insertBefore(previewContainer2, link.nextSibling);
  120.  
  121. link.addEventListener('mouseover', () => {
  122. img.style.display = "block";
  123. });
  124. link.addEventListener('mouseout', () => {
  125. img.style.display = "none";
  126. });
  127. }
  128.  
  129. for (let i = 4; i < 6; i++) {
  130. const img = newElement("img", {
  131. src: `https://cdn.milkie.cc/t/${context}/o_${i}.jpg`,
  132. style: `
  133. display: none;
  134. position: absolute;
  135. left: ${0 + (i - 4) * 452}px;
  136. top: 532px;
  137. max-width: 450px;
  138. `,
  139. loading: "lazy"
  140. });
  141. previewContainer3.appendChild(img);
  142. link.parentNode.insertBefore(previewContainer3, link.nextSibling);
  143.  
  144. link.addEventListener('mouseover', () => {
  145. img.style.display = "block";
  146. });
  147. link.addEventListener('mouseout', () => {
  148. img.style.display = "none";
  149. });
  150. }
  151.  
  152. });
  153. }
  154.  
  155. let interval = window.setInterval(init, 500);
  156.  
  157. })();