Chat User Blocker for Collaborate

Blocks messages from specific users on Collaborate chat panels

  1. // ==UserScript==
  2. // @name Chat User Blocker for Collaborate
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.3.1
  5. // @description Blocks messages from specific users on Collaborate chat panels
  6. // @author Lejafurigon
  7. // @match https://au.bbcollab.com/*
  8. // @grant none
  9. // @license MIT
  10. // @run-at document-end
  11. // ==/UserScript==
  12. (function() {
  13. 'use strict';
  14.  
  15. // List of usernames to block
  16. const BLOCKED_USERS = [
  17. "INSERT USER HERE",
  18. ];
  19.  
  20. // Key for storing blocked message IDs in storage
  21. const STORAGE_KEY = 'bb_chat_blocker_removed_ids';
  22.  
  23. // Clear any existing stored IDs to prevent incorrect filtering
  24. // If the script is misbehaving, this ensures a clean start
  25. localStorage.removeItem(STORAGE_KEY);
  26.  
  27. // Process an individual message
  28. function processMessage(item) {
  29. let nameElement = item.querySelector('.participant-name');
  30. if (!nameElement) return;
  31.  
  32. const username = nameElement.textContent.trim();
  33.  
  34. // ONLY remove messages from users in the BLOCKED_USERS list
  35. // No stored IDs to avoid false positives
  36. if (BLOCKED_USERS.includes(username)) {
  37. item.remove();
  38. console.log(`Blocked message from: ${username}`);
  39. }
  40. }
  41.  
  42. // Process all messages in the container
  43. function processAllMessages() {
  44. document.querySelectorAll('.chat-history__activity-item').forEach(item => {
  45. processMessage(item);
  46. });
  47. }
  48.  
  49. // Set up the mutation observer to watch for new messages and DOM changes
  50. function setupObserver() {
  51. // Watch for changes to the chat history list
  52. const chatHistoryContainer = document.getElementById('chat-channel-history');
  53. if (chatHistoryContainer) {
  54. const observer = new MutationObserver((mutations) => {
  55. // Check each added node to see if it's a message that should be blocked
  56. mutations.forEach(mutation => {
  57. if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
  58. mutation.addedNodes.forEach(node => {
  59. // Only process element nodes that are message items
  60. if (node.nodeType === 1 && node.classList &&
  61. node.classList.contains('chat-history__activity-item')) {
  62. processMessage(node);
  63. }
  64. });
  65. }
  66. });
  67. });
  68.  
  69. observer.observe(chatHistoryContainer, { childList: true, subtree: true });
  70. console.log("MutationObserver started for chat history");
  71. }
  72.  
  73. // Also watch for the entire panel being added/removed
  74. const contentObserver = new MutationObserver((mutations) => {
  75. mutations.forEach(mutation => {
  76. if (mutation.type === 'childList') {
  77. // If panel section is added to DOM
  78. if (document.querySelector('.panel-content') &&
  79. document.getElementById('chat-channel-history')) {
  80. console.log("Chat panel detected - processing messages");
  81. processAllMessages();
  82. }
  83. }
  84. });
  85. });
  86.  
  87. // Observe the body for changes, to catch when the panel is added/removed
  88. contentObserver.observe(document.body, { childList: true, subtree: true });
  89. console.log("Content observer started for panel changes");
  90. }
  91.  
  92. // Initialize the blocker functionality
  93. function initializeBlocker() {
  94. // Initial processing of existing messages
  95. if (document.getElementById('chat-channel-history')) {
  96. processAllMessages();
  97. setupObserver();
  98. console.log("Chat blocker initialized");
  99. } else {
  100. // If chat container isn't found yet, wait and retry
  101. setTimeout(initializeBlocker, 1000);
  102. console.log("Waiting for chat panel to load...");
  103. }
  104.  
  105. // Set up event listeners for page visibility/focus changes
  106. document.addEventListener('visibilitychange', () => {
  107. if (!document.hidden && document.getElementById('chat-channel-history')) {
  108. console.log("Page visibility changed, reprocessing messages");
  109. processAllMessages();
  110. }
  111. });
  112.  
  113. window.addEventListener('focus', () => {
  114. if (document.getElementById('chat-channel-history')) {
  115. console.log("Window focus event, reprocessing messages");
  116. processAllMessages();
  117. }
  118. });
  119. }
  120.  
  121. // Create a persistent checker that runs periodically
  122. function setupPeriodicChecker() {
  123. setInterval(() => {
  124. if (document.getElementById('chat-channel-history')) {
  125. processAllMessages();
  126. }
  127. }, 3000);
  128. }
  129.  
  130. // Start the process
  131. initializeBlocker();
  132. setupPeriodicChecker();
  133.  
  134. // Add a special event handler for Angular-based applications
  135. window.addEventListener('hashchange', () => {
  136. setTimeout(() => {
  137. if (document.getElementById('chat-channel-history')) {
  138. console.log("Hash change detected, reprocessing messages");
  139. processAllMessages();
  140. }
  141. }, 1000);
  142. });
  143. })();