Guest User

Untitled

a guest
Mar 1st, 2025
23
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.64 KB | None | 0 0
  1. // ==UserScript==
  2. // @name filter v3
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.4.3
  5. // @description
  6. // @author Anonymous
  7. // @match https://boards.4chan.org/vg*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function () {
  12. 'use strict';
  13.  
  14. if (!/^bag\/|\/bag\/|Blue Archive|BIue Archive/.test(
  15. document?.querySelector('.postInfo.desktop .subject')?.textContent?.trim() ?? '')) {
  16. return;
  17. }
  18.  
  19. let filterActive = true;
  20. let timerElement = null;
  21. let timerInterval = null;
  22. let timerEndTime = null;
  23.  
  24. const style = document.createElement('style');
  25. style.textContent = `
  26. .fileThumb img.filtered-image {
  27. clip-path: polygon(0% 0%, 100% 0%, 100% 25%, 0% 25%);
  28. width: 40px !important;
  29. height: 40px !important;
  30. object-fit: cover;
  31. object-position: center top;
  32. transition: all 0.2s ease;
  33. }
  34.  
  35. .fileThumb:hover img.filtered-image {
  36. clip-path: none;
  37. width: auto !important;
  38. height: auto !important;
  39. object-fit: initial;
  40. z-index: 100;
  41. }
  42.  
  43. .deleted-post {
  44. display: none;
  45. }
  46. `;
  47. document.head.appendChild(style);
  48.  
  49. function createTimerDisplay() {
  50. timerElement = document.createElement('div');
  51. timerElement.style.position = 'fixed';
  52. timerElement.style.top = '10px';
  53. timerElement.style.right = '10px';
  54. timerElement.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
  55. timerElement.style.color = 'white';
  56. timerElement.style.padding = '5px 10px';
  57. timerElement.style.borderRadius = '5px';
  58. timerElement.style.zIndex = '9999';
  59. timerElement.style.fontFamily = 'monospace';
  60. timerElement.style.fontSize = '14px';
  61. timerElement.style.cursor = 'pointer';
  62. timerElement.title = 'Click to restart filter timer';
  63.  
  64. timerElement.addEventListener('click', startFilterTimer);
  65.  
  66. document.body.appendChild(timerElement);
  67. }
  68.  
  69. function startFilterTimer() {
  70. if (timerInterval) {
  71. clearInterval(timerInterval);
  72. }
  73.  
  74. filterActive = true;
  75.  
  76. applyPartialImageFiltering();
  77.  
  78. timerEndTime = Date.now() + (15 * 60 * 1000);
  79.  
  80. updateTimerDisplay();
  81.  
  82. timerInterval = setInterval(updateTimerDisplay, 1000);
  83. }
  84.  
  85. function updateTimerDisplay() {
  86. if (!timerElement) return;
  87.  
  88. const currentTime = Date.now();
  89. const timeRemaining = timerEndTime - currentTime;
  90.  
  91. if (timeRemaining <= 0) {
  92. timerElement.textContent = "Filter Off";
  93. timerElement.style.backgroundColor = 'rgba(255, 0, 0, 0.7)';
  94. clearInterval(timerInterval);
  95.  
  96. filterActive = false;
  97.  
  98. removeAllFilters();
  99. } else {
  100. const minutes = Math.floor(timeRemaining / 60000);
  101. const seconds = Math.floor((timeRemaining % 60000) / 1000);
  102.  
  103. timerElement.textContent = `Filter: ${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
  104. timerElement.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
  105. }
  106. }
  107.  
  108. function removeAllFilters() {
  109. const filteredImages = document.querySelectorAll('.filtered-image');
  110. filteredImages.forEach(img => {
  111. img.classList.remove('filtered-image');
  112. });
  113. }
  114.  
  115. function applyPartialImageFiltering() {
  116. if (!filterActive) return;
  117.  
  118. const posts = document.querySelectorAll('.postContainer');
  119. posts.forEach((post) => {
  120. const fileText = post.querySelector('.fileText-original, .fileText');
  121. if (!fileText) return;
  122.  
  123. const link = fileText.querySelector('a');
  124. if (!link) return;
  125.  
  126. const filename = link.textContent.trim();
  127.  
  128. const isPng = /.png$/i.test(filename);
  129. const isJpg = /.jpg$/i.test(filename);
  130.  
  131. if (isPng || isJpg) {
  132. } else {
  133. const fileTypeRegex = /.(gif|mp4|webm)$/i;
  134. if (fileTypeRegex.test(filename)) return;
  135. }
  136.  
  137. const img = post.querySelector('.fileThumb img');
  138. if (img && !img.classList.contains('filtered-image')) {
  139. img.classList.add('filtered-image');
  140.  
  141. if (!img.dataset.originalWidth) {
  142. img.dataset.originalWidth = img.style.width || img.getAttribute('width') || '';
  143. img.dataset.originalHeight = img.style.height || img.getAttribute('height') || '';
  144. }
  145.  
  146. img.dataset.filtered = 'true';
  147. }
  148. });
  149. }
  150.  
  151. function patchExtensionCompatibility() {
  152. setTimeout(() => {
  153. if (window.ImageExpansion) {
  154. const originalExpand = window.ImageExpansion.expand;
  155. window.ImageExpansion.expand = function(e) {
  156. const img = e.target.nodeName === 'IMG' ? e.target : e.target.querySelector('img');
  157. if (img && img.dataset.filtered === 'true') {
  158. img.classList.remove('filtered-image');
  159. }
  160. return originalExpand.apply(this, arguments);
  161. };
  162. }
  163. }, 1000);
  164. }
  165.  
  166. const observer = new MutationObserver(() => {
  167. applyPartialImageFiltering();
  168. });
  169. observer.observe(document.body, { childList: true, subtree: true });
  170.  
  171. createTimerDisplay();
  172.  
  173. startFilterTimer();
  174. patchExtensionCompatibility();
  175. })();
Add Comment
Please, Sign In to add comment