Sleazy Fork is available in English.

Filter Videos

6/21/2023, 11:18:54 PM

  1. // ==UserScript==
  2. // @name Filter Videos
  3. // @namespace Violentmonkey Scripts
  4. // @match https://*.coomer.party/*/user/*
  5. // @match https://*.kemono.party/*/user/*
  6. // @match https://*.coomer.su/*/user/*
  7. // @match https://*.kemono.su/*/user/*
  8. // @grant GM_getValue
  9. // @grant GM_setValue
  10. // @version 2.03
  11. // @author -
  12. // @description 6/21/2023, 11:18:54 PM
  13. // @license MIT
  14. // ==/UserScript==
  15.  
  16. async function querySelectorAsync(element, selector) {
  17. return await new Promise(resolve => {
  18. let elm = element.querySelector(selector);
  19. if(elm) return resolve(elm);
  20.  
  21. const observer = new MutationObserver(_ => {
  22. elm = element.querySelector(selector);
  23. if(elm) {
  24. resolve(elm);
  25. observer.disconnect();
  26. }
  27. })
  28.  
  29. observer.observe(document.body, {
  30. childList: true,
  31. subtree: true
  32. })
  33. })
  34. }
  35.  
  36. async function hasVideo(postUrl) {
  37. // Check if the result has been cached, return cache if yes
  38. let cache = await GM_getValue(postUrl);
  39. if(cache !== undefined) return cache;
  40.  
  41. return new Promise(resolve => {
  42. let request = new XMLHttpRequest();
  43. request.open("GET", postUrl, true);
  44. request.send(null);
  45.  
  46. request.onreadystatechange = function() {
  47. if(request.readyState === 4) {
  48. let elm = document.createElement("html");
  49. elm.innerHTML = request.responseText;
  50.  
  51. // If we can find a video tag, then post has video
  52. let res = elm.querySelector("video") !== null;
  53. resolve(res);
  54.  
  55. // Cache value of this post
  56. GM_setValue(postUrl, res);
  57. }
  58. }
  59. })
  60. }
  61.  
  62. async function filterVideos() {
  63. // For every post, check the html and if there is no video, then remove post
  64. let posts = [...(await querySelectorAsync(document, ".card-list__items")).children];
  65. for(let post of posts) {
  66. let postUrl = (await querySelectorAsync(post, "a")).href;
  67. hasVideo(postUrl).then(res => {
  68. if(!res) post.remove();
  69. })
  70. }
  71. }
  72.  
  73. (async() => {
  74. let filterBtn = document.createElement("button");
  75. filterBtn.textContent = "Filter Videos";
  76. filterBtn.onclick = function(e) {
  77. // Prevent redirection
  78. e.preventDefault();
  79. // Remove the button to prevent spam
  80. filterBtn.remove();
  81. // Filter videos
  82. filterVideos();
  83. }
  84.  
  85. let searchInputForm = await querySelectorAsync(document, "form");
  86. searchInputForm.appendChild(filterBtn);
  87. })()