VK Verified Posts Only

Hides posts from unverified users and groups on VK.com

  1. // ==UserScript==
  2. // @name VK Verified Posts Only
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @description Hides posts from unverified users and groups on VK.com
  6. // @author You (adapted by Bard)
  7. // @match https://vk.com/*
  8. // @license MIT
  9. // @grant none
  10. // @run-at document-end // Important: Run after the initial page load
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. function isVerified(post) {
  17. // Check for the verification badge. The selectors might need adjustment
  18. // if VK changes its HTML structure. We check for two common locations.
  19. return (
  20. post.querySelector('.PostHeaderTitle__verified') !== null ||
  21. post.querySelector('.PostHeaderTitle__author .PostHeaderTitle__verifiedByOtherServicesIcon') !== null
  22. );
  23. }
  24.  
  25. function filterPosts() {
  26. const posts = document.querySelectorAll('._post'); // Select all post elements
  27.  
  28. for (const post of posts) {
  29. if (!isVerified(post)) {
  30. post.style.display = 'none'; // Hide unverified posts
  31. } else {
  32. post.style.display = ''; //Show verified posts
  33. }
  34. }
  35. }
  36.  
  37. // Initial filtering, but with a delay to allow for dynamic content.
  38. // We use requestAnimationFrame twice for better timing.
  39. requestAnimationFrame(() => {
  40. requestAnimationFrame(filterPosts);
  41. });
  42.  
  43.  
  44. // Set up the MutationObserver to watch for new posts being added.
  45. const observer = new MutationObserver(() => {
  46. // Debounce the filtering to avoid excessive calls. This is VERY IMPORTANT
  47. // for performance on a site like VK that loads content dynamically.
  48. clearTimeout(filterTimer);
  49. filterTimer = setTimeout(filterPosts, 200); // 200ms delay
  50.  
  51. });
  52.  
  53.  
  54. let filterTimer; // Store the timer ID for debouncing.
  55. // Start observing the document body for changes. We observe the body
  56. // because new posts can be added in various places within the DOM.
  57. observer.observe(document.body, {
  58. childList: true, // Watch for added or removed nodes
  59. subtree: true // Watch all descendant nodes, not just direct children
  60. });
  61.  
  62.  
  63. // --- Event Listener for "Show More" Button ---
  64.  
  65. // We need to find the button *after* a short delay because it might not
  66. // exist immediately when the script runs.
  67. function setupShowMoreListener() {
  68. const showMoreButton = document.getElementById('ui_search_load_more') || document.querySelector('.show_more');
  69. if (showMoreButton) {
  70. showMoreButton.addEventListener('click', () => {
  71. //Debounce to wait for the new posts.
  72. clearTimeout(filterTimer);
  73. filterTimer = setTimeout(filterPosts, 500); // 500ms delay
  74. });
  75. }
  76. }
  77.  
  78.  
  79. // Observe for changes and check every 3sec to not miss it if observer dont work
  80. setInterval(() => {
  81. setupShowMoreListener();
  82. }, 3000);
  83.  
  84. // Initial setup for show more button
  85. setupShowMoreListener();
  86.  
  87.  
  88. // Observe for changes in search type, and re-filter.
  89. const searchTabs = document.querySelector('.ui_filters_block, .ui_search_filters_row, .ui_search_sort');
  90. if (searchTabs) {
  91. searchTabs.addEventListener('click', () => {
  92. clearTimeout(filterTimer);
  93. filterTimer = setTimeout(filterPosts, 500); // Delay after click
  94. });
  95. }
  96.  
  97. })();