Anilist: Hide Uncommented Activity

Hides uncommented/unliked activity on the Anilist "Social" tab

当前为 2023-09-14 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Anilist: Hide Uncommented Activity
  3. // @namespace https://github.com/SeyTi01/
  4. // @version 1.1
  5. // @description Hides uncommented/unliked activity on the Anilist "Social" tab
  6. // @author SeyTi01
  7. // @match https://anilist.co/*/social
  8. // @grant none
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12. (function () {
  13. 'use strict';
  14.  
  15. const config = {
  16. removeUncommented: true, // Remove activities with no comments
  17. removeUnliked: false, // Remove activities with no likes
  18. targetLoadCount: 2 // Minimum number of activities to show per click on the "Load More"-button
  19. };
  20.  
  21. const SELECTORS = {
  22. activity: 'activity-entry',
  23. button: 'load-more',
  24. replies: 'div.action.replies',
  25. likes: 'div.action.likes'
  26. };
  27.  
  28. const observer = new MutationObserver(observeMutations);
  29. let currentLoadCount = 0;
  30. let userPressedButton = true;
  31. let loadMoreButton;
  32.  
  33. observer.observe(document.body, {childList: true, subtree: true});
  34.  
  35. function removeEntry(element) {
  36. let removed = false;
  37. if (element instanceof HTMLElement && element.classList.contains(SELECTORS.activity)) {
  38. const repliesDiv = element.querySelector(SELECTORS.replies);
  39. const likesDiv = element.querySelector(SELECTORS.likes);
  40.  
  41. if ((config.removeUncommented && !hasCount(repliesDiv)) || (config.removeUnliked && !hasCount(likesDiv))) {
  42. element.remove();
  43. removed = true;
  44. }
  45. }
  46.  
  47. return removed;
  48. }
  49.  
  50. function observeMutations(mutations) {
  51. for (const mutation of mutations) {
  52. if (mutation.addedNodes.length !== 0) {
  53. mutation.addedNodes.forEach(handleAddedNode);
  54. }
  55. }
  56.  
  57. if (currentLoadCount < config.targetLoadCount && userPressedButton) {
  58. clickLoadMoreButton();
  59. } else {
  60. resetState();
  61. }
  62. }
  63.  
  64. function handleAddedNode(node) {
  65. if (node instanceof HTMLElement) {
  66. if (node.classList.contains(SELECTORS.activity)) {
  67. if (!removeEntry(node)) {
  68. currentLoadCount++;
  69. }
  70.  
  71. } else if (node.classList.contains(SELECTORS.button)) {
  72. loadMoreButton = node;
  73. loadMoreButton.addEventListener('click', function() {
  74. userPressedButton = true;
  75. });
  76. }
  77. }
  78. }
  79.  
  80. function hasCount(element) {
  81. return element?.querySelector('span.count');
  82. }
  83.  
  84. function clickLoadMoreButton() {
  85. if (loadMoreButton) {
  86. loadMoreButton.click();
  87. loadMoreButton = null;
  88. }
  89. }
  90.  
  91. function resetState() {
  92. currentLoadCount = 0;
  93. userPressedButton = false;
  94. }
  95. })();